diff --git a/pkg/planner/core/issuetest/planner_issue_test.go b/pkg/planner/core/issuetest/planner_issue_test.go index 2702c4151a825..561736d7243ad 100644 --- a/pkg/planner/core/issuetest/planner_issue_test.go +++ b/pkg/planner/core/issuetest/planner_issue_test.go @@ -220,4 +220,15 @@ LIMIT 65122436;`).Check(testkit.Rows( " └─IndexReader_38 6.40 root index:StreamAgg_17", " └─StreamAgg_17 6.40 cop[tikv] group by:test.ta31c32a7.col_63, funcs:bit_xor(cast(test.ta31c32a7.col_63, bigint(22) BINARY))->Column#6", " └─IndexRangeScan_34 10.00 cop[tikv] table:ta31c32a7, index:idx_24(col_63) range:[NULL,NULL], keep order:true, stats:pseudo")) + tk.MustQuery(`explain SELECT BIT_XOR(ta31c32a7.col_63) AS r0 +FROM ta31c32a7 +WHERE ISNULL(ta31c32a7.col_63) + OR ta31c32a7.col_63 IN (1780.7418079754723, 5904.959667345741, 1531.4023068774668) +GROUP BY ta31c32a7.col_63 +LIMIT 65122436;`).Check(testkit.Rows( + "Limit_11 32.00 root offset:0, count:65122436", + "└─StreamAgg_35 32.00 root group by:test.ta31c32a7.col_63, funcs:bit_xor(Column#5)->Column#3", + " └─IndexReader_36 32.00 root index:StreamAgg_15", + " └─StreamAgg_15 32.00 cop[tikv] group by:test.ta31c32a7.col_63, funcs:bit_xor(cast(test.ta31c32a7.col_63, bigint(22) BINARY))->Column#5", + " └─IndexRangeScan_32 40.00 cop[tikv] table:ta31c32a7, index:idx_24(col_63) range:[NULL,NULL], [1531.4023068774668,1531.4023068774668], [1780.7418079754723,1780.7418079754723], [5904.959667345741,5904.959667345741], keep order:true, stats:pseudo")) } diff --git a/pkg/util/ranger/ranger.go b/pkg/util/ranger/ranger.go index 5d2d0a9edc8aa..27083db5314ab 100644 --- a/pkg/util/ranger/ranger.go +++ b/pkg/util/ranger/ranger.go @@ -735,21 +735,36 @@ func points2EqOrInCond(ctx expression.BuildContext, points []*point, col *expres retType := col.GetType(ctx.GetEvalCtx()) args := make([]expression.Expression, 0, len(points)/2) args = append(args, col) - if len(points) == 2 && points[0].value.IsNull() && points[0].value.IsNull() { - return expression.NewFunctionInternal(ctx, ast.IsNull, retType, args...) - } + orArgs := make([]expression.Expression, 0, 2) for i := 0; i < len(points); i = i + 2 { - value := &expression.Constant{ - Value: points[i].value, - RetType: retType, + if points[i].value.IsNull() { + orArgs = append(orArgs, expression.NewFunctionInternal(ctx, ast.IsNull, retType, col)) + } else { + value := &expression.Constant{ + Value: points[i].value, + RetType: retType, + } + args = append(args, value) } - args = append(args, value) } - funcName := ast.EQ - if len(args) > 2 { - funcName = ast.In + var result expression.Expression + if len(args) > 1 { + funcName := ast.EQ + if len(args) > 2 { + funcName = ast.In + } + result = expression.NewFunctionInternal(ctx, funcName, col.GetType(ctx.GetEvalCtx()), args...) + } + if len(orArgs) == 0 { + return result + } + if result != nil { + orArgs = append(orArgs, result) + } + if len(orArgs) == 1 { + return orArgs[0] } - return expression.NewFunctionInternal(ctx, funcName, col.GetType(ctx.GetEvalCtx()), args...) + return expression.NewFunctionInternal(ctx, ast.Or, col.GetType(ctx.GetEvalCtx()), orArgs...) } // RangesToString print a list of Ranges into a string which can appear in an SQL as a condition.