andialbrecht / sqlparse

A non-validating SQL parser module for Python
BSD 3-Clause "New" or "Revised" License
3.63k stars 685 forks source link

The group_order() function fails to identify an ordered identifier in the context when nested #745

Closed john-bodley closed 4 months ago

john-bodley commented 8 months ago

Describe the bug

The group_order() function does not leverage the @recurse decorator and thus the identifier and ASC/DESC token aren't grouped together in the context of a subquery.

To Reproduce

The following correctly groups bar DESC as a single identifier,

>>> from sqlparse import parse
>>>
>>> parse("SELECT * FROM foo ORDER BY bar DESC")[0]._pprint_tree()
|- 0 DML 'SELECT'
|- 1 Whitespace ' '
|- 2 Wildcard '*'
|- 3 Whitespace ' '
|- 4 Keyword 'FROM'
|- 5 Whitespace ' '
|- 6 Identifier 'foo'
|  `- 0 Name 'foo'
|- 7 Whitespace ' '
|- 8 Keyword 'ORDER ...'
|- 9 Whitespace ' '
`- 10 Identifier 'bar DE...'
   |- 0 Identifier 'bar'
   |  `- 0 Name 'bar'
   |- 1 Whitespace ' '
   `- 2 Order 'DESC'

whereas when wrapped within a subquery,

>>> from sqlparse import parse

>>> parse("SELECT * FROM (SELECT * FROM foo ORDER BY bar DESC)")[0]._pprint_tree()
|- 0 DML 'SELECT'
|- 1 Whitespace ' '
|- 2 Wildcard '*'
|- 3 Whitespace ' '
|- 4 Keyword 'FROM'
|- 5 Whitespace ' '
`- 6 Parenthesis '(SELEC...'
   |- 0 Punctuation '('
   |- 1 DML 'SELECT'
   |- 2 Whitespace ' '
   |- 3 Wildcard '*'
   |- 4 Whitespace ' '
   |- 5 Keyword 'FROM'
   |- 6 Whitespace ' '
   |- 7 Identifier 'foo'
   |  `- 0 Name 'foo'
   |- 8 Whitespace ' '
   |- 9 Keyword 'ORDER ...'
   |- 10 Whitespace ' '
   |- 11 Identifier 'bar'
   |  `- 0 Name 'bar'
   |- 12 Whitespace ' '
   |- 13 Order 'DESC'
   `- 14 Punctuation ')'

the bar DESC is not grouped.

Expected behavior

The group_order() function should leverage the recurse(sql.Identifier) decorator to ensure that nested orders are grouped appropriately.

Versions (please complete the following information):