@@ -354,6 +354,9 @@ func ConvertToString(ctx context.Context, v interface{}, t sql.StringType, dest
354354func ConvertToBytes (ctx context.Context , v interface {}, t sql.StringType , dest []byte ) ([]byte , error ) {
355355 var val []byte
356356 start := len (dest )
357+ // Based on the type of the input, convert it into a byte array, writing it into |dest| to avoid an allocation.
358+ // If the current implementation must make a separate allocation anyway, avoid copying it into dest by replacing
359+ // |val| entirely (and setting |start| to 0).
357360 switch s := v .(type ) {
358361 case bool :
359362 if s {
@@ -394,7 +397,10 @@ func ConvertToBytes(ctx context.Context, v interface{}, t sql.StringType, dest [
394397 case string :
395398 val = append (dest , s ... )
396399 case []byte :
397- val = append (dest , s ... )
400+ // We can avoid copying the slice if this isn't a conversion to BINARY
401+ // We'll check for that below, immediately before extending the slice.
402+ val = s
403+ start = 0
398404 case time.Time :
399405 val = s .AppendFormat (dest , sql .TimestampDatetimeLayout )
400406 case decimal.Decimal :
@@ -405,24 +411,29 @@ func ConvertToBytes(ctx context.Context, v interface{}, t sql.StringType, dest [
405411 }
406412 val = append (dest , s .Decimal .String ()... )
407413 case sql.JSONWrapper :
408- jsonString , err := StringifyJSON (s )
414+ var err error
415+ val , err = JsonToMySqlBytes (s )
409416 if err != nil {
410417 return nil , err
411418 }
412- st , err : = strings .Unquote ( jsonString )
419+ val , err = strings .UnquoteBytes ( val )
413420 if err != nil {
414421 return nil , err
415422 }
416- val = append ( dest , st ... )
417- case sql.AnyWrapper :
418- unwrapped , err := s .UnwrapAny (ctx )
423+ start = 0
424+ case sql.Wrapper [ string ] :
425+ unwrapped , err := s .Unwrap (ctx )
419426 if err != nil {
420427 return nil , err
421428 }
422- val , err = ConvertToBytes (ctx , unwrapped , t , dest )
429+ val = append (val , unwrapped ... )
430+ case sql.Wrapper [[]byte ]:
431+ var err error
432+ val , err = s .Unwrap (ctx )
423433 if err != nil {
424434 return nil , err
425435 }
436+ start = 0
426437 case GeometryValue :
427438 return s .Serialize (), nil
428439 default :
@@ -455,6 +466,11 @@ func ConvertToBytes(ctx context.Context, v interface{}, t sql.StringType, dest [
455466 }
456467
457468 if st .baseType == sqltypes .Binary {
469+ if b , ok := v .([]byte ); ok {
470+ // Make a copy now to avoid overwriting the original allocation.
471+ val = append (dest , b ... )
472+ start = len (dest )
473+ }
458474 val = append (val , bytes .Repeat ([]byte {0 }, int (st .maxCharLength )- len (val ))... )
459475 }
460476 }
0 commit comments