diff --git a/parser/parser_query.go b/parser/parser_query.go index b456d08..61b50d1 100644 --- a/parser/parser_query.go +++ b/parser/parser_query.go @@ -802,7 +802,7 @@ func (p *Parser) parseSelectQuery(_ Pos) (*SelectQuery, error) { } selectStmt.UnionAll = unionAllExpr case p.tryConsumeKeywords(KeywordDistinct): - unionDistinctExpr, err := p.parseSelectStmt(p.Pos()) + unionDistinctExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } @@ -811,7 +811,7 @@ func (p *Parser) parseSelectQuery(_ Pos) (*SelectQuery, error) { return nil, fmt.Errorf("expected ALL or DISTINCT, got %s", p.lastTokenKind()) } case p.tryConsumeKeywords(KeywordExcept): - exceptExpr, err := p.parseSelectStmt(p.Pos()) + exceptExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } diff --git a/parser/testdata/query/format/select_with_multi_except.sql b/parser/testdata/query/format/select_with_multi_except.sql new file mode 100644 index 0000000..fc1de3c --- /dev/null +++ b/parser/testdata/query/format/select_with_multi_except.sql @@ -0,0 +1,5 @@ +-- Origin SQL: +SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9) + +-- Format SQL: +SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9); diff --git a/parser/testdata/query/format/select_with_multi_union_distinct.sql b/parser/testdata/query/format/select_with_multi_union_distinct.sql new file mode 100644 index 0000000..b8633c3 --- /dev/null +++ b/parser/testdata/query/format/select_with_multi_union_distinct.sql @@ -0,0 +1,5 @@ +-- Origin SQL: +SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3 + +-- Format SQL: +SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3; diff --git a/parser/testdata/query/output/select_with_multi_except.sql.golden.json b/parser/testdata/query/output/select_with_multi_except.sql.golden.json new file mode 100644 index 0000000..cb5bf44 --- /dev/null +++ b/parser/testdata/query/output/select_with_multi_except.sql.golden.json @@ -0,0 +1,222 @@ +[ + { + "SelectPos": 0, + "StatementEnd": 32, + "With": null, + "Top": null, + "HasDistinct": false, + "SelectItems": [ + { + "Expr": { + "Name": "number", + "QuoteType": 1, + "NamePos": 7, + "NameEnd": 13 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 14, + "Expr": { + "Table": { + "TablePos": 19, + "TableEnd": 32, + "Alias": null, + "Expr": { + "Name": { + "Name": "numbers", + "QuoteType": 1, + "NamePos": 19, + "NameEnd": 26 + }, + "Args": { + "LeftParenPos": 26, + "RightParenPos": 32, + "Args": [ + { + "NumPos": 27, + "NumEnd": 28, + "Literal": "1", + "Base": 10 + }, + { + "NumPos": 30, + "NumEnd": 32, + "Literal": "10", + "Base": 10 + } + ] + } + }, + "HasFinal": false + }, + "StatementEnd": 32, + "SampleRatio": null, + "HasFinal": false + } + }, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": null, + "UnionDistinct": null, + "Except": { + "SelectPos": 41, + "StatementEnd": 72, + "With": null, + "Top": null, + "HasDistinct": false, + "SelectItems": [ + { + "Expr": { + "Name": "number", + "QuoteType": 1, + "NamePos": 48, + "NameEnd": 54 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 55, + "Expr": { + "Table": { + "TablePos": 60, + "TableEnd": 72, + "Alias": null, + "Expr": { + "Name": { + "Name": "numbers", + "QuoteType": 1, + "NamePos": 60, + "NameEnd": 67 + }, + "Args": { + "LeftParenPos": 67, + "RightParenPos": 72, + "Args": [ + { + "NumPos": 68, + "NumEnd": 69, + "Literal": "3", + "Base": 10 + }, + { + "NumPos": 71, + "NumEnd": 72, + "Literal": "6", + "Base": 10 + } + ] + } + }, + "HasFinal": false + }, + "StatementEnd": 72, + "SampleRatio": null, + "HasFinal": false + } + }, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": null, + "UnionDistinct": null, + "Except": { + "SelectPos": 81, + "StatementEnd": 112, + "With": null, + "Top": null, + "HasDistinct": false, + "SelectItems": [ + { + "Expr": { + "Name": "number", + "QuoteType": 1, + "NamePos": 88, + "NameEnd": 94 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 95, + "Expr": { + "Table": { + "TablePos": 100, + "TableEnd": 112, + "Alias": null, + "Expr": { + "Name": { + "Name": "numbers", + "QuoteType": 1, + "NamePos": 100, + "NameEnd": 107 + }, + "Args": { + "LeftParenPos": 107, + "RightParenPos": 112, + "Args": [ + { + "NumPos": 108, + "NumEnd": 109, + "Literal": "8", + "Base": 10 + }, + { + "NumPos": 111, + "NumEnd": 112, + "Literal": "9", + "Base": 10 + } + ] + } + }, + "HasFinal": false + }, + "StatementEnd": 112, + "SampleRatio": null, + "HasFinal": false + } + }, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": null, + "UnionDistinct": null, + "Except": null + } + } + } +] \ No newline at end of file diff --git a/parser/testdata/query/output/select_with_multi_union_distinct.sql.golden.json b/parser/testdata/query/output/select_with_multi_union_distinct.sql.golden.json new file mode 100644 index 0000000..ef1537c --- /dev/null +++ b/parser/testdata/query/output/select_with_multi_union_distinct.sql.golden.json @@ -0,0 +1,120 @@ +[ + { + "SelectPos": 0, + "StatementEnd": 14, + "With": null, + "Top": null, + "HasDistinct": false, + "SelectItems": [ + { + "Expr": { + "NumPos": 7, + "NumEnd": 8, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "v1", + "QuoteType": 1, + "NamePos": 12, + "NameEnd": 14 + } + } + ], + "From": null, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": null, + "UnionDistinct": { + "SelectPos": 30, + "StatementEnd": 44, + "With": null, + "Top": null, + "HasDistinct": false, + "SelectItems": [ + { + "Expr": { + "NumPos": 37, + "NumEnd": 38, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "v2", + "QuoteType": 1, + "NamePos": 42, + "NameEnd": 44 + } + } + ], + "From": null, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": null, + "UnionDistinct": { + "SelectPos": 60, + "StatementEnd": 74, + "With": null, + "Top": null, + "HasDistinct": false, + "SelectItems": [ + { + "Expr": { + "NumPos": 67, + "NumEnd": 68, + "Literal": "3", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "v3", + "QuoteType": 1, + "NamePos": 72, + "NameEnd": 74 + } + } + ], + "From": null, + "ArrayJoin": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": null, + "UnionDistinct": null, + "Except": null + }, + "Except": null + }, + "Except": null + } +] \ No newline at end of file diff --git a/parser/testdata/query/select_with_multi_except.sql b/parser/testdata/query/select_with_multi_except.sql new file mode 100644 index 0000000..fd33f7c --- /dev/null +++ b/parser/testdata/query/select_with_multi_except.sql @@ -0,0 +1 @@ +SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9) \ No newline at end of file diff --git a/parser/testdata/query/select_with_multi_union_distinct.sql b/parser/testdata/query/select_with_multi_union_distinct.sql new file mode 100644 index 0000000..8276e9e --- /dev/null +++ b/parser/testdata/query/select_with_multi_union_distinct.sql @@ -0,0 +1 @@ +SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3 \ No newline at end of file