Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 19f3efc

Browse files
Issue.1555 zrange withscores arg (#1565)
Allows ZRANGE to be called either with `true` or `['withscores' => true]` so it's consistent with `ZRANGEBYSCORE` but also backward compatible. Fixes #1555
1 parent 07b1e77 commit 19f3efc

3 files changed

Lines changed: 45 additions & 14 deletions

File tree

redis_cluster.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2440,7 +2440,7 @@ static void cluster_raw_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len)
24402440
}
24412441

24422442
/* We at least need the key or [host,port] argument */
2443-
if (argc<1) {
2443+
if (argc < 1) {
24442444
php_error_docref(0 TSRMLS_CC, E_WARNING,
24452445
"Command requires at least an argument to direct to a node");
24462446
RETURN_FALSE;
@@ -3069,6 +3069,8 @@ PHP_METHOD(RedisCluster, xtrim) {
30693069
CLUSTER_PROCESS_CMD(xtrim, cluster_long_resp, 0);
30703070
}
30713071

3072+
3073+
30723074
/* {{{ proto string RedisCluster::echo(string key, string msg)
30733075
* proto string RedisCluster::echo(array host_port, string msg) */
30743076
PHP_METHOD(RedisCluster, echo) {

redis_commands.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,12 @@ int redis_fmt_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len,
491491
return cmdstr.len;
492492
}
493493

494+
/* ZRANGEBYSCORE/ZREVRANGEBYSCORE */
495+
#define IS_WITHSCORES_ARG(s, l) \
496+
(l == sizeof("withscores") - 1 && !strncasecmp(s, "withscores", l))
497+
#define IS_LIMIT_ARG(s, l) \
498+
(l == sizeof("limit") - 1 && !strncasecmp(s,"limit", l))
499+
494500
/* ZRANGE/ZREVRANGE */
495501
int redis_zrange_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
496502
char *kw, char **cmd, int *cmd_len, int *withscores,
@@ -499,33 +505,43 @@ int redis_zrange_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
499505
char *key;
500506
size_t key_len;
501507
zend_long start, end;
502-
zend_bool ws = 0;
508+
zend_string *zkey;
509+
zval *z_ws = NULL, *z_ele;
503510

504-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|b", &key, &key_len,
505-
&start, &end, &ws) == FAILURE)
511+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|z", &key, &key_len,
512+
&start, &end, &z_ws) == FAILURE)
506513
{
507514
return FAILURE;
508515
}
509516

510-
if (ws) {
517+
// Clear withscores arg
518+
*withscores = 0;
519+
520+
/* Accept ['withscores' => true], or the legacy `true` value */
521+
if (z_ws) {
522+
if (Z_TYPE_P(z_ws) == IS_ARRAY) {
523+
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(z_ws), zkey, z_ele) {
524+
ZVAL_DEREF(z_ele);
525+
if (IS_WITHSCORES_ARG(ZSTR_VAL(zkey), ZSTR_LEN(zkey))) {
526+
*withscores = zval_is_true(z_ele);
527+
break;
528+
}
529+
} ZEND_HASH_FOREACH_END();
530+
} else if (Z_TYPE_P(z_ws) == IS_TRUE) {
531+
*withscores = Z_TYPE_P(z_ws) == IS_TRUE;
532+
}
533+
}
534+
535+
if (*withscores) {
511536
*cmd_len = REDIS_CMD_SPPRINTF(cmd, kw, "kdds", key, key_len, start, end,
512537
"WITHSCORES", sizeof("WITHSCORES") - 1);
513538
} else {
514539
*cmd_len = REDIS_CMD_SPPRINTF(cmd, kw, "kdd", key, key_len, start, end);
515540
}
516541

517-
// Push out WITHSCORES option
518-
*withscores = ws;
519-
520542
return SUCCESS;
521543
}
522544

523-
/* ZRANGEBYSCORE/ZREVRANGEBYSCORE */
524-
#define IS_WITHSCORES_ARG(s, l) \
525-
(l == sizeof("withscores") - 1 && !strncasecmp(s, "withscores", l))
526-
#define IS_LIMIT_ARG(s, l) \
527-
(l == sizeof("limit") - 1 && !strncasecmp(s,"limit", l))
528-
529545
int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
530546
char *kw, char **cmd, int *cmd_len, int *withscores,
531547
short *slot, void **ctx)

tests/RedisTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,19 @@ public function testZX() {
23502350
$this->assertTrue(0 === $this->redis->zRevRank('z', 'five'));
23512351
}
23522352

2353+
public function testZRangeScoreArg() {
2354+
$this->redis->del('{z}');
2355+
2356+
$arr_mems = ['one' => 1.0, 'two' => 2.0, 'three' => 3.0];
2357+
foreach ($arr_mems as $str_mem => $score) {
2358+
$this->redis->zAdd('{z}', $score, $str_mem);
2359+
}
2360+
2361+
/* Verify we can pass true and ['withscores' => true] */
2362+
$this->assertEquals($arr_mems, $this->redis->zRange('{z}', 0, -1, true));
2363+
$this->assertEquals($arr_mems, $this->redis->zRange('{z}', 0, -1, ['withscores' => true]));
2364+
}
2365+
23532366
public function testZRangeByLex() {
23542367
/* ZRANGEBYLEX available on versions >= 2.8.9 */
23552368
if(version_compare($this->version, "2.8.9", "lt")) {

0 commit comments

Comments
 (0)