Skip to content

Commit

Permalink
This is an automated cherry-pick of pingcap#54916
Browse files Browse the repository at this point in the history
Signed-off-by: ti-chi-bot <[email protected]>
  • Loading branch information
xzhangxian1008 authored and ti-chi-bot committed Jul 26, 2024
1 parent 6b5a88e commit 1d5cf66
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 1 deletion.
84 changes: 84 additions & 0 deletions expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -6931,6 +6931,90 @@ func (b *builtinTimestampAddSig) Clone() builtinFunc {
return newSig
}

<<<<<<< HEAD:expression/builtin_time.go
=======
var (
minDatetimeInGoTime, _ = types.MinDatetime.GoTime(time.Local)
minDatetimeNanos = float64(minDatetimeInGoTime.Unix())*1e9 + float64(minDatetimeInGoTime.Nanosecond())
maxDatetimeInGoTime, _ = types.MaxDatetime.GoTime(time.Local)
maxDatetimeNanos = float64(maxDatetimeInGoTime.Unix())*1e9 + float64(maxDatetimeInGoTime.Nanosecond())
minDatetimeMonths = float64(types.MinDatetime.Year()*12 + types.MinDatetime.Month() - 1) // 0001-01-01 00:00:00
maxDatetimeMonths = float64(types.MaxDatetime.Year()*12 + types.MaxDatetime.Month() - 1) // 9999-12-31 00:00:00
)

func validAddTime(nano1 float64, nano2 float64) bool {
return nano1+nano2 >= minDatetimeNanos && nano1+nano2 <= maxDatetimeNanos
}

func validAddMonth(month1 float64, year, month int) bool {
tmp := month1 + float64(year)*12 + float64(month-1)
return tmp >= minDatetimeMonths && tmp <= maxDatetimeMonths
}

func addUnitToTime(unit string, t time.Time, v float64) (time.Time, bool, error) {
s := math.Trunc(v * 1000000)
// round to the nearest int
v = math.Round(v)
var tb time.Time
nano := float64(t.Unix())*1e9 + float64(t.Nanosecond())
switch unit {
case "MICROSECOND":
if !validAddTime(v*float64(time.Microsecond), nano) {
return tb, true, nil
}
tb = t.Add(time.Duration(v) * time.Microsecond)
case "SECOND":
if !validAddTime(s*float64(time.Microsecond), nano) {
return tb, true, nil
}
tb = t.Add(time.Duration(s) * time.Microsecond)
case "MINUTE":
if !validAddTime(v*float64(time.Minute), nano) {
return tb, true, nil
}
tb = t.Add(time.Duration(v) * time.Minute)
case "HOUR":
if !validAddTime(v*float64(time.Hour), nano) {
return tb, true, nil
}
tb = t.Add(time.Duration(v) * time.Hour)
case "DAY":
if !validAddTime(v*24*float64(time.Hour), nano) {
return tb, true, nil
}
tb = t.AddDate(0, 0, int(v))
case "WEEK":
if !validAddTime(v*24*7*float64(time.Hour), nano) {
return tb, true, nil
}
tb = t.AddDate(0, 0, 7*int(v))
case "MONTH":
if !validAddMonth(v, t.Year(), int(t.Month())) {
return tb, true, nil
}

var err error
tb, err = types.AddDate(0, int64(v), 0, t)
if err != nil {
return tb, false, err
}
case "QUARTER":
if !validAddMonth(v*3, t.Year(), int(t.Month())) {
return tb, true, nil
}
tb = t.AddDate(0, 3*int(v), 0)
case "YEAR":
if !validAddMonth(v*12, t.Year(), int(t.Month())) {
return tb, true, nil
}
tb = t.AddDate(int(v), 0, 0)
default:
return tb, false, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, unit)
}
return tb, false, nil
}

