Skip to content

Commit

Permalink
Merge branch 'master' into 6.0.x
Browse files Browse the repository at this point in the history
Signed-off-by: William Desportes <williamdes@wdes.fr>
  • Loading branch information
williamdes committed Dec 13, 2022
2 parents e8120cb + a6da770 commit ff440a0
Show file tree
Hide file tree
Showing 280 changed files with 11,899 additions and 6,664 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -14,7 +14,8 @@
* Fixed differentiating between `ANALYZE` and `EXPLAIN` statements (#386)
* Added "NOT" to the select options (#374)
* Implement the `EXPLAIN` Parser (#389)
* Context: Updated contexts to contain `multipoint` and `multipolygon` data types. (#393)
* Context: Updated contexts to contain `multipoint` and `multipolygon` data types (#393)
* Support more keywords on `Expression` component (#399)

## [5.5.0] - 2021-12-08

Expand Down
37 changes: 29 additions & 8 deletions src/Components/Expression.php
Expand Up @@ -13,6 +13,7 @@

use function implode;
use function is_array;
use function rtrim;
use function strlen;
use function trim;

Expand All @@ -29,19 +30,22 @@ final class Expression implements Component
* @var array<string, int>
*/
private static $allowedKeywords = [
'AND' => 1,
'AS' => 1,
'DUAL' => 1,
'NULL' => 1,
'REGEXP' => 1,
'BETWEEN' => 1,
'CASE' => 1,
'DUAL' => 1,
'DIV' => 1,
'AND' => 1,
'IS' => 1,
'MOD' => 1,
'NOT' => 1,
'NOT NULL' => 1,
'NULL' => 1,
'OR' => 1,
'OVER' => 1,
'REGEXP' => 1,
'RLIKE' => 1,
'XOR' => 1,
'NOT' => 1,
'MOD' => 1,

'OVER' => 2,
];

/**
Expand Down Expand Up @@ -369,6 +373,23 @@ public static function parse(Parser $parser, TokensList $list, array $options =

$ret->alias = $prev[1]->value;
} else {
$currIdx = $list->idx;
--$list->idx;
$beforeToken = $list->getPrevious();
$list->idx = $currIdx;
// columns names tokens are of type NONE, or SYMBOL (`col`), and the columns options
// would start with a token of type KEYWORD, in that case, we want to have a space
// between the tokens.
if (
$ret->expr !== null &&
$beforeToken &&
($beforeToken->type === Token::TYPE_NONE ||
$beforeToken->type === Token::TYPE_SYMBOL || $beforeToken->type === Token::TYPE_STRING) &&
$token->type === Token::TYPE_KEYWORD
) {
$ret->expr = rtrim($ret->expr, ' ') . ' ';
}

$ret->expr .= $token->token;
}
} elseif (! $isExpr) {
Expand Down
2 changes: 1 addition & 1 deletion src/Utils/Formatter.php
Expand Up @@ -92,7 +92,7 @@ public function __construct(array $options = [])
*
* @return array<string, bool|string|array<int, array<string, int|string>>>
*/
private function getMergedOptions(array $options)
protected function getMergedOptions(array $options)
{
$options = array_merge(
$this->getDefaultOptions(),
Expand Down
53 changes: 53 additions & 0 deletions tests/Builder/SelectStatementTest.php
Expand Up @@ -22,6 +22,31 @@ public function testBuilder(): void
. 'ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)',
$stmt->build()
);

$parser = new Parser('SELECT NULL IS NULL');
$stmt = $parser->statements[0];

$this->assertEquals('SELECT NULL IS NULL', $stmt->build());

$parser = new Parser('SELECT NOT 1');
$stmt = $parser->statements[0];

$this->assertEquals('SELECT NOT 1', $stmt->build());

$parser = new Parser('SELECT 1 BETWEEN 0 AND 2');
$stmt = $parser->statements[0];

$this->assertEquals('SELECT 1 BETWEEN 0 AND 2', $stmt->build());

$parser = new Parser("SELECT 'a' NOT REGEXP '^[a-d]'");
$stmt = $parser->statements[0];

$this->assertEquals("SELECT 'a' NOT REGEXP '^[a-d]'", $stmt->build());

$parser = new Parser("SELECT 'a' RLIKE 'a'");
$stmt = $parser->statements[0];

$this->assertEquals("SELECT 'a' RLIKE 'a'", $stmt->build());
}

public function testBuilderUnion(): void
Expand All @@ -35,6 +60,34 @@ public function testBuilderUnion(): void
);
}

public function testBuilderWithIsNull(): void
{
$parser = new Parser('SELECT `test3`.`t1` is not null AS `is_not_null` FROM `test3` ;');
$stmt = $parser->statements[0];

$this->assertEquals('SELECT `test3`.`t1` is not null AS `is_not_null` FROM `test3`', $stmt->build());

$parser = new Parser('SELECT test3.t1 is null AS `col1` FROM test3');
$stmt = $parser->statements[0];

$this->assertEquals('SELECT test3.t1 is null AS `col1` FROM test3', $stmt->build());
}

public function testBuilderOrderByNull(): void
{
$query = 'SELECT * FROM some_table ORDER BY some_col IS NULL DESC;';
$parser = new Parser($query);
$stmt = $parser->statements[0];

$this->assertEquals('SELECT * FROM some_table ORDER BY some_col IS NULL DESC', $stmt->build());

$query = 'SELECT * FROM some_table ORDER BY some_col IS NOT NULL;';
$parser = new Parser($query);
$stmt = $parser->statements[0];

$this->assertEquals('SELECT * FROM some_table ORDER BY some_col IS NOT NULL ASC', $stmt->build());
}

public function testBuilderAlias(): void
{
$parser = new Parser(
Expand Down
1 change: 1 addition & 0 deletions tests/Parser/CreateStatementTest.php
Expand Up @@ -60,6 +60,7 @@ public function createProvider(): array
['parser/parseCreateView2'],
['parser/parseCreateView3'],
['parser/parseCreateView4'],
['parser/parseCreateView5'],
['parser/parseCreateViewMultiple'],
['parser/parseCreateViewWithoutQuotes'],
['parser/parseCreateViewWithQuotes'],
Expand Down
1 change: 1 addition & 0 deletions tests/Parser/SelectStatementTest.php
Expand Up @@ -89,6 +89,7 @@ public function selectProvider(): array
['parser/parseSelectWhere'],
['parser/parseSelectIndexHint1'],
['parser/parseSelectIndexHint2'],
['parser/parseSelectOrderByIsNull'],
['parser/parseSelectIndexHintErr1'],
['parser/parseSelectIndexHintErr2'],
['parser/parseSelectIndexHintErr3'],
Expand Down
40 changes: 24 additions & 16 deletions tests/data/bugs/gh14.out
Expand Up @@ -599,18 +599,22 @@
"table": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
"allowedKeywords": {
"AND": 1,
"AS": 1,
"DUAL": 1,
"NULL": 1,
"REGEXP": 1,
"BETWEEN": 1,
"CASE": 1,
"DUAL": 1,
"DIV": 1,
"AND": 1,
"OR": 1,
"XOR": 1,
"NOT": 1,
"IS": 1,
"MOD": 1,
"OVER": 2
"NOT": 1,
"NOT NULL": 1,
"NULL": 1,
"OR": 1,
"OVER": 1,
"REGEXP": 1,
"RLIKE": 1,
"XOR": 1
},
"database": null,
"table": "actor",
Expand Down Expand Up @@ -762,18 +766,22 @@
"field": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
"allowedKeywords": {
"AND": 1,
"AS": 1,
"DUAL": 1,
"NULL": 1,
"REGEXP": 1,
"BETWEEN": 1,
"CASE": 1,
"DUAL": 1,
"DIV": 1,
"AND": 1,
"OR": 1,
"XOR": 1,
"NOT": 1,
"IS": 1,
"MOD": 1,
"OVER": 2
"NOT": 1,
"NOT NULL": 1,
"NULL": 1,
"OR": 1,
"OVER": 1,
"REGEXP": 1,
"RLIKE": 1,
"XOR": 1
},
"database": null,
"table": null,
Expand Down

0 comments on commit ff440a0

Please sign in to comment.