Skip to content

Commit

Permalink
executor: fix incorrect result produced by addtime() or subtime() fun…
Browse files Browse the repository at this point in the history
…ction when using the date type (#57337) (#57569)

close #56861
  • Loading branch information
ti-chi-bot authored Nov 21, 2024
1 parent a568fdc commit 02ee4c6
Show file tree
Hide file tree
Showing 7 changed files with 1,057 additions and 64 deletions.
97 changes: 87 additions & 10 deletions pkg/expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -4579,7 +4579,7 @@ func getBf4TimeAddSub(ctx BuildContext, funcName string, args []Expression) (tp1
case mysql.TypeDuration:
argTp1, retTp = types.ETDuration, types.ETDuration
case mysql.TypeDate:
argTp1, retTp = types.ETDuration, types.ETString
argTp1, retTp = types.ETDatetime, types.ETString
default:
argTp1, retTp = types.ETString, types.ETString
}
Expand Down Expand Up @@ -4804,11 +4804,20 @@ func (b *builtinAddDatetimeAndDurationSig) evalTime(ctx EvalContext, row chunk.R
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
}

if arg0.IsZero() {
return types.ZeroDatetime, true, nil
}

arg1, isNull, err := b.args[1].EvalDuration(ctx, row)
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
}
result, err := arg0.Add(typeCtx(ctx), arg1)
if err != nil {
return types.ZeroDatetime, true, err
}

return result, err != nil, err
}

Expand All @@ -4829,6 +4838,11 @@ func (b *builtinAddDatetimeAndStringSig) evalTime(ctx EvalContext, row chunk.Row
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
}

if arg0.IsZero() {
return types.ZeroDatetime, true, nil
}

s, isNull, err := b.args[1].EvalString(ctx, row)
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
Expand All @@ -4846,6 +4860,10 @@ func (b *builtinAddDatetimeAndStringSig) evalTime(ctx EvalContext, row chunk.Row
return types.ZeroDatetime, true, err
}
result, err := arg0.Add(tc, arg1)
if err != nil {
return types.ZeroDatetime, true, err
}

return result, err != nil, err
}

Expand Down Expand Up @@ -5066,15 +5084,26 @@ func (b *builtinAddDateAndDurationSig) Clone() builtinFunc {
// evalString evals a builtinAddDurationAndDurationSig.
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
func (b *builtinAddDateAndDurationSig) evalString(ctx EvalContext, row chunk.Row) (string, bool, error) {
arg0, isNull, err := b.args[0].EvalDuration(ctx, row)
arg0, isNull, err := b.args[0].EvalTime(ctx, row)
if isNull || err != nil {
return "", isNull, err
}

if arg0.IsZero() {
return "", true, nil
}

arg1, isNull, err := b.args[1].EvalDuration(ctx, row)
if isNull || err != nil {
return "", isNull, err
}
result, err := arg0.Add(arg1)

arg0.SetType(mysql.TypeDatetime)
result, err := arg0.Add(typeCtx(ctx), arg1)
if err != nil {
return "", true, err
}

return result.String(), err != nil, err
}

Expand All @@ -5091,10 +5120,15 @@ func (b *builtinAddDateAndStringSig) Clone() builtinFunc {
// evalString evals a builtinAddDateAndStringSig.
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
func (b *builtinAddDateAndStringSig) evalString(ctx EvalContext, row chunk.Row) (string, bool, error) {
arg0, isNull, err := b.args[0].EvalDuration(ctx, row)
arg0, isNull, err := b.args[0].EvalTime(ctx, row)
if isNull || err != nil {
return "", isNull, err
}

if arg0.IsZero() {
return "", true, nil
}

s, isNull, err := b.args[1].EvalString(ctx, row)
if isNull || err != nil {
return "", isNull, err
Expand All @@ -5111,7 +5145,13 @@ func (b *builtinAddDateAndStringSig) evalString(ctx EvalContext, row chunk.Row)
}
return "", true, err
}
result, err := arg0.Add(arg1)

arg0.SetType(mysql.TypeDatetime)
result, err := arg0.Add(tc, arg1)
if err != nil {
return "", true, err
}

return result.String(), err != nil, err
}

Expand Down Expand Up @@ -5757,12 +5797,21 @@ func (b *builtinSubDatetimeAndDurationSig) evalTime(ctx EvalContext, row chunk.R
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
}

if arg0.IsZero() {
return types.ZeroDatetime, true, nil
}

arg1, isNull, err := b.args[1].EvalDuration(ctx, row)
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
}
tc := typeCtx(ctx)
result, err := arg0.Add(tc, arg1.Neg())
if err != nil {
return types.ZeroDatetime, true, err
}

return result, err != nil, err
}

Expand All @@ -5783,6 +5832,11 @@ func (b *builtinSubDatetimeAndStringSig) evalTime(ctx EvalContext, row chunk.Row
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
}

if arg0.IsZero() {
return types.ZeroDatetime, true, nil
}

s, isNull, err := b.args[1].EvalString(ctx, row)
if isNull || err != nil {
return types.ZeroDatetime, isNull, err
Expand All @@ -5800,6 +5854,10 @@ func (b *builtinSubDatetimeAndStringSig) evalTime(ctx EvalContext, row chunk.Row
return types.ZeroDatetime, true, err
}
result, err := arg0.Add(tc, arg1.Neg())
if err != nil {
return types.ZeroDatetime, true, err
}

return result, err != nil, err
}

Expand Down Expand Up @@ -6023,15 +6081,26 @@ func (b *builtinSubDateAndDurationSig) Clone() builtinFunc {
// evalString evals a builtinSubDateAndDurationSig.
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
func (b *builtinSubDateAndDurationSig) evalString(ctx EvalContext, row chunk.Row) (string, bool, error) {
arg0, isNull, err := b.args[0].EvalDuration(ctx, row)
arg0, isNull, err := b.args[0].EvalTime(ctx, row)
if isNull || err != nil {
return "", isNull, err
}

if arg0.IsZero() {
return "", true, nil
}

arg1, isNull, err := b.args[1].EvalDuration(ctx, row)
if isNull || err != nil {
return "", isNull, err
}
result, err := arg0.Sub(arg1)

arg0.SetType(mysql.TypeDatetime)
result, err := arg0.Add(typeCtx(ctx), arg1.Neg())
if err != nil {
return "", true, err
}

return result.String(), err != nil, err
}

Expand All @@ -6048,10 +6117,15 @@ func (b *builtinSubDateAndStringSig) Clone() builtinFunc {
// evalString evals a builtinSubDateAndStringSig.
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
func (b *builtinSubDateAndStringSig) evalString(ctx EvalContext, row chunk.Row) (string, bool, error) {
arg0, isNull, err := b.args[0].EvalDuration(ctx, row)
arg0, isNull, err := b.args[0].EvalTime(ctx, row)
if isNull || err != nil {
return "", isNull, err
}

if arg0.IsZero() {
return "", true, nil
}

s, isNull, err := b.args[1].EvalString(ctx, row)
if isNull || err != nil {
return "", isNull, err
Expand All @@ -6068,11 +6142,14 @@ func (b *builtinSubDateAndStringSig) evalString(ctx EvalContext, row chunk.Row)
}
return "", true, err
}
result, err := arg0.Sub(arg1)

arg0.SetType(mysql.TypeDatetime)
result, err := arg0.Add(tc, arg1.Neg())
if err != nil {
return "", true, err
}
return result.String(), false, nil

return result.String(), err != nil, err
}

type timeFormatFunctionClass struct {
Expand Down
Loading

0 comments on commit 02ee4c6

Please sign in to comment.