@@ -19,6 +19,7 @@ import (
1919 "fmt"
2020 "math"
2121 "reflect"
22+ "strconv"
2223 "time"
2324 "unicode"
2425
@@ -452,59 +453,85 @@ func (t datetimeType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltype
452453 return sqltypes.Value {}, err
453454 }
454455
455- var typ query.Type
456- var val []byte
457-
458456 switch t .baseType {
459457 case sqltypes .Date :
460- typ = sqltypes .Date
461458 if vt .Equal (ZeroTime ) {
462- val = vt . AppendFormat (dest , ZeroDateStr )
459+ dest = append (dest , ZeroDateStr ... )
463460 } else {
464- val = vt . AppendFormat (dest , sql . DateLayout )
461+ dest = appendDateFormat (dest , vt )
465462 }
466- case sqltypes .Datetime :
467- typ = sqltypes .Datetime
468- if vt .Equal (ZeroTime ) {
469- val = vt .AppendFormat (dest , ZeroTimestampDatetimeStr )
470- } else {
471- val = vt .AppendFormat (dest , sql .TimestampDatetimeLayout )
472- }
473- case sqltypes .Timestamp :
474- typ = sqltypes .Timestamp
463+ case sqltypes .Datetime , sqltypes .Timestamp :
475464 if vt .Equal (ZeroTime ) {
476- val = vt . AppendFormat (dest , ZeroTimestampDatetimeStr )
465+ dest = append (dest , ZeroTimestampDatetimeStr ... )
477466 } else {
478- val = vt . AppendFormat (dest , sql . TimestampDatetimeLayout )
467+ dest = appendDatetimeFormat (dest , vt )
479468 }
480469 default :
481470 return sqltypes.Value {}, sql .ErrInvalidBaseType .New (t .baseType .String (), "datetime" )
482471 }
483472
484- valBytes := val
485-
486- return sqltypes .MakeTrusted (typ , valBytes ), nil
473+ return sqltypes .MakeTrusted (t .baseType , dest ), nil
487474}
488475
489476// SQLValue implements the ValueType interface.
490477func (t datetimeType ) SQLValue (ctx * sql.Context , v sql.Value , dest []byte ) (sqltypes.Value , error ) {
491478 if v .IsNull () {
492479 return sqltypes .NULL , nil
493480 }
481+
494482 switch t .baseType {
495483 case sqltypes .Date :
496- t := values .ReadDate (v .Val )
497- dest = t .AppendFormat (dest , sql .DateLayout )
484+ vt := values .ReadDate (v .Val )
485+ if vt .Equal (ZeroTime ) {
486+ dest = append (dest , ZeroDateStr ... )
487+ } else {
488+ dest = appendDateFormat (dest , vt )
489+ }
498490 case sqltypes .Datetime , sqltypes .Timestamp :
499491 x := values .ReadInt64 (v .Val )
500- t := time .UnixMicro (x ).UTC ()
501- dest = t .AppendFormat (dest , sql .TimestampDatetimeLayout )
492+ vt := time .UnixMicro (x ).UTC ()
493+ if vt .Equal (ZeroTime ) {
494+ dest = append (dest , ZeroTimestampDatetimeStr ... )
495+ } else {
496+ dest = appendDatetimeFormat (dest , vt )
497+ }
502498 default :
503499 return sqltypes.Value {}, sql .ErrInvalidBaseType .New (t .baseType .String (), "datetime" )
504500 }
505501 return sqltypes .MakeTrusted (t .baseType , dest ), nil
506502}
507503
504+ func appendDateFormat (dest []byte , t time.Time ) []byte {
505+ year := t .Year ()
506+ if year == 0 {
507+ dest = append (dest , '0' , '0' , '0' , '0' )
508+ } else {
509+ dest = strconv .AppendInt (dest , int64 (year ), 10 )
510+ }
511+ dest = append (dest , '-' )
512+
513+ month := int64 (t .Month ())
514+ if month < 10 {
515+ dest = append (dest , '0' )
516+ }
517+ dest = strconv .AppendInt (dest , month , 10 )
518+ dest = append (dest , '-' )
519+
520+ day := int64 (t .Day ())
521+ if day < 10 {
522+ dest = append (dest , '0' )
523+ }
524+ dest = strconv .AppendInt (dest , day , 10 )
525+ return dest
526+ }
527+
528+ func appendDatetimeFormat (dest []byte , t time.Time ) []byte {
529+ dest = appendDateFormat (dest , t )
530+ dest = append (dest , ' ' )
531+ dest = appendTimeFormat (dest , int64 (t .Hour ()), int64 (t .Minute ()), int64 (t .Second ()), int64 (t .Nanosecond ()/ 1000 ))
532+ return dest
533+ }
534+
508535func (t datetimeType ) String () string {
509536 switch t .baseType {
510537 case sqltypes .Date :
0 commit comments