diff --git a/parser/ast.go b/parser/ast.go index b6eb41f..3566641 100644 --- a/parser/ast.go +++ b/parser/ast.go @@ -5267,8 +5267,14 @@ func (f *WindowFrameParam) Accept(visitor ASTVisitor) error { } type SelectQuery struct { - SelectPos Pos - StatementEnd Pos + SelectPos Pos + StatementEnd Pos + // InnerQuery makes this node a parenthesized group wrapping that query: + // (SELECT 1 UNION ALL SELECT 2). When set, every other clause field is + // empty except Settings, Format and the set-operation fields below, which + // bind clauses that follow the closing ')'. SelectPos and StatementEnd + // span the parentheses and any trailing clause. + InnerQuery *SelectQuery `json:",omitempty"` With *WithClause Top *TopClause HasDistinct bool @@ -5303,6 +5309,11 @@ func (s *SelectQuery) End() Pos { func (s *SelectQuery) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) + if s.InnerQuery != nil { + if err := s.InnerQuery.Accept(visitor); err != nil { + return err + } + } if s.With != nil { if err := s.With.Accept(visitor); err != nil { return err diff --git a/parser/format.go b/parser/format.go index 752c746..1f55d2d 100644 --- a/parser/format.go +++ b/parser/format.go @@ -2286,6 +2286,21 @@ func (s *SelectItem) FormatSQL(formatter *Formatter) { } func (s *SelectQuery) FormatSQL(formatter *Formatter) { + if s.InnerQuery != nil { + formatter.WriteByte('(') + formatter.WriteExpr(s.InnerQuery) + formatter.WriteByte(')') + if s.Settings != nil { + formatter.Break() + formatter.WriteExpr(s.Settings) + } + if s.Format != nil { + formatter.Break() + formatter.WriteExpr(s.Format) + } + s.formatSetOperation(formatter) + return + } if s.With != nil { formatter.WriteString("WITH") formatter.Indent() @@ -2368,6 +2383,10 @@ func (s *SelectQuery) FormatSQL(formatter *Formatter) { formatter.Break() formatter.WriteExpr(s.Format) } + s.formatSetOperation(formatter) +} + +func (s *SelectQuery) formatSetOperation(formatter *Formatter) { if s.UnionAll != nil { formatter.Break() formatter.WriteString("UNION ALL") diff --git a/parser/parser_query.go b/parser/parser_query.go index 6b5e48c..128d008 100644 --- a/parser/parser_query.go +++ b/parser/parser_query.go @@ -1053,48 +1053,100 @@ func (p *Parser) parseSelectQuery(_ Pos) (*SelectQuery, error) { return nil, fmt.Errorf("expected SELECT, WITH or (, got %s", p.currentTokenKind()) } - hasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil - selectStmt, err := p.parseSelectStmt(p.Pos()) - if err != nil { + var selectStmt *SelectQuery + var err error + if lparen := p.tryConsumeTokenKind(TokenKindLParen); lparen != nil { + inner, err := p.parseSelectQuery(p.Pos()) + if err != nil { + return nil, err + } + + rparenPos := p.Pos() + if err := p.expectTokenKind(TokenKindRParen); err != nil { + return nil, err + } + + selectStmt = &SelectQuery{ + SelectPos: lparen.Pos, + StatementEnd: rparenPos + 1, + InnerQuery: inner, + } + + settings, err := p.tryParseSettingsClause(p.Pos()) + if err != nil { + return nil, err + } + if settings != nil { + selectStmt.Settings = settings + selectStmt.StatementEnd = settings.End() + } + + format, err := p.tryParseFormat(p.Pos()) + if err != nil { + return nil, err + } + if format != nil { + selectStmt.Format = format + selectStmt.StatementEnd = format.End() + } + + // ClickHouse allows a set operator after ')' only when no SETTINGS + // or FORMAT was consumed: (SELECT 1) SETTINGS a=1 UNION ALL SELECT 2 + // is a syntax error there. + if settings != nil || format != nil { + return selectStmt, nil + } + } else { + selectStmt, err = p.parseSelectStmt(p.Pos()) + if err != nil { + return nil, err + } + } + + if err := p.parseSetOperation(selectStmt); err != nil { return nil, err } + + return selectStmt, nil +} + +// parseSetOperation binds a trailing UNION|EXCEPT|INTERSECT to selectStmt. +// The right operand consumes the rest of the chain by recursing into +// parseSelectQuery, so at most one operator is bound per call. +func (p *Parser) parseSetOperation(selectStmt *SelectQuery) error { switch { case p.tryConsumeKeywords(KeywordUnion): switch { case p.tryConsumeKeywords(KeywordAll): unionAllExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { - return nil, err + return err } selectStmt.UnionAll = unionAllExpr case p.tryConsumeKeywords(KeywordDistinct): unionDistinctExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { - return nil, err + return err } selectStmt.UnionDistinct = unionDistinctExpr default: - return nil, fmt.Errorf("expected ALL or DISTINCT, got %s", p.currentTokenKind()) + return fmt.Errorf("expected ALL or DISTINCT, got %s", p.currentTokenKind()) } case p.tryConsumeKeywords(KeywordExcept): exceptExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { - return nil, err + return err } selectStmt.Except = exceptExpr case p.tryConsumeKeywords(KeywordIntersect): intersectExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { - return nil, err + return err } selectStmt.Intersect = intersectExpr } - if hasParen { - if err := p.expectTokenKind(TokenKindRParen); err != nil { - return nil, err - } - } - return selectStmt, nil + + return nil } func (p *Parser) parseSelectStmt(pos Pos) (*SelectQuery, error) { // nolint: funlen @@ -1265,11 +1317,14 @@ func (p *Parser) parseCTEStmt(pos Pos) (*CTEStmt, error) { if err := p.expectKeyword(KeywordAs); err != nil { return nil, err } - if p.matchTokenKind(TokenKindLParen) { + if p.tryConsumeTokenKind(TokenKindLParen) != nil { selectQuery, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } + if err := p.expectTokenKind(TokenKindRParen); err != nil { + return nil, err + } return &CTEStmt{ CTEPos: pos, Expr: expr, diff --git a/parser/parser_table.go b/parser/parser_table.go index a29fd45..30bd1d9 100644 --- a/parser/parser_table.go +++ b/parser/parser_table.go @@ -1498,7 +1498,7 @@ func (p *Parser) parseStmt(pos Pos) (Expr, error) { p.matchKeyword(KeywordTruncate), p.matchKeyword(KeywordRename): expr, err = p.parseDDL(pos) - case p.matchKeyword(KeywordSelect), p.matchKeyword(KeywordWith): + case p.matchKeyword(KeywordSelect), p.matchKeyword(KeywordWith), p.matchTokenKind(TokenKindLParen): expr, err = p.parseSelectQuery(pos) case p.matchKeyword(KeywordDelete): expr, err = p.parseDeleteClause(pos) diff --git a/parser/parser_test.go b/parser/parser_test.go index 78a2b93..142c4e8 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -237,6 +237,13 @@ func TestParser_InvalidSyntax(t *testing.T) { "SELECT a GLOBAL", "SELECT a REGEXP", "SELECT * FROM t WHERE a AND", + // A parenthesized select must still be closed and UNION still needs + // ALL or DISTINCT + "(SELECT 1", + "(SELECT 1) UNION SELECT 2", + // ClickHouse rejects a set operator once SETTINGS is bound to a + // parenthesized group + "(SELECT 1) SETTINGS max_threads=1 UNION ALL SELECT 2", } for _, sql := range invalidSQLs { parser := NewParser(sql) @@ -244,3 +251,51 @@ func TestParser_InvalidSyntax(t *testing.T) { require.Error(t, err, "Expected error for SQL: %s", sql) } } + +func TestParser_ParenthesizedSetOperationOperands(t *testing.T) { + // A parenthesized operand becomes a group node, so the operator after + // ')' binds to the whole group instead of leaking into its chain. + stmts, err := NewParser("(SELECT 1 UNION DISTINCT SELECT 2) UNION ALL SELECT 3").ParseStmts() + require.NoError(t, err) + require.Len(t, stmts, 1) + + group, ok := stmts[0].(*SelectQuery) + require.True(t, ok) + require.NotNil(t, group.InnerQuery) + require.NotNil(t, group.InnerQuery.UnionDistinct) + require.NotNil(t, group.UnionAll) + require.Nil(t, group.InnerQuery.UnionDistinct.UnionAll) + + stmts, err = NewParser("SELECT a FROM ((SELECT 1 AS a) UNION ALL (SELECT 2 AS a))").ParseStmts() + require.NoError(t, err) + require.Len(t, stmts, 1) + + outer, ok := stmts[0].(*SelectQuery) + require.True(t, ok) + joinTable, ok := outer.From.Expr.(*JoinTableExpr) + require.True(t, ok) + subQuery, ok := joinTable.Table.Expr.(*SubQuery) + require.True(t, ok) + require.NotNil(t, subQuery.Select.InnerQuery) + require.NotNil(t, subQuery.Select.UnionAll) + require.NotNil(t, subQuery.Select.UnionAll.InnerQuery) + + // Grouping survives the round trip: ClickHouse gives INTERSECT higher + // precedence than UNION, so dropping the parens would change semantics. + sql := "(SELECT 1 UNION ALL SELECT 2) INTERSECT SELECT 2" + stmts, err = NewParser(sql).ParseStmts() + require.NoError(t, err) + require.Len(t, stmts, 1) + require.Equal(t, sql, Format(stmts[0])) + + // SETTINGS and FORMAT after ')' bind to the group. + stmts, err = NewParser("(SELECT 1) SETTINGS max_threads=1 FORMAT JSONEachRow").ParseStmts() + require.NoError(t, err) + require.Len(t, stmts, 1) + + group, ok = stmts[0].(*SelectQuery) + require.True(t, ok) + require.NotNil(t, group.InnerQuery) + require.NotNil(t, group.Settings) + require.NotNil(t, group.Format) +} diff --git a/parser/testdata/query/format/beautify/select_with_parenthesized_union.sql b/parser/testdata/query/format/beautify/select_with_parenthesized_union.sql new file mode 100644 index 0000000..7c775b9 --- /dev/null +++ b/parser/testdata/query/format/beautify/select_with_parenthesized_union.sql @@ -0,0 +1,102 @@ +-- Origin SQL: +SELECT a FROM ((SELECT 1 AS a) UNION ALL (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) UNION DISTINCT SELECT 2 AS a); +SELECT a FROM ((SELECT 1 AS a) EXCEPT (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) INTERSECT (SELECT 2 AS a)); +(SELECT 1 AS a) UNION ALL SELECT 2 AS a; +(SELECT 1 UNION ALL SELECT 2) UNION ALL SELECT 3; +SELECT 1 UNION ALL (SELECT 2) UNION ALL SELECT 3; +SELECT a FROM (((SELECT 1 AS a))); +(SELECT 1 UNION ALL SELECT 2) INTERSECT SELECT 2; +SELECT 1 INTERSECT (SELECT 2 UNION ALL SELECT 1); +(SELECT 1) SETTINGS max_threads=1; +(SELECT 1 UNION ALL SELECT 2) SETTINGS max_threads=1 FORMAT JSONEachRow; + + +-- Beautify SQL: +SELECT + a +FROM + ((SELECT + 1 AS a) + UNION ALL + (SELECT + 2 AS a)); +SELECT + a +FROM + ((SELECT + 1 AS a) + UNION DISTINCT + SELECT + 2 AS a); +SELECT + a +FROM + ((SELECT + 1 AS a) + EXCEPT + (SELECT + 2 AS a)); +SELECT + a +FROM + ((SELECT + 1 AS a) + INTERSECT + (SELECT + 2 AS a)); +(SELECT + 1 AS a) +UNION ALL +SELECT + 2 AS a; +(SELECT + 1 +UNION ALL +SELECT + 2) +UNION ALL +SELECT + 3; +SELECT + 1 +UNION ALL +(SELECT + 2) +UNION ALL +SELECT + 3; +SELECT + a +FROM + (((SELECT + 1 AS a))); +(SELECT + 1 +UNION ALL +SELECT + 2) +INTERSECT +SELECT + 2; +SELECT + 1 +INTERSECT +(SELECT + 2 +UNION ALL +SELECT + 1); +(SELECT + 1) +SETTINGS + max_threads=1; +(SELECT + 1 +UNION ALL +SELECT + 2) +SETTINGS + max_threads=1 +FORMAT JSONEachRow; diff --git a/parser/testdata/query/format/select_with_parenthesized_union.sql b/parser/testdata/query/format/select_with_parenthesized_union.sql new file mode 100644 index 0000000..52e14ca --- /dev/null +++ b/parser/testdata/query/format/select_with_parenthesized_union.sql @@ -0,0 +1,28 @@ +-- Origin SQL: +SELECT a FROM ((SELECT 1 AS a) UNION ALL (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) UNION DISTINCT SELECT 2 AS a); +SELECT a FROM ((SELECT 1 AS a) EXCEPT (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) INTERSECT (SELECT 2 AS a)); +(SELECT 1 AS a) UNION ALL SELECT 2 AS a; +(SELECT 1 UNION ALL SELECT 2) UNION ALL SELECT 3; +SELECT 1 UNION ALL (SELECT 2) UNION ALL SELECT 3; +SELECT a FROM (((SELECT 1 AS a))); +(SELECT 1 UNION ALL SELECT 2) INTERSECT SELECT 2; +SELECT 1 INTERSECT (SELECT 2 UNION ALL SELECT 1); +(SELECT 1) SETTINGS max_threads=1; +(SELECT 1 UNION ALL SELECT 2) SETTINGS max_threads=1 FORMAT JSONEachRow; + + +-- Format SQL: +SELECT a FROM ((SELECT 1 AS a) UNION ALL (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) UNION DISTINCT SELECT 2 AS a); +SELECT a FROM ((SELECT 1 AS a) EXCEPT (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) INTERSECT (SELECT 2 AS a)); +(SELECT 1 AS a) UNION ALL SELECT 2 AS a; +(SELECT 1 UNION ALL SELECT 2) UNION ALL SELECT 3; +SELECT 1 UNION ALL (SELECT 2) UNION ALL SELECT 3; +SELECT a FROM (((SELECT 1 AS a))); +(SELECT 1 UNION ALL SELECT 2) INTERSECT SELECT 2; +SELECT 1 INTERSECT (SELECT 2 UNION ALL SELECT 1); +(SELECT 1) SETTINGS max_threads=1; +(SELECT 1 UNION ALL SELECT 2) SETTINGS max_threads=1 FORMAT JSONEachRow; diff --git a/parser/testdata/query/output/select_with_parenthesized_union.sql.golden.json b/parser/testdata/query/output/select_with_parenthesized_union.sql.golden.json new file mode 100644 index 0000000..c86e647 --- /dev/null +++ b/parser/testdata/query/output/select_with_parenthesized_union.sql.golden.json @@ -0,0 +1,1687 @@ +[ + { + "SelectPos": 0, + "StatementEnd": 30, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "Name": "a", + "QuoteType": 1, + "NamePos": 7, + "NameEnd": 8 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 9, + "Expr": { + "Table": { + "TablePos": 14, + "TableEnd": 30, + "Alias": null, + "Expr": { + "HasParen": true, + "Select": { + "SelectPos": 15, + "StatementEnd": 30, + "InnerQuery": { + "SelectPos": 16, + "StatementEnd": 29, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 23, + "NumEnd": 24, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 28, + "NameEnd": 29 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 41, + "StatementEnd": 56, + "InnerQuery": { + "SelectPos": 42, + "StatementEnd": 55, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 49, + "NumEnd": 50, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 54, + "NameEnd": 55 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + } + }, + "HasFinal": false + }, + "StatementEnd": 30, + "SampleRatio": null, + "HasFinal": false + } + }, + "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, + "Intersect": null + }, + { + "SelectPos": 59, + "StatementEnd": 89, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "Name": "a", + "QuoteType": 1, + "NamePos": 66, + "NameEnd": 67 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 68, + "Expr": { + "Table": { + "TablePos": 73, + "TableEnd": 89, + "Alias": null, + "Expr": { + "HasParen": true, + "Select": { + "SelectPos": 74, + "StatementEnd": 89, + "InnerQuery": { + "SelectPos": 75, + "StatementEnd": 88, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 82, + "NumEnd": 83, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 87, + "NameEnd": 88 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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": 105, + "StatementEnd": 118, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 112, + "NumEnd": 113, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 117, + "NameEnd": 118 + } + } + ], + "From": 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, + "Intersect": null + }, + "Except": null, + "Intersect": null + } + }, + "HasFinal": false + }, + "StatementEnd": 89, + "SampleRatio": null, + "HasFinal": false + } + }, + "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, + "Intersect": null + }, + { + "SelectPos": 121, + "StatementEnd": 151, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "Name": "a", + "QuoteType": 1, + "NamePos": 128, + "NameEnd": 129 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 130, + "Expr": { + "Table": { + "TablePos": 135, + "TableEnd": 151, + "Alias": null, + "Expr": { + "HasParen": true, + "Select": { + "SelectPos": 136, + "StatementEnd": 151, + "InnerQuery": { + "SelectPos": 137, + "StatementEnd": 150, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 144, + "NumEnd": 145, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 149, + "NameEnd": 150 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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": 159, + "StatementEnd": 174, + "InnerQuery": { + "SelectPos": 160, + "StatementEnd": 173, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 167, + "NumEnd": 168, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 172, + "NameEnd": 173 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": null + }, + "Intersect": null + } + }, + "HasFinal": false + }, + "StatementEnd": 151, + "SampleRatio": null, + "HasFinal": false + } + }, + "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, + "Intersect": null + }, + { + "SelectPos": 177, + "StatementEnd": 207, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "Name": "a", + "QuoteType": 1, + "NamePos": 184, + "NameEnd": 185 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 186, + "Expr": { + "Table": { + "TablePos": 191, + "TableEnd": 207, + "Alias": null, + "Expr": { + "HasParen": true, + "Select": { + "SelectPos": 192, + "StatementEnd": 207, + "InnerQuery": { + "SelectPos": 193, + "StatementEnd": 206, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 200, + "NumEnd": 201, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 205, + "NameEnd": 206 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": { + "SelectPos": 218, + "StatementEnd": 233, + "InnerQuery": { + "SelectPos": 219, + "StatementEnd": 232, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 226, + "NumEnd": 227, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 231, + "NameEnd": 232 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": null + } + } + }, + "HasFinal": false + }, + "StatementEnd": 207, + "SampleRatio": null, + "HasFinal": false + } + }, + "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, + "Intersect": null + }, + { + "SelectPos": 236, + "StatementEnd": 251, + "InnerQuery": { + "SelectPos": 237, + "StatementEnd": 250, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 244, + "NumEnd": 245, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 249, + "NameEnd": 250 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 262, + "StatementEnd": 275, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 269, + "NumEnd": 270, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 274, + "NameEnd": 275 + } + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + { + "SelectPos": 277, + "StatementEnd": 306, + "InnerQuery": { + "SelectPos": 278, + "StatementEnd": 286, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 285, + "NumEnd": 286, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 297, + "StatementEnd": 305, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 304, + "NumEnd": 305, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 317, + "StatementEnd": 325, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 324, + "NumEnd": 325, + "Literal": "3", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + { + "SelectPos": 327, + "StatementEnd": 335, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 334, + "NumEnd": 335, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 346, + "StatementEnd": 356, + "InnerQuery": { + "SelectPos": 347, + "StatementEnd": 355, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 354, + "NumEnd": 355, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 367, + "StatementEnd": 375, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 374, + "NumEnd": 375, + "Literal": "3", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + { + "SelectPos": 377, + "StatementEnd": 409, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "Name": "a", + "QuoteType": 1, + "NamePos": 384, + "NameEnd": 385 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": { + "FromPos": 386, + "Expr": { + "Table": { + "TablePos": 391, + "TableEnd": 409, + "Alias": null, + "Expr": { + "HasParen": true, + "Select": { + "SelectPos": 392, + "StatementEnd": 409, + "InnerQuery": { + "SelectPos": 393, + "StatementEnd": 408, + "InnerQuery": { + "SelectPos": 394, + "StatementEnd": 407, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 401, + "NumEnd": 402, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": { + "Name": "a", + "QuoteType": 1, + "NamePos": 406, + "NameEnd": 407 + } + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": null + } + }, + "HasFinal": false + }, + "StatementEnd": 409, + "SampleRatio": null, + "HasFinal": false + } + }, + "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, + "Intersect": null + }, + { + "SelectPos": 412, + "StatementEnd": 441, + "InnerQuery": { + "SelectPos": 413, + "StatementEnd": 421, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 420, + "NumEnd": 421, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 432, + "StatementEnd": 440, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 439, + "NumEnd": 440, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": { + "SelectPos": 452, + "StatementEnd": 460, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 459, + "NumEnd": 460, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + } + }, + { + "SelectPos": 462, + "StatementEnd": 470, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 469, + "NumEnd": 470, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": { + "SelectPos": 481, + "StatementEnd": 510, + "InnerQuery": { + "SelectPos": 482, + "StatementEnd": 490, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 489, + "NumEnd": 490, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 501, + "StatementEnd": 509, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 508, + "NumEnd": 509, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": 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, + "Intersect": null + } + }, + { + "SelectPos": 512, + "StatementEnd": 545, + "InnerQuery": { + "SelectPos": 513, + "StatementEnd": 521, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 520, + "NumEnd": 521, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": { + "SettingsPos": 523, + "ListEnd": 545, + "Items": [ + { + "SettingsPos": 532, + "Name": { + "Name": "max_threads", + "QuoteType": 1, + "NamePos": 532, + "NameEnd": 543 + }, + "Expr": { + "NumPos": 544, + "NumEnd": 545, + "Literal": "1", + "Base": 10 + } + } + ] + }, + "Format": null, + "UnionAll": null, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + { + "SelectPos": 547, + "StatementEnd": 618, + "InnerQuery": { + "SelectPos": 548, + "StatementEnd": 556, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 555, + "NumEnd": 556, + "Literal": "1", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": null, + "Format": null, + "UnionAll": { + "SelectPos": 567, + "StatementEnd": 575, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": [ + { + "Expr": { + "NumPos": 574, + "NumEnd": 575, + "Literal": "2", + "Base": 10 + }, + "Modifiers": [], + "Alias": null + } + ], + "From": 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, + "Intersect": null + }, + "UnionDistinct": null, + "Except": null, + "Intersect": null + }, + "With": null, + "Top": null, + "HasDistinct": false, + "DistinctOn": null, + "SelectItems": null, + "From": null, + "Window": null, + "Prewhere": null, + "Where": null, + "GroupBy": null, + "WithTotal": false, + "Having": null, + "OrderBy": null, + "LimitBy": null, + "Limit": null, + "Settings": { + "SettingsPos": 577, + "ListEnd": 599, + "Items": [ + { + "SettingsPos": 586, + "Name": { + "Name": "max_threads", + "QuoteType": 1, + "NamePos": 586, + "NameEnd": 597 + }, + "Expr": { + "NumPos": 598, + "NumEnd": 599, + "Literal": "1", + "Base": 10 + } + } + ] + }, + "Format": { + "FormatPos": 600, + "Format": { + "Name": "JSONEachRow", + "QuoteType": 1, + "NamePos": 607, + "NameEnd": 618 + } + }, + "UnionAll": null, + "UnionDistinct": null, + "Except": null, + "Intersect": null + } +] \ No newline at end of file diff --git a/parser/testdata/query/select_with_parenthesized_union.sql b/parser/testdata/query/select_with_parenthesized_union.sql new file mode 100644 index 0000000..766d02c --- /dev/null +++ b/parser/testdata/query/select_with_parenthesized_union.sql @@ -0,0 +1,12 @@ +SELECT a FROM ((SELECT 1 AS a) UNION ALL (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) UNION DISTINCT SELECT 2 AS a); +SELECT a FROM ((SELECT 1 AS a) EXCEPT (SELECT 2 AS a)); +SELECT a FROM ((SELECT 1 AS a) INTERSECT (SELECT 2 AS a)); +(SELECT 1 AS a) UNION ALL SELECT 2 AS a; +(SELECT 1 UNION ALL SELECT 2) UNION ALL SELECT 3; +SELECT 1 UNION ALL (SELECT 2) UNION ALL SELECT 3; +SELECT a FROM (((SELECT 1 AS a))); +(SELECT 1 UNION ALL SELECT 2) INTERSECT SELECT 2; +SELECT 1 INTERSECT (SELECT 2 UNION ALL SELECT 1); +(SELECT 1) SETTINGS max_threads=1; +(SELECT 1 UNION ALL SELECT 2) SETTINGS max_threads=1 FORMAT JSONEachRow; diff --git a/parser/walk.go b/parser/walk.go index e129a35..67ff901 100644 --- a/parser/walk.go +++ b/parser/walk.go @@ -19,6 +19,9 @@ func Walk(node Expr, fn WalkFunc) bool { switch n := node.(type) { case *SelectQuery: + if !Walk(n.InnerQuery, fn) { + return false + } if !Walk(n.With, fn) { return false }