fix wrong data type conversion in zrangeResultBeginStore (#13148)
In `beginResultEmission`, -1 means the result length is not known in advance. But after #12185, if we pass -1 to `zrangeResultBeginStore`, it will convert to SIZE_MAX in `zsetTypeCreate` and try to `dictExpand`. Although `dictExpand` won't succeed because the size overflows, I think we'd better to avoid this wrong conversion. This bug can be triggered when the source of `zrangestore` doesn't exist or we use `zrangestore` command with `byscore` or `bylex`. The impact is that dst keys will be converted to use skiplist instead of listpack.
This commit is contained in:
parent
e04d41d78d
commit
bad33f8738
@ -1234,7 +1234,8 @@ unsigned long zsetLength(const robj *zobj) {
|
||||
* and the value len hint indicates the approximate individual size of the added elements,
|
||||
* they are used to determine the initial representation.
|
||||
*
|
||||
* If the hints are not known, and underestimation or 0 is suitable. */
|
||||
* If the hints are not known, and underestimation or 0 is suitable.
|
||||
* We should never pass a negative value because it will convert to a very large unsigned number. */
|
||||
robj *zsetTypeCreate(size_t size_hint, size_t val_len_hint) {
|
||||
if (size_hint <= server.zset_max_listpack_entries &&
|
||||
val_len_hint <= server.zset_max_listpack_value)
|
||||
@ -3073,7 +3074,7 @@ static void zrangeResultFinalizeClient(zrange_result_handler *handler,
|
||||
/* Result handler methods for storing the ZRANGESTORE to a zset. */
|
||||
static void zrangeResultBeginStore(zrange_result_handler *handler, long length)
|
||||
{
|
||||
handler->dstobj = zsetTypeCreate(length, 0);
|
||||
handler->dstobj = zsetTypeCreate(length >= 0 ? length : 0, 0);
|
||||
}
|
||||
|
||||
static void zrangeResultEmitCBufferForStore(zrange_result_handler *handler,
|
||||
|
@ -2286,12 +2286,18 @@ start_server {tags {"zset"}} {
|
||||
} {b 2 c 3}
|
||||
|
||||
test {ZRANGESTORE BYLEX} {
|
||||
set res [r zrangestore z3{t} z1{t} \[b \[c BYLEX]
|
||||
assert_equal $res 2
|
||||
assert_encoding listpack z3{t}
|
||||
set res [r zrangestore z2{t} z1{t} \[b \[c BYLEX]
|
||||
assert_equal $res 2
|
||||
r zrange z2{t} 0 -1 withscores
|
||||
} {b 2 c 3}
|
||||
|
||||
test {ZRANGESTORE BYSCORE} {
|
||||
set res [r zrangestore z4{t} z1{t} 1 2 BYSCORE]
|
||||
assert_equal $res 2
|
||||
assert_encoding listpack z4{t}
|
||||
set res [r zrangestore z2{t} z1{t} 1 2 BYSCORE]
|
||||
assert_equal $res 2
|
||||
r zrange z2{t} 0 -1 withscores
|
||||
|
Loading…
x
Reference in New Issue
Block a user