Skip to content

Commit bce68e6

Browse files
committed
day function has been fixed
1 parent 0d42aa0 commit bce68e6

File tree

3 files changed

+53
-47
lines changed

3 files changed

+53
-47
lines changed

enginetest/queries/function_queries.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,14 +1779,13 @@ var FunctionQueryTests = []QueryTest{
17791779
ExpectedWarningsCount: 1,
17801780
},
17811781
{
1782-
Query: "select day('0000-00-00')",
1783-
Expected: []sql.Row{{nil}},
1784-
ExpectedWarning: mysql.ERTruncatedWrongValue,
1785-
ExpectedWarningsCount: 1,
1782+
// This is not a valid time string in MySQL but we allow it
1783+
Query: "select day('0000-00-00')",
1784+
Expected: []sql.Row{{0}},
17861785
},
17871786
{
17881787
Query: "select day('0000-01-01')",
1789-
Expected: []sql.Row{{0}},
1788+
Expected: []sql.Row{{1}},
17901789
},
17911790
{
17921791
Query: "select dayname(0)",

sql/expression/function/time.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,14 @@ func datePartFunc(fn func(time.Time) int) func(interface{}) interface{} {
546546
return nil
547547
}
548548

549-
return int32(fn(v.(time.Time)))
549+
if vTime, ok := v.(time.Time); ok {
550+
if vTime.Equal(types.ZeroTime) {
551+
return 0
552+
}
553+
554+
return int32(fn(vTime))
555+
}
556+
return nil
550557
}
551558
}
552559

