From 2716e1834dd676a566bf507ca55c403647823096 Mon Sep 17 00:00:00 2001 From: Chengpeng Yan <41809508+Reminiscent@users.noreply.github.com> Date: Wed, 25 Nov 2020 14:40:41 +0800 Subject: [PATCH 1/3] cherry pick #21251 to release-4.0 Signed-off-by: ti-srebot --- util/ranger/detacher.go | 8 + util/ranger/ranger_test.go | 137 ++++++++++ util/ranger/testdata/ranger_suite_in.json | 53 ++++ util/ranger/testdata/ranger_suite_out.json | 304 +++++++++++++++++++++ 4 files changed, 502 insertions(+) diff --git a/util/ranger/detacher.go b/util/ranger/detacher.go index fd08210bfa108..a8dafed5a0e1f 100644 --- a/util/ranger/detacher.go +++ b/util/ranger/detacher.go @@ -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) } diff --git a/util/ranger/ranger_test.go b/util/ranger/ranger_test.go index 2aaf271cae238..f99cc4d65a1d1 100644 --- a/util/ranger/ranger_test.go +++ b/util/ranger/ranger_test.go @@ -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) diff --git a/util/ranger/testdata/ranger_suite_in.json b/util/ranger/testdata/ranger_suite_in.json index 5f6acf9731c5d..e020112ba5da1 100644 --- a/util/ranger/testdata/ranger_suite_in.json +++ b/util/ranger/testdata/ranger_suite_in.json @@ -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) } ] diff --git a/util/ranger/testdata/ranger_suite_out.json b/util/ranger/testdata/ranger_suite_out.json index 38adc21a07390..607f9a5d61a29 100644 --- a/util/ranger/testdata/ranger_suite_out.json +++ b/util/ranger/testdata/ranger_suite_out.json @@ -86,5 +86,309 @@ ] } ] +<<<<<<< HEAD +======= + }, + { + "Name": "TestCompIndexDNFMatch", + "Cases": [ + { + "SQL": "select * from t where a = 1 and b in (1, 2) and c > 1;", + "Plan": [ + "IndexReader_6 0.67 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 0.67 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], (1 2 1,1 2 +inf], keep order:false, stats:pseudo" + ], + "Result": [ + "1 2 2" + ] + }, + { + "SQL": "select * from t where a = 1 and (b = 1 or b = 2) and c > 1;", + "Plan": [ + "IndexReader_6 0.67 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 0.67 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], (1 2 1,1 2 +inf], keep order:false, stats:pseudo" + ], + "Result": [ + "1 2 2" + ] + }, + { + "SQL": "select * from t where a = 1 and (b = 1 or b in (2, 3)) and c > 1;", + "Plan": [ + "IndexReader_6 1.00 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 1.00 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], (1 2 1,1 2 +inf], (1 3 1,1 3 +inf], keep order:false, stats:pseudo" + ], + "Result": [ + "1 2 2" + ] + }, + { + "SQL": "select * from t where a = 1 and (b = 1 or b = 2) and b = 3 and c > 1;", + "Plan": [ + "TableDual_5 0.00 root rows:0" + ], + "Result": null + }, + { + "SQL": "select * from t where a = 1 and (b is null or b = 2);", + "Plan": [ + "IndexReader_6 0.20 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 0.20 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], [1 2,1 2], keep order:false, stats:pseudo" + ], + "Result": [ + "1 2 2" + ] + }, + { + "SQL": "select * from t where a = 1 and (b is null or b = 2) and c > 1;", + "Plan": [ + "IndexReader_7 0.07 root index:Selection_6", + "└─Selection_6 0.07 cop[tikv] gt(test.t.c, 1)", + " └─IndexRangeScan_5 0.20 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], [1 2,1 2], keep order:false, stats:pseudo" + ], + "Result": [ + "1 2 2" + ] + }, + { + "SQL": "select * from t where a = 1 and b is null and c > 1;", + "Plan": [ + "IndexReader_7 0.03 root index:Selection_6", + "└─Selection_6 0.03 cop[tikv] gt(test.t.c, 1)", + " └─IndexRangeScan_5 0.10 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], keep order:false, stats:pseudo" + ], + "Result": null + }, + { + "SQL": "select * from t where a = 1 and b is null and b is null and c > 1;", + "Plan": [ + "IndexReader_7 0.03 root index:Selection_6", + "└─Selection_6 0.03 cop[tikv] gt(test.t.c, 1)", + " └─IndexRangeScan_5 0.10 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], keep order:false, stats:pseudo" + ], + "Result": null + }, + { + "SQL": "select * from t where a = 1 and b is null and b = 1 and c > 1;", + "Plan": [ + "IndexReader_7 0.27 root index:Selection_6", + "└─Selection_6 0.27 cop[tikv] isnull(test.t.b)", + " └─IndexRangeScan_5 0.33 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], keep order:false, stats:pseudo" + ], + "Result": null + } + ] + }, + { + "Name": "TestCompIndexMultiColDNF1", + "Cases": [ + { + "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c = 3;", + "Plan": [ + "Selection_6 1.00 root eq(test.t.c, 3)", + "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3;", + "Plan": [ + "Selection_6 1.00 root eq(test.t.c, 3)", + "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t use index(primary) where ((a = 1) or (a = 2 and b = 2)) and c = 3;", + "Plan": [ + "TableReader_7 0.75 root data:Selection_6", + "└─Selection_6 0.75 cop[tikv] eq(test.t.c, 3), or(eq(test.t.a, 1), and(eq(test.t.a, 2), eq(test.t.b, 2)))", + " └─TableRangeScan_5 2.00 cop[tikv] table:t range:[1,1], [2,2], keep order:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3 and (a = 1 or a = 2);", + "Plan": [ + "Selection_6 1.00 root eq(test.t.c, 3), or(eq(test.t.a, 1), eq(test.t.a, 2))", + "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c > 2;", + "Plan": [ + "Selection_6 1.00 root gt(test.t.c, 2)", + "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c > 2;", + "Plan": [ + "Selection_6 1.00 root gt(test.t.c, 2)", + "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + } + ] + }, + { + "Name": "TestCompIndexMultiColDNF2", + "Cases": [ + { + "SQL": "select * from t where a = 1 and (b,c) in ((1,1),(2,3));", + "Plan": [ + "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" + ], + "Result": [ + "1 1 1" + ] + }, + { + "SQL": "select * from t where a = 1 and ((b = 1 and c = 1) or (b = 2 and c = 3));", + "Plan": [ + "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" + ], + "Result": [ + "1 1 1" + ] + }, + { + "SQL": "select * from t where a = 1 and ((b = 1) or (b = 2 and c = 3));", + "Plan": [ + "TableReader_6 2.00 root data:TableRangeScan_5", + "└─TableRangeScan_5 2.00 cop[tikv] table:t range:[1 1,1 1], [1 2 3,1 2 3], keep order:false" + ], + "Result": [ + "1 1 1" + ] + }, + { + "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c = 3;", + "Plan": [ + "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3;", + "Plan": [ + "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t use index(primary) where ((a = 1) or (a = 2 and b = 2)) and c = 3;", + "Plan": [ + "TableReader_7 0.75 root data:Selection_6", + "└─Selection_6 0.75 cop[tikv] eq(test.t.c, 3), or(eq(test.t.a, 1), and(eq(test.t.a, 2), eq(test.t.b, 2)))", + " └─TableRangeScan_5 2.00 cop[tikv] table:t range:[1,1], [2,2], keep order:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "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));", + "Plan": [ + "Selection_6 0.75 root gt(test.t.c, 2), or(and(eq(test.t.a, 1), eq(test.t.b, 1)), and(eq(test.t.a, 2), eq(test.t.b, 2)))", + "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c > 2;", + "Plan": [ + "TableReader_6 1.00 root data:TableRangeScan_5", + "└─TableRangeScan_5 1.00 cop[tikv] table:t range:(1 1 2,1 1 +inf], (2 2 2,2 2 +inf], keep order:false" + ], + "Result": [ + "2 2 3" + ] + }, + { + "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c > 2;", + "Plan": [ + "TableReader_6 1.00 root data:TableRangeScan_5", + "└─TableRangeScan_5 1.00 cop[tikv] table:t range:(1 1 2,1 1 +inf], (2 2 2,2 2 +inf], keep order:false" + ], + "Result": [ + "2 2 3" + ] + } + ] + }, + { + "Name": "TestPrefixIndexMultiColDNF", + "Cases": [ + { + "SQL": "select * from t2 where t='aaaa';", + "Plan": [ + "IndexLookUp_11 10.00 root ", + "├─IndexRangeScan_8(Build) 10.00 cop[tikv] table:t2, index:t(t) range:[\"aaa\",\"aaa\"], keep order:false, stats:pseudo", + "└─Selection_10(Probe) 10.00 cop[tikv] eq(test.t2.t, \"aaaa\")", + " └─TableRowIDScan_9 10.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 aaaa" + ] + }, + { + "SQL": "select * from t2 where t='aaaa' or t = 'a';", + "Plan": [ + "IndexLookUp_11 16.00 root ", + "├─IndexRangeScan_8(Build) 20.00 cop[tikv] table:t2, index:t(t) range:[\"a\",\"a\"], [\"aaa\",\"aaa\"], keep order:false, stats:pseudo", + "└─Selection_10(Probe) 16.00 cop[tikv] or(eq(test.t2.t, \"aaaa\"), eq(test.t2.t, \"a\"))", + " └─TableRowIDScan_9 20.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 aaaa", + "2 a" + ] + }, + { + "SQL": "select * from t2 where t='aaaa';", + "Plan": [ + "TableReader_7 0.00 root data:Selection_6", + "└─Selection_6 0.00 cop[tikv] eq(test.t2.t, \"aaaa\")", + " └─TableRangeScan_5 2.00 cop[tikv] table:t2 range:[0,+inf], keep order:false" + ], + "Result": [ + "1 aaaa" + ] + }, + { + "SQL": "select * from t2 where t='aaaa' or t = 'a';", + "Plan": [ + "TableReader_7 0.80 root data:Selection_6", + "└─Selection_6 0.80 cop[tikv] or(eq(test.t2.t, \"aaaa\"), eq(test.t2.t, \"a\"))", + " └─TableRangeScan_5 2.00 cop[tikv] table:t2 range:[0,+inf], keep order:false" + ], + "Result": [ + "1 aaaa", + "2 a" + ] + } + ] +>>>>>>> 06e99582d... planner: fix incorrect results when using a prefix index with OR condition (#21251) } ] From 2ea9a869ebc5b1b17012fc344bea47ca55c1aa15 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Wed, 25 Nov 2020 20:05:41 +0800 Subject: [PATCH 2/3] fix conflicts --- util/ranger/detacher.go | 10 +- util/ranger/ranger_test.go | 101 -------- util/ranger/testdata/ranger_suite_in.json | 46 +--- util/ranger/testdata/ranger_suite_out.json | 259 +-------------------- 4 files changed, 8 insertions(+), 408 deletions(-) diff --git a/util/ranger/detacher.go b/util/ranger/detacher.go index a8dafed5a0e1f..8b1f6f696fa3c 100644 --- a/util/ranger/detacher.go +++ b/util/ranger/detacher.go @@ -317,15 +317,11 @@ 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) + if hasPrefix(lengths) { + fixPrefixColRange(totalRanges, lengths, newTpSlice) } - totalRanges, err := UnionRanges(sc, totalRanges, d.mergeConsecutive) ->>>>>>> 06e99582d... planner: fix incorrect results when using a prefix index with OR condition (#21251) + totalRanges, err := UnionRanges(sc, totalRanges) if err != nil { return nil, nil, false, errors.Trace(err) } diff --git a/util/ranger/ranger_test.go b/util/ranger/ranger_test.go index f99cc4d65a1d1..e9cafc3f4f354 100644 --- a/util/ranger/ranger_test.go +++ b/util/ranger/ranger_test.go @@ -1200,106 +1200,6 @@ 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) @@ -1336,7 +1236,6 @@ func (s *testRangerSuite) TestPrefixIndexMultiColDNF(c *C) { } } ->>>>>>> 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) diff --git a/util/ranger/testdata/ranger_suite_in.json b/util/ranger/testdata/ranger_suite_in.json index e020112ba5da1..fb33638e98a7c 100644 --- a/util/ranger/testdata/ranger_suite_in.json +++ b/util/ranger/testdata/ranger_suite_in.json @@ -17,49 +17,6 @@ "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", @@ -69,6 +26,5 @@ "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) - } + } ] diff --git a/util/ranger/testdata/ranger_suite_out.json b/util/ranger/testdata/ranger_suite_out.json index 607f9a5d61a29..e683c790f3c8f 100644 --- a/util/ranger/testdata/ranger_suite_out.json +++ b/util/ranger/testdata/ranger_suite_out.json @@ -86,256 +86,6 @@ ] } ] -<<<<<<< HEAD -======= - }, - { - "Name": "TestCompIndexDNFMatch", - "Cases": [ - { - "SQL": "select * from t where a = 1 and b in (1, 2) and c > 1;", - "Plan": [ - "IndexReader_6 0.67 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 0.67 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], (1 2 1,1 2 +inf], keep order:false, stats:pseudo" - ], - "Result": [ - "1 2 2" - ] - }, - { - "SQL": "select * from t where a = 1 and (b = 1 or b = 2) and c > 1;", - "Plan": [ - "IndexReader_6 0.67 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 0.67 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], (1 2 1,1 2 +inf], keep order:false, stats:pseudo" - ], - "Result": [ - "1 2 2" - ] - }, - { - "SQL": "select * from t where a = 1 and (b = 1 or b in (2, 3)) and c > 1;", - "Plan": [ - "IndexReader_6 1.00 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 1.00 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], (1 2 1,1 2 +inf], (1 3 1,1 3 +inf], keep order:false, stats:pseudo" - ], - "Result": [ - "1 2 2" - ] - }, - { - "SQL": "select * from t where a = 1 and (b = 1 or b = 2) and b = 3 and c > 1;", - "Plan": [ - "TableDual_5 0.00 root rows:0" - ], - "Result": null - }, - { - "SQL": "select * from t where a = 1 and (b is null or b = 2);", - "Plan": [ - "IndexReader_6 0.20 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 0.20 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], [1 2,1 2], keep order:false, stats:pseudo" - ], - "Result": [ - "1 2 2" - ] - }, - { - "SQL": "select * from t where a = 1 and (b is null or b = 2) and c > 1;", - "Plan": [ - "IndexReader_7 0.07 root index:Selection_6", - "└─Selection_6 0.07 cop[tikv] gt(test.t.c, 1)", - " └─IndexRangeScan_5 0.20 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], [1 2,1 2], keep order:false, stats:pseudo" - ], - "Result": [ - "1 2 2" - ] - }, - { - "SQL": "select * from t where a = 1 and b is null and c > 1;", - "Plan": [ - "IndexReader_7 0.03 root index:Selection_6", - "└─Selection_6 0.03 cop[tikv] gt(test.t.c, 1)", - " └─IndexRangeScan_5 0.10 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], keep order:false, stats:pseudo" - ], - "Result": null - }, - { - "SQL": "select * from t where a = 1 and b is null and b is null and c > 1;", - "Plan": [ - "IndexReader_7 0.03 root index:Selection_6", - "└─Selection_6 0.03 cop[tikv] gt(test.t.c, 1)", - " └─IndexRangeScan_5 0.10 cop[tikv] table:t, index:a(a, b, c) range:[1 NULL,1 NULL], keep order:false, stats:pseudo" - ], - "Result": null - }, - { - "SQL": "select * from t where a = 1 and b is null and b = 1 and c > 1;", - "Plan": [ - "IndexReader_7 0.27 root index:Selection_6", - "└─Selection_6 0.27 cop[tikv] isnull(test.t.b)", - " └─IndexRangeScan_5 0.33 cop[tikv] table:t, index:a(a, b, c) range:(1 1 1,1 1 +inf], keep order:false, stats:pseudo" - ], - "Result": null - } - ] - }, - { - "Name": "TestCompIndexMultiColDNF1", - "Cases": [ - { - "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c = 3;", - "Plan": [ - "Selection_6 1.00 root eq(test.t.c, 3)", - "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3;", - "Plan": [ - "Selection_6 1.00 root eq(test.t.c, 3)", - "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t use index(primary) where ((a = 1) or (a = 2 and b = 2)) and c = 3;", - "Plan": [ - "TableReader_7 0.75 root data:Selection_6", - "└─Selection_6 0.75 cop[tikv] eq(test.t.c, 3), or(eq(test.t.a, 1), and(eq(test.t.a, 2), eq(test.t.b, 2)))", - " └─TableRangeScan_5 2.00 cop[tikv] table:t range:[1,1], [2,2], keep order:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3 and (a = 1 or a = 2);", - "Plan": [ - "Selection_6 1.00 root eq(test.t.c, 3), or(eq(test.t.a, 1), eq(test.t.a, 2))", - "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c > 2;", - "Plan": [ - "Selection_6 1.00 root gt(test.t.c, 2)", - "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c > 2;", - "Plan": [ - "Selection_6 1.00 root gt(test.t.c, 2)", - "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - } - ] - }, - { - "Name": "TestCompIndexMultiColDNF2", - "Cases": [ - { - "SQL": "select * from t where a = 1 and (b,c) in ((1,1),(2,3));", - "Plan": [ - "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" - ], - "Result": [ - "1 1 1" - ] - }, - { - "SQL": "select * from t where a = 1 and ((b = 1 and c = 1) or (b = 2 and c = 3));", - "Plan": [ - "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" - ], - "Result": [ - "1 1 1" - ] - }, - { - "SQL": "select * from t where a = 1 and ((b = 1) or (b = 2 and c = 3));", - "Plan": [ - "TableReader_6 2.00 root data:TableRangeScan_5", - "└─TableRangeScan_5 2.00 cop[tikv] table:t range:[1 1,1 1], [1 2 3,1 2 3], keep order:false" - ], - "Result": [ - "1 1 1" - ] - }, - { - "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c = 3;", - "Plan": [ - "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c = 3;", - "Plan": [ - "Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t use index(primary) where ((a = 1) or (a = 2 and b = 2)) and c = 3;", - "Plan": [ - "TableReader_7 0.75 root data:Selection_6", - "└─Selection_6 0.75 cop[tikv] eq(test.t.c, 3), or(eq(test.t.a, 1), and(eq(test.t.a, 2), eq(test.t.b, 2)))", - " └─TableRangeScan_5 2.00 cop[tikv] table:t range:[1,1], [2,2], keep order:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "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));", - "Plan": [ - "Selection_6 0.75 root gt(test.t.c, 2), or(and(eq(test.t.a, 1), eq(test.t.b, 1)), and(eq(test.t.a, 2), eq(test.t.b, 2)))", - "└─Batch_Point_Get_5 2.00 root table:t, clustered index:PRIMARY(a, b, c) keep order:false, desc:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where (a,b) in ((1,1),(2,2)) and c > 2;", - "Plan": [ - "TableReader_6 1.00 root data:TableRangeScan_5", - "└─TableRangeScan_5 1.00 cop[tikv] table:t range:(1 1 2,1 1 +inf], (2 2 2,2 2 +inf], keep order:false" - ], - "Result": [ - "2 2 3" - ] - }, - { - "SQL": "select * from t where ((a = 1 and b = 1) or (a = 2 and b = 2)) and c > 2;", - "Plan": [ - "TableReader_6 1.00 root data:TableRangeScan_5", - "└─TableRangeScan_5 1.00 cop[tikv] table:t range:(1 1 2,1 1 +inf], (2 2 2,2 2 +inf], keep order:false" - ], - "Result": [ - "2 2 3" - ] - } - ] }, { "Name": "TestPrefixIndexMultiColDNF", @@ -368,8 +118,8 @@ { "SQL": "select * from t2 where t='aaaa';", "Plan": [ - "TableReader_7 0.00 root data:Selection_6", - "└─Selection_6 0.00 cop[tikv] eq(test.t2.t, \"aaaa\")", + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.t2.t, \"aaaa\")", " └─TableRangeScan_5 2.00 cop[tikv] table:t2 range:[0,+inf], keep order:false" ], "Result": [ @@ -379,8 +129,8 @@ { "SQL": "select * from t2 where t='aaaa' or t = 'a';", "Plan": [ - "TableReader_7 0.80 root data:Selection_6", - "└─Selection_6 0.80 cop[tikv] or(eq(test.t2.t, \"aaaa\"), eq(test.t2.t, \"a\"))", + "TableReader_7 1.60 root data:Selection_6", + "└─Selection_6 1.60 cop[tikv] or(eq(test.t2.t, \"aaaa\"), eq(test.t2.t, \"a\"))", " └─TableRangeScan_5 2.00 cop[tikv] table:t2 range:[0,+inf], keep order:false" ], "Result": [ @@ -389,6 +139,5 @@ ] } ] ->>>>>>> 06e99582d... planner: fix incorrect results when using a prefix index with OR condition (#21251) } ] From 5cdafb735954638decc1f44df00f15a9d1d8509e Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Thu, 26 Nov 2020 14:34:58 +0800 Subject: [PATCH 3/3] format --- util/ranger/testdata/ranger_suite_in.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/ranger/testdata/ranger_suite_in.json b/util/ranger/testdata/ranger_suite_in.json index fb33638e98a7c..e3ef63d0c9814 100644 --- a/util/ranger/testdata/ranger_suite_in.json +++ b/util/ranger/testdata/ranger_suite_in.json @@ -26,5 +26,5 @@ "select * from t2 where t='aaaa';", "select * from t2 where t='aaaa' or t = 'a';" ] - } + } ]