Skip to content

Commit

Permalink
cherry pick pingcap#27246 to release-4.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
wshwsh12 authored and ti-srebot committed Aug 17, 2021
1 parent 6f4dd17 commit bb444f6
Show file tree
Hide file tree
Showing 5 changed files with 550 additions and 7 deletions.
10 changes: 10 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8251,3 +8251,13 @@ func (s *testIntegrationSuite) TestJiraSetInnoDBDefaultRowFormat(c *C) {
tk.MustQuery("SHOW VARIABLES LIKE 'innodb_file_format'").Check(testkit.Rows("innodb_file_format Barracuda"))
tk.MustQuery("SHOW VARIABLES LIKE 'innodb_large_prefix'").Check(testkit.Rows("innodb_large_prefix ON"))
}

func (s *testIntegrationSuite) TestIssue27233(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test;")
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (\n `COL1` tinyint(45) NOT NULL,\n `COL2` tinyint(45) NOT NULL,\n PRIMARY KEY (`COL1`,`COL2`) /*T![clustered_index] NONCLUSTERED */\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("insert into t values(122,100),(124,-22),(124,34),(127,103);")
tk.MustQuery("SELECT col2 FROM t AS T1 WHERE ( SELECT count(DISTINCT COL1, COL2) FROM t AS T2 WHERE T2.COL1 > T1.COL1 ) > 2 ;").
Check(testkit.Rows("100"))
}
133 changes: 133 additions & 0 deletions planner/core/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1548,3 +1548,136 @@ func (s *testPlanSuite) TestHintFromDiffDatabase(c *C) {
c.Assert(core.ToString(p), Equals, output[i].Plan, comment)
}
}
<<<<<<< HEAD
=======

func (s *testPlanSuite) TestNthPlanHintWithExplain(c *C) {
defer testleak.AfterTest(c)()
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
tk := testkit.NewTestKit(c, store)
defer func() {
dom.Close()
store.Close()
}()
se, err := session.CreateSession4Test(store)
c.Assert(err, IsNil)
ctx := context.Background()
_, err = se.Execute(ctx, "use test")
c.Assert(err, IsNil)
_, err = se.Execute(ctx, `drop table if exists test.tt`)
c.Assert(err, IsNil)
_, err = se.Execute(ctx, `create table test.tt (a int,b int, index(a), index(b));`)
c.Assert(err, IsNil)

_, err = se.Execute(ctx, "insert into tt values (1, 1), (2, 2), (3, 4)")
c.Assert(err, IsNil)

tk.MustExec(`set @@tidb_partition_prune_mode='` + string(variable.Static) + `'`)

var input []string
var output []struct {
SQL string
Plan []string
}
s.testData.GetTestCases(c, &input, &output)
for i, ts := range input {
s.testData.OnRecord(func() {
output[i].SQL = ts
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + ts).Rows())
})
tk.MustQuery("explain format = 'brief' " + ts).Check(testkit.Rows(output[i].Plan...))
}

// This assert makes sure a query with or without nth_plan() hint output exactly the same plan(including plan ID).
// The query below is the same as queries in the testdata except for nth_plan() hint.
// Currently its output is the same as the second test case in the testdata, which is `output[1]`. If this doesn't
// hold in the future, you may need to modify this.
tk.MustQuery("explain format = 'brief' select * from test.tt where a=1 and b=1").Check(testkit.Rows(output[1].Plan...))
}

func (s *testPlanSuite) TestEnumIndex(c *C) {
var (
input []string
output []struct {
SQL string
Plan []string
Result []string
}
)
s.testData.GetTestCases(c, &input, &output)
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer func() {
dom.Close()
store.Close()
}()
tk := testkit.NewTestKit(c, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(e enum('c','b','a',''), index idx(e))")
tk.MustExec("insert ignore into t values(0),(1),(2),(3),(4);")

for i, ts := range input {
s.testData.OnRecord(func() {
output[i].SQL = ts
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery("explain format='brief'" + ts).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(ts).Sort().Rows())
})
tk.MustQuery("explain format='brief' " + ts).Check(testkit.Rows(output[i].Plan...))
tk.MustQuery(ts).Sort().Check(testkit.Rows(output[i].Result...))
}
}