>>>>>>> a8d29c27d56 (expression: fix infinity loop in `timestampadd` (#54916)):pkg/expression/builtin_time.go
// evalString evals a builtinTimestampAddSig.
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampadd
func (b *builtinTimestampAddSig) evalString(row chunk.Row) (string, bool, error) {
Expand Down
42 changes: 41 additions & 1 deletion expression/builtin_time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2493,7 +2493,7 @@ func TestTimestampAdd(t *testing.T) {
{"MICROSECOND", 1, 950501, "1995-05-01 00:00:00.000001"},
{"DAY", 28768, 0, ""},

// issue41052
// issue 41052
{"MONTH", 1, "2024-01-31", "2024-02-29 00:00:00"},
{"MONTH", 1, "2024-01-30", "2024-02-29 00:00:00"},
{"MONTH", 1, "2024-01-29", "2024-02-29 00:00:00"},
Expand All @@ -2504,6 +2504,46 @@ func TestTimestampAdd(t *testing.T) {
{"MONTH", 10, "2024-10-31", "2025-08-31 00:00:00"},
{"MONTH", 1, "2024-11-30", "2024-12-30 00:00:00"},
{"MONTH", 13, "2024-11-30", "2025-12-30 00:00:00"},

// issue 54908
{"MONTH", 0, "2024-09-01", "2024-09-01 00:00:00"},
{"MONTH", -10, "2024-09-01", "2023-11-01 00:00:00"},
{"MONTH", -2, "2024-04-28", "2024-02-28 00:00:00"},
{"MONTH", -2, "2024-04-29", "2024-02-29 00:00:00"},
{"MONTH", -2, "2024-04-30", "2024-02-29 00:00:00"},
{"MONTH", -1, "2024-03-28", "2024-02-28 00:00:00"},
{"MONTH", -1, "2024-03-29", "2024-02-29 00:00:00"},
{"MONTH", -1, "2024-03-30", "2024-02-29 00:00:00"},
{"MONTH", -1, "2024-03-31", "2024-02-29 00:00:00"},
{"MONTH", -1, "2024-03-25", "2024-02-25 00:00:00"},
{"MONTH", -12, "2024-03-31", "2023-03-31 00:00:00"},
{"MONTH", -13, "2024-03-31", "2023-02-28 00:00:00"},
{"MONTH", -14, "2024-03-31", "2023-01-31 00:00:00"},
{"MONTH", -24, "2024-03-31", "2022-03-31 00:00:00"},
{"MONTH", -25, "2024-03-31", "2022-02-28 00:00:00"},
{"MONTH", -26, "2024-03-31", "2022-01-31 00:00:00"},
{"MONTH", -1, "2024-02-25", "2024-01-25 00:00:00"},
{"MONTH", -11, "2025-02-28", "2024-03-28 00:00:00"},
{"MONTH", -12, "2025-02-28", "2024-02-28 00:00:00"},
{"MONTH", -13, "2025-02-28", "2024-01-28 00:00:00"},
{"MONTH", -11, "2024-02-29", "2023-03-29 00:00:00"},
{"MONTH", -12, "2024-02-29", "2023-02-28 00:00:00"},
{"MONTH", -13, "2024-02-29", "2023-01-29 00:00:00"},
{"MONTH", -11, "2023-02-28", "2022-03-28 00:00:00"},
{"MONTH", -12, "2023-02-28", "2022-02-28 00:00:00"},
{"MONTH", -13, "2023-02-28", "2022-01-28 00:00:00"},
{"MONTH", -2, "2023-02-28", "2022-12-28 00:00:00"},
{"MONTH", -14, "2023-02-28", "2021-12-28 00:00:00"},
{"MONTH", -3, "2023-03-20", "2022-12-20 00:00:00"},
{"MONTH", -3, "2023-03-31", "2022-12-31 00:00:00"},
{"MONTH", -15, "2023-03-20", "2021-12-20 00:00:00"},
{"MONTH", -15, "2023-03-31", "2021-12-31 00:00:00"},
{"MONTH", 12, "2020-02-29", "2021-02-28 00:00:00"},
{"MONTH", -12, "2020-02-29", "2019-02-28 00:00:00"},
{"MONTH", 10000*365 + 1, "2024-10-29", ""},
{"MONTH", -10000*365 - 1, "2024-10-29", ""},
{"MONTH", 3, "9999-10-29", ""},
{"MONTH", -3, "0001-01-29", ""},
}

fc := funcs[ast.TimestampAdd]
Expand Down

0 comments on commit 1d5cf66

Please sign in to comment.