@@ -503,55 +503,84 @@ func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Va
503
503
return nil , fmt .Errorf ("Invalid DATETIME-packet length %d" , num )
504
504
}
505
505
506
- func formatBinaryDate (num uint64 , data []byte ) (driver.Value , error ) {
507
- switch num {
508
- case 0 :
509
- return []byte ("0000-00-00" ), nil
510
- case 4 :
511
- return []byte (fmt .Sprintf (
512
- "%04d-%02d-%02d" ,
513
- binary .LittleEndian .Uint16 (data [:2 ]),
514
- data [2 ],
515
- data [3 ],
516
- )), nil
517
- }
518
- return nil , fmt .Errorf ("Invalid DATE-packet length %d" , num )
519
- }
520
-
521
- func formatBinaryDateTime (num uint64 , data []byte ) (driver.Value , error ) {
522
- switch num {
523
- case 0 :
524
- return []byte ("0000-00-00 00:00:00" ), nil
525
- case 4 :
526
- return []byte (fmt .Sprintf (
527
- "%04d-%02d-%02d 00:00:00" ,
528
- binary .LittleEndian .Uint16 (data [:2 ]),
529
- data [2 ],
530
- data [3 ],
531
- )), nil
532
- case 7 :
533
- return []byte (fmt .Sprintf (
534
- "%04d-%02d-%02d %02d:%02d:%02d" ,
535
- binary .LittleEndian .Uint16 (data [:2 ]),
536
- data [2 ],
537
- data [3 ],
538
- data [4 ],
539
- data [5 ],
540
- data [6 ],
541
- )), nil
542
- case 11 :
543
- return []byte (fmt .Sprintf (
544
- "%04d-%02d-%02d %02d:%02d:%02d.%06d" ,
545
- binary .LittleEndian .Uint16 (data [:2 ]),
546
- data [2 ],
547
- data [3 ],
548
- data [4 ],
549
- data [5 ],
550
- data [6 ],
551
- binary .LittleEndian .Uint32 (data [7 :11 ]),
552
- )), nil
506
+ // zeroDateTime is used in formatBinaryDateTime to avoid an allocation
507
+ // if the DATE or DATETIME has the zero value.
508
+ // It must never be changed.
509
+ // The current behavior depends on database/sql copying the result.
510
+ var zeroDateTime = []byte ("0000-00-00 00:00:00" )
511
+
512
+ func formatBinaryDateTime (src []byte , withTime bool ) (driver.Value , error ) {
513
+ if len (src ) == 0 {
514
+ if withTime {
515
+ return zeroDateTime , nil
516
+ }
517
+ return zeroDateTime [:10 ], nil
518
+ }
519
+ var dst []byte
520
+ if withTime {
521
+ if len (src ) == 11 {
522
+ dst = []byte ("0000-00-00 00:00:00.000000" )
523
+ } else {
524
+ dst = []byte ("0000-00-00 00:00:00" )
525
+ }
526
+ } else {
527
+ dst = []byte ("0000-00-00" )
553
528
}
554
- return nil , fmt .Errorf ("Invalid DATETIME-packet length %d" , num )
529
+ switch len (src ) {
530
+ case 11 :
531
+ microsecs := binary .LittleEndian .Uint32 (src [7 :11 ])
532
+ tmp32 := microsecs / 10
533
+ dst [25 ] += byte (microsecs - 10 * tmp32 )
534
+ tmp32 , microsecs = tmp32 / 10 , tmp32
535
+ dst [24 ] += byte (microsecs - 10 * tmp32 )
536
+ tmp32 , microsecs = tmp32 / 10 , tmp32
537
+ dst [23 ] += byte (microsecs - 10 * tmp32 )
538
+ tmp32 , microsecs = tmp32 / 10 , tmp32
539
+ dst [22 ] += byte (microsecs - 10 * tmp32 )
540
+ tmp32 , microsecs = tmp32 / 10 , tmp32
541
+ dst [21 ] += byte (microsecs - 10 * tmp32 )
542
+ dst [20 ] += byte (microsecs / 10 )
543
+ fallthrough
544
+ case 7 :
545
+ second := src [6 ]
546
+ tmp := second / 10
547
+ dst [18 ] += second - 10 * tmp
548
+ dst [17 ] += tmp
549
+ minute := src [5 ]
550
+ tmp = minute / 10
551
+ dst [15 ] += minute - 10 * tmp
552
+ dst [14 ] += tmp
553
+ hour := src [4 ]
554
+ tmp = hour / 10
555
+ dst [12 ] += hour - 10 * tmp
556
+ dst [11 ] += tmp
557
+ fallthrough
558
+ case 4 :
559
+ day := src [3 ]
560
+ tmp := day / 10
561
+ dst [9 ] += day - 10 * tmp
562
+ dst [8 ] += tmp
563
+ month := src [2 ]
564
+ tmp = month / 10
565
+ dst [6 ] += month - 10 * tmp
566
+ dst [5 ] += tmp
567
+ year := binary .LittleEndian .Uint16 (src [:2 ])
568
+ tmp16 := year / 10
569
+ dst [3 ] += byte (year - 10 * tmp16 )
570
+ tmp16 , year = tmp16 / 10 , tmp16
571
+ dst [2 ] += byte (year - 10 * tmp16 )
572
+ tmp16 , year = tmp16 / 10 , tmp16
573
+ dst [1 ] += byte (year - 10 * tmp16 )
574
+ dst [0 ] += byte (tmp16 )
575
+ return dst , nil
576
+ }
577
+ var t string
578
+ if withTime {
579
+ t = "DATETIME"
580
+ } else {
581
+ t = "DATE"
582
+ }
583
+ return nil , fmt .Errorf ("invalid %s-packet length %d" , t , len (src ))
555
584
}
556
585
557
586
/******************************************************************************
0 commit comments