Skip to content

Commit

Permalink
cherry pick pingcap#30231 to release-5.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
time-and-fate authored and ti-srebot committed Dec 17, 2021
1 parent f29e1c5 commit ef3d42c
Show file tree
Hide file tree
Showing 2 changed files with 351 additions and 0 deletions.
334 changes: 334 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3724,3 +3724,337 @@ func (s *testIntegrationSuite) TestGroupBySetVar(c *C) {
res.Check(testkit.Rows(output[i].Plan...))
}
}
<<<<<<< HEAD
=======

func (s *testIntegrationSerialSuite) TestPushDownGroupConcatToTiFlash(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists ts")
tk.MustExec("create table ts (col_0 char(64), col_1 varchar(64) not null, col_2 varchar(1), id int primary key);")

// Create virtual tiflash replica info.
dom := domain.GetDomain(tk.Se)
is := dom.InfoSchema()
db, exists := is.SchemaByName(model.NewCIStr("test"))
c.Assert(exists, IsTrue)
for _, tblInfo := range db.Tables {
if tblInfo.Name.L == "ts" {
tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{
Count: 1,
Available: true,
}
}
}

tk.MustExec("set @@tidb_isolation_read_engines='tiflash,tidb'; set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1;")

var input []string
var output []struct {
SQL string
Plan []string
Warning []string
}
s.testData.GetTestCases(c, &input, &output)
for i, tt := range input {
s.testData.OnRecord(func() {
output[i].SQL = tt
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows())
})
res := tk.MustQuery(tt)
res.Check(testkit.Rows(output[i].Plan...))

comment := Commentf("case:%v sql:%s", i, tt)
warnings := tk.Se.GetSessionVars().StmtCtx.GetWarnings()
s.testData.OnRecord(func() {
if len(warnings) > 0 {
output[i].Warning = make([]string, len(warnings))
for j, warning := range warnings {
output[i].Warning[j] = warning.Err.Error()
}
}
})
if len(output[i].Warning) == 0 {
c.Assert(len(warnings), Equals, 0, comment)
} else {
c.Assert(len(warnings), Equals, len(output[i].Warning), comment)
for j, warning := range warnings {
c.Assert(warning.Level, Equals, stmtctx.WarnLevelWarning, comment)
c.Assert(warning.Err.Error(), Equals, output[i].Warning[j], comment)
}
}
}
}

func (s *testIntegrationSuite) TestIssue27797(c *C) {
tk := testkit.NewTestKit(c, s.store)
origin := tk.MustQuery("SELECT @@session.tidb_partition_prune_mode")
originStr := origin.Rows()[0][0].(string)
defer func() {
tk.MustExec("set @@session.tidb_partition_prune_mode = '" + originStr + "'")
}()
tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'")
tk.MustExec("use test")
tk.MustExec("drop table if exists t27797")
tk.MustExec("create table t27797(a int, b int, c int, d int) " +
"partition by range columns(d) (" +
"partition p0 values less than (20)," +
"partition p1 values less than(40)," +
"partition p2 values less than(60));")
tk.MustExec("insert into t27797 values(1,1,1,1), (2,2,2,2), (22,22,22,22), (44,44,44,44);")
tk.MustExec("set sql_mode='';")
result := tk.MustQuery("select count(*) from (select a, b from t27797 where d > 1 and d < 60 and b > 0 group by b, c) tt;")
result.Check(testkit.Rows("3"))

tk.MustExec("drop table if exists IDT_HP24172")
tk.MustExec("CREATE TABLE `IDT_HP24172` ( " +
"`COL1` mediumint(16) DEFAULT NULL, " +
"`COL2` varchar(20) DEFAULT NULL, " +
"`COL4` datetime DEFAULT NULL, " +
"`COL3` bigint(20) DEFAULT NULL, " +
"`COL5` float DEFAULT NULL, " +
"KEY `UM_COL` (`COL1`,`COL3`) " +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin " +
"PARTITION BY HASH( `COL1`+`COL3` ) " +
"PARTITIONS 8;")
tk.MustExec("insert into IDT_HP24172(col1) values(8388607);")
result = tk.MustQuery("select col2 from IDT_HP24172 where col1 = 8388607 and col1 in (select col1 from IDT_HP24172);")
result.Check(testkit.Rows("<nil>"))
}

func (s *testIntegrationSuite) TestIssue27949(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t27949")
tk.MustExec("create table t27949 (a int, b int, key(b))")
tk.MustQuery("explain format = 'brief' select * from t27949 where b=1").Check(testkit.Rows("IndexLookUp 10.00 root ",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t27949, index:b(b) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t27949 keep order:false, stats:pseudo"))
tk.MustExec("create global binding for select * from t27949 where b=1 using select * from t27949 ignore index(b) where b=1")
tk.MustQuery("explain format = 'brief' select * from t27949 where b=1").Check(testkit.Rows("TableReader 10.00 root data:Selection",
"└─Selection 10.00 cop[tikv] eq(test.t27949.b, 1)",
" └─TableFullScan 10000.00 cop[tikv] table:t27949 keep order:false, stats:pseudo"))
tk.MustExec("set @@sql_select_limit=100")
tk.MustQuery("explain format = 'brief' select * from t27949 where b=1").Check(testkit.Rows("Limit 10.00 root offset:0, count:100",
"└─TableReader 10.00 root data:Limit",
" └─Limit 10.00 cop[tikv] offset:0, count:100",
" └─Selection 10.00 cop[tikv] eq(test.t27949.b, 1)",
" └─TableFullScan 10000.00 cop[tikv] table:t27949 keep order:false, stats:pseudo"))

tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, index idx_a(a));")
tk.MustExec("create binding for select * from t using select * from t use index(idx_a);")
tk.MustExec("select * from t;")
tk.MustQuery("select @@last_plan_from_binding;").Check(testkit.Rows("1"))
tk.MustExec("prepare stmt from 'select * from t';")
tk.MustExec("execute stmt;")
tk.MustQuery("select @@last_plan_from_binding;").Check(testkit.Rows("1"))
}

func (s *testIntegrationSuite) TestIssue28154(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
defer func() {
tk.Exec("drop table if exists t")
}()
tk.MustExec("create table t(a TEXT)")
tk.MustExec("insert into t values('abc')")
result := tk.MustQuery("select * from t where from_base64('')")
result.Check(testkit.Rows())
_, err := tk.Exec("update t set a = 'def' where from_base64('')")
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "[types:1292]Truncated incorrect DOUBLE value: ''")
result = tk.MustQuery("select * from t where from_base64('invalidbase64')")
result.Check(testkit.Rows())
tk.MustExec("update t set a = 'hig' where from_base64('invalidbase64')")
result = tk.MustQuery("select * from t where from_base64('test')")
result.Check(testkit.Rows())
_, err = tk.Exec("update t set a = 'xyz' where from_base64('test')")
c.Assert(err, NotNil)
c.Assert(err, ErrorMatches, "\\[types:1292\\]Truncated incorrect DOUBLE value.*")
result = tk.MustQuery("select * from t")
result.Check(testkit.Rows("abc"))
}

func (s *testIntegrationSerialSuite) TestRejectSortForMPP(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (id int, value decimal(6,3), name char(128))")
tk.MustExec("analyze table t")

// Create virtual tiflash replica info.
dom := domain.GetDomain(tk.Se)
is := dom.InfoSchema()
db, exists := is.SchemaByName(model.NewCIStr("test"))
c.Assert(exists, IsTrue)
for _, tblInfo := range db.Tables {
if tblInfo.Name.L == "t" {
tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{
Count: 1,
Available: true,
}
}
}

tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_opt_broadcast_join=0; set @@tidb_enforce_mpp=1;")

var input []string
var output []struct {
SQL string
Plan []string
}
s.testData.GetTestCases(c, &input, &output)
for i, tt := range input {
s.testData.OnRecord(func() {
output[i].SQL = tt
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows())
})
res := tk.MustQuery(tt)
res.Check(testkit.Rows(output[i].Plan...))
}
}

