Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser fails for updates that include subqueries for source tables #269

Open
juacala opened this issue Nov 14, 2019 · 4 comments
Open

Parser fails for updates that include subqueries for source tables #269

juacala opened this issue Nov 14, 2019 · 4 comments
Labels

Comments

@juacala
Copy link

juacala commented Nov 14, 2019

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"
            }
        ]
    }
]
@williamdes williamdes added the bug label Nov 14, 2019
@williamdes
Copy link
Member

@Tithugues can I have some help with this one?
Can I ask your help on issues?

@Tithugues
Copy link
Contributor

@juacala , what does it mean that the parser "fails" please? Do you have an error? If not, what result do you expect?

@juacala
Copy link
Author

juacala commented Dec 5, 2019

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
    }
]

@maryglo
Copy link

maryglo commented Sep 23, 2024

I also encountered this issue. I tried to dump the list of statements but it separated the statements
(select * from table2) e2 and set e.id = e2.id
I expected that the whole Update statement above as just one but they are separated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants