Skip to content

Commit 7e80053

Browse files
erjiaqingqw4990
authored andcommitted
planner: fix wrong DATE/DATETIME comparison in BETWEEN function (#10313)
1 parent 190990b commit 7e80053

File tree

3 files changed

+17
-6
lines changed

3 files changed

+17
-6
lines changed

expression/builtin_compare.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,8 @@ func temporalWithDateAsNumEvalType(argTp *types.FieldType) (argEvalType types.Ev
379379
return
380380
}
381381

382-
// getCmpTp4MinMax gets compare type for GREATEST and LEAST.
383-
func getCmpTp4MinMax(args []Expression) (argTp types.EvalType) {
382+
// GetCmpTp4MinMax gets compare type for GREATEST and LEAST and BETWEEN (mainly for datetime).
383+
func GetCmpTp4MinMax(args []Expression) (argTp types.EvalType) {
384384
datetimeFound, isAllStr := false, true
385385
cmpEvalType, isStr, isTemporalWithDate := temporalWithDateAsNumEvalType(args[0].GetType())
386386
if !isStr {
@@ -421,7 +421,7 @@ func (c *greatestFunctionClass) getFunction(ctx sessionctx.Context, args []Expre
421421
if err = c.verifyArgs(args); err != nil {
422422
return nil, err
423423
}
424-
tp, cmpAsDatetime := getCmpTp4MinMax(args), false
424+
tp, cmpAsDatetime := GetCmpTp4MinMax(args), false
425425
if tp == types.ETDatetime {
426426
cmpAsDatetime = true
427427
tp = types.ETString
@@ -615,7 +615,7 @@ func (c *leastFunctionClass) getFunction(ctx sessionctx.Context, args []Expressi
615615
if err = c.verifyArgs(args); err != nil {
616616
return nil, err
617617
}
618-
tp, cmpAsDatetime := getCmpTp4MinMax(args), false
618+
tp, cmpAsDatetime := GetCmpTp4MinMax(args), false
619619
if tp == types.ETDatetime {
620620
cmpAsDatetime = true
621621
tp = types.ETString

planner/core/expression_rewriter.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,11 +1259,20 @@ func (er *expressionRewriter) betweenToExpression(v *ast.BetweenExpr) {
12591259
if er.err != nil {
12601260
return
12611261
}
1262+
1263+
expr, lexp, rexp := er.ctxStack[stkLen-3], er.ctxStack[stkLen-2], er.ctxStack[stkLen-1]
1264+
1265+
if expression.GetCmpTp4MinMax([]expression.Expression{expr, lexp, rexp}) == types.ETDatetime {
1266+
expr = expression.WrapWithCastAsTime(er.ctx, expr, types.NewFieldType(mysql.TypeDatetime))
1267+
lexp = expression.WrapWithCastAsTime(er.ctx, lexp, types.NewFieldType(mysql.TypeDatetime))
1268+
rexp = expression.WrapWithCastAsTime(er.ctx, rexp, types.NewFieldType(mysql.TypeDatetime))
1269+
}
1270+
12621271
var op string
12631272
var l, r expression.Expression
1264-
l, er.err = er.newFunction(ast.GE, &v.Type, er.ctxStack[stkLen-3], er.ctxStack[stkLen-2])
1273+
l, er.err = er.newFunction(ast.GE, &v.Type, expr, lexp)
12651274
if er.err == nil {
1266-
r, er.err = er.newFunction(ast.LE, &v.Type, er.ctxStack[stkLen-3], er.ctxStack[stkLen-1])
1275+
r, er.err = er.newFunction(ast.LE, &v.Type, expr, rexp)
12671276
}
12681277
op = ast.LogicAnd
12691278
if er.err != nil {

planner/core/expression_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ func (s *testExpressionSuite) TestBetween(c *C) {
7070
tests := []testCase{
7171
{exprStr: "1 between 2 and 3", resultStr: "0"},
7272
{exprStr: "1 not between 2 and 3", resultStr: "1"},
73+
{exprStr: "'2001-04-10 12:34:56' between cast('2001-01-01 01:01:01' as datetime) and '01-05-01'", resultStr: "1"},
74+
{exprStr: "20010410123456 between cast('2001-01-01 01:01:01' as datetime) and 010501", resultStr: "0"},
7375
}
7476
s.runTests(c, tests)
7577
}

0 commit comments

Comments
 (0)