func (s *testIntegrationSerialSuite) TestRegardNULLAsPoint(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

tk.MustExec("drop table if exists tpk")
tk.MustExec(`create table tuk (a int, b int, c int, unique key (a, b, c))`)
tk.MustExec(`create table tik (a int, b int, c int, key (a, b, c))`)
for _, va := range []string{"NULL", "1"} {
for _, vb := range []string{"NULL", "1"} {
for _, vc := range []string{"NULL", "1"} {
tk.MustExec(fmt.Sprintf(`insert into tuk values (%v, %v, %v)`, va, vb, vc))
tk.MustExec(fmt.Sprintf(`insert into tik values (%v, %v, %v)`, va, vb, vc))
if va == "1" && vb == "1" && vc == "1" {
continue
}
// duplicated NULL rows
tk.MustExec(fmt.Sprintf(`insert into tuk values (%v, %v, %v)`, va, vb, vc))
tk.MustExec(fmt.Sprintf(`insert into tik values (%v, %v, %v)`, va, vb, vc))
}
}
}

var input []string
var output []struct {
SQL string
PlanEnabled []string
PlanDisabled []string
Result []string
}
s.testData.GetTestCases(c, &input, &output)
for i, tt := range input {
s.testData.OnRecord(func() {
output[i].SQL = tt
tk.MustExec(`set @@session.tidb_regard_null_as_point=true`)
output[i].PlanEnabled = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + tt).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows())

tk.MustExec(`set @@session.tidb_regard_null_as_point=false`)
output[i].PlanDisabled = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + tt).Rows())
})
tk.MustExec(`set @@session.tidb_regard_null_as_point=true`)
tk.MustQuery("explain " + tt).Check(testkit.Rows(output[i].PlanEnabled...))
tk.MustQuery(tt).Check(testkit.Rows(output[i].Result...))

tk.MustExec(`set @@session.tidb_regard_null_as_point=false`)
tk.MustQuery("explain " + tt).Check(testkit.Rows(output[i].PlanDisabled...))
tk.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
}
}

func (s *testIntegrationSuite) TestIssues29711(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

tk.MustExec("drop table if exists tbl_29711")
tk.MustExec("CREATE TABLE `tbl_29711` (" +
"`col_250` text COLLATE utf8_unicode_ci NOT NULL," +
"`col_251` enum('Alice','Bob','Charlie','David') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Charlie'," +
"PRIMARY KEY (`col_251`,`col_250`(1)) NONCLUSTERED);")
tk.MustQuery("explain format=brief " +
"select col_250,col_251 from tbl_29711 where col_251 between 'Bob' and 'David' order by col_250,col_251 limit 6;").
Check(testkit.Rows(
"TopN 6.00 root test.tbl_29711.col_250, test.tbl_29711.col_251, offset:0, count:6",
"└─IndexLookUp 6.00 root ",
" ├─IndexRangeScan(Build) 30.00 cop[tikv] table:tbl_29711, index:PRIMARY(col_251, col_250) range:[\"Bob\",\"Bob\"], [\"Charlie\",\"Charlie\"], [\"David\",\"David\"], keep order:false, stats:pseudo",
" └─TopN(Probe) 6.00 cop[tikv] test.tbl_29711.col_250, test.tbl_29711.col_251, offset:0, count:6",
" └─TableRowIDScan 30.00 cop[tikv] table:tbl_29711 keep order:false, stats:pseudo",
))

tk.MustExec("drop table if exists t29711")
tk.MustExec("CREATE TABLE `t29711` (" +
"`a` varchar(10) DEFAULT NULL," +
"`b` int(11) DEFAULT NULL," +
"`c` int(11) DEFAULT NULL," +
"KEY `ia` (`a`(2)))")
tk.MustQuery("explain format=brief select * from t29711 use index (ia) order by a limit 10;").
Check(testkit.Rows(
"TopN 10.00 root test.t29711.a, offset:0, count:10",
"└─IndexLookUp 10.00 root ",
" ├─IndexFullScan(Build) 10000.00 cop[tikv] table:t29711, index:ia(a) keep order:false, stats:pseudo",
" └─TopN(Probe) 10.00 cop[tikv] test.t29711.a, offset:0, count:10",
" └─TableRowIDScan 10000.00 cop[tikv] table:t29711 keep order:false, stats:pseudo",
))
}

