@@ -183,11 +183,8 @@ func (r *RedisServer) set(conn redcon.Conn, cmd redcon.Command) {
183183 return
184184 }
185185 if isList {
186- // delete list metadata so this becomes a plain string key
187- if err := r .deleteList (context .Background (), cmd .Args [1 ]); err != nil {
188- conn .WriteError (err .Error ())
189- return
190- }
186+ conn .WriteError ("WRONGTYPE Operation against a key holding the wrong kind of value" )
187+ return
191188 }
192189
193190 res , err := r .redisTranscoder .SetToRequest (cmd .Args [1 ], cmd .Args [2 ])
@@ -629,15 +626,15 @@ func (t *txnContext) applyLRange(cmd redcon.Command) (redisResult, error) {
629626}
630627
631628func parseRangeBounds (startRaw , endRaw []byte , total int ) (int , int , error ) {
632- start , err := strconv . Atoi ( string ( startRaw ) )
629+ start , err := parseInt ( startRaw )
633630 if err != nil {
634- return 0 , 0 , errors . WithStack ( err )
631+ return 0 , 0 , err
635632 }
636- end , err := strconv . Atoi ( string ( endRaw ) )
633+ end , err := parseInt ( endRaw )
637634 if err != nil {
638- return 0 , 0 , errors . WithStack ( err )
635+ return 0 , 0 , err
639636 }
640- s , e := clampRange (start , end , total )
637+ s , e := clampRange (int ( start ), int ( end ) , total )
641638 return s , e , nil
642639}
643640
@@ -723,6 +720,10 @@ func (t *txnContext) buildListElems() ([]*kv.Elem[kv.OP], error) {
723720 userKey := []byte (k )
724721
725722 if st .deleted {
723+ // delete all persisted list items
724+ for seq := st .meta .Head ; seq < st .meta .Tail ; seq ++ {
725+ elems = append (elems , & kv.Elem [kv.OP ]{Op : kv .Del , Key : listItemKey (userKey , seq )})
726+ }
726727 elems = append (elems , & kv.Elem [kv.OP ]{Op : kv .Del , Key : listMetaKey (userKey )})
727728 continue
728729 }
@@ -884,17 +885,32 @@ func (r *RedisServer) listRPush(ctx context.Context, key []byte, values [][]byte
884885}
885886
886887func (r * RedisServer ) deleteList (ctx context.Context , key []byte ) error {
887- _ , exists , err := r .loadListMeta (ctx , key )
888+ meta , exists , err := r .loadListMeta (ctx , key )
888889 if err != nil {
889890 return err
890891 }
891892 if ! exists {
892893 return nil
893894 }
894895
895- ops := []* kv.Elem [kv.OP ]{
896- {Op : kv .Del , Key : listMetaKey (key )},
896+ start := listItemKey (key , math .MinInt64 )
897+ end := listItemKey (key , math .MaxInt64 )
898+
899+ kvs , err := r .store .Scan (ctx , start , end , math .MaxInt )
900+ if err != nil {
901+ return errors .WithStack (err )
902+ }
903+
904+ ops := make ([]* kv.Elem [kv.OP ], 0 , len (kvs )+ 1 )
905+ for _ , kvp := range kvs {
906+ ops = append (ops , & kv.Elem [kv.OP ]{Op : kv .Del , Key : kvp .Key })
897907 }
908+ // delete meta last
909+ ops = append (ops , & kv.Elem [kv.OP ]{Op : kv .Del , Key : listMetaKey (key )})
910+
911+ // ensure meta bounds consistent even if scan missed (in case of empty list)
912+ _ = meta
913+
898914 group := & kv.OperationGroup [kv.OP ]{IsTxn : true , Elems : ops }
899915 _ , err = r .coordinator .Dispatch (group )
900916 return errors .WithStack (err )
@@ -966,7 +982,16 @@ func (r *RedisServer) proxyLRange(key []byte, startRaw, endRaw []byte) ([]string
966982 cli := redis .NewClient (& redis.Options {Addr : leaderAddr })
967983 defer func () { _ = cli .Close () }()
968984
969- res , err := cli .LRange (context .Background (), string (key ), parseInt (startRaw ), parseInt (endRaw )).Result ()
985+ start , err := parseInt (startRaw )
986+ if err != nil {
987+ return nil , err
988+ }
989+ end , err := parseInt (endRaw )
990+ if err != nil {
991+ return nil , err
992+ }
993+
994+ res , err := cli .LRange (context .Background (), string (key ), start , end ).Result ()
970995 return res , errors .WithStack (err )
971996}
972997
@@ -992,9 +1017,9 @@ func (r *RedisServer) proxyRPush(key []byte, values [][]byte) (int64, error) {
9921017 return res , errors .WithStack (err )
9931018}
9941019
995- func parseInt (b []byte ) int64 {
996- i , _ := strconv .ParseInt (string (b ), 10 , 64 )
997- return i
1020+ func parseInt (b []byte ) ( int64 , error ) {
1021+ i , err := strconv .ParseInt (string (b ), 10 , 64 )
1022+ return i , errors . WithStack ( err )
9981023}
9991024
10001025// tryLeaderGet proxies a GET to the current Raft leader, returning the value and
0 commit comments