@@ -465,19 +465,43 @@ func (r *StateStore) registerSchemas(ctx context.Context) error {
465465 return nil
466466}
467467
468- func (r * StateStore ) getKeyVersion (vals []interface {}) (data string , version * string , err error ) {
469- seenData := false
470- seenVersion := false
471- for i := 0 ; i < len (vals ); i += 2 {
472- field , _ := strconv .Unquote (fmt .Sprintf ("%q" , vals [i ]))
473- switch field {
474- case "data" :
475- data , _ = strconv .Unquote (fmt .Sprintf ("%q" , vals [i + 1 ]))
476- seenData = true
477- case "version" :
478- versionVal , _ := strconv .Unquote (fmt .Sprintf ("%q" , vals [i + 1 ]))
479- version = ptr .Of (versionVal )
480- seenVersion = true
468+ func (r * StateStore ) getKeyVersion (vals []any ) (data string , version * string , err error ) {
469+ var seenData , seenVersion bool
470+
471+ // step by 2: key, value. we only expect string or byte slice
472+ for i := 0 ; i + 1 < len (vals ); i += 2 {
473+ switch key := vals [i ].(type ) {
474+ case string :
475+ switch key {
476+ case "data" :
477+ if s , ok := toString (vals [i + 1 ]); ok {
478+ data = s
479+ seenData = true
480+ }
481+ case "version" :
482+ if s , ok := toString (vals [i + 1 ]); ok {
483+ version = & s
484+ seenVersion = true
485+ }
486+ }
487+ case []byte :
488+ switch string (key ) {
489+ case "data" :
490+ if s , ok := toString (vals [i + 1 ]); ok {
491+ data = s
492+ seenData = true
493+ }
494+ case "version" :
495+ if s , ok := toString (vals [i + 1 ]); ok {
496+ version = & s
497+ seenVersion = true
498+ }
499+ }
500+ }
501+
502+ // Early exit once both values have been found
503+ if seenData && seenVersion {
504+ break
481505 }
482506 }
483507 if ! seenData || ! seenVersion {
@@ -487,6 +511,17 @@ func (r *StateStore) getKeyVersion(vals []interface{}) (data string, version *st
487511 return data , version , nil
488512}
489513
514+ func toString (v any ) (string , bool ) {
515+ switch x := v .(type ) {
516+ case string :
517+ return x , true
518+ case []byte :
519+ return string (x ), true // some allocation here unless we go to unsafe: return unsafe.String(unsafe.SliceData(x), len(x)), true
520+ default :
521+ return "" , false
522+ }
523+ }
524+
490525func (r * StateStore ) parseETag (req * state.SetRequest ) (int , error ) {
491526 if req .Options .Concurrency == state .LastWrite || req .ETag == nil || * req .ETag == "" {
492527 return 0 , nil
0 commit comments