Skip to content

Commit 8d1d4b4

Browse files
committed
fix more time functions
1 parent 2047b55 commit 8d1d4b4

File tree

3 files changed

+103
-10
lines changed

3 files changed

+103
-10
lines changed

enginetest/queries/function_queries.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,18 @@ var FunctionQueryTests = []QueryTest{
16151615
Query: "SELECT TIMESTAMPADD(DAY, 1, '2018-05-02')",
16161616
Expected: []sql.Row{{"2018-05-03"}},
16171617
},
1618+
{
1619+
Query: "select timestampadd(day, 1, '0000-00-00')",
1620+
Expected: []sql.Row{{nil}},
1621+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1622+
ExpectedWarningsCount: 1,
1623+
},
1624+
{
1625+
Query: "select timestampadd(day, 1, 0)",
1626+
Expected: []sql.Row{{nil}},
1627+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1628+
ExpectedWarningsCount: 1,
1629+
},
16181630
{
16191631
Query: "SELECT DATE_ADD('2018-05-02', INTERVAL 1 day)",
16201632
Expected: []sql.Row{{"2018-05-03"}},
@@ -1627,6 +1639,18 @@ var FunctionQueryTests = []QueryTest{
16271639
Query: "select date_add(time('12:13:14'), interval 1 minute);",
16281640
Expected: []sql.Row{{types.Timespan(44054000000)}},
16291641
},
1642+
{
1643+
Query: "select date_add(0, interval 1 day)",
1644+
Expected: []sql.Row{{nil}},
1645+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1646+
ExpectedWarningsCount: 1,
1647+
},
1648+
{
1649+
Query: "select date_sub(0, interval 1 day)",
1650+
Expected: []sql.Row{{nil}},
1651+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1652+
ExpectedWarningsCount: 1,
1653+
},
16301654
{
16311655
Query: "SELECT DATE_SUB('2018-05-02', INTERVAL 1 DAY)",
16321656
Expected: []sql.Row{{"2018-05-01"}},
@@ -1671,6 +1695,42 @@ var FunctionQueryTests = []QueryTest{
16711695
Query: "SELECT DATE_ADD('9999-12-31 23:59:59', INTERVAL 1 DAY)",
16721696
Expected: []sql.Row{{nil}},
16731697
},
1698+
{
1699+
Query: "select 0 + interval 1 day",
1700+
Expected: []sql.Row{{nil}},
1701+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1702+
ExpectedWarningsCount: 1,
1703+
},
1704+
{
1705+
Query: "select 0 - interval 1 day",
1706+
Expected: []sql.Row{{nil}},
1707+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1708+
ExpectedWarningsCount: 1,
1709+
},
1710+
{
1711+
Query: "select datediff(0, '2020-10-10')",
1712+
Expected: []sql.Row{{nil}},
1713+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1714+
ExpectedWarningsCount: 1,
1715+
},
1716+
{
1717+
Query: "select datediff('0000-00-00', '2020-10-10')",
1718+
Expected: []sql.Row{{nil}},
1719+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1720+
ExpectedWarningsCount: 1,
1721+
},
1722+
{
1723+
Query: "select datediff('2020-10-10', 0)",
1724+
Expected: []sql.Row{{nil}},
1725+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1726+
ExpectedWarningsCount: 1,
1727+
},
1728+
{
1729+
Query: "select datediff('2020-10-10', '0000-00-00')",
1730+
Expected: []sql.Row{{nil}},
1731+
ExpectedWarning: mysql.ERTruncatedWrongValue,
1732+
ExpectedWarningsCount: 1,
1733+
},
16741734
{
16751735
Query: "SELECT EXTRACT(DAY FROM '9999-12-31 23:59:59')",
16761736
Expected: []sql.Row{{31}},

sql/expression/arithmetic.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,13 @@ func convertValueToType(ctx *sql.Context, typ sql.Type, val interface{}, isTimeT
440440
// the value is interpreted as 0, but we need to match the type of the other valid value
441441
// to avoid additional conversion, the nil value is handled in each operation
442442
}
443+
if types.IsTime(typ) {
444+
time, ok := cval.(time.Time)
445+
if !ok || time.Equal(types.ZeroTime) {
446+
ctx.Warn(1292, "Incorrect datetime value: '%s'", val)
447+
return nil
448+
}
449+
}
443450
return cval
444451
}
445452

@@ -462,6 +469,9 @@ func convertTimeTypeToString(val interface{}) interface{} {
462469
}
463470

464471
func plus(lval, rval interface{}) (interface{}, error) {
472+
if lval == nil || rval == nil {
473+
return nil, nil
474+
}
465475
switch l := lval.(type) {
466476
case uint8:
467477
switch r := rval.(type) {
@@ -536,6 +546,9 @@ func plus(lval, rval interface{}) (interface{}, error) {
536546
}
537547

538548
func minus(lval, rval interface{}) (interface{}, error) {
549+
if lval == nil || rval == nil {
550+
return nil, nil
551+
}
539552
switch l := lval.(type) {
540553
case uint8:
541554
switch r := rval.(type) {

sql/expression/function/time_math.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,37 +82,47 @@ func (d *DateDiff) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
8282
return nil, nil
8383
}
8484

85-
expr1, err := d.LeftChild.Eval(ctx, row)
85+
val1, err := d.LeftChild.Eval(ctx, row)
8686
if err != nil {
8787
return nil, err
8888
}
89-
if expr1 == nil {
89+
if val1 == nil {
9090
return nil, nil
9191
}
9292

93-
expr1, _, err = types.DatetimeMaxPrecision.Convert(ctx, expr1)
93+
expr1, _, err := types.DatetimeMaxPrecision.Convert(ctx, val1)
9494
if err != nil {
95-
return nil, err
95+
ctx.Warn(1292, "Incorrect datetime value: '%s'", val1)
96+
return nil, nil
9697
}
9798

9899
expr1str := expr1.(time.Time).String()[:10]
99100
expr1, _, _ = types.DatetimeMaxPrecision.Convert(ctx, expr1str)
101+
if expr1 == nil {
102+
ctx.Warn(1292, "Incorrect datetime value: '%s'", val1)
103+
return nil, nil
104+
}
100105

101-
expr2, err := d.RightChild.Eval(ctx, row)
106+
val2, err := d.RightChild.Eval(ctx, row)
102107
if err != nil {
103108
return nil, err
104109
}
105-
if expr2 == nil {
110+
if val2 == nil {
106111
return nil, nil
107112
}
108113

109-
expr2, _, err = types.DatetimeMaxPrecision.Convert(ctx, expr2)
114+
expr2, _, err := types.DatetimeMaxPrecision.Convert(ctx, val2)
110115
if err != nil {
111-
return nil, err
116+
ctx.Warn(1292, "Incorrect datetime value: '%s'", val2)
117+
return nil, nil
112118
}
113119

114120
expr2str := expr2.(time.Time).String()[:10]
115121
expr2, _, _ = types.DatetimeMaxPrecision.Convert(ctx, expr2str)
122+
if expr2 == nil {
123+
ctx.Warn(1292, "Incorrect datetime value: '%s'", val2)
124+
return nil, nil
125+
}
116126

117127
date1 := expr1.(time.Time)
118128
date2 := expr2.(time.Time)
@@ -237,9 +247,14 @@ func (d *DateAdd) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
237247
ctx.Warn(1292, "%s", err.Error())
238248
return nil, nil
239249
}
250+
datetime, ok := dateVal.(time.Time)
251+
if ok || datetime.Equal(types.ZeroTime) {
252+
ctx.Warn(1292, "Incorrect datetime value: '%s'", date)
253+
return nil, nil
254+
}
240255

241256
// return appropriate type
242-
res := types.ValidateTime(delta.Add(dateVal.(time.Time)))
257+
res := types.ValidateTime(delta.Add(datetime))
243258
if res == nil {
244259
return nil, nil
245260
}
@@ -385,9 +400,14 @@ func (d *DateSub) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
385400
ctx.Warn(1292, "%s", err.Error())
386401
return nil, nil
387402
}
403+
datetime, ok := dateVal.(time.Time)
404+
if ok || datetime.Equal(types.ZeroTime) {
405+
ctx.Warn(1292, "Incorrect datetime value: '%s'", date)
406+
return nil, nil
407+
}
388408

389409
// return appropriate type
390-
res := types.ValidateTime(delta.Sub(dateVal.(time.Time)))
410+
res := types.ValidateTime(delta.Sub(datetime))
391411
if res == nil {
392412
return nil, nil
393413
}

0 commit comments

Comments
 (0)