Skip to content

Commit

Permalink
cherry pick pingcap#21251 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
Reminiscent authored and ti-srebot committed Nov 25, 2020
1 parent bf8591c commit 2716e18
Show file tree
Hide file tree
Showing 4 changed files with 502 additions and 0 deletions.
8 changes: 8 additions & 0 deletions util/ranger/detacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,15 @@ func detachDNFCondAndBuildRangeForIndex(sctx sessionctx.Context, condition *expr
}
}

<<<<<<< HEAD
totalRanges, err := UnionRanges(sc, totalRanges)
=======
// Take prefix index into consideration.
if hasPrefix(d.lengths) {
fixPrefixColRange(totalRanges, d.lengths, newTpSlice)
}
totalRanges, err := UnionRanges(sc, totalRanges, d.mergeConsecutive)
>>>>>>> 06e99582d... planner: fix incorrect results when using a prefix index with OR condition (#21251)
if err != nil {
return nil, nil, false, errors.Trace(err)
}
Expand Down
137 changes: 137 additions & 0 deletions util/ranger/ranger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,143 @@ func (s *testRangerSuite) TestIndexStringIsTrueRange(c *C) {
}
}

<<<<<<< HEAD
=======
func (s *testRangerSuite) TestCompIndexDNFMatch(c *C) {
defer testleak.AfterTest(c)()
dom, store, err := newDomainStoreWithBootstrap(c)
defer func() {
dom.Close()
store.Close()
}()
c.Assert(err, IsNil)
testKit := testkit.NewTestKit(c, store)
testKit.MustExec("use test")
testKit.MustExec("drop table if exists t")
testKit.MustExec("create table t(a int, b int, c int, key(a,b,c));")
testKit.MustExec("insert into t values(1,2,2)")

var input []string
var output []struct {
SQL string
Plan []string
Result []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(testKit.MustQuery("explain " + tt).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
})
testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Plan...))
testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
}
}

func (s *testRangerSuite) TestCompIndexMultiColDNF1(c *C) {
defer testleak.AfterTest(c)()
dom, store, err := newDomainStoreWithBootstrap(c)
defer func() {
dom.Close()
store.Close()
}()
c.Assert(err, IsNil)
testKit := testkit.NewTestKit(c, store)
testKit.MustExec("use test")
testKit.MustExec("drop table if exists t")
testKit.MustExec("create table t(a int, b int, c int, primary key(a,b));")
testKit.MustExec("insert into t values(1,1,1),(2,2,3)")
testKit.MustExec("analyze table t")

var input []string
var output []struct {
SQL string
Plan []string
Result []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(testKit.MustQuery("explain " + tt).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
})
testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Plan...))
testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
}
}

func (s *testRangerSuite) TestCompIndexMultiColDNF2(c *C) {
defer testleak.AfterTest(c)()
dom, store, err := newDomainStoreWithBootstrap(c)
defer func() {
dom.Close()
store.Close()
}()
c.Assert(err, IsNil)
testKit := testkit.NewTestKit(c, store)
testKit.MustExec("use test")
testKit.MustExec("drop table if exists t")
testKit.MustExec("create table t(a int, b int, c int, primary key(a,b,c));")
testKit.MustExec("insert into t values(1,1,1),(2,2,3)")
testKit.MustExec("analyze table t")

var input []string
var output []struct {
SQL string
Plan []string
Result []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(testKit.MustQuery("explain " + tt).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
})
testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Plan...))
testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
}
}

