andialbrecht / sqlparse

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

CREATE TABLE tbl AS SELECT should return get_alias() for its column #662

Closed chezou closed 2 years ago

chezou commented 2 years ago

Currently, CREATE TABLE AS SELECT a.k.a. CTAS doesn't parse column aliases with functions e.g., coalesce, if, appropriately.

In the following example, coalesce is parsed as Name while it should be Function to get get_alias() appropriately.

Before

>>> import sqlparse
>>> p = sqlparse.parse('CREATE TABLE tbl1 AS SELECT coalesce(t1.col1, 0) AS col1 FROM t1')[0]
>>> p._pprint_tree()
|- 0 DDL 'CREATE'
|- 1 Whitespace ' '
|- 2 Keyword 'TABLE'
|- 3 Whitespace ' '
|- 4 Identifier 'tbl1'
|  `- 0 Name 'tbl1'
|- 5 Whitespace ' '
|- 6 Keyword 'AS'
|- 7 Whitespace ' '
|- 8 DML 'SELECT'
|- 9 Whitespace ' '
|- 10 Identifier 'coales...'
|  |- 0 Name 'coales...'
|  `- 1 Identifier '(t1.co...'
|     |- 0 Parenthesis '(t1.co...'
|     |  |- 0 Punctuation '('
|     |  |- 1 IdentifierList 't1.col...'
|     |  |  |- 0 Identifier 't1.col1'
|     |  |  |  |- 0 Name 't1'
|     |  |  |  |- 1 Punctuation '.'
|     |  |  |  `- 2 Name 'col1'
|     |  |  |- 1 Punctuation ','
|     |  |  |- 2 Whitespace ' '
|     |  |  `- 3 Integer '0'
|     |  `- 2 Punctuation ')'
|     |- 1 Whitespace ' '
|     |- 2 Keyword 'AS'
|     |- 3 Whitespace ' '
|     `- 4 Identifier 'col1'
|        `- 0 Name 'col1'
|- 11 Whitespace ' '
|- 12 Keyword 'FROM'
|- 13 Whitespace ' '
`- 14 Identifier 't1'
   `- 0 Name 't1'
>>> p.tokens[10].get_alias()
# Should return 'col1'

After

>>> p = sqlparse.parse('CREATE TABLE tbl1 AS SELECT coalesce(t1.col1, 0) AS col1 FROM t1')[0]
>>> p._pprint_tree()
|- 0 DDL 'CREATE'
|- 1 Whitespace ' '
|- 2 Keyword 'TABLE'
|- 3 Whitespace ' '
|- 4 Identifier 'tbl1'
|  `- 0 Name 'tbl1'
|- 5 Whitespace ' '
|- 6 Keyword 'AS'
|- 7 Whitespace ' '
|- 8 DML 'SELECT'
|- 9 Whitespace ' '
|- 10 Identifier 'coales...'
|  |- 0 Function 'coales...'
|  |  |- 0 Identifier 'coales...'
|  |  |  `- 0 Name 'coales...'
|  |  `- 1 Parenthesis '(t1.co...'
|  |     |- 0 Punctuation '('
|  |     |- 1 IdentifierList 't1.col...'
|  |     |  |- 0 Identifier 't1.col1'
|  |     |  |  |- 0 Name 't1'
|  |     |  |  |- 1 Punctuation '.'
|  |     |  |  `- 2 Name 'col1'
|  |     |  |- 1 Punctuation ','
|  |     |  |- 2 Whitespace ' '
|  |     |  `- 3 Integer '0'
|  |     `- 2 Punctuation ')'
|  |- 1 Whitespace ' '
|  |- 2 Keyword 'AS'
|  |- 3 Whitespace ' '
|  `- 4 Identifier 'col1'
|     `- 0 Name 'col1'
|- 11 Whitespace ' '
|- 12 Keyword 'FROM'
|- 13 Whitespace ' '
`- 14 Identifier 't1'
   `- 0 Name 't1'
>>> p.tokens[10].get_alias()
'col1'
andialbrecht commented 2 years ago

Thanks a lot!