Skip to content

Commit

Permalink
executor: fix wrong key range of index scan when filter is comparing …
Browse files Browse the repository at this point in the history
…year column with NULL (pingcap#23079) (pingcap#23104)
  • Loading branch information
ti-srebot authored Mar 18, 2021
1 parent aad2f72 commit 11a9254
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
26 changes: 26 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,32 @@ func (s *testSuiteP1) TestIssue5055(c *C) {
result.Check(testkit.Rows("1 1"))
}

// issue-23038: wrong key range of index scan for year column
func (s *testSuiteWithData) TestIndexScanWithYearCol(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test;")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (c1 year(4), c2 int, key(c1));")
tk.MustExec("insert into t values(2001, 1);")

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

func (s *testSuiteP2) TestUnion(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down
12 changes: 12 additions & 0 deletions executor/testdata/executor_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,17 @@
"select * from t1 natural right join t2 order by a",
"SELECT * FROM t1 NATURAL LEFT JOIN t2 WHERE not(t1.a <=> t2.a)"
]
},
{
"name": "TestIndexScanWithYearCol",
"cases": [
"select t1.c1, t2.c1 from t as t1 inner join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"select * from t as t1 inner join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"select count(*) from t as t1 inner join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"select t1.c1, t2.c1 from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"select * from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"select count(*) from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"select * from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 is not NULL"
]
}
]
84 changes: 84 additions & 0 deletions executor/testdata/executor_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,89 @@
]
}
]
},
{
"Name": "TestIndexScanWithYearCol",
"Cases": [
{
"SQL": "select t1.c1, t2.c1 from t as t1 inner join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"Plan": [
"MergeJoin_8 0.00 root inner join, left key:test.t.c1, right key:test.t.c1",
"├─TableDual_24(Build) 0.00 root rows:0",
"└─TableDual_23(Probe) 0.00 root rows:0"
],
"Res": [
]
},
{
"SQL": "select * from t as t1 inner join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"Plan": [
"MergeJoin_8 0.00 root inner join, left key:test.t.c1, right key:test.t.c1",
"├─TableDual_26(Build) 0.00 root rows:0",
"└─TableDual_25(Probe) 0.00 root rows:0"
],
"Res": [
]
},
{
"SQL": "select count(*) from t as t1 inner join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"Plan": [
"StreamAgg_10 1.00 root funcs:count(1)->Column#7",
"└─MergeJoin_11 0.00 root inner join, left key:test.t.c1, right key:test.t.c1",
" ├─TableDual_27(Build) 0.00 root rows:0",
" └─TableDual_26(Probe) 0.00 root rows:0"
],
"Res": [
"0"
]
},
{
"SQL": "select t1.c1, t2.c1 from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"Plan": [
"MergeJoin_7 0.00 root left outer join, left key:test.t.c1, right key:test.t.c1",
"├─TableDual_17(Build) 0.00 root rows:0",
"└─TableDual_16(Probe) 0.00 root rows:0"
],
"Res": [
]
},
{
"SQL": "select * from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"Plan": [
"MergeJoin_7 0.00 root left outer join, left key:test.t.c1, right key:test.t.c1",
"├─TableDual_18(Build) 0.00 root rows:0",
"└─TableDual_17(Probe) 0.00 root rows:0"
],
"Res": [
]
},
{
"SQL": "select count(*) from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 != NULL",
"Plan": [
"StreamAgg_9 1.00 root funcs:count(1)->Column#7",
"└─MergeJoin_10 0.00 root left outer join, left key:test.t.c1, right key:test.t.c1",
" ├─TableDual_20(Build) 0.00 root rows:0",
" └─TableDual_19(Probe) 0.00 root rows:0"
],
"Res": [
"0"
]
},
{
"SQL": "select * from t as t1 left join t as t2 on t1.c1 = t2.c1 where t1.c1 is not NULL",
"Plan": [
"HashJoin_15 12487.50 root left outer join, equal:[eq(test.t.c1, test.t.c1)]",
"├─TableReader_33(Build) 9990.00 root data:Selection_32",
"│ └─Selection_32 9990.00 cop[tikv] not(isnull(test.t.c1))",
"│ └─TableFullScan_31 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─TableReader_27(Probe) 9990.00 root data:Selection_26",
" └─Selection_26 9990.00 cop[tikv] not(isnull(test.t.c1))",
" └─TableFullScan_25 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"Res": [
"2001 1 2001 1"
]
}
]
}
]
4 changes: 4 additions & 0 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,10 @@ func (d *Datum) convertToMysqlFloatYear(sc *stmtctx.StatementContext, target *Fi
y = float64(d.GetMysqlTime().Year())
case KindMysqlDuration:
y = float64(time.Now().Year())
case KindNull:
// if datum is NULL, we should keep it as it is, instead of setting it to zero or any other value.
ret = *d
return ret, nil
default:
ret, err = d.convertToFloat(sc, NewFieldType(mysql.TypeDouble))
if err != nil {
Expand Down

0 comments on commit 11a9254

Please sign in to comment.