From eeeb53ac6757ebef6e6881eccd8acb9885cdf230 Mon Sep 17 00:00:00 2001 From: Jason Mo Date: Fri, 29 Dec 2023 10:15:39 +0800 Subject: [PATCH 1/6] parser: fix limit lost in SetOprStmt --- pkg/parser/parser.go | 36 ++++++++++++++++++++++++++++++------ pkg/parser/parser.y | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 76a1f7134f5be..89db7b3b6385c 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -19931,6 +19931,8 @@ yynewstate: } var setOprList2 []ast.Node var with2 *ast.WithClause + var limit2 *ast.Limit + var orderBy2 *ast.OrderByClause switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList2 = []ast.Node{x} @@ -19938,8 +19940,10 @@ yynewstate: case *ast.SetOprStmt: setOprList2 = x.SelectList.Selects with2 = x.With + limit2 = x.Limit + orderBy2 = x.OrderBy } - nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2} + nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2, Limit: limit2, OrderBy: orderBy2} nextSetOprList.AfterSetOperator = yyS[yypt-2].item.(*ast.SetOprType) setOprList := append(setOprList1, nextSetOprList) setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} @@ -19955,6 +19959,8 @@ yynewstate: } var setOprList2 []ast.Node var with2 *ast.WithClause + var limit2 *ast.Limit + var orderBy2 *ast.OrderByClause switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList2 = []ast.Node{x} @@ -19962,8 +19968,10 @@ yynewstate: case *ast.SetOprStmt: setOprList2 = x.SelectList.Selects with2 = x.With + limit2 = x.Limit + orderBy2 = x.OrderBy } - nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2} + nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2, Limit: limit2, OrderBy: orderBy2} nextSetOprList.AfterSetOperator = yyS[yypt-2].item.(*ast.SetOprType) setOprList := append(setOprList1, nextSetOprList) setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} @@ -19979,6 +19987,8 @@ yynewstate: } var setOprList2 []ast.Node var with2 *ast.WithClause + var limit2 *ast.Limit + var orderBy2 *ast.OrderByClause switch x := yyS[yypt-2].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList2 = []ast.Node{x} @@ -19986,8 +19996,10 @@ yynewstate: case *ast.SetOprStmt: setOprList2 = x.SelectList.Selects with2 = x.With + limit2 = x.Limit + orderBy2 = x.OrderBy } - nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2} + nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2, Limit: limit2, OrderBy: orderBy2} nextSetOprList.AfterSetOperator = yyS[yypt-3].item.(*ast.SetOprType) setOprList := append(setOprList1, nextSetOprList) setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} @@ -19999,6 +20011,8 @@ yynewstate: { var setOprList []ast.Node var with *ast.WithClause + var limit *ast.Limit + var orderBy *ast.OrderByClause switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList = []ast.Node{x} @@ -20006,8 +20020,10 @@ yynewstate: case *ast.SetOprStmt: setOprList = x.SelectList.Selects with = x.With + limit = x.Limit + orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} setOpr.OrderBy = yyS[yypt-0].item.(*ast.OrderByClause) parser.yyVAL.statement = setOpr } @@ -20015,6 +20031,8 @@ yynewstate: { var setOprList []ast.Node var with *ast.WithClause + var limit *ast.Limit + var orderBy *ast.OrderByClause switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList = []ast.Node{x} @@ -20022,8 +20040,10 @@ yynewstate: case *ast.SetOprStmt: setOprList = x.SelectList.Selects with = x.With + limit = x.Limit + orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } @@ -20031,6 +20051,8 @@ yynewstate: { var setOprList []ast.Node var with *ast.WithClause + var limit *ast.Limit + var orderBy *ast.OrderByClause switch x := yyS[yypt-2].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList = []ast.Node{x} @@ -20038,8 +20060,10 @@ yynewstate: case *ast.SetOprStmt: setOprList = x.SelectList.Selects with = x.With + limit = x.Limit + orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} setOpr.OrderBy = yyS[yypt-1].item.(*ast.OrderByClause) setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr diff --git a/pkg/parser/parser.y b/pkg/parser/parser.y index ef5bebda7edf1..84e09d386df9f 100644 --- a/pkg/parser/parser.y +++ b/pkg/parser/parser.y @@ -10260,6 +10260,8 @@ SetOprStmtWithLimitOrderBy: } var setOprList2 []ast.Node var with2 *ast.WithClause + var limit2 *ast.Limit + var orderBy2 *ast.OrderByClause switch x := $3.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList2 = []ast.Node{x} @@ -10267,8 +10269,10 @@ SetOprStmtWithLimitOrderBy: case *ast.SetOprStmt: setOprList2 = x.SelectList.Selects with2 = x.With + limit2 = x.Limit + orderBy2 = x.OrderBy } - nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2} + nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2, Limit: limit2, OrderBy: orderBy2} nextSetOprList.AfterSetOperator = $2.(*ast.SetOprType) setOprList := append(setOprList1, nextSetOprList) setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} @@ -10284,6 +10288,8 @@ SetOprStmtWithLimitOrderBy: } var setOprList2 []ast.Node var with2 *ast.WithClause + var limit2 *ast.Limit + var orderBy2 *ast.OrderByClause switch x := $3.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList2 = []ast.Node{x} @@ -10291,8 +10297,10 @@ SetOprStmtWithLimitOrderBy: case *ast.SetOprStmt: setOprList2 = x.SelectList.Selects with2 = x.With + limit2 = x.Limit + orderBy2 = x.OrderBy } - nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2} + nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2, Limit: limit2, OrderBy: orderBy2} nextSetOprList.AfterSetOperator = $2.(*ast.SetOprType) setOprList := append(setOprList1, nextSetOprList) setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} @@ -10308,6 +10316,8 @@ SetOprStmtWithLimitOrderBy: } var setOprList2 []ast.Node var with2 *ast.WithClause + var limit2 *ast.Limit + var orderBy2 *ast.OrderByClause switch x := $3.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList2 = []ast.Node{x} @@ -10315,8 +10325,10 @@ SetOprStmtWithLimitOrderBy: case *ast.SetOprStmt: setOprList2 = x.SelectList.Selects with2 = x.With + limit2 = x.Limit + orderBy2 = x.OrderBy } - nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2} + nextSetOprList := &ast.SetOprSelectList{Selects: setOprList2, With: with2, Limit: limit2, OrderBy: orderBy2} nextSetOprList.AfterSetOperator = $2.(*ast.SetOprType) setOprList := append(setOprList1, nextSetOprList) setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} @@ -10328,6 +10340,8 @@ SetOprStmtWithLimitOrderBy: { var setOprList []ast.Node var with *ast.WithClause + var limit *ast.Limit + var orderBy *ast.OrderByClause switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList = []ast.Node{x} @@ -10335,8 +10349,10 @@ SetOprStmtWithLimitOrderBy: case *ast.SetOprStmt: setOprList = x.SelectList.Selects with = x.With + limit = x.Limit + orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} setOpr.OrderBy = $2.(*ast.OrderByClause) $$ = setOpr } @@ -10344,6 +10360,8 @@ SetOprStmtWithLimitOrderBy: { var setOprList []ast.Node var with *ast.WithClause + var limit *ast.Limit + var orderBy *ast.OrderByClause switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList = []ast.Node{x} @@ -10351,8 +10369,10 @@ SetOprStmtWithLimitOrderBy: case *ast.SetOprStmt: setOprList = x.SelectList.Selects with = x.With + limit = x.Limit + orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} setOpr.Limit = $2.(*ast.Limit) $$ = setOpr } @@ -10360,6 +10380,8 @@ SetOprStmtWithLimitOrderBy: { var setOprList []ast.Node var with *ast.WithClause + var limit *ast.Limit + var orderBy *ast.OrderByClause switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: setOprList = []ast.Node{x} @@ -10367,8 +10389,10 @@ SetOprStmtWithLimitOrderBy: case *ast.SetOprStmt: setOprList = x.SelectList.Selects with = x.With + limit = x.Limit + orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} setOpr.OrderBy = $2.(*ast.OrderByClause) setOpr.Limit = $3.(*ast.Limit) $$ = setOpr From c3b4ccd8de0c05c4e80fed0fd3e747433e019ec3 Mon Sep 17 00:00:00 2001 From: Jason Mo Date: Fri, 29 Dec 2023 11:09:07 +0800 Subject: [PATCH 2/6] add test --- pkg/parser/ast/dml.go | 29 +++++++++++++++++++++++++++++ pkg/parser/parser_test.go | 4 ++++ 2 files changed, 33 insertions(+) diff --git a/pkg/parser/ast/dml.go b/pkg/parser/ast/dml.go index c13b836b18331..fad988a29eb6a 100644 --- a/pkg/parser/ast/dml.go +++ b/pkg/parser/ast/dml.go @@ -1569,6 +1569,7 @@ func (n *SetOprSelectList) Restore(ctx *format.RestoreCtx) error { return errors.Annotate(err, "An error occurred while restore SetOprSelectList.With") } } + for i, stmt := range n.Selects { switch selectStmt := stmt.(type) { case *SelectStmt: @@ -1590,6 +1591,20 @@ func (n *SetOprSelectList) Restore(ctx *format.RestoreCtx) error { ctx.WritePlain(")") } } + + if n.OrderBy != nil { + ctx.WritePlain(" ") + if err := n.OrderBy.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore SetOprSelectList.OrderBy") + } + } + + if n.Limit != nil { + ctx.WritePlain(" ") + if err := n.Limit.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore SetOprSelectList.Limit") + } + } return nil } @@ -1614,6 +1629,20 @@ func (n *SetOprSelectList) Accept(v Visitor) (Node, bool) { } n.Selects[i] = node } + if n.OrderBy != nil { + node, ok := n.OrderBy.Accept(v) + if !ok { + return n, false + } + n.OrderBy = node.(*OrderByClause) + } + if n.Limit != nil { + node, ok := n.Limit.Accept(v) + if !ok { + return n, false + } + n.Limit = node.(*Limit) + } return v.Leave(n) } diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go index a1ef0c55127ec..c0fdca15e67ed 100644 --- a/pkg/parser/parser_test.go +++ b/pkg/parser/parser_test.go @@ -5155,6 +5155,10 @@ func TestSetOperator(t *testing.T) { {"(select c1 from t1) union all (select c2 from t2 except select c3 from t3) order by c1 limit 1", true, "(SELECT `c1` FROM `t1`) UNION ALL (SELECT `c2` FROM `t2` EXCEPT SELECT `c3` FROM `t3`) ORDER BY `c1` LIMIT 1"}, {"((select c1 from t1) except select c2 from t2) intersect all (select c3 from t3) order by c1 limit 1", true, "((SELECT `c1` FROM `t1`) EXCEPT SELECT `c2` FROM `t2`) INTERSECT ALL (SELECT `c3` FROM `t3`) ORDER BY `c1` LIMIT 1"}, {"select 1 union distinct (select 1 except all select 1 intersect select 1)", true, "SELECT 1 UNION (SELECT 1 EXCEPT ALL SELECT 1 INTERSECT SELECT 1)"}, + {"select * from a where PK = 0 union all (select * from b where PK = 0 union all (select * from b where PK != 0) order by pk limit 1)", true, + "SELECT * FROM `a` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`!=0) ORDER BY `pk` LIMIT 1)"}, + {"select * from a where PK = 0 union all (select * from b where PK = 0 union all (select * from b where PK != 0) order by pk limit 1) order by pk limit 2", true, + "SELECT * FROM `a` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`!=0) ORDER BY `pk` LIMIT 1) ORDER BY `pk` LIMIT 2"}, } RunTest(t, table, false) } From 502e4213a72be5a610efd4246782a9cd9ac22e4d Mon Sep 17 00:00:00 2001 From: Jason Mo Date: Fri, 29 Dec 2023 13:01:25 +0800 Subject: [PATCH 3/6] add more test cases --- pkg/parser/ast/dml.go | 8 ++++++++ pkg/parser/parser.go | 8 ++++---- pkg/parser/parser.y | 8 ++++---- pkg/parser/parser_test.go | 6 ++++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/pkg/parser/ast/dml.go b/pkg/parser/ast/dml.go index fad988a29eb6a..56dd5a6d61441 100644 --- a/pkg/parser/ast/dml.go +++ b/pkg/parser/ast/dml.go @@ -1554,6 +1554,7 @@ func (n *SelectStmt) Accept(v Visitor) (Node, bool) { type SetOprSelectList struct { node + IsInBraces bool With *WithClause AfterSetOperator *SetOprType Selects []Node @@ -1570,6 +1571,13 @@ func (n *SetOprSelectList) Restore(ctx *format.RestoreCtx) error { } } + if n.IsInBraces { + ctx.WritePlain("(") + defer func() { + ctx.WritePlain(")") + }() + } + for i, stmt := range n.Selects { switch selectStmt := stmt.(type) { case *SelectStmt: diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 89db7b3b6385c..9287b5c9cf288 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -20023,7 +20023,7 @@ yynewstate: limit = x.Limit orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} setOpr.OrderBy = yyS[yypt-0].item.(*ast.OrderByClause) parser.yyVAL.statement = setOpr } @@ -20043,7 +20043,7 @@ yynewstate: limit = x.Limit orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } @@ -20063,7 +20063,7 @@ yynewstate: limit = x.Limit orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} setOpr.OrderBy = yyS[yypt-1].item.(*ast.OrderByClause) setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr @@ -20095,7 +20095,7 @@ yynewstate: case *ast.SelectStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } parser.yyVAL.item = setOprList } diff --git a/pkg/parser/parser.y b/pkg/parser/parser.y index 84e09d386df9f..15085c5bbf2f6 100644 --- a/pkg/parser/parser.y +++ b/pkg/parser/parser.y @@ -10352,7 +10352,7 @@ SetOprStmtWithLimitOrderBy: limit = x.Limit orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} setOpr.OrderBy = $2.(*ast.OrderByClause) $$ = setOpr } @@ -10372,7 +10372,7 @@ SetOprStmtWithLimitOrderBy: limit = x.Limit orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} setOpr.Limit = $2.(*ast.Limit) $$ = setOpr } @@ -10392,7 +10392,7 @@ SetOprStmtWithLimitOrderBy: limit = x.Limit orderBy = x.OrderBy } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}, With: with, Limit: limit, OrderBy: orderBy} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} setOpr.OrderBy = $2.(*ast.OrderByClause) setOpr.Limit = $3.(*ast.Limit) $$ = setOpr @@ -10429,7 +10429,7 @@ SetOprClause: case *ast.SelectStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } $$ = setOprList } diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go index c0fdca15e67ed..dadc5e77f121b 100644 --- a/pkg/parser/parser_test.go +++ b/pkg/parser/parser_test.go @@ -5155,10 +5155,16 @@ func TestSetOperator(t *testing.T) { {"(select c1 from t1) union all (select c2 from t2 except select c3 from t3) order by c1 limit 1", true, "(SELECT `c1` FROM `t1`) UNION ALL (SELECT `c2` FROM `t2` EXCEPT SELECT `c3` FROM `t3`) ORDER BY `c1` LIMIT 1"}, {"((select c1 from t1) except select c2 from t2) intersect all (select c3 from t3) order by c1 limit 1", true, "((SELECT `c1` FROM `t1`) EXCEPT SELECT `c2` FROM `t2`) INTERSECT ALL (SELECT `c3` FROM `t3`) ORDER BY `c1` LIMIT 1"}, {"select 1 union distinct (select 1 except all select 1 intersect select 1)", true, "SELECT 1 UNION (SELECT 1 EXCEPT ALL SELECT 1 INTERSECT SELECT 1)"}, + + // https://github.com/pingcap/tidb/issues/49874 {"select * from a where PK = 0 union all (select * from b where PK = 0 union all (select * from b where PK != 0) order by pk limit 1)", true, "SELECT * FROM `a` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`!=0) ORDER BY `pk` LIMIT 1)"}, {"select * from a where PK = 0 union all (select * from b where PK = 0 union all (select * from b where PK != 0) order by pk limit 1) order by pk limit 2", true, "SELECT * FROM `a` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`=0 UNION ALL (SELECT * FROM `b` WHERE `PK`!=0) ORDER BY `pk` LIMIT 1) ORDER BY `pk` LIMIT 2"}, + {"(select * from b where pk= 0 union all (select * from b where pk !=0) order by pk limit 1) order by pk limit 2", true, + "(SELECT * FROM `b` WHERE `pk`=0 UNION ALL (SELECT * FROM `b` WHERE `pk`!=0) ORDER BY `pk` LIMIT 1) ORDER BY `pk` LIMIT 2"}, + {"(select * from b where pk= 0 union all (select * from b where pk !=0) order by pk limit 1) order by pk", true, + "(SELECT * FROM `b` WHERE `pk`=0 UNION ALL (SELECT * FROM `b` WHERE `pk`!=0) ORDER BY `pk` LIMIT 1) ORDER BY `pk`"}, } RunTest(t, table, false) } From a600ed1c43f06b3021b90546248234ba08cf8cc1 Mon Sep 17 00:00:00 2001 From: Jason Mo Date: Fri, 29 Dec 2023 13:06:18 +0800 Subject: [PATCH 4/6] update --- pkg/parser/parser.go | 2 +- pkg/parser/parser.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 9287b5c9cf288..6ed212d72f60a 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -20095,7 +20095,7 @@ yynewstate: case *ast.SelectStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy, IsInBraces: true}} } parser.yyVAL.item = setOprList } diff --git a/pkg/parser/parser.y b/pkg/parser/parser.y index 15085c5bbf2f6..85f87c5ae79e6 100644 --- a/pkg/parser/parser.y +++ b/pkg/parser/parser.y @@ -10429,7 +10429,7 @@ SetOprClause: case *ast.SelectStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy, IsInBraces: true}} } $$ = setOprList } From 331b60189731152f304a754c89d01da05032a9ed Mon Sep 17 00:00:00 2001 From: Jason Mo Date: Fri, 29 Dec 2023 13:41:28 +0800 Subject: [PATCH 5/6] update --- pkg/parser/ast/dml.go | 8 -------- pkg/parser/parser.go | 41 ++++++++++------------------------------- pkg/parser/parser.y | 41 ++++++++++------------------------------- 3 files changed, 20 insertions(+), 70 deletions(-) diff --git a/pkg/parser/ast/dml.go b/pkg/parser/ast/dml.go index 56dd5a6d61441..fad988a29eb6a 100644 --- a/pkg/parser/ast/dml.go +++ b/pkg/parser/ast/dml.go @@ -1554,7 +1554,6 @@ func (n *SelectStmt) Accept(v Visitor) (Node, bool) { type SetOprSelectList struct { node - IsInBraces bool With *WithClause AfterSetOperator *SetOprType Selects []Node @@ -1571,13 +1570,6 @@ func (n *SetOprSelectList) Restore(ctx *format.RestoreCtx) error { } } - if n.IsInBraces { - ctx.WritePlain("(") - defer func() { - ctx.WritePlain(")") - }() - } - for i, stmt := range n.Selects { switch selectStmt := stmt.(type) { case *SelectStmt: diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 6ed212d72f60a..d62a72bf9ad19 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -20010,60 +20010,39 @@ yynewstate: case 1842: { var setOprList []ast.Node - var with *ast.WithClause - var limit *ast.Limit - var orderBy *ast.OrderByClause switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{x} - with = x.With + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = x.SelectList.Selects - with = x.With - limit = x.Limit - orderBy = x.OrderBy + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} setOpr.OrderBy = yyS[yypt-0].item.(*ast.OrderByClause) parser.yyVAL.statement = setOpr } case 1843: { var setOprList []ast.Node - var with *ast.WithClause - var limit *ast.Limit - var orderBy *ast.OrderByClause switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{x} - with = x.With + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = x.SelectList.Selects - with = x.With - limit = x.Limit - orderBy = x.OrderBy + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } case 1844: { var setOprList []ast.Node - var with *ast.WithClause - var limit *ast.Limit - var orderBy *ast.OrderByClause switch x := yyS[yypt-2].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{x} - with = x.With + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = x.SelectList.Selects - with = x.With - limit = x.Limit - orderBy = x.OrderBy + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} setOpr.OrderBy = yyS[yypt-1].item.(*ast.OrderByClause) setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr @@ -20095,7 +20074,7 @@ yynewstate: case *ast.SelectStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy, IsInBraces: true}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } parser.yyVAL.item = setOprList } diff --git a/pkg/parser/parser.y b/pkg/parser/parser.y index 85f87c5ae79e6..8461366a92a88 100644 --- a/pkg/parser/parser.y +++ b/pkg/parser/parser.y @@ -10339,60 +10339,39 @@ SetOprStmtWithLimitOrderBy: | SubSelect OrderBy { var setOprList []ast.Node - var with *ast.WithClause - var limit *ast.Limit - var orderBy *ast.OrderByClause switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{x} - with = x.With + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = x.SelectList.Selects - with = x.With - limit = x.Limit - orderBy = x.OrderBy + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} setOpr.OrderBy = $2.(*ast.OrderByClause) $$ = setOpr } | SubSelect SelectStmtLimit { var setOprList []ast.Node - var with *ast.WithClause - var limit *ast.Limit - var orderBy *ast.OrderByClause switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{x} - with = x.With + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = x.SelectList.Selects - with = x.With - limit = x.Limit - orderBy = x.OrderBy + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} setOpr.Limit = $2.(*ast.Limit) $$ = setOpr } | SubSelect OrderBy SelectStmtLimit { var setOprList []ast.Node - var with *ast.WithClause - var limit *ast.Limit - var orderBy *ast.OrderByClause switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{x} - with = x.With + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = x.SelectList.Selects - with = x.With - limit = x.Limit - orderBy = x.OrderBy + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } - setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList, With: with, Limit: limit, OrderBy: orderBy, IsInBraces: true}} + setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} setOpr.OrderBy = $2.(*ast.OrderByClause) setOpr.Limit = $3.(*ast.Limit) $$ = setOpr @@ -10429,7 +10408,7 @@ SetOprClause: case *ast.SelectStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} case *ast.SetOprStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy, IsInBraces: true}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } $$ = setOprList } From 41016342a3f9b0e4a41a50d4cc36f20b2501da56 Mon Sep 17 00:00:00 2001 From: Jason Mo Date: Fri, 29 Dec 2023 13:48:33 +0800 Subject: [PATCH 6/6] update --- pkg/parser/parser.go | 6 +++--- pkg/parser/parser.y | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index d62a72bf9ad19..fb5434872ee67 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -20012,7 +20012,7 @@ yynewstate: var setOprList []ast.Node switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}, With: x.With}} case *ast.SetOprStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } @@ -20025,7 +20025,7 @@ yynewstate: var setOprList []ast.Node switch x := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}, With: x.With}} case *ast.SetOprStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } @@ -20038,7 +20038,7 @@ yynewstate: var setOprList []ast.Node switch x := yyS[yypt-2].expr.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}, With: x.With}} case *ast.SetOprStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } diff --git a/pkg/parser/parser.y b/pkg/parser/parser.y index 8461366a92a88..5a5ec90db8fc9 100644 --- a/pkg/parser/parser.y +++ b/pkg/parser/parser.y @@ -10341,7 +10341,7 @@ SetOprStmtWithLimitOrderBy: var setOprList []ast.Node switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}, With: x.With}} case *ast.SetOprStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } @@ -10354,7 +10354,7 @@ SetOprStmtWithLimitOrderBy: var setOprList []ast.Node switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}, With: x.With}} case *ast.SetOprStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} } @@ -10367,7 +10367,7 @@ SetOprStmtWithLimitOrderBy: var setOprList []ast.Node switch x := $1.(*ast.SubqueryExpr).Query.(type) { case *ast.SelectStmt: - setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}}} + setOprList = []ast.Node{&ast.SetOprSelectList{Selects: []ast.Node{x}, With: x.With}} case *ast.SetOprStmt: setOprList = []ast.Node{&ast.SetOprSelectList{Selects: x.SelectList.Selects, With: x.With, Limit: x.Limit, OrderBy: x.OrderBy}} }