sql/types/datetime.go

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ var (
100100

101101
// zeroTime is -0001-11-30 00:00:00 UTC which is the closest Go can get to 0000-00-00 00:00:00 without conflicting
102102
// with a valid timestamp in MySQL
103-
zeroTime = time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
103+
ZeroTime = time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
104104

105105
// Date is a date with day, month and year.
106106
Date = MustCreateDatetimeType(sqltypes.Date, 0)
@@ -223,8 +223,8 @@ func ConvertToTime(ctx context.Context, v interface{}, t datetimeType) (time.Tim
223223
return time.Time{}, err
224224
}
225225

226-
if res.Equal(zeroTime) {
227-
return zeroTime, nil
226+
if res.Equal(ZeroTime) {
227+
return ZeroTime, nil
228228
}
229229

230230
// Round the date to the precision of this type
@@ -276,103 +276,103 @@ func (t datetimeType) ConvertWithoutRangeCheck(ctx context.Context, v interface{
276276
switch value := v.(type) {
277277
case string:
278278
if value == ZeroDateStr || value == ZeroTimestampDatetimeStr {
279-
return zeroTime, nil
279+
return ZeroTime, nil
280280
}
281281
// TODO: consider not using time.Parse if we want to match MySQL exactly ('2010-06-03 11:22.:.:.:.:' is a valid timestamp)
282282
var parsed bool
283283
res, parsed, err = parseDatetime(value)
284284
if !parsed {
285-
return zeroTime, ErrConvertingToTime.New(v)
285+
return ZeroTime, ErrConvertingToTime.New(v)
286286
}
287287
case time.Time:
288288
res = value.UTC()
289289
// For most integer values, we just return an error (but MySQL is more lenient for some of these). A special case
290290
// is zero values, which are important when converting from postgres defaults.
291291
case int:
292292
if value == 0 {
293-
return zeroTime, nil
293+
return ZeroTime, nil
294294
}
295-
return zeroTime, ErrConvertingToTime.New(v)
295+
return ZeroTime, ErrConvertingToTime.New(v)
296296
case int8:
297297
if value == 0 {
298-
return zeroTime, nil
298+
return ZeroTime, nil
299299
}
300-
return zeroTime, ErrConvertingToTime.New(v)
300+
return ZeroTime, ErrConvertingToTime.New(v)
301301
case int16:
302302
if value == 0 {
303-
return zeroTime, nil
303+
return ZeroTime, nil
304304
}
305-
return zeroTime, ErrConvertingToTime.New(v)
305+
return ZeroTime, ErrConvertingToTime.New(v)
306306
case int32:
307307
if value == 0 {
308-
return zeroTime, nil
308+
return ZeroTime, nil
309309
}
310-
return zeroTime, ErrConvertingToTime.New(v)
310+
return ZeroTime, ErrConvertingToTime.New(v)
311311
case int64:
312312
if value == 0 {
313-
return zeroTime, nil
313+
return ZeroTime, nil
314314
}
315-
return zeroTime, ErrConvertingToTime.New(v)
315+
return ZeroTime, ErrConvertingToTime.New(v)
316316
case uint:
317317
if value == 0 {
318-
return zeroTime, nil
318+
return ZeroTime, nil
319319
}
320-
return zeroTime, ErrConvertingToTime.New(v)
320+
return ZeroTime, ErrConvertingToTime.New(v)
321321
case uint8:
322322
if value == 0 {
323-
return zeroTime, nil
323+
return ZeroTime, nil
324324
}
325-
return zeroTime, ErrConvertingToTime.New(v)
325+
return ZeroTime, ErrConvertingToTime.New(v)
326326
case uint16:
327327
if value == 0 {
328-
return zeroTime, nil
328+
return ZeroTime, nil
329329
}
330-
return zeroTime, ErrConvertingToTime.New(v)
330+
return ZeroTime, ErrConvertingToTime.New(v)
331331
case uint32:
332332
if value == 0 {
333-
return zeroTime, nil
333+
return ZeroTime, nil
334334
}
335-
return zeroTime, ErrConvertingToTime.New(v)
335+
return ZeroTime, ErrConvertingToTime.New(v)
336336
case uint64:
337337
if value == 0 {
338-
return zeroTime, nil
338+
return ZeroTime, nil
339339
}
340-
return zeroTime, ErrConvertingToTime.New(v)
340+
return ZeroTime, ErrConvertingToTime.New(v)
341341
case float32:
342342
if value == 0 {
343-
return zeroTime, nil
343+
return ZeroTime, nil
344344
}
345-
return zeroTime, ErrConvertingToTime.New(v)
345+
return ZeroTime, ErrConvertingToTime.New(v)
346346
case float64:
347347
if value == 0 {
348-
return zeroTime, nil
348+
return ZeroTime, nil
349349
}
350-
return zeroTime, ErrConvertingToTime.New(v)
350+
return ZeroTime, ErrConvertingToTime.New(v)
351351
case decimal.Decimal:
352352
if value.IsZero() {
353-
return zeroTime, nil
353+
return ZeroTime, nil
354354
}
355-
return zeroTime, ErrConvertingToTime.New(v)
355+
return ZeroTime, ErrConvertingToTime.New(v)
356356
case decimal.NullDecimal:
357357
if value.Valid && value.Decimal.IsZero() {
358-
return zeroTime, nil
358+
return ZeroTime, nil
359359
}
360-
return zeroTime, ErrConvertingToTime.New(v)
360+
return ZeroTime, ErrConvertingToTime.New(v)
361361
case Timespan:
362362
// when receiving TIME, MySQL fills in date with today
363363
nowTimeStr := sql.Now().Format("2006-01-02")
364364
nowTime, err := time.Parse("2006-01-02", nowTimeStr)
365365
if err != nil {
366-
return zeroTime, ErrConvertingToTime.New(v)
366+
return ZeroTime, ErrConvertingToTime.New(v)
367367
}
368368
return nowTime.Add(value.AsTimeDuration()), nil
369369
case bool:
370370
if !value {
371-
return zeroTime, nil
371+
return ZeroTime, nil
372372
}
373-
return zeroTime, ErrConvertingToTime.New(v)
373+
return ZeroTime, ErrConvertingToTime.New(v)
374374
default:
375-
return zeroTime, sql.ErrConvertToSQL.New(value, t)
375+
return ZeroTime, sql.ErrConvertToSQL.New(value, t)
376376
}
377377

378378
if t.baseType == sqltypes.Date {
@@ -458,21 +458,21 @@ func (t datetimeType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltype
458458
switch t.baseType {
459459
case sqltypes.Date:
460460
typ = sqltypes.Date
461-
if vt.Equal(zeroTime) {
461+
if vt.Equal(ZeroTime) {
462462
val = vt.AppendFormat(dest, ZeroDateStr)
463463
} else {
464464
val = vt.AppendFormat(dest, sql.DateLayout)
465465
}
466466
case sqltypes.Datetime:
467467
typ = sqltypes.Datetime
468-
if vt.Equal(zeroTime) {
468+
if vt.Equal(ZeroTime) {
469469
val = vt.AppendFormat(dest, ZeroTimestampDatetimeStr)
470470
} else {
471471
val = vt.AppendFormat(dest, sql.TimestampDatetimeLayout)
472472
}
473473
case sqltypes.Timestamp:
474474
typ = sqltypes.Timestamp
475-
if vt.Equal(zeroTime) {
475+
if vt.Equal(ZeroTime) {
476476
val = vt.AppendFormat(dest, ZeroTimestampDatetimeStr)
477477
} else {
478478
val = vt.AppendFormat(dest, sql.TimestampDatetimeLayout)
@@ -535,7 +535,7 @@ func (t datetimeType) ValueType() reflect.Type {
535535
}
536536

537537
func (t datetimeType) Zero() interface{} {
538-
return zeroTime
538+
return ZeroTime
539539
}
540540

541541
// CollationCoercibility implements sql.CollationCoercible interface.

0 commit comments

Comments
 (0)