Skip to content

Commit

Permalink
cherry pick pingcap#22122 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
XuHuaiyu authored and ti-srebot committed Dec 31, 2020
1 parent 7545e57 commit 493d694
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
44 changes: 44 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,12 +1185,19 @@ 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(
<<<<<<< HEAD
"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] eq(length(cast(test.t.a)), 1), eq(length(cast(test.t.b)), 1)",
" └─TableRowIDScan_7 2.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery("show warnings").Check(testkit.Rows())
=======
"TableReader_7 1.60 root data:Selection_6",
"└─Selection_6 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)))",
" └─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"))
>>>>>>> f1805f3de... planner: avoid using index_merge when there are multiple table filters (#22122)
}

func (s *testIntegrationSerialSuite) TestIssue16407(c *C) {
Expand Down Expand Up @@ -1626,3 +1633,40 @@ func (s *testIntegrationSuite) TestUpdateMultiUpdatePK(c *C) {
tk.MustExec(`UPDATE t m, t n SET m.a = m.a + 1, n.b = n.b + 10`)
tk.MustQuery("SELECT * FROM t").Check(testkit.Rows("2 12"))
}

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

tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec(`CREATE TABLE t1 (
key1 int(11) NOT NULL,
key2 int(11) NOT NULL,
key3 int(11) NOT NULL,
key4 int(11) NOT NULL,
key5 int(11) DEFAULT NULL,
key6 int(11) DEFAULT NULL,
key7 int(11) NOT NULL,
key8 int(11) NOT NULL,
KEY i1 (key1),
KEY i2 (key2),
KEY i3 (key3),
KEY i4 (key4),
KEY i5 (key5),
KEY i6 (key6)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`)

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())
})
tk.MustQuery(tt).Check(testkit.Rows(output[i].Plan...))
}
}
14 changes: 14 additions & 0 deletions planner/core/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,13 @@ func (ds *DataSource) generateIndexMergeOrPaths() {
}
if len(partialPaths) > 1 {
possiblePath := ds.buildIndexMergeOrPath(partialPaths, i)
<<<<<<< HEAD
=======
if possiblePath == nil {
return
}

>>>>>>> f1805f3de... planner: avoid using index_merge when there are multiple table filters (#22122)
accessConds := make([]expression.Expression, 0, len(partialPaths))
for _, p := range partialPaths {
accessConds = append(accessConds, p.AccessConds...)
Expand Down Expand Up @@ -460,8 +467,15 @@ 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 len(path.TableFilters) > 0 {
tableFilterCnt++
if tableFilterCnt > 1 {
return nil
}
indexMergePath.TableFilters = append(indexMergePath.TableFilters, path.TableFilters...)
}
}
Expand Down
18 changes: 18 additions & 0 deletions planner/core/testdata/integration_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,23 @@
"select approx_percentile(a, 10*10) from t",
"select approx_percentile(a, 50) from t group by b order by b"
]
<<<<<<< HEAD
=======
},
{
"name": "TestConvertRangeToPoint",
"cases": [
"explain select * from t0 where a > 1 and a < 3 order by b limit 2",
"explain select * from t1 where a >= 2 and a <= 2 and b = 2 and c > 2",
"explain select * from t2 where a >= 2.5 and a <= 2.5 order by b limit 2",
"explain select * from t3 where a >= 'a' and a <= 'a' and b = 'b' and c > 'c'"
]
},
{
"name": "TestIssue22105",
"cases": [
"explain SELECT /*+ use_index_merge(t1)*/ COUNT(*) FROM t1 WHERE (key4=42 AND key6 IS NOT NULL) OR (key1=4 AND key3=6)"
]
>>>>>>> f1805f3de... planner: avoid using index_merge when there are multiple table filters (#22122)
}
]
55 changes: 55 additions & 0 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -889,5 +889,60 @@
]
}
]
<<<<<<< HEAD
=======
},
{
"Name": "TestConvertRangeToPoint",
"Cases": [
{
"SQL": "explain select * from t0 where a > 1 and a < 3 order by b limit 2",
"Plan": [
"Limit_11 2.00 root offset:0, count:2",
"└─IndexReader_21 2.00 root index:Limit_20",
" └─Limit_20 2.00 cop[tikv] offset:0, count:2",
" └─IndexRangeScan_19 2.50 cop[tikv] table:t0, index:a(a, b) range:[2,2], keep order:true, stats:pseudo"
]
},
{
"SQL": "explain select * from t1 where a >= 2 and a <= 2 and b = 2 and c > 2",
"Plan": [
"IndexReader_6 0.33 root index:IndexRangeScan_5",
"└─IndexRangeScan_5 0.33 cop[tikv] table:t1, index:a(a, b, c) range:(2 2 2,2 2 +inf], keep order:false, stats:pseudo"
]
},
{
"SQL": "explain select * from t2 where a >= 2.5 and a <= 2.5 order by b limit 2",
"Plan": [
"Limit_11 2.00 root offset:0, count:2",
"└─IndexReader_21 2.00 root index:Limit_20",
" └─Limit_20 2.00 cop[tikv] offset:0, count:2",
" └─IndexRangeScan_19 2.00 cop[tikv] table:t2, index:a(a, b) range:[2.5,2.5], keep order:true, stats:pseudo"
]
},
{
"SQL": "explain select * from t3 where a >= 'a' and a <= 'a' and b = 'b' and c > 'c'",
"Plan": [
"IndexReader_6 0.33 root index:IndexRangeScan_5",
"└─IndexRangeScan_5 0.33 cop[tikv] table:t3, index:a(a, b, c) range:(\"a\" \"b\" \"c\",\"a\" \"b\" +inf], keep order:false, stats:pseudo"
]
}
]
},
{
"Name": "TestIssue22105",
"Cases": [
{
"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 10.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"
]
}
]
>>>>>>> f1805f3de... planner: avoid using index_merge when there are multiple table filters (#22122)
}
]

0 comments on commit 493d694

Please sign in to comment.