Skip to content

Commit

Permalink
Fix #434 - No error when using UPDATE ... SET (#577)
Browse files Browse the repository at this point in the history
* Preparing tests about missing assignment in SET operation.

* Fix empty SET operations now throw error.

* Move the check about missing assignment in SET operation to focus UPDATE statements only.

* Improve PHPDoc.

* Fix linint issue with PHPDoc.

* Fix linint issue with PHPDoc.

Fixes #434
Closes #577
  • Loading branch information
niconoe- authored Aug 29, 2024
1 parent 99b9f38 commit e9debaf
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/Statements/UpdateStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
use PhpMyAdmin\SqlParser\Components\Limit;
use PhpMyAdmin\SqlParser\Components\OrderKeyword;
use PhpMyAdmin\SqlParser\Components\SetOperation;
use PhpMyAdmin\SqlParser\Exceptions\ParserException;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statement;
use PhpMyAdmin\SqlParser\Token;
use PhpMyAdmin\SqlParser\TokensList;

/**
* `UPDATE` statement.
Expand Down Expand Up @@ -135,4 +139,25 @@ class UpdateStatement extends Statement
* @var JoinKeyword[]|null
*/
public $join;

/**
* Function called after the token was processed.
* In the update statement, this is used to check that at least one assignment has been set to throw an error if a
* query like `UPDATE acme SET WHERE 1;` is parsed.
*
* @return void
*
* @throws ParserException throws the exception, if strict mode is enabled.
*/
public function after(Parser $parser, TokensList $list, Token $token)
{
/** @psalm-var string $tokenValue */
$tokenValue = $token->value;
// Ensure we finished to parse the "SET" token, and if yes, ensure that assignments are defined.
if ($this->set !== [] || (Parser::$KEYWORD_PARSERS[$tokenValue]['field'] ?? null) !== 'set') {
return;
}

$parser->error('Missing assignment in SET operation.', $list->tokens[$list->idx]);
}
}
1 change: 1 addition & 0 deletions tests/Parser/UpdateStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public static function updateProvider(): array
['parser/parseUpdate6'],
['parser/parseUpdate7'],
['parser/parseUpdateErr'],
['parser/parseUpdateEmptySet'],
];
}
}
7 changes: 7 additions & 0 deletions tests/data/parser/parseUpdate3.out
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@
"@type": "@12"
},
0
],
[
"Missing assignment in SET operation.",
{
"@type": "@11"
},
0
]
]
}
Expand Down
1 change: 1 addition & 0 deletions tests/data/parser/parseUpdateEmptySet.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
UPDATE test SET WHERE 1;
184 changes: 184 additions & 0 deletions tests/data/parser/parseUpdateEmptySet.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{
"query": "UPDATE test SET WHERE 1;\n",
"lexer": {
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
"str": "UPDATE test SET WHERE 1;\n",
"len": 25,
"last": 25,
"list": {
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
"tokens": [
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "UPDATE",
"value": "UPDATE",
"keyword": "UPDATE",
"type": 1,
"flags": 3,
"position": 0
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 6
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "test",
"value": "test",
"keyword": null,
"type": 0,
"flags": 0,
"position": 7
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 11
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "SET",
"value": "SET",
"keyword": "SET",
"type": 1,
"flags": 11,
"position": 12
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 15
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "WHERE",
"value": "WHERE",
"keyword": "WHERE",
"type": 1,
"flags": 3,
"position": 16
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": " ",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 21
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "1",
"value": 1,
"keyword": null,
"type": 6,
"flags": 0,
"position": 22
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": ";",
"value": ";",
"keyword": null,
"type": 9,
"flags": 0,
"position": 23
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "\n",
"value": " ",
"keyword": null,
"type": 3,
"flags": 0,
"position": 24
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": null,
"value": null,
"keyword": null,
"type": 9,
"flags": 0,
"position": null
}
],
"count": 12,
"idx": 12
},
"delimiter": ";",
"delimiterLen": 1,
"strict": false,
"errors": []
},
"parser": {
"@type": "PhpMyAdmin\\SqlParser\\Parser",
"list": {
"@type": "@1"
},
"statements": [
{
"@type": "PhpMyAdmin\\SqlParser\\Statements\\UpdateStatement",
"tables": [
{
"@type": "PhpMyAdmin\\SqlParser\\Components\\Expression",
"database": null,
"table": "test",
"column": null,
"expr": "test",
"alias": null,
"function": null,
"subquery": null
}
],
"set": [],
"where": [
{
"@type": "PhpMyAdmin\\SqlParser\\Components\\Condition",
"identifiers": [],
"isOperator": false,
"expr": "1"
}
],
"order": null,
"limit": null,
"join": null,
"options": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
"options": []
},
"first": 0,
"last": 8
}
],
"brackets": 0,
"strict": false,
"errors": []
},
"errors": {
"lexer": [],
"parser": [
[
"Missing assignment in SET operation.",
{
"@type": "@7"
},
0
]
]
}
}

0 comments on commit e9debaf

Please sign in to comment.