Skip to content

Commit e4afdef

Browse files
committed
Fix replace clause of select statement with FOR UPDATE
FOR UPDATE and LOCK IN SHARE MODE are not in the clauses array, replace _END_OPTIONS with these values so they are found. Signed-off-by: Maximilian Krög <maxi_kroeg@web.de>
1 parent 29f982a commit e4afdef

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/Statement.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use function array_flip;
1111
use function array_keys;
12+
use function array_push;
1213
use function count;
1314
use function in_array;
1415
use function stripos;
@@ -457,6 +458,28 @@ public function getClauses()
457458
return static::$CLAUSES;
458459
}
459460

461+
/**
462+
* Gets the clause order of this statement as an array
463+
* with clause as key and index as value.
464+
*
465+
* @return array<string, int>
466+
*/
467+
public function getClauseOrder(): array
468+
{
469+
$clauses = [];
470+
foreach (array_keys($this->getClauses()) as $key) {
471+
if ($key === '_END_OPTIONS') {
472+
if (static::$END_OPTIONS !== []) {
473+
array_push($clauses, ...array_keys(static::$END_OPTIONS));
474+
}
475+
} else {
476+
$clauses[] = $key;
477+
}
478+
}
479+
480+
return array_flip($clauses);
481+
}
482+
460483
/**
461484
* Builds the string representation of this statement.
462485
*

src/Utils/Query.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ public static function getClause($statement, $list, $clause, $type = 0, $skipFir
641641
/**
642642
* The clauses of this type of statement and their index.
643643
*/
644-
$clauses = array_flip(array_keys($statement->getClauses()));
644+
$clauses = $statement->getClauseOrder();
645645

646646
/**
647647
* Lexer used for lexing the clause.

tests/Utils/QueryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,16 @@ public function testReplaceClause(): void
600600
'ORDER BY city'
601601
)
602602
);
603+
604+
$parser = new Parser('SELECT * FROM `t` FOR UPDATE');
605+
$this->assertEquals(
606+
'SELECT * FROM `t` LIMIT 0, 25 FOR UPDATE',
607+
Query::replaceClause(
608+
$parser->statements[0],
609+
$parser->list,
610+
'LIMIT 0, 25'
611+
)
612+
);
603613
}
604614

605615
public function testReplaceClauseOnlyKeyword(): void

0 commit comments

Comments
 (0)