sql-parser
sql-parser copied to clipboard
Parser fails for updates that include subqueries for source tables
The SQL Parser fails to parse the following query:
update `table1` as e, (select * from table2) e2
set
e.`id` = e2.id,
where e.id=e2.id
It returns the output below. This appears to always be an issue when using subqueries in the table references.
[
{
"tables": [
{
"database": null,
"table": "table1",
"column": null,
"expr": "`table1`",
"alias": "e",
"function": null,
"subquery": null
}
],
"set": null,
"where": null,
"order": null,
"limit": null,
"options": {
"options": []
},
"first": 0,
"last": 10
},
{
"expr": [
{
"database": null,
"table": null,
"column": null,
"expr": "*",
"alias": null,
"function": null,
"subquery": null
}
],
"from": [
{
"database": null,
"table": "table2",
"column": null,
"expr": "table2",
"alias": null,
"function": null,
"subquery": null
}
],
"index_hints": null,
"partition": null,
"where": null,
"group": null,
"having": null,
"order": null,
"limit": null,
"procedure": null,
"into": null,
"join": null,
"union": [],
"end_options": null,
"options": {
"options": []
},
"first": 11,
"last": 21
},
{
"options": {
"options": []
},
"end_options": null,
"set": [
{
"column": "e.`id`",
"value": "e2.id"
}
],
"first": 22,
"last": 44,
"where": [
{
"identifiers": [
"e",
"id",
"e2"
],
"isOperator": false,
"expr": "e.id=e2.id"
}
]
}
]
@Tithugues can I have some help with this one? Can I ask your help on issues?
@juacala , what does it mean that the parser "fails" please? Do you have an error? If not, what result do you expect?
To clarify, below is the same output but using var_dump (together with the JSON above, they give you an idea of what is being output). The query being parsed is a single update statement, but it returns, separately, an incomplete update statement, a select and then a set statement.
array (size=3)
0 =>
object(PhpMyAdmin\SqlParser\Statements\UpdateStatement)[53]
public 'tables' =>
array (size=1)
0 =>
object(PhpMyAdmin\SqlParser\Components\Expression)[55]
...
public 'set' => null
public 'where' => null
public 'order' => null
public 'limit' => null
public 'options' =>
object(PhpMyAdmin\SqlParser\Components\OptionsArray)[54]
public 'options' =>
array (size=0)
...
public 'first' => int 0
public 'last' => int 12
1 =>
object(PhpMyAdmin\SqlParser\Statements\SelectStatement)[59]
public 'expr' =>
array (size=1)
0 =>
object(PhpMyAdmin\SqlParser\Components\Expression)[61]
...
public 'from' =>
array (size=1)
0 =>
object(PhpMyAdmin\SqlParser\Components\Expression)[62]
...
public 'index_hints' => null
public 'partition' => null
public 'where' => null
public 'group' => null
public 'having' => null
public 'order' => null
public 'limit' => null
public 'procedure' => null
public 'into' => null
public 'join' => null
public 'union' =>
array (size=0)
empty
public 'end_options' => null
public 'options' =>
object(PhpMyAdmin\SqlParser\Components\OptionsArray)[60]
public 'options' =>
array (size=0)
...
public 'first' => int 13
public 'last' => int 23
2 =>
object(PhpMyAdmin\SqlParser\Statements\SetStatement)[66]
public 'options' =>
object(PhpMyAdmin\SqlParser\Components\OptionsArray)[67]
public 'options' =>
array (size=0)
...
public 'end_options' => null
public 'set' =>
array (size=1)
0 =>
object(PhpMyAdmin\SqlParser\Components\SetOperation)[68]
...
public 'first' => int 24
public 'last' => int 46
public 'where' =>
array (size=1)
0 =>
object(PhpMyAdmin\SqlParser\Components\Condition)[69]
...
Perhaps I'm confused as to what I should expect, but I would have expected a single Update object that has the subquery as one of the source tables. Something liike:
[
{
"tables": [
{
"database": "db",
"table": "table1",
"column": null,
"expr": "db.`table1`",
"alias": "e",
"function": null,
"subquery": null
},
{
"database": null,
"table": "table2",
"column": null,
"expr": "?",
"alias": "e2",
"function": null,
"subquery": "select * from table2"
}
],
"set": [
{
"column": "e.`id`",
"value": "e2.id"
}
],
"where": [
{
"identifiers": [
"e",
"id",
"e2"
],
"isOperator": false,
"expr": "e.id=e2.id"
}
],
"order": null,
"limit": null,
"options": {
"options": []
},
"first": 0,
"last": 38
}
]