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 (#23079)
  • Loading branch information
guo-shaoge authored Mar 4, 2021
1 parent 2cdd8a3 commit db62e34
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 @@ -1216,6 +1216,32 @@ func (s *testSuiteWithData) TestSetOperationOnDiffColType(c *C) {
}
}

// 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 @@ -39,5 +39,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 @@ -518,5 +518,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_9 0.00 root inner join, left key:test.t.c1, right key:test.t.c1",
"├─TableDual_35(Build) 0.00 root rows:0",
"└─TableDual_34(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_9 0.00 root inner join, left key:test.t.c1, right key:test.t.c1",
"├─TableDual_41(Build) 0.00 root rows:0",
"└─TableDual_40(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_11 1.00 root funcs:count(1)->Column#7",
"└─MergeJoin_12 0.00 root inner join, left key:test.t.c1, right key:test.t.c1",
" ├─TableDual_38(Build) 0.00 root rows:0",
" └─TableDual_37(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_22(Build) 0.00 root rows:0",
"└─TableDual_21(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_25(Build) 0.00 root rows:0",
"└─TableDual_24(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_25(Build) 0.00 root rows:0",
" └─TableDual_24(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_22 12487.50 root left outer join, equal:[eq(test.t.c1, test.t.c1)]",
"├─TableReader_40(Build) 9990.00 root data:Selection_39",
"│ └─Selection_39 9990.00 cop[tikv] not(isnull(test.t.c1))",
"│ └─TableFullScan_38 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─TableReader_34(Probe) 9990.00 root data:Selection_33",
" └─Selection_33 9990.00 cop[tikv] not(isnull(test.t.c1))",
" └─TableFullScan_32 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 @@ -1424,6 +1424,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 db62e34

Please sign in to comment.