Skip to content

Commit

Permalink
feat: Skip FORCE INDEX for JOIN
Browse files Browse the repository at this point in the history
  • Loading branch information
Javakky-pxv committed Jan 31, 2025
1 parent eab6311 commit 2c50cf2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/Parser/FromParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,26 @@ private function buildJoin(string $left_table, Token $token)
}
}

/*
* Unlike other clauses (e.g., FROM), the buildJoin advances the pointer to the specified keyword (e.g., FORCE).
* Therefore, the pointer needs to be adjusted.
* For instance, in "FROM a FORCE INDEX ...", processing for other clauses ends just before the identifier (a),
* but for the JOIN clause, the pointer advances to "FORCE".
* To address this issue, we adjusted the pointer before and after calling SQLParser::skipIndexHints(),
* and modified the code to advance the pointer to the closing parenthesis ')' if necessary.
*/
$this->pointer--;
$this->pointer = SQLParser::skipIndexHints($this->pointer, $this->tokens);
$this->pointer++;
if ($this->tokens[$this->pointer]->type === TokenType::SEPARATOR
&& $this->tokens[$this->pointer]->value === ")") {
$this->pointer++;
}
$next = $this->tokens[$this->pointer] ?? null;
if ($next === null) {
/** @psalm-suppress InvalidReturnStatement */
return $table;
}

if ($table['join_type'] === JoinType::NATURAL || $table['join_type'] === JoinType::CROSS) {
return $table;
Expand Down
21 changes: 21 additions & 0 deletions tests/EndToEndTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,27 @@ public function testLeftJoinWithCount()
);
}

public function testLeftJoinSkipIndex()
{
$pdo = self::getConnectionToFullDB(false);

$query = $pdo->prepare(
"SELECT `id`
FROM `video_game_characters` FORCE INDEX (`PRIMARY`)
LEFT JOIN `character_tags` FORCE INDEX (`PRIMARY`)
ON `character_tags`.`character_id` = `video_game_characters`.`id`
LIMIT 1"
);
$query->execute();

$this->assertSame(
[
['id' => 1]
],
$query->fetchAll(\PDO::FETCH_ASSOC)
);
}

public function testMaxValueAliasedToColumnName()
{
$pdo = self::getConnectionToFullDB(false);
Expand Down

0 comments on commit 2c50cf2

Please sign in to comment.