diff --git a/parser/parser_column.go b/parser/parser_column.go index afc4ca2..38d226d 100644 --- a/parser/parser_column.go +++ b/parser/parser_column.go @@ -19,14 +19,13 @@ func (p *Parser) parseExpr(pos Pos) (Expr, error) { } switch { case p.matchKeyword(KeywordAs): // syntax: columnExpr (alias | AS identifier) - aliasPos := p.Pos() _ = p.lexer.consumeToken() alias, err := p.parseIdent() if err != nil { return nil, err } return &AliasExpr{ - AliasPos: aliasPos, + AliasPos: alias.Pos(), Expr: orExpr, Alias: alias, }, nil diff --git a/parser/parser_query.go b/parser/parser_query.go index e62f8fc..6ff3a5d 100644 --- a/parser/parser_query.go +++ b/parser/parser_query.go @@ -320,7 +320,18 @@ func (p *Parser) parseTableExpr(pos Pos) (*TableExpr, error) { } expr = &AliasExpr{ Expr: expr, - AliasPos: asToken.Pos, + AliasPos: alias.Pos(), + Alias: alias, + } + tableEnd = expr.End() + } else if p.matchTokenKind(TokenIdent) && p.lastTokenKind() != TokenKeyword { + alias, err := p.parseIdent() + if err != nil { + return nil, err + } + expr = &AliasExpr{ + Expr: expr, + AliasPos: alias.Pos(), Alias: alias, } tableEnd = expr.End() diff --git a/parser/testdata/ddl/output/bug_001.sql.golden.json b/parser/testdata/ddl/output/bug_001.sql.golden.json index 609a2c0..3a07232 100644 --- a/parser/testdata/ddl/output/bug_001.sql.golden.json +++ b/parser/testdata/ddl/output/bug_001.sql.golden.json @@ -100,7 +100,7 @@ "ColumnArgList": null } }, - "AliasPos": 185, + "AliasPos": 188, "Alias": { "Name": "x", "QuoteType": 1, @@ -140,7 +140,7 @@ "ColumnArgList": null } }, - "AliasPos": 236, + "AliasPos": 239, "Alias": { "Name": "y", "QuoteType": 1, @@ -180,7 +180,7 @@ "ColumnArgList": null } }, - "AliasPos": 287, + "AliasPos": 290, "Alias": { "Name": "z", "QuoteType": 1, @@ -220,7 +220,7 @@ "ColumnArgList": null } }, - "AliasPos": 338, + "AliasPos": 341, "Alias": { "Name": "a", "QuoteType": 1, @@ -260,7 +260,7 @@ "ColumnArgList": null } }, - "AliasPos": 389, + "AliasPos": 392, "Alias": { "Name": "b", "QuoteType": 1, @@ -300,7 +300,7 @@ "ColumnArgList": null } }, - "AliasPos": 440, + "AliasPos": 443, "Alias": { "Name": "c", "QuoteType": 1, @@ -340,7 +340,7 @@ "ColumnArgList": null } }, - "AliasPos": 491, + "AliasPos": 494, "Alias": { "Name": "d", "QuoteType": 1, @@ -380,7 +380,7 @@ "ColumnArgList": null } }, - "AliasPos": 539, + "AliasPos": 542, "Alias": { "Name": "e", "QuoteType": 1, @@ -420,7 +420,7 @@ "ColumnArgList": null } }, - "AliasPos": 587, + "AliasPos": 590, "Alias": { "Name": "f", "QuoteType": 1, diff --git a/parser/testdata/ddl/output/create_materialized_view_basic.sql.golden.json b/parser/testdata/ddl/output/create_materialized_view_basic.sql.golden.json index 64c847f..3e50d25 100644 --- a/parser/testdata/ddl/output/create_materialized_view_basic.sql.golden.json +++ b/parser/testdata/ddl/output/create_materialized_view_basic.sql.golden.json @@ -285,7 +285,7 @@ "ColumnArgList": null } }, - "AliasPos": 281, + "AliasPos": 284, "Alias": { "Name": "f3", "QuoteType": 1, @@ -325,7 +325,7 @@ "ColumnArgList": null } }, - "AliasPos": 342, + "AliasPos": 345, "Alias": { "Name": "f4", "QuoteType": 1, @@ -365,7 +365,7 @@ "ColumnArgList": null } }, - "AliasPos": 401, + "AliasPos": 404, "Alias": { "Name": "f5", "QuoteType": 1, @@ -405,7 +405,7 @@ "ColumnArgList": null } }, - "AliasPos": 451, + "AliasPos": 454, "Alias": { "Name": "f6", "QuoteType": 1, diff --git a/parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json b/parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json index 900b924..a379f2a 100644 --- a/parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json +++ b/parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json @@ -185,7 +185,7 @@ "ColumnArgList": null } }, - "AliasPos": 236, + "AliasPos": 239, "Alias": { "Name": "f333", "QuoteType": 1, @@ -317,7 +317,7 @@ "Frame": null } }, - "AliasPos": 349, + "AliasPos": 352, "Alias": { "Name": "rn", "QuoteType": 1, @@ -431,7 +431,7 @@ "UnionDistinct": null, "Except": null }, - "AliasPos": 441, + "AliasPos": 444, "Alias": { "Name": "tmp", "QuoteType": 1, diff --git a/parser/testdata/query/format/select_table_alias_without_keyword.sql b/parser/testdata/query/format/select_table_alias_without_keyword.sql new file mode 100644 index 0000000..460bcee --- /dev/null +++ b/parser/testdata/query/format/select_table_alias_without_keyword.sql @@ -0,0 +1,10 @@ +-- Origin SQL: +SELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b + +-- Format SQL: + +SELECT + t1.Timestamp +FROM + my_table AS t1 + INNER JOIN my_other_table AS t2 ON t1.a = t2.b; diff --git a/parser/testdata/query/output/select_cast.sql.golden.json b/parser/testdata/query/output/select_cast.sql.golden.json index 077537a..33bc315 100644 --- a/parser/testdata/query/output/select_cast.sql.golden.json +++ b/parser/testdata/query/output/select_cast.sql.golden.json @@ -29,7 +29,7 @@ } } }, - "AliasPos": 26, + "AliasPos": 29, "Alias": { "Name": "value", "QuoteType": 1, @@ -82,7 +82,7 @@ "Literal": "Float64" } }, - "AliasPos": 62, + "AliasPos": 65, "Alias": { "Name": "value", "QuoteType": 1, @@ -134,7 +134,7 @@ "Literal": "1", "Base": 10 }, - "AliasPos": 82, + "AliasPos": 85, "Alias": { "Name": "Float64", "QuoteType": 1, @@ -146,7 +146,7 @@ }, "ColumnArgList": null }, - "AliasPos": 94, + "AliasPos": 97, "Alias": { "Name": "value", "QuoteType": 1, @@ -200,7 +200,7 @@ "HasGlobal": false, "HasNot": false }, - "AliasPos": 122, + "AliasPos": 125, "Alias": { "Name": "value", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_column_alias_string.sql.golden.json b/parser/testdata/query/output/select_column_alias_string.sql.golden.json index 47f5b56..6bb5559 100644 --- a/parser/testdata/query/output/select_column_alias_string.sql.golden.json +++ b/parser/testdata/query/output/select_column_alias_string.sql.golden.json @@ -15,7 +15,7 @@ "LiteralEnd": 11, "Literal": "abc" }, - "AliasPos": 13, + "AliasPos": 17, "Alias": { "Name": "value2", "QuoteType": 2, diff --git a/parser/testdata/query/output/select_simple.sql.golden.json b/parser/testdata/query/output/select_simple.sql.golden.json index c6961ad..25f492a 100644 --- a/parser/testdata/query/output/select_simple.sql.golden.json +++ b/parser/testdata/query/output/select_simple.sql.golden.json @@ -48,7 +48,7 @@ "ColumnArgList": null } }, - "AliasPos": 32, + "AliasPos": 35, "Alias": { "Name": "f3", "QuoteType": 1, @@ -116,7 +116,7 @@ "Frame": null } }, - "AliasPos": 91, + "AliasPos": 94, "Alias": { "Name": "rn", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_simple_with_bracket.sql.golden.json b/parser/testdata/query/output/select_simple_with_bracket.sql.golden.json index 7fd68f8..6eb1271 100644 --- a/parser/testdata/query/output/select_simple_with_bracket.sql.golden.json +++ b/parser/testdata/query/output/select_simple_with_bracket.sql.golden.json @@ -99,7 +99,7 @@ "ColumnArgList": null } }, - "AliasPos": 43, + "AliasPos": 46, "Alias": { "Name": "res", "QuoteType": 1, @@ -133,7 +133,7 @@ } } }, - "AliasPos": 61, + "AliasPos": 64, "Alias": { "Name": "f2", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_simple_with_cte_with_column_aliases.sql.golden.json b/parser/testdata/query/output/select_simple_with_cte_with_column_aliases.sql.golden.json index c22f878..c818d37 100644 --- a/parser/testdata/query/output/select_simple_with_cte_with_column_aliases.sql.golden.json +++ b/parser/testdata/query/output/select_simple_with_cte_with_column_aliases.sql.golden.json @@ -130,7 +130,7 @@ "NamePos": 71, "NameEnd": 73 }, - "AliasPos": 74, + "AliasPos": 77, "Alias": { "Name": "new_f1", "QuoteType": 1, @@ -145,7 +145,7 @@ "NamePos": 89, "NameEnd": 91 }, - "AliasPos": 92, + "AliasPos": 95, "Alias": { "Name": "new_f2", "QuoteType": 1, @@ -160,7 +160,7 @@ "NamePos": 107, "NameEnd": 109 }, - "AliasPos": 110, + "AliasPos": 113, "Alias": { "Name": "new_f3", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_simple_with_is_not_null.sql.golden.json b/parser/testdata/query/output/select_simple_with_is_not_null.sql.golden.json index 3b698f9..58968b2 100644 --- a/parser/testdata/query/output/select_simple_with_is_not_null.sql.golden.json +++ b/parser/testdata/query/output/select_simple_with_is_not_null.sql.golden.json @@ -34,7 +34,7 @@ "NamePos": 16, "NameEnd": 18 }, - "AliasPos": 19, + "AliasPos": 22, "Alias": { "Name": "a0", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_simple_with_is_null.sql.golden.json b/parser/testdata/query/output/select_simple_with_is_null.sql.golden.json index cfa867d..b41a093 100644 --- a/parser/testdata/query/output/select_simple_with_is_null.sql.golden.json +++ b/parser/testdata/query/output/select_simple_with_is_null.sql.golden.json @@ -34,7 +34,7 @@ "NamePos": 16, "NameEnd": 18 }, - "AliasPos": 19, + "AliasPos": 22, "Alias": { "Name": "a0", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_table_alias_without_keyword.sql.golden.json b/parser/testdata/query/output/select_table_alias_without_keyword.sql.golden.json new file mode 100644 index 0000000..6207280 --- /dev/null +++ b/parser/testdata/query/output/select_table_alias_without_keyword.sql.golden.json @@ -0,0 +1,163 @@ +[ + { + "SelectPos": 0, + "StatementEnd": 36, + "With": null, + "Top": null, + "SelectColumns": { + "ListPos": 7, + "ListEnd": 19, + "HasDistinct": false, + "Items": [ + { + "Database": null, + "Table": { + "Name": "t1", + "QuoteType": 1, + "NamePos": 7, + "NameEnd": 9 + }, + "Column": { + "Name": "Timestamp", + "QuoteType": 1, + "NamePos": 10, + "NameEnd": 19 + } + } + ] + }, + "From": { + "FromPos": 20, + "Expr": { + "JoinPos": 25, + "Left": { + "Table": { + "TablePos": 25, + "TableEnd": 36, + "Alias": null, + "Expr": { + "Expr": { + "Database": null, + "Table": { + "Name": "my_table", + "QuoteType": 1, + "NamePos": 25, + "NameEnd": 33 + } + }, + "AliasPos": 34, + "Alias": { + "Name": "t1", + "QuoteType": 1, + "NamePos": 34, + "NameEnd": 36 + } + }, + "HasFinal": false + }, + "StatementEnd": 36, + "SampleRatio": null, + "HasFinal": false + }, + "Right": { + "JoinPos": 37, + "Left": { + "Table": { + "TablePos": 48, + "TableEnd": 65, + "Alias": null, + "Expr": { + "Expr": { + "Database": null, + "Table": { + "Name": "my_other_table", + "QuoteType": 1, + "NamePos": 48, + "NameEnd": 62 + } + }, + "AliasPos": 63, + "Alias": { + "Name": "t2", + "QuoteType": 1, + "NamePos": 63, + "NameEnd": 65 + } + }, + "HasFinal": false + }, + "StatementEnd": 65, + "SampleRatio": null, + "HasFinal": false + }, + "Right": null, + "Modifiers": [ + "INNER", + "JOIN" + ], + "Constraints": { + "OnPos": 66, + "On": { + "ListPos": 69, + "ListEnd": 78, + "HasDistinct": false, + "Items": [ + { + "LeftExpr": { + "Database": null, + "Table": { + "Name": "t1", + "QuoteType": 1, + "NamePos": 69, + "NameEnd": 71 + }, + "Column": { + "Name": "a", + "QuoteType": 1, + "NamePos": 72, + "NameEnd": 73 + } + }, + "Operation": "=", + "RightExpr": { + "Database": null, + "Table": { + "Name": "t2", + "QuoteType": 1, + "NamePos": 74, + "NameEnd": 76 + }, + "Column": { + "Name": "b", + "QuoteType": 1, + "NamePos": 77, + "NameEnd": 78 + } + }, + "HasGlobal": false, + "HasNot": false + } + ] + } + } + }, + "Modifiers": null, + "Constraints": null + } + }, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "UnionAll": null, + "UnionDistinct": null, + "Except": null + } +] \ No newline at end of file diff --git a/parser/testdata/query/output/select_with_left_join.sql.golden.json b/parser/testdata/query/output/select_with_left_join.sql.golden.json index 2ba78e7..e4eb41a 100644 --- a/parser/testdata/query/output/select_with_left_join.sql.golden.json +++ b/parser/testdata/query/output/select_with_left_join.sql.golden.json @@ -31,7 +31,7 @@ "Literal": "1", "Base": 10 }, - "AliasPos": 46, + "AliasPos": 49, "Alias": { "Name": "value", "QuoteType": 1, @@ -83,7 +83,7 @@ "Literal": "2", "Base": 10 }, - "AliasPos": 90, + "AliasPos": 93, "Alias": { "Name": "value", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_with_multi_join.sql.golden.json b/parser/testdata/query/output/select_with_multi_join.sql.golden.json index b647f3a..b4eed35 100644 --- a/parser/testdata/query/output/select_with_multi_join.sql.golden.json +++ b/parser/testdata/query/output/select_with_multi_join.sql.golden.json @@ -30,7 +30,7 @@ "LiteralEnd": 31, "Literal": "value1" }, - "AliasPos": 33, + "AliasPos": 36, "Alias": { "Name": "value", "QuoteType": 1, @@ -81,7 +81,7 @@ "LiteralEnd": 71, "Literal": "value2" }, - "AliasPos": 73, + "AliasPos": 76, "Alias": { "Name": "value", "QuoteType": 1, @@ -132,7 +132,7 @@ "LiteralEnd": 111, "Literal": "value3" }, - "AliasPos": 113, + "AliasPos": 116, "Alias": { "Name": "value", "QuoteType": 1, @@ -183,7 +183,7 @@ "NameEnd": 147 } }, - "AliasPos": 148, + "AliasPos": 151, "Alias": { "Name": "value1", "QuoteType": 1, @@ -207,7 +207,7 @@ "NameEnd": 171 } }, - "AliasPos": 172, + "AliasPos": 175, "Alias": { "Name": "value2", "QuoteType": 1, @@ -231,7 +231,7 @@ "NameEnd": 195 } }, - "AliasPos": 196, + "AliasPos": 199, "Alias": { "Name": "value3", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_with_string_expr.sql.golden.json b/parser/testdata/query/output/select_with_string_expr.sql.golden.json index a5b61b2..90e27d4 100644 --- a/parser/testdata/query/output/select_with_string_expr.sql.golden.json +++ b/parser/testdata/query/output/select_with_string_expr.sql.golden.json @@ -31,7 +31,7 @@ "Literal": "1", "Base": 10 }, - "AliasPos": 24, + "AliasPos": 27, "Alias": { "Name": "a", "QuoteType": 1, diff --git a/parser/testdata/query/output/select_with_variable.sql.golden.json b/parser/testdata/query/output/select_with_variable.sql.golden.json index 6d6e07a..ad5b84c 100644 --- a/parser/testdata/query/output/select_with_variable.sql.golden.json +++ b/parser/testdata/query/output/select_with_variable.sql.golden.json @@ -31,7 +31,7 @@ "Literal": "1", "Base": 10 }, - "AliasPos": 23, + "AliasPos": 26, "Alias": { "Name": "a", "QuoteType": 1, diff --git a/parser/testdata/query/select_table_alias_without_keyword.sql b/parser/testdata/query/select_table_alias_without_keyword.sql new file mode 100644 index 0000000..f3531e6 --- /dev/null +++ b/parser/testdata/query/select_table_alias_without_keyword.sql @@ -0,0 +1 @@ +SELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b \ No newline at end of file