@@ -216,21 +216,27 @@ var (
216
216
_ builtinFunc = & builtinExtractDurationSig {}
217
217
_ builtinFunc = & builtinAddDateStringStringSig {}
218
218
_ builtinFunc = & builtinAddDateStringIntSig {}
219
+ _ builtinFunc = & builtinAddDateStringRealSig {}
219
220
_ builtinFunc = & builtinAddDateStringDecimalSig {}
220
221
_ builtinFunc = & builtinAddDateIntStringSig {}
221
222
_ builtinFunc = & builtinAddDateIntIntSig {}
223
+ _ builtinFunc = & builtinAddDateIntRealSig {}
222
224
_ builtinFunc = & builtinAddDateIntDecimalSig {}
223
225
_ builtinFunc = & builtinAddDateDatetimeStringSig {}
224
226
_ builtinFunc = & builtinAddDateDatetimeIntSig {}
227
+ _ builtinFunc = & builtinAddDateDatetimeRealSig {}
225
228
_ builtinFunc = & builtinAddDateDatetimeDecimalSig {}
226
229
_ builtinFunc = & builtinSubDateStringStringSig {}
227
230
_ builtinFunc = & builtinSubDateStringIntSig {}
231
+ _ builtinFunc = & builtinSubDateStringRealSig {}
228
232
_ builtinFunc = & builtinSubDateStringDecimalSig {}
229
233
_ builtinFunc = & builtinSubDateIntStringSig {}
230
234
_ builtinFunc = & builtinSubDateIntIntSig {}
235
+ _ builtinFunc = & builtinSubDateIntRealSig {}
231
236
_ builtinFunc = & builtinSubDateIntDecimalSig {}
232
237
_ builtinFunc = & builtinSubDateDatetimeStringSig {}
233
238
_ builtinFunc = & builtinSubDateDatetimeIntSig {}
239
+ _ builtinFunc = & builtinSubDateDatetimeRealSig {}
234
240
_ builtinFunc = & builtinSubDateDatetimeDecimalSig {}
235
241
)
236
242
@@ -2631,6 +2637,14 @@ func (du *baseDateArithmitical) getIntervalFromInt(ctx sessionctx.Context, args
2631
2637
return strconv .FormatInt (interval , 10 ), false , nil
2632
2638
}
2633
2639
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
+
2634
2648
func (du * baseDateArithmitical ) add (ctx sessionctx.Context , date types.Time , interval string , unit string ) (types.Time , bool , error ) {
2635
2649
year , month , day , nano , err := types .ParseDurationValue (unit , interval )
2636
2650
if err := handleInvalidTimeError (ctx , err ); err != nil {
@@ -2710,7 +2724,7 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
2710
2724
}
2711
2725
2712
2726
intervalEvalTp := args [1 ].GetType ().EvalType ()
2713
- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
2727
+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
2714
2728
intervalEvalTp = types .ETInt
2715
2729
}
2716
2730
@@ -2729,6 +2743,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
2729
2743
baseBuiltinFunc : bf ,
2730
2744
baseDateArithmitical : newDateArighmeticalUtil (),
2731
2745
}
2746
+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
2747
+ sig = & builtinAddDateStringRealSig {
2748
+ baseBuiltinFunc : bf ,
2749
+ baseDateArithmitical : newDateArighmeticalUtil (),
2750
+ }
2732
2751
case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
2733
2752
sig = & builtinAddDateStringDecimalSig {
2734
2753
baseBuiltinFunc : bf ,
@@ -2744,6 +2763,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
2744
2763
baseBuiltinFunc : bf ,
2745
2764
baseDateArithmitical : newDateArighmeticalUtil (),
2746
2765
}
2766
+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
2767
+ sig = & builtinAddDateIntRealSig {
2768
+ baseBuiltinFunc : bf ,
2769
+ baseDateArithmitical : newDateArighmeticalUtil (),
2770
+ }
2747
2771
case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
2748
2772
sig = & builtinAddDateIntDecimalSig {
2749
2773
baseBuiltinFunc : bf ,
@@ -2759,6 +2783,11 @@ func (c *addDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
2759
2783
baseBuiltinFunc : bf ,
2760
2784
baseDateArithmitical : newDateArighmeticalUtil (),
2761
2785
}
2786
+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
2787
+ sig = & builtinAddDateDatetimeRealSig {
2788
+ baseBuiltinFunc : bf ,
2789
+ baseDateArithmitical : newDateArighmeticalUtil (),
2790
+ }
2762
2791
case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
2763
2792
sig = & builtinAddDateDatetimeDecimalSig {
2764
2793
baseBuiltinFunc : bf ,
@@ -2834,6 +2863,39 @@ func (b *builtinAddDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
2834
2863
return result , isNull || err != nil , errors .Trace (err )
2835
2864
}
2836
2865
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
+
2837
2899
type builtinAddDateStringDecimalSig struct {
2838
2900
baseBuiltinFunc
2839
2901
baseDateArithmitical
@@ -2933,6 +2995,39 @@ func (b *builtinAddDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
2933
2995
return result , isNull || err != nil , errors .Trace (err )
2934
2996
}
2935
2997
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
+
2936
3031
type builtinAddDateIntDecimalSig struct {
2937
3032
baseBuiltinFunc
2938
3033
baseDateArithmitical
@@ -3032,6 +3127,39 @@ func (b *builtinAddDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
3032
3127
return result , isNull || err != nil , errors .Trace (err )
3033
3128
}
3034
3129
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
+
3035
3163
type builtinAddDateDatetimeDecimalSig struct {
3036
3164
baseBuiltinFunc
3037
3165
baseDateArithmitical
@@ -3080,7 +3208,7 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
3080
3208
}
3081
3209
3082
3210
intervalEvalTp := args [1 ].GetType ().EvalType ()
3083
- if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal {
3211
+ if intervalEvalTp != types .ETString && intervalEvalTp != types .ETDecimal && intervalEvalTp != types . ETReal {
3084
3212
intervalEvalTp = types .ETInt
3085
3213
}
3086
3214
@@ -3099,6 +3227,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
3099
3227
baseBuiltinFunc : bf ,
3100
3228
baseDateArithmitical : newDateArighmeticalUtil (),
3101
3229
}
3230
+ case dateEvalTp == types .ETString && intervalEvalTp == types .ETReal :
3231
+ sig = & builtinSubDateStringRealSig {
3232
+ baseBuiltinFunc : bf ,
3233
+ baseDateArithmitical : newDateArighmeticalUtil (),
3234
+ }
3102
3235
case dateEvalTp == types .ETString && intervalEvalTp == types .ETDecimal :
3103
3236
sig = & builtinSubDateStringDecimalSig {
3104
3237
baseBuiltinFunc : bf ,
@@ -3114,6 +3247,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
3114
3247
baseBuiltinFunc : bf ,
3115
3248
baseDateArithmitical : newDateArighmeticalUtil (),
3116
3249
}
3250
+ case dateEvalTp == types .ETInt && intervalEvalTp == types .ETReal :
3251
+ sig = & builtinSubDateIntRealSig {
3252
+ baseBuiltinFunc : bf ,
3253
+ baseDateArithmitical : newDateArighmeticalUtil (),
3254
+ }
3117
3255
case dateEvalTp == types .ETInt && intervalEvalTp == types .ETDecimal :
3118
3256
sig = & builtinSubDateIntDecimalSig {
3119
3257
baseBuiltinFunc : bf ,
@@ -3129,6 +3267,11 @@ func (c *subDateFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
3129
3267
baseBuiltinFunc : bf ,
3130
3268
baseDateArithmitical : newDateArighmeticalUtil (),
3131
3269
}
3270
+ case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETReal :
3271
+ sig = & builtinSubDateDatetimeRealSig {
3272
+ baseBuiltinFunc : bf ,
3273
+ baseDateArithmitical : newDateArighmeticalUtil (),
3274
+ }
3132
3275
case dateEvalTp == types .ETDatetime && intervalEvalTp == types .ETDecimal :
3133
3276
sig = & builtinSubDateDatetimeDecimalSig {
3134
3277
baseBuiltinFunc : bf ,
@@ -3204,6 +3347,39 @@ func (b *builtinSubDateStringIntSig) evalTime(row chunk.Row) (types.Time, bool,
3204
3347
return result , isNull || err != nil , errors .Trace (err )
3205
3348
}
3206
3349
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
+
3207
3383
type builtinSubDateStringDecimalSig struct {
3208
3384
baseBuiltinFunc
3209
3385
baseDateArithmitical
@@ -3301,6 +3477,39 @@ func (b *builtinSubDateIntIntSig) evalTime(row chunk.Row) (types.Time, bool, err
3301
3477
return result , isNull || err != nil , errors .Trace (err )
3302
3478
}
3303
3479
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
+
3304
3513
type builtinSubDateDatetimeStringSig struct {
3305
3514
baseBuiltinFunc
3306
3515
baseDateArithmitical
@@ -3400,6 +3609,39 @@ func (b *builtinSubDateDatetimeIntSig) evalTime(row chunk.Row) (types.Time, bool
3400
3609
return result , isNull || err != nil , errors .Trace (err )
3401
3610
}
3402
3611
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
+
3403
3645
type builtinSubDateDatetimeDecimalSig struct {
3404
3646
baseBuiltinFunc
3405
3647
baseDateArithmitical
0 commit comments