Skip to content

Commit 82ec943

Browse files
committed
make ZUNION, ZUNIONSTORE to avoid command_keys as well
1 parent b011b6b commit 82ec943

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

redis/cluster.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,22 @@ def determine_slot(self, *args):
968968
if len(eval_keys) == 0:
969969
return random.randrange(0, REDIS_CLUSTER_HASH_SLOTS)
970970
keys = eval_keys
971+
elif command == "ZUNIONSTORE":
972+
# https://sendbird.slack.com/archives/GFLAQKVDZ/p1688047132982659?thread_ts=1688046729.152689&cid=GFLAQKVDZ
973+
# command syntax: ZUNIONSTORE destination numkeys key [key ...]
974+
# [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]
975+
if len(args) <= 3:
976+
raise RedisClusterException(f"Invalid args in ZUNIONSTORE: {args}")
977+
num_actual_keys = args[2]
978+
keys = (args[1],) + args[3 : 3 + num_actual_keys]
979+
elif command == "ZUNION":
980+
# https://sendbird.slack.com/archives/GFLAQKVDZ/p1688047132982659?thread_ts=1688046729.152689&cid=GFLAQKVDZ
981+
# command syntax: ZUNION numkeys key [key ...] [WEIGHTS weight [weight ...]]
982+
# [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]
983+
if len(args) <= 2:
984+
raise RedisClusterException(f"Invalid args in ZUNION: {args}")
985+
num_actual_keys = args[1]
986+
keys = args[2 : 2 + num_actual_keys]
971987
else:
972988
keys = self._get_command_keys(*args)
973989
if keys is None or len(keys) == 0:

tests/test_cluster.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,10 +1978,21 @@ def test_cluster_zrangestore(self, r):
19781978

19791979
@skip_if_server_version_lt("6.2.0")
19801980
def test_cluster_zunion(self, r):
1981+
assert r.zunion(["{foo}" + str(i) for i in range(0, 256)]) == []
1982+
19811983
r.zadd("{foo}a", {"a1": 1, "a2": 1, "a3": 1})
19821984
r.zadd("{foo}b", {"a1": 2, "a2": 2, "a3": 2})
19831985
r.zadd("{foo}c", {"a1": 6, "a3": 5, "a4": 4})
1986+
1987+
failed_keys = ["{foo1}a", "{foo}b", "{foo}c"]
1988+
with pytest.raises(
1989+
RedisClusterException,
1990+
match="ZUNION - all keys must map to the same key slot",
1991+
):
1992+
r.zunion(failed_keys)
1993+
19841994
# sum
1995+
assert r.zunion(["{foo}a"]) == [b"a1", b"a2", b"a3"]
19851996
assert r.zunion(["{foo}a", "{foo}b", "{foo}c"]) == [b"a2", b"a4", b"a3", b"a1"]
19861997
assert r.zunion(["{foo}a", "{foo}b", "{foo}c"], withscores=True) == [
19871998
(b"a2", 3),
@@ -2006,10 +2017,30 @@ def test_cluster_zunion(self, r):
20062017
]
20072018

20082019
def test_cluster_zunionstore_sum(self, r):
2020+
assert r.zunionstore("{foo}d", ["{foo}" + str(i) for i in range(0, 256)]) == 0
2021+
20092022
r.zadd("{foo}a", {"a1": 1, "a2": 1, "a3": 1})
20102023
r.zadd("{foo}b", {"a1": 2, "a2": 2, "a3": 2})
20112024
r.zadd("{foo}c", {"a1": 6, "a3": 5, "a4": 4})
2025+
2026+
result_key = "{foo}d"
2027+
failed_keys = ["{foo1}a", "{foo}b", "{foo}c"]
2028+
with pytest.raises(
2029+
RedisClusterException,
2030+
match="ZUNIONSTORE - all keys must map to the same key slot",
2031+
):
2032+
r.zunionstore(result_key, failed_keys)
2033+
2034+
result_key = "{foo1}d"
2035+
failed_keys = ["{foo}a", "{foo}b"]
2036+
with pytest.raises(
2037+
RedisClusterException,
2038+
match="ZUNIONSTORE - all keys must map to the same key slot",
2039+
):
2040+
r.zunionstore(result_key, failed_keys)
2041+
20122042
assert r.zunionstore("{foo}d", ["{foo}a", "{foo}b", "{foo}c"]) == 4
2043+
assert r.zunionstore("{foo}e", ["{foo}a"]) == 3
20132044
assert r.zrange("{foo}d", 0, -1, withscores=True) == [
20142045
(b"a2", 3),
20152046
(b"a4", 4),

0 commit comments

Comments
 (0)