Skip to content

Commit

Permalink
cherry pick #23132 to release-4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
eurekaka committed Mar 8, 2021
1 parent 31fd1f3 commit ac11792
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 21 deletions.
48 changes: 40 additions & 8 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1145,10 +1145,10 @@ func (s *testIntegrationSerialSuite) TestIssue16837(c *C) {
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int,b int,c int,d int,e int,unique key idx_ab(a,b),unique key(c),unique key(d))")
tk.MustQuery("explain select /*+ use_index_merge(t,c,idx_ab) */ * from t where a = 1 or (e = 1 and c = 1)").Check(testkit.Rows(
"IndexMerge_9 0.01 root ",
"IndexMerge_9 8.80 root ",
"├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t, index:idx_ab(a, b) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan_6(Build) 1.00 cop[tikv] table:t, index:c(c) range:[1,1], keep order:false, stats:pseudo",
"└─Selection_8(Probe) 0.01 cop[tikv] eq(test.t.e, 1)",
"└─Selection_8(Probe) 8.80 cop[tikv] or(eq(test.t.a, 1), and(eq(test.t.e, 1), eq(test.t.c, 1)))",
" └─TableRowIDScan_7 11.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustExec("insert into t values (2, 1, 1, 1, 2)")
Expand Down Expand Up @@ -1186,10 +1186,13 @@ func (s *testIntegrationSerialSuite) TestIndexMerge(c *C) {
tk.MustQuery("show warnings").Check(testkit.Rows())

tk.MustQuery("desc select /*+ use_index_merge(t) */ * from t where (a=1 and length(b)=1) or (b=1 and length(a)=1)").Check(testkit.Rows(
"TableReader_7 8000.00 root data:Selection_6",
"└─Selection_6 8000.00 cop[tikv] or(and(eq(test.t.a, 1), eq(length(cast(test.t.b)), 1)), and(eq(test.t.b, 1), eq(length(cast(test.t.a)), 1)))",
" └─TableFullScan_5 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 IndexMerge is inapplicable or disabled"))
"IndexMerge_9 1.60 root ",
"├─IndexRangeScan_5(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan_6(Build) 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false, stats:pseudo",
"└─Selection_8(Probe) 1.60 cop[tikv] or(and(eq(test.t.a, 1), eq(length(cast(test.t.b)), 1)), and(eq(test.t.b, 1), eq(length(cast(test.t.a)), 1)))",
" └─TableRowIDScan_7 2.00 cop[tikv] table:t keep order:false, stats:pseudo",
))
tk.MustQuery("show warnings").Check(testkit.Rows())
}

