@@ -216,21 +216,27 @@ var (
216216 _ builtinFunc = & builtinExtractDurationSig {}
217217 _ builtinFunc = & builtinAddDateStringStringSig {}
218218 _ builtinFunc = & builtinAddDateStringIntSig {}
219+ _ builtinFunc = & builtinAddDateStringRealSig {}
219220 _ builtinFunc = & builtinAddDateStringDecimalSig {}
220221 _ builtinFunc = & builtinAddDateIntStringSig {}
221222 _ builtinFunc = & builtinAddDateIntIntSig {}
223+ _ builtinFunc = & builtinAddDateIntRealSig {}
222224 _ builtinFunc = & builtinAddDateIntDecimalSig {}
223225 _ builtinFunc = & builtinAddDateDatetimeStringSig {}
224226 _ builtinFunc = & builtinAddDateDatetimeIntSig {}
227+ _ builtinFunc = & builtinAddDateDatetimeRealSig {}
225228 _ builtinFunc = & builtinAddDateDatetimeDecimalSig {}
226229 _ builtinFunc = & builtinSubDateStringStringSig {}
227230 _ builtinFunc = & builtinSubDateStringIntSig {}
231+ _ builtinFunc = & builtinSubDateStringRealSig {}
228232 _ builtinFunc = & builtinSubDateStringDecimalSig {}
229233 _ builtinFunc = & builtinSubDateIntStringSig {}
230234 _ builtinFunc = & builtinSubDateIntIntSig {}
235+ _ builtinFunc = & builtinSubDateIntRealSig {}
231236 _ builtinFunc = & builtinSubDateIntDecimalSig {}
232237 _ builtinFunc = & builtinSubDateDatetimeStringSig {}
233238 _ builtinFunc = & builtinSubDateDatetimeIntSig {}
239+ _ builtinFunc = & builtinSubDateDatetimeRealSig {}
234240 _ builtinFunc = & builtinSubDateDatetimeDecimalSig {}
235241)
236242
@@ -2631,6 +2637,14 @@ func (du *baseDateArithmitical) getIntervalFromInt(ctx sessionctx.Context, args
26312637 return strconv .FormatInt (interval , 10 ), false , nil
26322638}
26332639
2640+ func (du * baseDateArithmitical ) getIntervalFromReal (ctx sessionctx.Context , args []Expression , row chunk.Row , unit string ) (string , bool , error ) {
2641+ interval , isNull , err := args [1 ].EvalReal (ctx , row )
2642+ if isNull || err != nil {
2643+ return "" , true , err
2644+ }
2645+ return strconv .FormatFloat (interval , 'f' , - 1 , 64 ), false , nil
2646+ }
2647+
26342648func (du * baseDateArithmitical ) add (ctx sessionctx.Context , date types.Time , interval string , unit string ) (types.Time , bool , error ) {
26352649 year , month , day , nano , err := types .ParseDurationValue (unit , interval )
26362650 if err := handleInvalidTimeError (ctx , err ); err != nil {
@@ -2710,7 +2724,7 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27102724 }
27112725
27122726 intervalEvalTp := args [1 ].GetType ().EvalType ()
2713- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
2727+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
27142728 intervalEvalTp = types .ETInt
27152729 }
27162730
@@ -2729,6 +2743,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27292743 baseBuiltinFunc : bf ,
27302744 baseDateArithmitical : newDateArighmeticalUtil (),
27312745 }
2746+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
2747+ sig = & builtinAddDateStringRealSig {
2748+ baseBuiltinFunc : bf ,
2749+ baseDateArithmitical : newDateArighmeticalUtil (),
2750+ }
27322751 case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
27332752 sig = & builtinAddDateStringDecimalSig {
27342753 baseBuiltinFunc : bf ,
@@ -2744,6 +2763,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27442763 baseBuiltinFunc : bf ,
27452764 baseDateArithmitical : newDateArighmeticalUtil (),
27462765 }
2766+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
2767+ sig = & builtinAddDateIntRealSig {
2768+ baseBuiltinFunc : bf ,
2769+ baseDateArithmitical : newDateArighmeticalUtil (),
2770+ }
27472771 case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
27482772 sig = & builtinAddDateIntDecimalSig {
27492773 baseBuiltinFunc : bf ,
@@ -2759,6 +2783,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27592783 baseBuiltinFunc : bf ,
27602784 baseDateArithmitical : newDateArighmeticalUtil (),
27612785 }
2786+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
2787+ sig = & builtinAddDateDatetimeRealSig {
2788+ baseBuiltinFunc : bf ,
2789+ baseDateArithmitical : newDateArighmeticalUtil (),
2790+ }
27622791 case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
27632792 sig = & builtinAddDateDatetimeDecimalSig {
27642793 baseBuiltinFunc : bf ,
@@ -2834,6 +2863,39 @@ func (b *builtinAddDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
28342863 return result , isNull || err != nil , errors .Trace (err )
28352864}
28362865
2866+ type builtinAddDateStringRealSig struct {
2867+ baseBuiltinFunc
2868+ baseDateArithmitical
2869+ }
2870+
2871+ func (b * builtinAddDateStringRealSig ) Clone () builtinFunc {
2872+ newSig := & builtinAddDateStringRealSig {baseDateArithmitical : b .baseDateArithmitical }
2873+ newSig .cloneFrom (& b .baseBuiltinFunc )
2874+ return newSig
2875+ }
2876+
2877+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
2878+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
2879+ func (b * builtinAddDateStringRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
2880+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
2881+ if isNull || err != nil {
2882+ return types.Time {}, true , err
2883+ }
2884+
2885+ date , isNull , err := b .getDateFromString (b .ctx , b .args , row , unit )
2886+ if isNull || err != nil {
2887+ return types.Time {}, true , err
2888+ }
2889+
2890+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
2891+ if isNull || err != nil {
2892+ return types.Time {}, true , err
2893+ }
2894+
2895+ result , isNull , err := b .add (b .ctx , date , interval , unit )
2896+ return result , isNull || err != nil , err
2897+ }
2898+
28372899type builtinAddDateStringDecimalSig struct {
28382900 baseBuiltinFunc
28392901 baseDateArithmitical
@@ -2933,6 +2995,39 @@ func (b *builtinAddDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
29332995 return result , isNull || err != nil , errors .Trace (err )
29342996}
29352997
2998+ type builtinAddDateIntRealSig struct {
2999+ baseBuiltinFunc
3000+ baseDateArithmitical
3001+ }
3002+
3003+ func (b * builtinAddDateIntRealSig ) Clone () builtinFunc {
3004+ newSig := & builtinAddDateIntRealSig {baseDateArithmitical : b .baseDateArithmitical }
3005+ newSig .cloneFrom (& b .baseBuiltinFunc )
3006+ return newSig
3007+ }
3008+
3009+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
3010+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
3011+ func (b * builtinAddDateIntRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3012+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3013+ if isNull || err != nil {
3014+ return types.Time {}, true , err
3015+ }
3016+
3017+ date , isNull , err := b .getDateFromInt (b .ctx , b .args , row , unit )
3018+ if isNull || err != nil {
3019+ return types.Time {}, true , err
3020+ }
3021+
3022+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3023+ if isNull || err != nil {
3024+ return types.Time {}, true , err
3025+ }
3026+
3027+ result , isNull , err := b .add (b .ctx , date , interval , unit )
3028+ return result , isNull || err != nil , err
3029+ }
3030+
29363031type builtinAddDateIntDecimalSig struct {
29373032 baseBuiltinFunc
29383033 baseDateArithmitical
@@ -3032,6 +3127,39 @@ func (b *builtinAddDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
30323127 return result , isNull || err != nil , errors .Trace (err )
30333128}
30343129
3130+ type builtinAddDateDatetimeRealSig struct {
3131+ baseBuiltinFunc
3132+ baseDateArithmitical
3133+ }
3134+
3135+ func (b * builtinAddDateDatetimeRealSig ) Clone () builtinFunc {
3136+ newSig := & builtinAddDateDatetimeRealSig {baseDateArithmitical : b .baseDateArithmitical }
3137+ newSig .cloneFrom (& b .baseBuiltinFunc )
3138+ return newSig
3139+ }
3140+
3141+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
3142+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
3143+ func (b * builtinAddDateDatetimeRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3144+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3145+ if isNull || err != nil {
3146+ return types.Time {}, true , err
3147+ }
3148+
3149+ date , isNull , err := b .getDateFromDatetime (b .ctx , b .args , row , unit )
3150+ if isNull || err != nil {
3151+ return types.Time {}, true , err
3152+ }
3153+
3154+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3155+ if isNull || err != nil {
3156+ return types.Time {}, true , err
3157+ }
3158+
3159+ result , isNull , err := b .add (b .ctx , date , interval , unit )
3160+ return result , isNull || err != nil , err
3161+ }
3162+
30353163type builtinAddDateDatetimeDecimalSig struct {
30363164 baseBuiltinFunc
30373165 baseDateArithmitical
@@ -3080,7 +3208,7 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
30803208 }
30813209
30823210 intervalEvalTp := args [1 ].GetType ().EvalType ()
3083- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
3211+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
30843212 intervalEvalTp = types .ETInt
30853213 }
30863214
@@ -3099,6 +3227,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
30993227 baseBuiltinFunc : bf ,
31003228 baseDateArithmitical : newDateArighmeticalUtil (),
31013229 }
3230+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
3231+ sig = & builtinSubDateStringRealSig {
3232+ baseBuiltinFunc : bf ,
3233+ baseDateArithmitical : newDateArighmeticalUtil (),
3234+ }
31023235 case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
31033236 sig = & builtinSubDateStringDecimalSig {
31043237 baseBuiltinFunc : bf ,
@@ -3114,6 +3247,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31143247 baseBuiltinFunc : bf ,
31153248 baseDateArithmitical : newDateArighmeticalUtil (),
31163249 }
3250+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
3251+ sig = & builtinSubDateIntRealSig {
3252+ baseBuiltinFunc : bf ,
3253+ baseDateArithmitical : newDateArighmeticalUtil (),
3254+ }
31173255 case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
31183256 sig = & builtinSubDateIntDecimalSig {
31193257 baseBuiltinFunc : bf ,
@@ -3129,6 +3267,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31293267 baseBuiltinFunc : bf ,
31303268 baseDateArithmitical : newDateArighmeticalUtil (),
31313269 }
3270+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
3271+ sig = & builtinSubDateDatetimeRealSig {
3272+ baseBuiltinFunc : bf ,
3273+ baseDateArithmitical : newDateArighmeticalUtil (),
3274+ }
31323275 case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
31333276 sig = & builtinSubDateDatetimeDecimalSig {
31343277 baseBuiltinFunc : bf ,
@@ -3204,6 +3347,39 @@ func (b *builtinSubDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
32043347 return result , isNull || err != nil , errors .Trace (err )
32053348}
32063349
3350+ type builtinSubDateStringRealSig struct {
3351+ baseBuiltinFunc
3352+ baseDateArithmitical
3353+ }
3354+
3355+ func (b * builtinSubDateStringRealSig ) Clone () builtinFunc {
3356+ newSig := & builtinSubDateStringRealSig {baseDateArithmitical : b .baseDateArithmitical }
3357+ newSig .cloneFrom (& b .baseBuiltinFunc )
3358+ return newSig
3359+ }
3360+
3361+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3362+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3363+ func (b * builtinSubDateStringRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3364+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3365+ if isNull || err != nil {
3366+ return types.Time {}, true , err
3367+ }
3368+
3369+ date , isNull , err := b .getDateFromString (b .ctx , b .args , row , unit )
3370+ if isNull || err != nil {
3371+ return types.Time {}, true , err
3372+ }
3373+
3374+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3375+ if isNull || err != nil {
3376+ return types.Time {}, true , err
3377+ }
3378+
3379+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3380+ return result , isNull || err != nil , err
3381+ }
3382+
32073383type builtinSubDateStringDecimalSig struct {
32083384 baseBuiltinFunc
32093385 baseDateArithmitical
@@ -3301,6 +3477,39 @@ func (b *builtinSubDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
33013477 return result , isNull || err != nil , errors .Trace (err )
33023478}
33033479
3480+ type builtinSubDateIntRealSig struct {
3481+ baseBuiltinFunc
3482+ baseDateArithmitical
3483+ }
3484+
3485+ func (b * builtinSubDateIntRealSig ) Clone () builtinFunc {
3486+ newSig := & builtinSubDateIntRealSig {baseDateArithmitical : b .baseDateArithmitical }
3487+ newSig .cloneFrom (& b .baseBuiltinFunc )
3488+ return newSig
3489+ }
3490+
3491+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3492+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3493+ func (b * builtinSubDateIntRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3494+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3495+ if isNull || err != nil {
3496+ return types.Time {}, true , err
3497+ }
3498+
3499+ date , isNull , err := b .getDateFromInt (b .ctx , b .args , row , unit )
3500+ if isNull || err != nil {
3501+ return types.Time {}, true , err
3502+ }
3503+
3504+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3505+ if isNull || err != nil {
3506+ return types.Time {}, true , err
3507+ }
3508+
3509+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3510+ return result , isNull || err != nil , err
3511+ }
3512+
33043513type builtinSubDateDatetimeStringSig struct {
33053514 baseBuiltinFunc
33063515 baseDateArithmitical
@@ -3400,6 +3609,39 @@ func (b *builtinSubDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
34003609 return result , isNull || err != nil , errors .Trace (err )
34013610}
34023611
3612+ type builtinSubDateDatetimeRealSig struct {
3613+ baseBuiltinFunc
3614+ baseDateArithmitical
3615+ }
3616+
3617+ func (b * builtinSubDateDatetimeRealSig ) Clone () builtinFunc {
3618+ newSig := & builtinSubDateDatetimeRealSig {baseDateArithmitical : b .baseDateArithmitical }
3619+ newSig .cloneFrom (& b .baseBuiltinFunc )
3620+ return newSig
3621+ }
3622+
3623+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3624+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3625+ func (b * builtinSubDateDatetimeRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3626+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3627+ if isNull || err != nil {
3628+ return types.Time {}, true , err
3629+ }
3630+
3631+ date , isNull , err := b .getDateFromDatetime (b .ctx , b .args , row , unit )
3632+ if isNull || err != nil {
3633+ return types.Time {}, true , err
3634+ }
3635+
3636+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3637+ if isNull || err != nil {
3638+ return types.Time {}, true , err
3639+ }
3640+
3641+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3642+ return result , isNull || err != nil , err
3643+ }
3644+
34033645type builtinSubDateDatetimeDecimalSig struct {
34043646 baseBuiltinFunc
34053647 baseDateArithmitical
0 commit comments