@@ -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 , dur , err := types .ExtractTimeValue (unit , interval )
26362650 if err != nil {
@@ -2711,7 +2725,7 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27112725 }
27122726
27132727 intervalEvalTp := args [1 ].GetType ().EvalType ()
2714- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
2728+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
27152729 intervalEvalTp = types .ETInt
27162730 }
27172731
@@ -2730,6 +2744,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27302744 baseBuiltinFunc : bf ,
27312745 baseDateArithmitical : newDateArighmeticalUtil (),
27322746 }
2747+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
2748+ sig = & builtinAddDateStringRealSig {
2749+ baseBuiltinFunc : bf ,
2750+ baseDateArithmitical : newDateArighmeticalUtil (),
2751+ }
27332752 case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
27342753 sig = & builtinAddDateStringDecimalSig {
27352754 baseBuiltinFunc : bf ,
@@ -2745,6 +2764,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27452764 baseBuiltinFunc : bf ,
27462765 baseDateArithmitical : newDateArighmeticalUtil (),
27472766 }
2767+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
2768+ sig = & builtinAddDateIntRealSig {
2769+ baseBuiltinFunc : bf ,
2770+ baseDateArithmitical : newDateArighmeticalUtil (),
2771+ }
27482772 case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
27492773 sig = & builtinAddDateIntDecimalSig {
27502774 baseBuiltinFunc : bf ,
@@ -2760,6 +2784,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27602784 baseBuiltinFunc : bf ,
27612785 baseDateArithmitical : newDateArighmeticalUtil (),
27622786 }
2787+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
2788+ sig = & builtinAddDateDatetimeRealSig {
2789+ baseBuiltinFunc : bf ,
2790+ baseDateArithmitical : newDateArighmeticalUtil (),
2791+ }
27632792 case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
27642793 sig = & builtinAddDateDatetimeDecimalSig {
27652794 baseBuiltinFunc : bf ,
@@ -2835,6 +2864,39 @@ func (b *builtinAddDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
28352864 return result , isNull || err != nil , errors .Trace (err )
28362865}
28372866
2867+ type builtinAddDateStringRealSig struct {
2868+ baseBuiltinFunc
2869+ baseDateArithmitical
2870+ }
2871+
2872+ func (b * builtinAddDateStringRealSig ) Clone () builtinFunc {
2873+ newSig := & builtinAddDateStringRealSig {baseDateArithmitical : b .baseDateArithmitical }
2874+ newSig .cloneFrom (& b .baseBuiltinFunc )
2875+ return newSig
2876+ }
2877+
2878+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
2879+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
2880+ func (b * builtinAddDateStringRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
2881+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
2882+ if isNull || err != nil {
2883+ return types.Time {}, true , err
2884+ }
2885+
2886+ date , isNull , err := b .getDateFromString (b .ctx , b .args , row , unit )
2887+ if isNull || err != nil {
2888+ return types.Time {}, true , err
2889+ }
2890+
2891+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
2892+ if isNull || err != nil {
2893+ return types.Time {}, true , err
2894+ }
2895+
2896+ result , isNull , err := b .add (b .ctx , date , interval , unit )
2897+ return result , isNull || err != nil , err
2898+ }
2899+
28382900type builtinAddDateStringDecimalSig struct {
28392901 baseBuiltinFunc
28402902 baseDateArithmitical
@@ -2934,6 +2996,39 @@ func (b *builtinAddDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
29342996 return result , isNull || err != nil , errors .Trace (err )
29352997}
29362998
2999+ type builtinAddDateIntRealSig struct {
3000+ baseBuiltinFunc
3001+ baseDateArithmitical
3002+ }
3003+
3004+ func (b * builtinAddDateIntRealSig ) Clone () builtinFunc {
3005+ newSig := & builtinAddDateIntRealSig {baseDateArithmitical : b .baseDateArithmitical }
3006+ newSig .cloneFrom (& b .baseBuiltinFunc )
3007+ return newSig
3008+ }
3009+
3010+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
3011+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
3012+ func (b * builtinAddDateIntRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3013+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3014+ if isNull || err != nil {
3015+ return types.Time {}, true , err
3016+ }
3017+
3018+ date , isNull , err := b .getDateFromInt (b .ctx , b .args , row , unit )
3019+ if isNull || err != nil {
3020+ return types.Time {}, true , err
3021+ }
3022+
3023+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3024+ if isNull || err != nil {
3025+ return types.Time {}, true , err
3026+ }
3027+
3028+ result , isNull , err := b .add (b .ctx , date , interval , unit )
3029+ return result , isNull || err != nil , err
3030+ }
3031+
29373032type builtinAddDateIntDecimalSig struct {
29383033 baseBuiltinFunc
29393034 baseDateArithmitical
@@ -3033,6 +3128,39 @@ func (b *builtinAddDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
30333128 return result , isNull || err != nil , errors .Trace (err )
30343129}
30353130
3131+ type builtinAddDateDatetimeRealSig struct {
3132+ baseBuiltinFunc
3133+ baseDateArithmitical
3134+ }
3135+
3136+ func (b * builtinAddDateDatetimeRealSig ) Clone () builtinFunc {
3137+ newSig := & builtinAddDateDatetimeRealSig {baseDateArithmitical : b .baseDateArithmitical }
3138+ newSig .cloneFrom (& b .baseBuiltinFunc )
3139+ return newSig
3140+ }
3141+
3142+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
3143+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
3144+ func (b * builtinAddDateDatetimeRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3145+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3146+ if isNull || err != nil {
3147+ return types.Time {}, true , err
3148+ }
3149+
3150+ date , isNull , err := b .getDateFromDatetime (b .ctx , b .args , row , unit )
3151+ if isNull || err != nil {
3152+ return types.Time {}, true , err
3153+ }
3154+
3155+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3156+ if isNull || err != nil {
3157+ return types.Time {}, true , err
3158+ }
3159+
3160+ result , isNull , err := b .add (b .ctx , date , interval , unit )
3161+ return result , isNull || err != nil , err
3162+ }
3163+
30363164type builtinAddDateDatetimeDecimalSig struct {
30373165 baseBuiltinFunc
30383166 baseDateArithmitical
@@ -3081,7 +3209,7 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
30813209 }
30823210
30833211 intervalEvalTp := args [1 ].GetType ().EvalType ()
3084- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
3212+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
30853213 intervalEvalTp = types .ETInt
30863214 }
30873215
@@ -3100,6 +3228,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31003228 baseBuiltinFunc : bf ,
31013229 baseDateArithmitical : newDateArighmeticalUtil (),
31023230 }
3231+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
3232+ sig = & builtinSubDateStringRealSig {
3233+ baseBuiltinFunc : bf ,
3234+ baseDateArithmitical : newDateArighmeticalUtil (),
3235+ }
31033236 case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
31043237 sig = & builtinSubDateStringDecimalSig {
31053238 baseBuiltinFunc : bf ,
@@ -3115,6 +3248,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31153248 baseBuiltinFunc : bf ,
31163249 baseDateArithmitical : newDateArighmeticalUtil (),
31173250 }
3251+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
3252+ sig = & builtinSubDateIntRealSig {
3253+ baseBuiltinFunc : bf ,
3254+ baseDateArithmitical : newDateArighmeticalUtil (),
3255+ }
31183256 case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
31193257 sig = & builtinSubDateIntDecimalSig {
31203258 baseBuiltinFunc : bf ,
@@ -3130,6 +3268,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31303268 baseBuiltinFunc : bf ,
31313269 baseDateArithmitical : newDateArighmeticalUtil (),
31323270 }
3271+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
3272+ sig = & builtinSubDateDatetimeRealSig {
3273+ baseBuiltinFunc : bf ,
3274+ baseDateArithmitical : newDateArighmeticalUtil (),
3275+ }
31333276 case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
31343277 sig = & builtinSubDateDatetimeDecimalSig {
31353278 baseBuiltinFunc : bf ,
@@ -3205,6 +3348,39 @@ func (b *builtinSubDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
32053348 return result , isNull || err != nil , errors .Trace (err )
32063349}
32073350
3351+ type builtinSubDateStringRealSig struct {
3352+ baseBuiltinFunc
3353+ baseDateArithmitical
3354+ }
3355+
3356+ func (b * builtinSubDateStringRealSig ) Clone () builtinFunc {
3357+ newSig := & builtinSubDateStringRealSig {baseDateArithmitical : b .baseDateArithmitical }
3358+ newSig .cloneFrom (& b .baseBuiltinFunc )
3359+ return newSig
3360+ }
3361+
3362+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3363+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3364+ func (b * builtinSubDateStringRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3365+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3366+ if isNull || err != nil {
3367+ return types.Time {}, true , err
3368+ }
3369+
3370+ date , isNull , err := b .getDateFromString (b .ctx , b .args , row , unit )
3371+ if isNull || err != nil {
3372+ return types.Time {}, true , err
3373+ }
3374+
3375+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3376+ if isNull || err != nil {
3377+ return types.Time {}, true , err
3378+ }
3379+
3380+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3381+ return result , isNull || err != nil , err
3382+ }
3383+
32083384type builtinSubDateStringDecimalSig struct {
32093385 baseBuiltinFunc
32103386 baseDateArithmitical
@@ -3302,6 +3478,39 @@ func (b *builtinSubDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
33023478 return result , isNull || err != nil , errors .Trace (err )
33033479}
33043480
3481+ type builtinSubDateIntRealSig struct {
3482+ baseBuiltinFunc
3483+ baseDateArithmitical
3484+ }
3485+
3486+ func (b * builtinSubDateIntRealSig ) Clone () builtinFunc {
3487+ newSig := & builtinSubDateIntRealSig {baseDateArithmitical : b .baseDateArithmitical }
3488+ newSig .cloneFrom (& b .baseBuiltinFunc )
3489+ return newSig
3490+ }
3491+
3492+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3493+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3494+ func (b * builtinSubDateIntRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3495+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3496+ if isNull || err != nil {
3497+ return types.Time {}, true , err
3498+ }
3499+
3500+ date , isNull , err := b .getDateFromInt (b .ctx , b .args , row , unit )
3501+ if isNull || err != nil {
3502+ return types.Time {}, true , err
3503+ }
3504+
3505+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3506+ if isNull || err != nil {
3507+ return types.Time {}, true , err
3508+ }
3509+
3510+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3511+ return result , isNull || err != nil , err
3512+ }
3513+
33053514type builtinSubDateDatetimeStringSig struct {
33063515 baseBuiltinFunc
33073516 baseDateArithmitical
@@ -3401,6 +3610,39 @@ func (b *builtinSubDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
34013610 return result , isNull || err != nil , errors .Trace (err )
34023611}
34033612
3613+ type builtinSubDateDatetimeRealSig struct {
3614+ baseBuiltinFunc
3615+ baseDateArithmitical
3616+ }
3617+
3618+ func (b * builtinSubDateDatetimeRealSig ) Clone () builtinFunc {
3619+ newSig := & builtinSubDateDatetimeRealSig {baseDateArithmitical : b .baseDateArithmitical }
3620+ newSig .cloneFrom (& b .baseBuiltinFunc )
3621+ return newSig
3622+ }
3623+
3624+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3625+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3626+ func (b * builtinSubDateDatetimeRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3627+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3628+ if isNull || err != nil {
3629+ return types.Time {}, true , err
3630+ }
3631+
3632+ date , isNull , err := b .getDateFromDatetime (b .ctx , b .args , row , unit )
3633+ if isNull || err != nil {
3634+ return types.Time {}, true , err
3635+ }
3636+
3637+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3638+ if isNull || err != nil {
3639+ return types.Time {}, true , err
3640+ }
3641+
3642+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3643+ return result , isNull || err != nil , err
3644+ }
3645+
34043646type builtinSubDateDatetimeDecimalSig struct {
34053647 baseBuiltinFunc
34063648 baseDateArithmitical
0 commit comments