func (s *testIntegrationSerialSuite) TestIssue16407(c *C) {
Expand All @@ -1198,10 +1201,10 @@ func (s *testIntegrationSerialSuite) TestIssue16407(c *C) {
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int,b char(100),key(a),key(b(10)))")
tk.MustQuery("explain select /*+ use_index_merge(t) */ * from t where a=10 or b='x'").Check(testkit.Rows(
"IndexMerge_9 0.02 root ",
"IndexMerge_9 16.00 root ",
"├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t, index:a(a) range:[10,10], keep order:false, stats:pseudo",
"├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t, index:b(b) range:[\"x\",\"x\"], keep order:false, stats:pseudo",
"└─Selection_8(Probe) 0.02 cop[tikv] eq(test.t.b, \"x\")",
"└─Selection_8(Probe) 16.00 cop[tikv] or(eq(test.t.a, 10), eq(test.t.b, \"x\"))",
" └─TableRowIDScan_7 20.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustExec("insert into t values (1, 'xx')")
Expand Down Expand Up @@ -1832,3 +1835,32 @@ func (s *testIntegrationSuite) TestIssue22071(c *C) {
tk.MustQuery("select n in (1,2) from (select a in (1,2) as n from t) g;").Sort().Check(testkit.Rows("0", "1", "1"))
tk.MustQuery("select n in (1,n) from (select a in (1,2) as n from t) g;").Check(testkit.Rows("1", "1", "1"))
}

func (s *testIntegrationSuite) TestIndexMergeTableFilter(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 int, b int, c int, d int, key(a), key(b));")
tk.MustExec("insert into t values(10,1,1,10)")

tk.MustQuery("explain select /*+ use_index_merge(t) */ * from t where a=10 or (b=10 and c=10)").Check(testkit.Rows(
"IndexMerge_9 16.00 root ",
"├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t, index:a(a) range:[10,10], keep order:false, stats:pseudo",
"├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t, index:b(b) range:[10,10], keep order:false, stats:pseudo",
"└─Selection_8(Probe) 16.00 cop[tikv] or(eq(test.t.a, 10), and(eq(test.t.b, 10), eq(test.t.c, 10)))",
" └─TableRowIDScan_7 20.00 cop[tikv] table:t keep order:false, stats:pseudo",
))
tk.MustQuery("select /*+ use_index_merge(t) */ * from t where a=10 or (b=10 and c=10)").Check(testkit.Rows(
"10 1 1 10",
))
tk.MustQuery("explain select /*+ use_index_merge(t) */ * from t where (a=10 and d=10) or (b=10 and c=10)").Check(testkit.Rows(
"IndexMerge_9 16.00 root ",
"├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t, index:a(a) range:[10,10], keep order:false, stats:pseudo",
"├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t, index:b(b) range:[10,10], keep order:false, stats:pseudo",
"└─Selection_8(Probe) 16.00 cop[tikv] or(and(eq(test.t.a, 10), eq(test.t.d, 10)), and(eq(test.t.b, 10), eq(test.t.c, 10)))",
" └─TableRowIDScan_7 20.00 cop[tikv] table:t keep order:false, stats:pseudo",
))
tk.MustQuery("select /*+ use_index_merge(t) */ * from t where (a=10 and d=10) or (b=10 and c=10)").Check(testkit.Rows(
"10 1 1 10",
))
}
11 changes: 3 additions & 8 deletions planner/core/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,16 +464,11 @@ func (ds *DataSource) buildIndexMergeOrPath(partialPaths []*util.AccessPath, cur
indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths}
indexMergePath.TableFilters = append(indexMergePath.TableFilters, ds.pushedDownConds[:current]...)
indexMergePath.TableFilters = append(indexMergePath.TableFilters, ds.pushedDownConds[current+1:]...)
tableFilterCnt := 0
for _, path := range partialPaths {
// IndexMerge should not be used when the SQL is like 'select x from t WHERE (key1=1 AND key2=2) OR (key1=4 AND key3=6);'.
// Check issue https://github.com/pingcap/tidb/issues/22105 for details.
// If any partial path contains table filters, we need to keep the whole DNF filter in the Selection.
if len(path.TableFilters) > 0 {
tableFilterCnt++
if tableFilterCnt > 1 {
return nil
}
indexMergePath.TableFilters = append(indexMergePath.TableFilters, path.TableFilters...)
indexMergePath.TableFilters = append(indexMergePath.TableFilters, ds.pushedDownConds[current])
break
}
}
return indexMergePath
Expand Down
11 changes: 6 additions & 5 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -897,11 +897,12 @@
{
"SQL": "explain SELECT /*+ use_index_merge(t1)*/ COUNT(*) FROM t1 WHERE (key4=42 AND key6 IS NOT NULL) OR (key1=4 AND key3=6)",
"Plan": [
"StreamAgg_20 1.00 root funcs:count(Column#12)->Column#10",
"└─TableReader_21 1.00 root data:StreamAgg_9",
" └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#12",
" └─Selection_19 8000.00 cop[tikv] or(and(eq(test.t1.key4, 42), not(isnull(test.t1.key6))), and(eq(test.t1.key1, 4), eq(test.t1.key3, 6)))",
" └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
"HashAgg_8 1.00 root funcs:count(1)->Column#10",
"└─IndexMerge_15 16.00 root ",
" ├─IndexRangeScan_11(Build) 10.00 cop[tikv] table:t1, index:i4(key4) range:[42,42], keep order:false, stats:pseudo",
" ├─IndexRangeScan_12(Build) 10.00 cop[tikv] table:t1, index:i1(key1) range:[4,4], keep order:false, stats:pseudo",
" └─Selection_14(Probe) 16.00 cop[tikv] or(and(eq(test.t1.key4, 42), not(isnull(test.t1.key6))), and(eq(test.t1.key1, 4), eq(test.t1.key3, 6)))",
" └─TableRowIDScan_13 20.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
]
}
]
Expand Down

0 comments on commit ac11792

Please sign in to comment.