@@ -17,14 +17,14 @@ package types
1717import (
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
367368func (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.
385402func (t datetimeType ) Equals (otherType sql.Type ) bool {
386403 if dtType , isDtType := otherType .(sql.DatetimeType ); isDtType {
0 commit comments