Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 11756e6

Browse files
committed
Add handling of index hints on join clauses too. Fixes #593 and #497.
1 parent b14fd66 commit 11756e6

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed

‎src/Components/JoinKeyword.php‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,29 @@ class JoinKeyword extends Component
7272
*/
7373
public $using;
7474

75+
/**
76+
* Index hints
77+
*
78+
* @var IndexHint[]
79+
*/
80+
public $indexHints = [];
81+
7582
/**
7683
* @see JoinKeyword::$JOINS
7784
*
78-
* @param string $type Join type
79-
* @param Expression $expr join expression
80-
* @param Condition[] $on join conditions
81-
* @param ArrayObj $using columns joined
85+
* @param string $type Join type
86+
* @param Expression $expr join expression
87+
* @param Condition[] $on join conditions
88+
* @param ArrayObj $using columns joined
89+
* @param IndexHint[] $indexHints index hints
8290
*/
83-
public function __construct($type = null, $expr = null, $on = null, $using = null)
91+
public function __construct($type = null, $expr = null, $on = null, $using = null, $indexHints = [])
8492
{
8593
$this->type = $type;
8694
$this->expr = $expr;
8795
$this->on = $on;
8896
$this->using = $using;
97+
$this->indexHints = $indexHints;
8998
}
9099

91100
/**
@@ -110,6 +119,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
110119
*
111120
* 1 -----------------------[ expr ]----------------------> 2
112121
*
122+
* 2 -------------------[ index_hints ]-------------------> 2
113123
* 2 ------------------------[ ON ]-----------------------> 3
114124
* 2 -----------------------[ USING ]---------------------> 4
115125
*
@@ -163,6 +173,12 @@ public static function parse(Parser $parser, TokensList $list, array $options =
163173
case 'USING':
164174
$state = 4;
165175
break;
176+
case 'USE':
177+
case 'IGNORE':
178+
case 'FORCE':
179+
// Adding index hint on the JOIN clause.
180+
$expr->indexHints = IndexHint::parse($parser, $list);
181+
break;
166182
default:
167183
if (empty(static::$JOINS[$token->keyword])) {
168184
/* Next clause is starting */
@@ -210,6 +226,7 @@ public static function build($component, array $options = [])
210226
$ret = [];
211227
foreach ($component as $c) {
212228
$ret[] = array_search($c->type, static::$JOINS) . '' . $c->expr
229+
. ($c->indexHints !== [] ? '' . IndexHint::build($c->indexHints) : '')
213230
. (! empty($c->on)
214231
? ' ON ' . Condition::build($c->on) : '')
215232
. (! empty($c->using)

‎tests/Builder/SelectStatementTest.php‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,65 @@ public function testBuilderSurroundedByParanthesisWithLimit(): void
353353
$stmt->build()
354354
);
355355
}
356+
357+
public function testBuilderSelectFromWithForceIndex(): void
358+
{
359+
$query = 'SELECT *'
360+
. ' FROM uno FORCE INDEX (id)';
361+
$parser = new Parser($query);
362+
$stmt = $parser->statements[0];
363+
364+
self::assertSame($query, $stmt->build());
365+
}
366+
367+
/**
368+
* Ensures issue #497 is fixed.
369+
*/
370+
public function testBuilderSelectFromJoinWithForceIndex(): void
371+
{
372+
$query = 'SELECT *'
373+
. ' FROM uno'
374+
. ' JOIN dos FORCE INDEX (two_id) ON dos.id = uno.id';
375+
$parser = new Parser($query);
376+
$stmt = $parser->statements[0];
377+
378+
self::assertSame($query, $stmt->build());
379+
}
380+
381+
/**
382+
* Ensures issue #593 is fixed.
383+
*/
384+
public function testBuilderSelectFromInnerJoinWithForceIndex(): void
385+
{
386+
$query = 'SELECT a.id, a.name, b.order_id, b.total'
387+
. ' FROM customers a'
388+
. ' INNER JOIN orders b FORCE INDEX (idx_customer_id)'
389+
. ' ON a.id = b.customer_id'
390+
. " WHERE a.status = 'active'";
391+
392+
$parser = new Parser($query);
393+
$stmt = $parser->statements[0];
394+
395+
$expectedQuery = 'SELECT a.id, a.name, b.order_id, b.total'
396+
. ' FROM customers AS `a`'
397+
. ' INNER JOIN orders AS `b` FORCE INDEX (idx_customer_id)'
398+
. ' ON a.id = b.customer_id'
399+
. " WHERE a.status = 'active'";
400+
401+
self::assertSame($expectedQuery, $stmt->build());
402+
}
403+
404+
public function testBuilderSelectAllFormsOfIndexHints(): void
405+
{
406+
$query = 'SELECT *'
407+
. ' FROM one USE INDEX (col1) IGNORE INDEX (col1, col2) FORCE INDEX (col1, col2, col3)'
408+
. ' INNER JOIN two USE INDEX (col3) IGNORE INDEX (col2, col3) FORCE INDEX (col1, col2, col3)'
409+
. ' ON one.col1 = two.col2'
410+
. ' WHERE 1 = 1';
411+
412+
$parser = new Parser($query);
413+
$stmt = $parser->statements[0];
414+
415+
self::assertSame($query, $stmt->build());
416+
}
356417
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /