Skip to content

Commit

Permalink
Fixing phpstan issues, and adding more test cases
Browse files Browse the repository at this point in the history
Signed-off-by: Fawzi E. Abdulfattah <[email protected]>
  • Loading branch information
iifawzi committed Dec 6, 2021
1 parent 835a537 commit 75436a9
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 42 deletions.
17 changes: 12 additions & 5 deletions src/Statements/CreateStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,13 @@ public function build()
. Expression::build($this->like);
}

if ($this->with !== null) {
return 'CREATE '
. OptionsArray::build($this->options) . ' '
. Expression::build($this->name) . ' '
. $this->with->build();
}

$partition = '';

if (! empty($this->partitionBy)) {
Expand Down Expand Up @@ -477,9 +484,9 @@ public function build()
. $partition;
} elseif ($this->options->has('VIEW')) {
$builtStatement = '';
if ($this->select) {
if ($this->select !== null) {
$builtStatement = $this->select->build();
} elseif ($this->with) {
} elseif ($this->with !== null) {
$builtStatement = $this->with->build();
}

Expand Down Expand Up @@ -564,7 +571,7 @@ public function parse(Parser $parser, TokensList $list)
if (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'SELECT')) {
/* CREATE TABLE ... SELECT */
$this->select = new SelectStatement($parser, $list);
} elseif (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'WITH')) {
} elseif ($token->type === Token::TYPE_KEYWORD && ($token->keyword === 'WITH')) {
/* CREATE TABLE WITH */
$this->with = new WithStatement($parser, $list);
} elseif (
Expand All @@ -575,10 +582,10 @@ public function parse(Parser $parser, TokensList $list)
/* CREATE TABLE ... AS SELECT */
$list->idx = $nextidx;
$this->select = new SelectStatement($parser, $list);
} elseif ($list->tokens[$nextidx]->value === 'SELECT') {
} elseif ($list->tokens[$nextidx]->value === 'WITH') {
/* CREATE TABLE WITH */
$list->idx = $nextidx;
$this->select = new WithStatement($parser, $list);
$this->with = new WithStatement($parser, $list);
}
} elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'LIKE') {
/* CREATE TABLE `new_tbl` LIKE 'orig_tbl' */
Expand Down
10 changes: 9 additions & 1 deletion src/Statements/InsertStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ class InsertStatement extends Statement
*/
public $select;

/**
* If WITH CTE is present
* holds the WithStatement.
*
* @var WithStatement|null
*/
public $with;

/**
* If ON DUPLICATE KEY UPDATE clause is present
* holds the SetOperation.
Expand Down Expand Up @@ -211,7 +219,7 @@ public function parse(Parser $parser, TokensList $list)
} elseif ($token->keyword === 'SELECT') {
$this->select = new SelectStatement($parser, $list);
} elseif ($token->keyword === 'WITH') {
$this->select = new WithStatement($parser, $list);
$this->with = new WithStatement($parser, $list);
} else {
$parser->error('Unexpected keyword.', $token);
break;
Expand Down
35 changes: 23 additions & 12 deletions src/Statements/WithStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,14 @@ public function parse(Parser $parser, TokensList $list)
}

if ($state === 0) {
if ($token->type === Token::TYPE_NONE) {
$wither = $token->value;
$this->withers[$wither] = new WithKeyword($wither);
$state = 1;
} else {
if ($token->type !== Token::TYPE_NONE) {
$parser->error('The name of the CTE was expected.', $token);
break;
}

$wither = $token->value;
$this->withers[$wither] = new WithKeyword($wither);
$state = 1;
} elseif ($state === 1) {
if ($token->type === Token::TYPE_OPERATOR && $token->value === '(') {
$this->withers[$wither]->columns = Array2d::parse($parser, $list);
Expand All @@ -133,21 +134,29 @@ public function parse(Parser $parser, TokensList $list)

$state = 3;
} elseif ($state === 3) {
if ($token->value !== '(') {
$idxBeforeGetNext = $list->idx;

// We want to get the next non-comment and non-space token after $token
// therefore, the first getNext call will start with the current $idx which's $token,
// will return it and increase $idx by 1, which's not guaranteed to be non-comment
// and non-space, that's why we're calling getNext again.
$list->getNext();
$nextKeyword = $list->getNext();

if (! ($token->value === '(' && ($nextKeyword && $nextKeyword->value === 'SELECT'))) {
$parser->error('Subquery of the CTE was expected.', $token);
$list->idx = $idxBeforeGetNext;
break;
}

if ($token->value !== 'SELECT') {
$parser->error('Unexpected keyword', $token);
break;
}
// Restore the index
$list->idx = $idxBeforeGetNext;

++$list->idx;
$subList = $this->getSubTokenList($list);
if ($subList instanceof ParserException) {
$parser->errors[] = $subList;
continue;
break;
}

$subParser = new Parser($subList);
Expand All @@ -156,6 +165,8 @@ public function parse(Parser $parser, TokensList $list)
foreach ($subParser->errors as $error) {
$parser->errors[] = $error;
}

break;
}

$this->withers[$wither]->statement = $subParser;
Expand Down Expand Up @@ -229,7 +240,7 @@ public function parse(Parser $parser, TokensList $list)

// 5 is the only valid end state
if ($state !== 5) {
$parser->error('Unexpected end of WITH CTE.', $token);
$parser->error('Unexpected end of WITH CTE.', $list->tokens[$list->idx]);
}

--$list->idx;
Expand Down
14 changes: 14 additions & 0 deletions tests/Builder/CreateStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ public function testBuilderTable(): void
') ENGINE=InnoDB DEFAULT CHARSET=latin1';
$parser = new Parser($query);
$this->assertEquals($query, $parser->statements[0]->build());

/* Assertion 5 */
$parser = new Parser(
'CREATE table table_name WITH' .
' cte (col1) AS ( SELECT 1 UNION ALL SELECT 2 )' .
' SELECT col1 FROM cte'
);
$stmt = $parser->statements[0];

$this->assertEquals(
'CREATE TABLE table_name WITH' .
' cte(col1) AS (SELECT 1 UNION ALL SELECT 2)',
$stmt->build()
);
}

public function testBuilderPartitions(): void
Expand Down
10 changes: 6 additions & 4 deletions tests/Parser/WithStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
class WithStatementTest extends TestCase
{
/**
* @param mixed $test
*
* @dataProvider parseWith
*/
public function testParse($test): void
public function testParse(string $test): void
{
$this->runParserTest($test);
}

/**
* @return array<int,array<int, string>>
*/
public function parseWith(): array
{
return [
Expand All @@ -35,6 +36,7 @@ public function parseWith(): array
['parser/parseWithStatementErr3'],
['parser/parseWithStatementErr4'],
['parser/parseWithStatementErr5'],
['parser/parseWithStatementErr6'],
];
}

Expand Down Expand Up @@ -81,7 +83,7 @@ public function testWithHasErrors(): void
$this->assertCount(0, $lexerErrors);
$parser = new Parser($lexer->list);
$parserErrors = $this->getErrorsAsArray($parser);
$this->assertCount(2, $parserErrors);
$this->assertCount(4, $parserErrors);
}

public function testWithEmbedParenthesis(): void
Expand Down
3 changes: 2 additions & 1 deletion tests/data/parser/parseWithStatement.out
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,8 @@
},
"values": null,
"set": null,
"select": {
"select": null,
"with": {
"@type": "PhpMyAdmin\\SqlParser\\Statements\\WithStatement",
"OPTIONS": {
"RECURSIVE": 1
Expand Down
3 changes: 2 additions & 1 deletion tests/data/parser/parseWithStatement2.out
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,8 @@
},
"values": null,
"set": null,
"select": {
"select": null,
"with": {
"@type": "PhpMyAdmin\\SqlParser\\Statements\\WithStatement",
"OPTIONS": {
"RECURSIVE": 1
Expand Down
3 changes: 2 additions & 1 deletion tests/data/parser/parseWithStatementErr.out
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,8 @@
},
"values": null,
"set": null,
"select": {
"select": null,
"with": {
"@type": "PhpMyAdmin\\SqlParser\\Statements\\WithStatement",
"OPTIONS": {
"RECURSIVE": 1
Expand Down
2 changes: 1 addition & 1 deletion tests/data/parser/parseWithStatementErr3.out
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,7 @@
}
},
"first": 0,
"last": 30
"last": 29
}
],
"brackets": 0,
Expand Down
21 changes: 7 additions & 14 deletions tests/data/parser/parseWithStatementErr5.out
Original file line number Diff line number Diff line change
Expand Up @@ -862,14 +862,7 @@
2
]
},
"withers": {
"col1": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\WithKeyword",
"name": "col1",
"columns": [],
"statement": null
}
},
"withers": [],
"END_OPTIONS": [],
"options": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
Expand Down Expand Up @@ -898,10 +891,10 @@
}
},
"first": 0,
"last": 9
"last": 7
}
],
"brackets": 0,
"brackets": 1,
"strict": false,
"errors": []
},
Expand All @@ -916,16 +909,16 @@
0
],
[
"Unexpected token.",
"Unexpected end of WITH CTE.",
{
"@type": "@12"
"@type": "@10"
},
0
],
[
"Unexpected end of WITH CTE.",
"Unexpected beginning of statement.",
{
"@type": "@12"
"@type": "@11"
},
0
],
Expand Down
6 changes: 4 additions & 2 deletions tests/data/parser/parseWithStatementErr6.out
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,8 @@
},
"values": null,
"set": null,
"select": {
"select": null,
"with": {
"@type": "PhpMyAdmin\\SqlParser\\Statements\\WithStatement",
"OPTIONS": {
"RECURSIVE": 1
Expand Down Expand Up @@ -1173,6 +1174,7 @@
],
"set": null,
"select": null,
"with": null,
"onDuplicateSet": null,
"CLAUSES": [],
"END_OPTIONS": [],
Expand Down Expand Up @@ -1412,7 +1414,7 @@
"lexer": [],
"parser": [
[
"Unexpected keyword",
"Subquery of the CTE was expected.",
{
"@type": "@18"
},
Expand Down

0 comments on commit 75436a9

Please sign in to comment.