Skip to content

Commit

Permalink
parser, planner: fix embedded setOprStmt will be seen as SetOprSelect…
Browse files Browse the repository at this point in the history
…List item and lost its orderBy and Limit (pingcap#49421)

close pingcap#49377
  • Loading branch information
AilinKid committed Dec 19, 2023
1 parent aab2da0 commit ba2e5a6
Show file tree
Hide file tree
Showing 12 changed files with 32,205 additions and 4 deletions.
35 changes: 35 additions & 0 deletions executor/explain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,3 +702,38 @@ func TestExplainFormatPlanCache(t *testing.T) {
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
}
}

func TestIssues49377(t *testing.T) {
t.Skip()
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists employee")
tk.MustExec("create table employee (employee_id int, name varchar(20), dept_id int)")
tk.MustExec("insert into employee values (1, 'Furina', 1), (2, 'Klee', 1), (3, 'Eula', 1), (4, 'Diluc', 2), (5, 'Tartaglia', 2)")

tk.MustQuery("select 1,1,1 union all ( " +
"(select * from employee where dept_id = 1) " +
"union all " +
"(select * from employee where dept_id = 1 order by employee_id) " +
"order by 1 limit 1 " +
");").Sort().Check(testkit.Rows("1 1 1", "1 Furina 1"))

tk.MustQuery("select 1,1,1 union all ( " +
"(select * from employee where dept_id = 1) " +
"union all " +
"(select * from employee where dept_id = 1 order by employee_id) " +
"order by 1" +
");").Sort().Check(testkit.Rows("1 1 1", "1 Furina 1", "1 Furina 1", "2 Klee 1", "2 Klee 1", "3 Eula 1", "3 Eula 1"))

tk.MustQuery("select * from employee where dept_id = 1 " +
"union all " +
"(select * from employee where dept_id = 1 order by employee_id) " +
"union all" +
"(" +
"select * from employee where dept_id = 1 " +
"union all " +
"(select * from employee where dept_id = 1 order by employee_id) " +
"limit 1" +
");").Sort().Check(testkit.Rows("1 Furina 1", "1 Furina 1", "1 Furina 1", "2 Klee 1", "2 Klee 1", "3 Eula 1", "3 Eula 1"))
}
2 changes: 2 additions & 0 deletions parser/ast/dml.go
Original file line number Diff line number Diff line change
Expand Up @@ -1550,6 +1550,8 @@ type SetOprSelectList struct {
With *WithClause
AfterSetOperator *SetOprType
Selects []Node
Limit *Limit
OrderBy *OrderByClause
}

// Restore implements Node interface.
Expand Down
8 changes: 7 additions & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19364,15 +19364,21 @@ yynewstate:
}
var setOprList2 []ast.Node
var with2 *ast.WithClause
var limit2 *ast.Limit
var orderBy2 *ast.OrderByClause
switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) {
case *ast.SelectStmt:
setOprList2 = []ast.Node{x}
with2 = x.With
case *ast.SetOprStmt:
// child setOprStmt's limit and order should also make sense
// we should separate it out from other normal SetOprSelectList.
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-1].item.(*ast.SetOprType)
setOprList := append(setOprList1, nextSetOprList)
setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}}
Expand Down
8 changes: 7 additions & 1 deletion parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -9994,15 +9994,21 @@ SetOprStmtWoutLimitOrderBy:
}
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}
with2 = x.With
case *ast.SetOprStmt:
// child setOprStmt's limit and order should also make sense
// we should separate it out from other normal SetOprSelectList.
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}}
Expand Down
60 changes: 60 additions & 0 deletions pkg/executor/test/executor/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
load("@io_bazel_rules_go//go:def.bzl", "go_test")

go_test(
name = "executor_test",
timeout = "short",
srcs = [
"executor_test.go",
"main_test.go",
],
flaky = True,
shard_count = 47,
deps = [
"//pkg/config",
"//pkg/ddl",
"//pkg/domain",
"//pkg/domain/infosync",
"//pkg/executor",
"//pkg/executor/internal/exec",
"//pkg/expression",
"//pkg/infoschema",
"//pkg/kv",
"//pkg/meta",
"//pkg/meta/autoid",
"//pkg/parser",
"//pkg/parser/model",
"//pkg/parser/mysql",
"//pkg/parser/terror",
"//pkg/planner",
"//pkg/planner/core",
"//pkg/session",
"//pkg/sessionctx",
"//pkg/sessionctx/stmtctx",
"//pkg/sessionctx/variable",
"//pkg/sessiontxn",
"//pkg/store/mockstore",
"//pkg/table/tables",
"//pkg/tablecodec",
"//pkg/testkit",
"//pkg/testkit/testdata",
"//pkg/types",
"//pkg/util",
"//pkg/util/dbterror/exeerrors",
"//pkg/util/memory",
"//pkg/util/mock",
"//pkg/util/replayer",
"//pkg/util/rowcodec",
"//pkg/util/sqlexec",
"//pkg/util/timeutil",
"@com_github_golang_protobuf//proto",
"@com_github_pingcap_errors//:errors",
"@com_github_pingcap_failpoint//:failpoint",
"@com_github_pingcap_tipb//go-tipb",
"@com_github_stretchr_testify//require",
"@com_github_tikv_client_go_v2//oracle",
"@com_github_tikv_client_go_v2//testutils",
"@com_github_tikv_client_go_v2//tikv",
"@io_opencensus_go//stats/view",
"@org_uber_go_goleak//:goleak",
],
)
Loading

0 comments on commit ba2e5a6

Please sign in to comment.