@@ -19,8 +19,9 @@ type luaScriptContext struct {
1919 startTS uint64
2020 readPin * kv.ActiveTimestampToken
2121
22- touched map [string ]struct {}
23- deleted map [string ]bool
22+ touched map [string ]struct {}
23+ deleted map [string ]bool
24+ everDeleted map [string ]bool
2425
2526 strings map [string ]* luaStringState
2627 lists map [string ]* luaListState
@@ -189,18 +190,19 @@ var luaRenameHandlers = map[redisValueType]luaRenameHandler{
189190func newLuaScriptContext (server * RedisServer ) * luaScriptContext {
190191 startTS := server .readTS ()
191192 return & luaScriptContext {
192- server : server ,
193- startTS : startTS ,
194- readPin : server .pinReadTS (startTS ),
195- touched : map [string ]struct {}{},
196- deleted : map [string ]bool {},
197- strings : map [string ]* luaStringState {},
198- lists : map [string ]* luaListState {},
199- hashes : map [string ]* luaHashState {},
200- sets : map [string ]* luaSetState {},
201- zsets : map [string ]* luaZSetState {},
202- streams : map [string ]* luaStreamState {},
203- ttls : map [string ]* luaTTLState {},
193+ server : server ,
194+ startTS : startTS ,
195+ readPin : server .pinReadTS (startTS ),
196+ touched : map [string ]struct {}{},
197+ deleted : map [string ]bool {},
198+ everDeleted : map [string ]bool {},
199+ strings : map [string ]* luaStringState {},
200+ lists : map [string ]* luaListState {},
201+ hashes : map [string ]* luaHashState {},
202+ sets : map [string ]* luaSetState {},
203+ zsets : map [string ]* luaZSetState {},
204+ streams : map [string ]* luaStreamState {},
205+ ttls : map [string ]* luaTTLState {},
204206 }
205207}
206208
@@ -265,6 +267,7 @@ func (c *luaScriptContext) deleteLogical(key []byte) {
265267 k := string (key )
266268 c .markTouched (key )
267269 c .deleted [k ] = true
270+ c .everDeleted [k ] = true
268271 c .clearTTL (key )
269272
270273 if st , ok := c .strings [k ]; ok {
@@ -2517,6 +2520,14 @@ func (c *luaScriptContext) listCommitPlan(key string) (luaCommitPlan, error) {
25172520 elems , err := c .listCommitElems (key )
25182521 return luaCommitPlan {elems : elems }, err
25192522 }
2523+ // If the key was deleted earlier in this script and later recreated as a
2524+ // list, we must perform a full rewrite (preserveExisting=false) so that
2525+ // deleteLogicalKeyElems is called and any orphaned storage items from the
2526+ // previous incarnation of the key are cleaned up before writing the delta.
2527+ if c .everDeleted [key ] {
2528+ elems , err := c .listCommitElems (key )
2529+ return luaCommitPlan {elems : elems }, err
2530+ }
25202531 elems , err := c .listDeltaCommitElems (key , st )
25212532 return luaCommitPlan {preserveExisting : true , elems : elems }, err
25222533}
0 commit comments