Skip to content

Commit 65dd960

Browse files
committed
optimize finding end
1 parent 91f83ef commit 65dd960

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

enginetest/queries/queries.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4183,14 +4183,25 @@ SELECT * FROM cte WHERE d = 2;`,
41834183
Query: "SELECT date_add('9999-12-31:23:59:59.99999944444444444-', INTERVAL 0 day);",
41844184
Expected: []sql.Row{{nil}},
41854185
},
4186+
// https://github.com/dolthub/dolt/issues/9917
41864187
{
4187-
// https://github.com/dolthub/dolt/issues/9917
41884188
Query: "select cast('2020-01-01 a' as datetime)",
41894189
ExpectedWarning: 1292,
41904190
ExpectedWarningsCount: 1,
41914191
Expected: []sql.Row{{time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)}},
41924192
},
4193-
{},
4193+
{
4194+
Query: "select cast('2020-01-01 abc123' as datetime)",
4195+
ExpectedWarning: 1292,
4196+
ExpectedWarningsCount: 1,
4197+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)}},
4198+
},
4199+
{
4200+
Query: "select cast('2020-01-01 12:30asdf123' as datetime)",
4201+
ExpectedWarning: 1292,
4202+
ExpectedWarningsCount: 1,
4203+
Expected: []sql.Row{{time.Date(2020, time.January, 1, 12, 30, 0, 0, time.UTC)}},
4204+
},
41944205
{
41954206
Query: `SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM othertable) othertable_one) othertable_two) othertable_three WHERE s2 = 'first'`,
41964207
Expected: []sql.Row{

sql/types/datetime.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ package types
1717
import (
1818
"context"
1919
"fmt"
20-
"math"
21-
"reflect"
22-
"time"
23-
2420
"github.com/dolthub/vitess/go/sqltypes"
2521
"github.com/dolthub/vitess/go/vt/proto/query"
2622
"github.com/shopspring/decimal"
2723
"gopkg.in/src-d/go-errors.v1"
24+
"math"
25+
"reflect"
26+
"time"
27+
"unicode"
2828

2929
"github.com/dolthub/go-mysql-server/sql"
3030
)
@@ -70,13 +70,14 @@ var (
7070
"2006-1-2",
7171
}
7272

73+
TimezoneTimestampDatetimeLayout = "2006-01-02 15:04:05.999999999 -0700 MST" // represents standard Time.time.UTC()
74+
7375
// TimestampDatetimeLayouts hold extra timestamps allowed for parsing. It does
7476
// not have all the layouts supported by mysql. Missing are two digit year
7577
// versions of common cases and dates that use non common separators.
7678
//
7779
// https://github.com/MariaDB/server/blob/mysql-5.5.36/sql-common/my_time.c#L124
7880
TimestampDatetimeLayouts = append([]string{
79-
"2006-01-02 15:04:05.999999999 -0700 MST", // represents standard Time.time.UTC()
8081
time.RFC3339Nano,
8182
"2006-01-02 15:04:05.999999999",
8283
"2006-1-2 15:4:5.999999999",
@@ -365,8 +366,13 @@ func (t datetimeType) ConvertWithoutRangeCheck(ctx context.Context, v interface{
365366
}
366367

367368
func (t datetimeType) parseDatetime(value string) (time.Time, bool, error) {
369+
if t, err := time.Parse(TimezoneTimestampDatetimeLayout, value); err == nil {
370+
return t.UTC(), true, nil
371+
}
372+
368373
valueLen := len(value)
369374
end := valueLen
375+
370376
for end > 0 {
371377
for _, layout := range TimestampDatetimeLayouts {
372378
if t, err := time.Parse(layout, value[0:end]); err == nil {
@@ -376,11 +382,22 @@ func (t datetimeType) parseDatetime(value string) (time.Time, bool, error) {
376382
return t.UTC(), true, err
377383
}
378384
}
379-
end--
385+
end = findEnd(value, end-1)
380386
}
381387
return time.Time{}, false, nil
382388
}
383389

390+
func findEnd(value string, end int) int {
391+
for end > 0 {
392+
char := rune(value[end-1])
393+
if unicode.IsDigit(char) {
394+
return end
395+
}
396+
end--
397+
}
398+
return end
399+
}
400+
384401
// Equals implements the Type interface.
385402
func (t datetimeType) Equals(otherType sql.Type) bool {
386403
if dtType, isDtType := otherType.(sql.DatetimeType); isDtType {

0 commit comments

Comments
 (0)