func (s *testRangerSuite) TestPrefixIndexMultiColDNF(c *C) {
defer testleak.AfterTest(c)()
dom, store, err := newDomainStoreWithBootstrap(c)
defer func() {
dom.Close()
store.Close()
}()
c.Assert(err, IsNil)
testKit := testkit.NewTestKit(c, store)
testKit.MustExec("use test;")
testKit.MustExec("drop table if exists t2;")
testKit.MustExec("create table t2 (id int unsigned not null auto_increment primary key, t text, index(t(3)));")
testKit.MustExec("insert into t2 (t) values ('aaaa'),('a');")

var input []string
var output []struct {
SQL string
Plan []string
Result []string
}
s.testData.GetTestCases(c, &input, &output)
inputLen := len(input)
for i, tt := range input {
s.testData.OnRecord(func() {
output[i].SQL = tt
output[i].Plan = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
})
testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Plan...))
testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
if i+1 == inputLen/2 {
testKit.MustExec("analyze table t2;")
}
}
}

>>>>>>> 06e99582d... planner: fix incorrect results when using a prefix index with OR condition (#21251)
func (s *testRangerSuite) TestIndexRangeForYear(c *C) {
defer testleak.AfterTest(c)()
dom, store, err := newDomainStoreWithBootstrap(c)
Expand Down
53 changes: 53 additions & 0 deletions util/ranger/testdata/ranger_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,58 @@
"explain select * from t0 where c0 and c0 in ('123','456','789')",
"explain SELECT * FROM t0 WHERE ('a' != t0.c0) AND t0.c0;"
]
<<<<<<< HEAD
=======
},
{
"name": "TestCompIndexDNFMatch",
"cases": [
"select * from t where a = 1 and b in (1, 2) and c > 1;",
"select * from t where a = 1 and (b = 1 or b = 2) and c > 1;",
"select * from t where a = 1 and (b = 1 or b in (2, 3)) and c > 1;",
"select * from t where a = 1 and (b = 1 or b = 2) and b = 3 and c > 1;",
"select * from t where a = 1 and (b is null or b = 2);",
"select * from t where a = 1 and (b is null or b = 2) and c > 1;",
"select * from t where a = 1 and b is null and c > 1;",
"select * from t where a = 1 and b is null and b is null and c > 1;",
"select * from t where a = 1 and b is null and b = 1 and c > 1;"
]
},
{
"name": "TestCompIndexMultiColDNF1",
"cases": [
"select * from t where (a,b) in ((1,1),(2,2)) and c = 3;",
"select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3;",
"select * from t use index(primary) where ((a = 1) or (a = 2 and b = 2)) and c = 3;",
"select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3 and (a = 1 or a = 2);",
"select * from t where (a,b) in ((1,1),(2,2)) and c > 2;",
"select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c > 2;"
]
},
{
"name": "TestCompIndexMultiColDNF2",
"cases": [
// TODO: row count of BatchPointGet should be 1.00 instead of 2.00 actually, but getEqualCondSelectivity specially
// handles unique index, i.e, row count 1.00 is returned with CMSketch not checked at all. We should optimize this.
"select * from t where a = 1 and (b,c) in ((1,1),(2,3));",
"select * from t where a = 1 and ((b = 1 and c = 1) or (b = 2 and c = 3));",
"select * from t where a = 1 and ((b = 1) or (b = 2 and c = 3));",
"select * from t where (a,b) in ((1,1),(2,2)) and c = 3;",
"select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3;",
"select * from t use index(primary) where ((a = 1) or (a = 2 and b = 2)) and c = 3;",
"select * from t where (a,b) in ((1,1),(2,2)) and c > 2 and (a,b,c) in ((1,1,1),(2,2,3));",
"select * from t where (a,b) in ((1,1),(2,2)) and c > 2;",
"select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c > 2;"
]
},
{
"name": "TestPrefixIndexMultiColDNF",
"cases": [
"select * from t2 where t='aaaa';",
"select * from t2 where t='aaaa' or t = 'a';",
"select * from t2 where t='aaaa';",
"select * from t2 where t='aaaa' or t = 'a';"
]
>>>>>>> 06e99582d... planner: fix incorrect results when using a prefix index with OR condition (#21251)
}
]
Loading

0 comments on commit 2716e18

Please sign in to comment.