-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
planner: regard NULL as point when accessing composite index #30244
Changes from 3 commits
77e4b43
f3400d7
dfd5eb0
663cf33
37b9001
f3419ad
a1160a9
1d79c33
1344648
538089f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4835,6 +4835,50 @@ func (s *testIntegrationSerialSuite) TestRejectSortForMPP(c *C) { | |
} | ||
} | ||
|
||
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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it is better to insert each value twice expect (1,1,1). In this way we can check whether it returns multiple rows (expected) or just a single row(wrong). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
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") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -212,6 +212,22 @@ func checkCoverIndex(idx *model.IndexInfo, ranges []*ranger.Range) bool { | |
if len(rg.LowVal) != len(idx.Columns) { | ||
return false | ||
} | ||
if !rg.LowExclude { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to check whether null exists if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated. |
||
for _, v := range rg.LowVal { | ||
if v.IsNull() { | ||
// a unique index may have duplicated rows with NULLs, so we cannot set the unique attribute to true when the range has NULL | ||
// please see https://github.com/pingcap/tidb/issues/29650 for more details | ||
return false | ||
} | ||
} | ||
} | ||
if !rg.HighExclude { | ||
for _, v := range rg.HighVal { | ||
if v.IsNull() { | ||
return false | ||
} | ||
} | ||
} | ||
} | ||
return true | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -961,6 +961,7 @@ func TestCompIndexDNFMatch(t *testing.T) { | |
require.NoError(t, err) | ||
testKit := testkit.NewTestKit(t, store) | ||
testKit.MustExec("use test") | ||
testKit.MustExec(`set @@session.tidb_regard_null_as_point=false`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would happen if we don't add this line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then the default value There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't affect the correctness, right? |
||
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)") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we remove the hard-code operation in the following PRs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I plan to remove this hard-code operation with the switch
tidb_regard_null_as_point
together a few months later if there is no new bug.