func (s *testPlanSuite) TestIssue27233(c *C) {
var (
input []string
output []struct {
SQL string
Plan []string
Result []string
}
)
s.testData.GetTestCases(c, &input, &output)
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer func() {
dom.Close()
store.Close()
}()
tk := testkit.NewTestKit(c, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("CREATE TABLE `PK_S_MULTI_31` (\n `COL1` tinyint(45) NOT NULL,\n `COL2` tinyint(45) NOT NULL,\n PRIMARY KEY (`COL1`,`COL2`) /*T![clustered_index] NONCLUSTERED */\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("insert into PK_S_MULTI_31 values(122,100),(124,-22),(124,34),(127,103);")

for i, ts := range input {
s.testData.OnRecord(func() {
output[i].SQL = ts
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery("explain format='brief'" + ts).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(ts).Sort().Rows())
})
tk.MustQuery("explain format='brief' " + ts).Check(testkit.Rows(output[i].Plan...))
tk.MustQuery(ts).Sort().Check(testkit.Rows(output[i].Result...))
}
}

func (s *testPlanSuite) TestPossibleProperties(c *C) {
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer func() {
dom.Close()
store.Close()
}()
tk := testkit.NewTestKit(c, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists student, sc")
tk.MustExec("create table student(id int primary key auto_increment, name varchar(4) not null)")
tk.MustExec("create table sc(id int primary key auto_increment, student_id int not null, course_id int not null, score int not null)")
tk.MustExec("insert into student values (1,'s1'), (2,'s2')")
tk.MustExec("insert into sc (student_id, course_id, score) values (1,1,59), (1,2,57), (1,3,76), (2,1,99), (2,2,100), (2,3,100)")
tk.MustQuery("select /*+ stream_agg() */ a.id, avg(b.score) as afs from student a join sc b on a.id = b.student_id where b.score < 60 group by a.id having count(b.course_id) >= 2").Check(testkit.Rows(
"1 58.0000",
))
}
>>>>>>> 1c6c54833... planner: add missing column for Apply convert to Join (#27246)
29 changes: 22 additions & 7 deletions planner/core/rule_decorrelate.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,37 @@ func (s *decorrelateSolver) optimize(ctx context.Context, p LogicalPlan) (Logica
resetNotNullFlag(apply.schema, outerPlan.Schema().Len(), apply.schema.Len())

for i, aggFunc := range agg.AggFuncs {
<<<<<<< HEAD
switch expr := aggFunc.Args[0].(type) {
case *expression.Column:
if idx := apply.schema.ColumnIndex(expr); idx != -1 {
desc, err := aggregation.NewAggFuncDesc(agg.ctx, agg.AggFuncs[i].Name, []expression.Expression{apply.schema.Columns[idx]}, false)
if err != nil {
return nil, err
=======
aggArgs := make([]expression.Expression, 0, len(aggFunc.Args))
for _, arg := range aggFunc.Args {
switch expr := arg.(type) {
case *expression.Column:
if idx := apply.schema.ColumnIndex(expr); idx != -1 {
aggArgs = append(aggArgs, apply.schema.Columns[idx])
} else {
aggArgs = append(aggArgs, expr)
>>>>>>> 1c6c54833... planner: add missing column for Apply convert to Join (#27246)
}
newAggFuncs = append(newAggFuncs, desc)
case *expression.ScalarFunction:
expr.RetType = expr.RetType.Clone()
expr.RetType.Flag &= ^mysql.NotNullFlag
aggArgs = append(aggArgs, expr)
default:
aggArgs = append(aggArgs, expr)
}
case *expression.ScalarFunction:
expr.RetType = expr.RetType.Clone()
expr.RetType.Flag &= ^mysql.NotNullFlag
newAggFuncs = append(newAggFuncs, aggFunc)
default:
newAggFuncs = append(newAggFuncs, aggFunc)
}
desc, err := aggregation.NewAggFuncDesc(agg.ctx, agg.AggFuncs[i].Name, aggArgs, agg.AggFuncs[i].HasDistinct)
if err != nil {
return nil, err
}
newAggFuncs = append(newAggFuncs, desc)
}
agg.AggFuncs = newAggFuncs
np, err := s.optimize(ctx, p)
Expand Down
54 changes: 54 additions & 0 deletions planner/core/testdata/plan_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -639,5 +639,59 @@
"cases": [
"select /*+ inl_hash_join(test.t1) */ * from test.t2 join test.t1 on test.t2.a = test.t1.a"
]
<<<<<<< HEAD
=======
},
{
"name": "TestNthPlanHintWithExplain",
"cases": [
"select /*+nth_plan(1)*/ * from test.tt where a=1 and b=1",
"select /*+nth_plan(2)*/ * from test.tt where a=1 and b=1;",
"select /*+nth_plan(3)*/ * from test.tt where a=1 and b=1;",
"select /*+nth_plan(2)*/ * from test.tt where a=1 and b=1;",
"select * from test.tt where a=1 and b=1"
]
},
{
"name": "TestEliminateMaxOneRow",
"cases": [
"select a from t2 where t2.a < (select t1.a from t1 where t1.a = t2.a);",
"select a from t2 where t2.a < (select t1.a from t1 where t1.b = t2.b and t1.a is null);",
"select a from t2 where t2.a < (select t3.a from t3 where t3.a = t2.a);"
]
},
{
"name": "TestEnumIndex",
"cases": [
"select e from t where e = 'b'",
"select e from t where e != 'b'",
"select e from t where e > 'b'",
"select e from t where e >= 'b'",
"select e from t where e < 'b'",
"select e from t where e <= 'b'",
"select e from t where e = 2",
"select e from t where e != 2",
"select e from t where e > 2",
"select e from t where e >= 2",
"select e from t where e < 2",
"select e from t where e <= 2",

// Out of range
"select e from t where e > ''",
"select e from t where e > 'd'",
"select e from t where e > -1",
"select e from t where e > 5",

// zero-value
"select e from t where e = ''",
"select e from t where e != ''"
]
},
{
"name": "TestIssue27233",
"cases": [
"SELECT col2 FROM PK_S_MULTI_31 AS T1 WHERE (SELECT count(DISTINCT COL1, COL2) FROM PK_S_MULTI_31 AS T2 WHERE T2.COL1>T1.COL1)>2 order by col2;"
]
>>>>>>> 1c6c54833... planner: add missing column for Apply convert to Join (#27246)
}
]
Loading

0 comments on commit bb444f6

Please sign in to comment.