func (s *testIntegrationSuite) TestIssue27313(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a varchar(100), b int, c int, index idx1(a(2), b), index idx2(a))")
tk.MustExec("explain format = 'verbose' select * from t where a = 'abcdefghijk' and b > 4")
// no warning indicates that idx2 is not pruned by idx1.
tk.MustQuery("show warnings").Check(testkit.Rows())
}

func (s *testIntegrationSuite) TestIssue30094(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("use test")
tk.MustExec(`drop table if exists t30094;`)
tk.MustExec(`create table t30094(a varchar(10));`)
tk.MustQuery(`explain format = 'brief' select * from t30094 where cast(a as float) and cast(a as char);`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] cast(test.t30094.a, float BINARY), cast(test.t30094.a, var_string(5))",
" └─TableFullScan 10000.00 cop[tikv] table:t30094 keep order:false, stats:pseudo",
))
tk.MustQuery(`explain format = 'brief' select * from t30094 where concat(a,'1') = _binary 0xe59388e59388e59388 collate binary and concat(a,'1') = _binary 0xe598bfe598bfe598bf collate binary;`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] eq(to_binary(concat(test.t30094.a, \"1\")), \"0xe59388e59388e59388\"), eq(to_binary(concat(test.t30094.a, \"1\")), \"0xe598bfe598bfe598bf\")",
" └─TableFullScan 10000.00 cop[tikv] table:t30094 keep order:false, stats:pseudo",
))
}

func (s *testIntegrationSuite) TestIssue29705(c *C) {
tk := testkit.NewTestKit(c, s.store)
origin := tk.MustQuery("SELECT @@session.tidb_partition_prune_mode")
originStr := origin.Rows()[0][0].(string)
defer func() {
tk.MustExec("set @@session.tidb_partition_prune_mode = '" + originStr + "'")
}()
tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'")
tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t(id int) partition by hash(id) partitions 4;")
tk.MustExec("insert into t values(1);")
result := tk.MustQuery("SELECT COUNT(1) FROM ( SELECT COUNT(1) FROM t b GROUP BY id) a;")
result.Check(testkit.Rows("1"))
}

func (s *testIntegrationSerialSuite) TestIssue30271(c *C) {
defer collate.SetNewCollationEnabledForTest(false)
collate.SetNewCollationEnabledForTest(true)
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a char(10), b char(10), c char(10), index (a, b, c)) collate utf8mb4_bin;")
tk.MustExec("insert into t values ('b', 'a', '1'), ('b', 'A', '2'), ('c', 'a', '3');")
tk.MustExec("set names utf8mb4 collate utf8mb4_general_ci;")
tk.MustQuery("select * from t where (a>'a' and b='a') or (b = 'A' and a < 'd') order by a,c;").Check(testkit.Rows("b a 1", "b A 2", "c a 3"))

}
>>>>>>> 4785dc4a6... planner: fix inconsistent schema between UnionAll and child operator (#30231)
17 changes: 17 additions & 0 deletions planner/core/rule_column_pruning.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,23 @@ func (p *LogicalUnionAll) PruneColumns(parentUsedCols []*expression.Column) erro
p.schema.Columns = append(p.schema.Columns[:i], p.schema.Columns[i+1:]...)
}
}
// It's possible that the child operator adds extra columns to the schema.
// Currently, (*LogicalAggregation).PruneColumns() might do this.
// But we don't need such columns, so we add an extra Projection to prune this column when this happened.
for i, child := range p.Children() {
if p.schema.Len() < child.Schema().Len() {
schema := p.schema.Clone()
exprs := make([]expression.Expression, len(p.schema.Columns))
for j, col := range schema.Columns {
exprs[j] = col
}
proj := LogicalProjection{Exprs: exprs, AvoidColumnEvaluator: true}.Init(p.ctx, p.blockOffset)
proj.SetSchema(schema)

proj.SetChildren(child)
p.children[i] = proj
}
}
}
return nil
}
Expand Down

0 comments on commit ef3d42c

Please sign in to comment.