@@ -217,21 +217,27 @@ var (
217217 _ builtinFunc = & builtinExtractDurationSig {}
218218 _ builtinFunc = & builtinAddDateStringStringSig {}
219219 _ builtinFunc = & builtinAddDateStringIntSig {}
220+ _ builtinFunc = & builtinAddDateStringRealSig {}
220221 _ builtinFunc = & builtinAddDateStringDecimalSig {}
221222 _ builtinFunc = & builtinAddDateIntStringSig {}
222223 _ builtinFunc = & builtinAddDateIntIntSig {}
224+ _ builtinFunc = & builtinAddDateIntRealSig {}
223225 _ builtinFunc = & builtinAddDateIntDecimalSig {}
224226 _ builtinFunc = & builtinAddDateDatetimeStringSig {}
225227 _ builtinFunc = & builtinAddDateDatetimeIntSig {}
228+ _ builtinFunc = & builtinAddDateDatetimeRealSig {}
226229 _ builtinFunc = & builtinAddDateDatetimeDecimalSig {}
227230 _ builtinFunc = & builtinSubDateStringStringSig {}
228231 _ builtinFunc = & builtinSubDateStringIntSig {}
232+ _ builtinFunc = & builtinSubDateStringRealSig {}
229233 _ builtinFunc = & builtinSubDateStringDecimalSig {}
230234 _ builtinFunc = & builtinSubDateIntStringSig {}
231235 _ builtinFunc = & builtinSubDateIntIntSig {}
236+ _ builtinFunc = & builtinSubDateIntRealSig {}
232237 _ builtinFunc = & builtinSubDateIntDecimalSig {}
233238 _ builtinFunc = & builtinSubDateDatetimeStringSig {}
234239 _ builtinFunc = & builtinSubDateDatetimeIntSig {}
240+ _ builtinFunc = & builtinSubDateDatetimeRealSig {}
235241 _ builtinFunc = & builtinSubDateDatetimeDecimalSig {}
236242)
237243
@@ -2703,6 +2709,14 @@ func (du *baseDateArithmitical) getIntervalFromInt(ctx sessionctx.Context, args
27032709 return strconv .FormatInt (interval , 10 ), false , nil
27042710}
27052711
2712+ func (du * baseDateArithmitical ) getIntervalFromReal (ctx sessionctx.Context , args []Expression , row chunk.Row , unit string ) (string , bool , error ) {
2713+ interval , isNull , err := args [1 ].EvalReal (ctx , row )
2714+ if isNull || err != nil {
2715+ return "" , true , err
2716+ }
2717+ return strconv .FormatFloat (interval , 'f' , - 1 , 64 ), false , nil
2718+ }
2719+
27062720func (du * baseDateArithmitical ) add (ctx sessionctx.Context , date types.Time , interval string , unit string ) (types.Time , bool , error ) {
27072721 year , month , day , dur , err := types .ExtractTimeValue (unit , interval )
27082722 if err != nil {
@@ -2783,7 +2797,7 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
27832797 }
27842798
27852799 intervalEvalTp := args [1 ].GetType ().EvalType ()
2786- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
2800+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
27872801 intervalEvalTp = types .ETInt
27882802 }
27892803
@@ -2802,6 +2816,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
28022816 baseBuiltinFunc : bf ,
28032817 baseDateArithmitical : newDateArighmeticalUtil (),
28042818 }
2819+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
2820+ sig = & builtinAddDateStringRealSig {
2821+ baseBuiltinFunc : bf ,
2822+ baseDateArithmitical : newDateArighmeticalUtil (),
2823+ }
28052824 case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
28062825 sig = & builtinAddDateStringDecimalSig {
28072826 baseBuiltinFunc : bf ,
@@ -2817,6 +2836,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
28172836 baseBuiltinFunc : bf ,
28182837 baseDateArithmitical : newDateArighmeticalUtil (),
28192838 }
2839+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
2840+ sig = & builtinAddDateIntRealSig {
2841+ baseBuiltinFunc : bf ,
2842+ baseDateArithmitical : newDateArighmeticalUtil (),
2843+ }
28202844 case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
28212845 sig = & builtinAddDateIntDecimalSig {
28222846 baseBuiltinFunc : bf ,
@@ -2832,6 +2856,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
28322856 baseBuiltinFunc : bf ,
28332857 baseDateArithmitical : newDateArighmeticalUtil (),
28342858 }
2859+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
2860+ sig = & builtinAddDateDatetimeRealSig {
2861+ baseBuiltinFunc : bf ,
2862+ baseDateArithmitical : newDateArighmeticalUtil (),
2863+ }
28352864 case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
28362865 sig = & builtinAddDateDatetimeDecimalSig {
28372866 baseBuiltinFunc : bf ,
@@ -2907,6 +2936,39 @@ func (b *builtinAddDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
29072936 return result , isNull || err != nil , err
29082937}
29092938
2939+ type builtinAddDateStringRealSig struct {
2940+ baseBuiltinFunc
2941+ baseDateArithmitical
2942+ }
2943+
2944+ func (b * builtinAddDateStringRealSig ) Clone () builtinFunc {
2945+ newSig := & builtinAddDateStringRealSig {baseDateArithmitical : b .baseDateArithmitical }
2946+ newSig .cloneFrom (& b .baseBuiltinFunc )
2947+ return newSig
2948+ }
2949+
2950+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
2951+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
2952+ func (b * builtinAddDateStringRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
2953+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
2954+ if isNull || err != nil {
2955+ return types.Time {}, true , err
2956+ }
2957+
2958+ date , isNull , err := b .getDateFromString (b .ctx , b .args , row , unit )
2959+ if isNull || err != nil {
2960+ return types.Time {}, true , err
2961+ }
2962+
2963+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
2964+ if isNull || err != nil {
2965+ return types.Time {}, true , err
2966+ }
2967+
2968+ result , isNull , err := b .add (b .ctx , date , interval , unit )
2969+ return result , isNull || err != nil , err
2970+ }
2971+
29102972type builtinAddDateStringDecimalSig struct {
29112973 baseBuiltinFunc
29122974 baseDateArithmitical
@@ -3006,6 +3068,39 @@ func (b *builtinAddDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
30063068 return result , isNull || err != nil , err
30073069}
30083070
3071+ type builtinAddDateIntRealSig struct {
3072+ baseBuiltinFunc
3073+ baseDateArithmitical
3074+ }
3075+
3076+ func (b * builtinAddDateIntRealSig ) Clone () builtinFunc {
3077+ newSig := & builtinAddDateIntRealSig {baseDateArithmitical : b .baseDateArithmitical }
3078+ newSig .cloneFrom (& b .baseBuiltinFunc )
3079+ return newSig
3080+ }
3081+
3082+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
3083+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
3084+ func (b * builtinAddDateIntRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3085+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3086+ if isNull || err != nil {
3087+ return types.Time {}, true , err
3088+ }
3089+
3090+ date , isNull , err := b .getDateFromInt (b .ctx , b .args , row , unit )
3091+ if isNull || err != nil {
3092+ return types.Time {}, true , err
3093+ }
3094+
3095+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3096+ if isNull || err != nil {
3097+ return types.Time {}, true , err
3098+ }
3099+
3100+ result , isNull , err := b .add (b .ctx , date , interval , unit )
3101+ return result , isNull || err != nil , err
3102+ }
3103+
30093104type builtinAddDateIntDecimalSig struct {
30103105 baseBuiltinFunc
30113106 baseDateArithmitical
@@ -3105,6 +3200,39 @@ func (b *builtinAddDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
31053200 return result , isNull || err != nil , err
31063201}
31073202
3203+ type builtinAddDateDatetimeRealSig struct {
3204+ baseBuiltinFunc
3205+ baseDateArithmitical
3206+ }
3207+
3208+ func (b * builtinAddDateDatetimeRealSig ) Clone () builtinFunc {
3209+ newSig := & builtinAddDateDatetimeRealSig {baseDateArithmitical : b .baseDateArithmitical }
3210+ newSig .cloneFrom (& b .baseBuiltinFunc )
3211+ return newSig
3212+ }
3213+
3214+ // evalTime evals ADDDATE(date,INTERVAL expr unit).
3215+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
3216+ func (b * builtinAddDateDatetimeRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3217+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3218+ if isNull || err != nil {
3219+ return types.Time {}, true , err
3220+ }
3221+
3222+ date , isNull , err := b .getDateFromDatetime (b .ctx , b .args , row , unit )
3223+ if isNull || err != nil {
3224+ return types.Time {}, true , err
3225+ }
3226+
3227+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3228+ if isNull || err != nil {
3229+ return types.Time {}, true , err
3230+ }
3231+
3232+ result , isNull , err := b .add (b .ctx , date , interval , unit )
3233+ return result , isNull || err != nil , err
3234+ }
3235+
31083236type builtinAddDateDatetimeDecimalSig struct {
31093237 baseBuiltinFunc
31103238 baseDateArithmitical
@@ -3153,7 +3281,7 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31533281 }
31543282
31553283 intervalEvalTp := args [1 ].GetType ().EvalType ()
3156- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
3284+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
31573285 intervalEvalTp = types .ETInt
31583286 }
31593287
@@ -3172,6 +3300,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31723300 baseBuiltinFunc : bf ,
31733301 baseDateArithmitical : newDateArighmeticalUtil (),
31743302 }
3303+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
3304+ sig = & builtinSubDateStringRealSig {
3305+ baseBuiltinFunc : bf ,
3306+ baseDateArithmitical : newDateArighmeticalUtil (),
3307+ }
31753308 case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
31763309 sig = & builtinSubDateStringDecimalSig {
31773310 baseBuiltinFunc : bf ,
@@ -3187,6 +3320,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
31873320 baseBuiltinFunc : bf ,
31883321 baseDateArithmitical : newDateArighmeticalUtil (),
31893322 }
3323+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
3324+ sig = & builtinSubDateIntRealSig {
3325+ baseBuiltinFunc : bf ,
3326+ baseDateArithmitical : newDateArighmeticalUtil (),
3327+ }
31903328 case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
31913329 sig = & builtinSubDateIntDecimalSig {
31923330 baseBuiltinFunc : bf ,
@@ -3202,6 +3340,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
32023340 baseBuiltinFunc : bf ,
32033341 baseDateArithmitical : newDateArighmeticalUtil (),
32043342 }
3343+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
3344+ sig = & builtinSubDateDatetimeRealSig {
3345+ baseBuiltinFunc : bf ,
3346+ baseDateArithmitical : newDateArighmeticalUtil (),
3347+ }
32053348 case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
32063349 sig = & builtinSubDateDatetimeDecimalSig {
32073350 baseBuiltinFunc : bf ,
@@ -3277,6 +3420,39 @@ func (b *builtinSubDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
32773420 return result , isNull || err != nil , err
32783421}
32793422
3423+ type builtinSubDateStringRealSig struct {
3424+ baseBuiltinFunc
3425+ baseDateArithmitical
3426+ }
3427+
3428+ func (b * builtinSubDateStringRealSig ) Clone () builtinFunc {
3429+ newSig := & builtinSubDateStringRealSig {baseDateArithmitical : b .baseDateArithmitical }
3430+ newSig .cloneFrom (& b .baseBuiltinFunc )
3431+ return newSig
3432+ }
3433+
3434+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3435+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3436+ func (b * builtinSubDateStringRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3437+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3438+ if isNull || err != nil {
3439+ return types.Time {}, true , err
3440+ }
3441+
3442+ date , isNull , err := b .getDateFromString (b .ctx , b .args , row , unit )
3443+ if isNull || err != nil {
3444+ return types.Time {}, true , err
3445+ }
3446+
3447+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3448+ if isNull || err != nil {
3449+ return types.Time {}, true , err
3450+ }
3451+
3452+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3453+ return result , isNull || err != nil , err
3454+ }
3455+
32803456type builtinSubDateStringDecimalSig struct {
32813457 baseBuiltinFunc
32823458 baseDateArithmitical
@@ -3374,6 +3550,39 @@ func (b *builtinSubDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
33743550 return result , isNull || err != nil , err
33753551}
33763552
3553+ type builtinSubDateIntRealSig struct {
3554+ baseBuiltinFunc
3555+ baseDateArithmitical
3556+ }
3557+
3558+ func (b * builtinSubDateIntRealSig ) Clone () builtinFunc {
3559+ newSig := & builtinSubDateIntRealSig {baseDateArithmitical : b .baseDateArithmitical }
3560+ newSig .cloneFrom (& b .baseBuiltinFunc )
3561+ return newSig
3562+ }
3563+
3564+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3565+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3566+ func (b * builtinSubDateIntRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3567+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3568+ if isNull || err != nil {
3569+ return types.Time {}, true , err
3570+ }
3571+
3572+ date , isNull , err := b .getDateFromInt (b .ctx , b .args , row , unit )
3573+ if isNull || err != nil {
3574+ return types.Time {}, true , err
3575+ }
3576+
3577+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3578+ if isNull || err != nil {
3579+ return types.Time {}, true , err
3580+ }
3581+
3582+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3583+ return result , isNull || err != nil , err
3584+ }
3585+
33773586type builtinSubDateDatetimeStringSig struct {
33783587 baseBuiltinFunc
33793588 baseDateArithmitical
@@ -3473,6 +3682,39 @@ func (b *builtinSubDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
34733682 return result , isNull || err != nil , err
34743683}
34753684
3685+ type builtinSubDateDatetimeRealSig struct {
3686+ baseBuiltinFunc
3687+ baseDateArithmitical
3688+ }
3689+
3690+ func (b * builtinSubDateDatetimeRealSig ) Clone () builtinFunc {
3691+ newSig := & builtinSubDateDatetimeRealSig {baseDateArithmitical : b .baseDateArithmitical }
3692+ newSig .cloneFrom (& b .baseBuiltinFunc )
3693+ return newSig
3694+ }
3695+
3696+ // evalTime evals SUBDATE(date,INTERVAL expr unit).
3697+ // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
3698+ func (b * builtinSubDateDatetimeRealSig ) evalTime (row chunk.Row ) (types.Time , bool , error ) {
3699+ unit , isNull , err := b .args [2 ].EvalString (b .ctx , row )
3700+ if isNull || err != nil {
3701+ return types.Time {}, true , err
3702+ }
3703+
3704+ date , isNull , err := b .getDateFromDatetime (b .ctx , b .args , row , unit )
3705+ if isNull || err != nil {
3706+ return types.Time {}, true , err
3707+ }
3708+
3709+ interval , isNull , err := b .getIntervalFromReal (b .ctx , b .args , row , unit )
3710+ if isNull || err != nil {
3711+ return types.Time {}, true , err
3712+ }
3713+
3714+ result , isNull , err := b .sub (b .ctx , date , interval , unit )
3715+ return result , isNull || err != nil , err
3716+ }
3717+
34763718type builtinSubDateDatetimeDecimalSig struct {
34773719 baseBuiltinFunc
34783720 baseDateArithmitical
0 commit comments