Skip to content

Commit 01a7e18

Browse files
ari-eAri Ekmekji
authored andcommitted
Use ordered index with is null predicate
1 parent 4793f5e commit 01a7e18

File tree

3 files changed

+49
-16
lines changed

3 files changed

+49
-16
lines changed

pkg/planner/core/casetest/index/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ go_test(
99
],
1010
data = glob(["testdata/**"]),
1111
flaky = True,
12-
shard_count = 5,
12+
shard_count = 6,
1313
deps = [
1414
"//pkg/testkit",
1515
"//pkg/testkit/testdata",

pkg/planner/core/casetest/index/index_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,15 @@ func TestRangeIntersection(t *testing.T) {
209209
tk.MustQuery(sql).Sort().Check(testkit.Rows(output[i].Result...))
210210
}
211211
}
212+
213+
func TestOrderedIndexWithIsNull(t *testing.T) {
214+
store := testkit.CreateMockStore(t)
215+
tk := testkit.NewTestKit(t, store)
216+
tk.MustExec("use test")
217+
tk.MustExec("CREATE TABLE t1 (a int key, b int, c int, index (b, c));")
218+
tk.MustQuery("explain select a from t1 where b is null order by c").Check(testkit.Rows(
219+
"Projection_6 10.00 root test.t1.a",
220+
"└─IndexReader_12 10.00 root index:IndexRangeScan_11",
221+
" └─IndexRangeScan_11 10.00 cop[tikv] table:t1, index:b(b, c) range:[NULL,NULL], keep order:true, stats:pseudo",
222+
))
223+
}

pkg/util/ranger/detacher.go

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ func getPotentialEqOrInColOffset(sctx *rangerctx.RangerContext, expr expression.
182182
return i
183183
}
184184
}
185+
case ast.IsNull:
186+
c, ok := f.GetArgs()[0].(*expression.Column)
187+
if !ok {
188+
return -1
189+
}
190+
for i, col := range cols {
191+
if col.EqualColumn(c) {
192+
return i
193+
}
194+
}
185195
}
186196
return -1
187197
}
@@ -635,27 +645,34 @@ func allEqOrIn(expr expression.Expression) bool {
635645
}
636646
}
637647
return true
638-
case ast.EQ, ast.NullEQ, ast.In:
648+
case ast.EQ, ast.NullEQ, ast.In, ast.IsNull:
639649
return true
640650
}
641651
return false
642652
}
643653

644654
func extractValueInfo(expr expression.Expression) *valueInfo {
645-
if f, ok := expr.(*expression.ScalarFunction); ok && (f.FuncName.L == ast.EQ || f.FuncName.L == ast.NullEQ) {
646-
getValueInfo := func(c *expression.Constant) *valueInfo {
647-
mutable := c.ParamMarker != nil || c.DeferredExpr != nil
648-
var value *types.Datum
649-
if !mutable {
650-
value = &c.Value
655+
if f, ok := expr.(*expression.ScalarFunction); ok {
656+
if f.FuncName.L == ast.IsNull {
657+
val := &types.Datum{}
658+
val.SetNull()
659+
return &valueInfo{value: val, mutable: false}
660+
}
661+
if f.FuncName.L == ast.EQ || f.FuncName.L == ast.NullEQ {
662+
getValueInfo := func(c *expression.Constant) *valueInfo {
663+
mutable := c.ParamMarker != nil || c.DeferredExpr != nil
664+
var value *types.Datum
665+
if !mutable {
666+
value = &c.Value
667+
}
668+
return &valueInfo{value, mutable}
669+
}
670+
if c, ok := f.GetArgs()[0].(*expression.Constant); ok {
671+
return getValueInfo(c)
672+
}
673+
if c, ok := f.GetArgs()[1].(*expression.Constant); ok {
674+
return getValueInfo(c)
651675
}
652-
return &valueInfo{value, mutable}
653-
}
654-
if c, ok := f.GetArgs()[0].(*expression.Constant); ok {
655-
return getValueInfo(c)
656-
}
657-
if c, ok := f.GetArgs()[1].(*expression.Constant); ok {
658-
return getValueInfo(c)
659676
}
660677
}
661678
return nil
@@ -714,8 +731,12 @@ func ExtractEqAndInCondition(sctx *rangerctx.RangerContext, conditions []express
714731
if ma == nil {
715732
if accesses[i] != nil {
716733
if allEqOrIn(accesses[i]) {
717-
newConditions = append(newConditions, accesses[i])
718734
columnValues[i] = extractValueInfo(accesses[i])
735+
if columnValues[i] != nil && columnValues[i].value != nil && columnValues[i].value.IsNull() {
736+
accesses[i] = nil
737+
} else {
738+
newConditions = append(newConditions, accesses[i])
739+
}
719740
} else {
720741
accesses[i] = nil
721742
}

0 commit comments

Comments
 (0)