Skip to content

Commit b8d4aae

Browse files
committed
add more tests, set default precision for datetime conversion
1 parent a6b77b6 commit b8d4aae

File tree

3 files changed

+100
-5
lines changed

3 files changed

+100
-5
lines changed

enginetest/queries/queries.go

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4178,7 +4178,7 @@ SELECT * FROM cte WHERE d = 2;`,
41784178
Expected: []sql.Row{{"9999-12-31 23:59:59.999999"}},
41794179
},
41804180
{
4181-
// This returns nil in MySQL but we are able to truncate the string and convert to a datetime
4181+
// This returns null in MySQL, but we are able to truncate the string and convert to a datetime
41824182
Skip: true,
41834183
Query: "SELECT date_add('9999-12-31:23:59:59.99999944444444444-', INTERVAL 0 day);",
41844184
Expected: []sql.Row{{nil}},
@@ -4202,6 +4202,97 @@ SELECT * FROM cte WHERE d = 2;`,
42024202
ExpectedWarningsCount: 1,
42034203
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 30, 0, 0, time.UTC)}},
42044204
},
4205+
{
4206+
Query: "select cast('2020-01-01 12:34:56abc' as datetime);",
4207+
ExpectedWarning: 1292,
4208+
ExpectedWarningsCount: 1,
4209+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4210+
},
4211+
{
4212+
Query: "select cast('2020-01-01 12:34:56 abc' as datetime);",
4213+
ExpectedWarning: 1292,
4214+
ExpectedWarningsCount: 1, // MySQL has 2 warnings, but we don't have a warning for deprecated delimiter
4215+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4216+
},
4217+
{
4218+
Query: "select cast('2020-01-01 12:34:56.1 abc' as datetime);",
4219+
ExpectedWarning: 1292,
4220+
ExpectedWarningsCount: 1, // MySQL has 2 warnings, but we don't have a warning for deprecated delimiter
4221+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4222+
},
4223+
{
4224+
Query: "select cast('2020-01-01 12:34:56:123456 abc' as datetime);",
4225+
ExpectedWarning: 1292,
4226+
ExpectedWarningsCount: 1,
4227+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4228+
},
4229+
{
4230+
Query: "select cast('2020-01-01 12:34:56...123456 abc' as datetime);",
4231+
ExpectedWarning: 1292,
4232+
ExpectedWarningsCount: 1,
4233+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4234+
},
4235+
{
4236+
Query: "select cast('2020-01-01 12:34:56-123456 abc' as datetime);",
4237+
ExpectedWarning: 1292,
4238+
ExpectedWarningsCount: 1,
4239+
// MySQL returns null, but we are able to truncate and convert
4240+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4241+
},
4242+
{
4243+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(0));",
4244+
ExpectedWarning: 1292,
4245+
ExpectedWarningsCount: 1,
4246+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 0, time.UTC)}},
4247+
},
4248+
{
4249+
// TODO: implement precision for datetime casting
4250+
Skip: true,
4251+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(1));",
4252+
ExpectedWarning: 1292,
4253+
ExpectedWarningsCount: 1,
4254+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 100000000, time.UTC)}},
4255+
},
4256+
{
4257+
// TODO: implement precision for datetime casting
4258+
Skip: true,
4259+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(2));",
4260+
ExpectedWarning: 1292,
4261+
ExpectedWarningsCount: 1,
4262+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 120000000, time.UTC)}},
4263+
},
4264+
{
4265+
// TODO: implement precision for datetime casting
4266+
Skip: true,
4267+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(3));",
4268+
ExpectedWarning: 1292,
4269+
ExpectedWarningsCount: 1,
4270+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 123000000, time.UTC)}},
4271+
},
4272+
{
4273+
// TODO: implement precision for datetime casting
4274+
Skip: true,
4275+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(4));",
4276+
ExpectedWarning: 1292,
4277+
ExpectedWarningsCount: 1,
4278+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 123500000, time.UTC)}},
4279+
},
4280+
{
4281+
// TODO: implement precision for datetime casting
4282+
Skip: true,
4283+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(5));",
4284+
ExpectedWarning: 1292,
4285+
ExpectedWarningsCount: 1,
4286+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 123460000, time.UTC)}},
4287+
},
4288+
{
4289+
// TODO: implement precision for datetime casting
4290+
Skip: true,
4291+
Query: "select cast('2020-01-01 12:34:56.123456abc' as datetime(6));",
4292+
ExpectedWarning: 1292,
4293+
ExpectedWarningsCount: 1,
4294+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 34, 56, 123456000, time.UTC)}},
4295+
},
42054296
{
42064297
Query: `SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM othertable) othertable_one) othertable_two) othertable_three WHERE s2 = 'first'`,
42074298
Expected: []sql.Row{

sql/expression/convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ func convertValue(ctx *sql.Context, val interface{}, castTo string, originType s
341341
if !(isTime || isString || isBinary) {
342342
return nil, nil
343343
}
344-
d, _, err := types.DatetimeMaxPrecision.Convert(ctx, val)
344+
d, _, err := types.DatetimeDefaultPrecision.Convert(ctx, val)
345345
if err != nil {
346346
if !sql.ErrTruncatedIncorrect.Is(err) {
347347
return nil, err

sql/types/datetime.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const ZeroDateStr = "0000-00-00"
3434

3535
const ZeroTimestampDatetimeStr = "0000-00-00 00:00:00"
3636

37+
const MinDatetimeStringLength = 8 // length of "2000-1-1"
38+
3739
var (
3840
// ErrConvertingToTime is thrown when a value cannot be converted to a Time
3941
ErrConvertingToTime = errors.NewKind("Incorrect datetime value: '%v'")
@@ -100,6 +102,8 @@ var (
100102
Date = MustCreateDatetimeType(sqltypes.Date, 0)
101103
// Datetime is a date and a time with default precision (no fractional seconds).
102104
Datetime = MustCreateDatetimeType(sqltypes.Datetime, 0)
105+
// DatetimeDefaultPrecision is a date and a time without a specified precision
106+
DatetimeDefaultPrecision = MustCreateDatetimeType(sqltypes.Datetime, 0)
103107
// DatetimeMaxPrecision is a date and a time with maximum precision
104108
DatetimeMaxPrecision = MustCreateDatetimeType(sqltypes.Datetime, 6)
105109
// Timestamp is a UNIX timestamp with default precision (no fractional seconds).
@@ -374,7 +378,7 @@ func (t datetimeType) parseDatetime(value string) (time.Time, bool, error) {
374378
valueLen := len(value)
375379
end := valueLen
376380

377-
for end > 0 {
381+
for end >= MinDatetimeStringLength {
378382
for _, layout := range TimestampDatetimeLayouts {
379383
if t, err := time.Parse(layout, value[0:end]); err == nil {
380384
if end != valueLen {
@@ -383,14 +387,14 @@ func (t datetimeType) parseDatetime(value string) (time.Time, bool, error) {
383387
return t.UTC(), true, err
384388
}
385389
}
386-
end = findEnd(value, end-1)
390+
end = findDatetimeEnd(value, end-1)
387391
}
388392
return time.Time{}, false, nil
389393
}
390394

391395
// findDatetimeEnd returns the index of the last digit before `end`
392396
func findDatetimeEnd(value string, end int) int {
393-
for end > 0 {
397+
for end >= MinDatetimeStringLength {
394398
char := rune(value[end-1])
395399
if unicode.IsDigit(char) {
396400
return end

0 commit comments

Comments
 (0)