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

Skip to content

Commit 5cb30fb

Browse files
Adds OPT_REPLY_LITERAL for rawCommand and EVAL
Adds an option to process the actual strings in simple string replies as opposed to translating them to `true`. This only applies to `rawCommand` and `eval` because as far as I know know vanilla Redis command attaches any information besides `OK` to simple string replies. Addresses #1550
1 parent be3089c commit 5cb30fb

10 files changed

Lines changed: 75 additions & 8 deletions

cluster_library.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,12 @@ PHP_REDIS_API void cluster_variant_resp(INTERNAL_FUNCTION_PARAMETERS, redisClust
20982098
cluster_variant_resp_generic(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, 0, ctx);
20992099
}
21002100

2101+
PHP_REDIS_API void cluster_variant_raw_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
2102+
void *ctx)
2103+
{
2104+
cluster_variant_resp_generic(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, c->flags->reply_literal, ctx);
2105+
}
2106+
21012107
PHP_REDIS_API void cluster_variant_resp_strings(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
21022108
void *ctx)
21032109
{

cluster_library.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,10 +431,12 @@ PHP_REDIS_API void cluster_sub_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *
431431
PHP_REDIS_API void cluster_unsub_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
432432
void *ctx);
433433

434-
/* Generic/Variant handler for stuff like EVAL */
435434
PHP_REDIS_API void cluster_variant_resp(INTERNAL_FUNCTION_PARAMETERS,
436435
redisCluster *c, void *ctx);
437436

437+
PHP_REDIS_API void cluster_variant_raw_resp(INTERNAL_FUNCTION_PARAMETERS,
438+
redisCluster *c, void *ctx);
439+
438440
PHP_REDIS_API void cluster_variant_resp_strings(INTERNAL_FUNCTION_PARAMETERS,
439441
redisCluster *c, void *ctx);
440442

common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ typedef enum _PUBSUB_TYPE {
7878
#define REDIS_OPT_FAILOVER 5
7979
#define REDIS_OPT_TCP_KEEPALIVE 6
8080
#define REDIS_OPT_COMPRESSION 7
81+
#define REDIS_OPT_REPLY_LITERAL 8
8182

8283
/* cluster options */
8384
#define REDIS_FAILOVER_NONE 0
@@ -272,6 +273,7 @@ typedef struct {
272273
int scan;
273274

274275
int readonly;
276+
int reply_literal;
275277
int tcp_keepalive;
276278
} RedisSock;
277279
/* }}} */

library.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,7 @@ redis_sock_create(char *host, int host_len, unsigned short port,
16841684

16851685
redis_sock->readonly = 0;
16861686
redis_sock->tcp_keepalive = 0;
1687+
redis_sock->reply_literal = 0;
16871688

16881689
return redis_sock;
16891690
}
@@ -2558,6 +2559,14 @@ variant_reply_generic(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
25582559
return 0;
25592560
}
25602561

2562+
PHP_REDIS_API int
2563+
redis_read_raw_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
2564+
zval *z_tab, void *ctx)
2565+
{
2566+
return variant_reply_generic(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
2567+
redis_sock->reply_literal, z_tab, ctx);
2568+
}
2569+
25612570
PHP_REDIS_API int
25622571
redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
25632572
zval *z_tab, void *ctx)

library.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ PHP_REDIS_API int redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE
116116
PHP_REDIS_API int redis_read_variant_bulk(RedisSock *redis_sock, int size, zval *z_ret TSRMLS_DC);
117117
PHP_REDIS_API int redis_read_multibulk_recursive(RedisSock *redis_sock, int elements, int status_strings, zval *z_ret TSRMLS_DC);
118118
PHP_REDIS_API int redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
119+
PHP_REDIS_API int redis_read_raw_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
119120
PHP_REDIS_API int redis_read_variant_reply_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
120121
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab);
121122

redis.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ static void add_class_constants(zend_class_entry *ce, int is_cluster TSRMLS_DC)
666666
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_READ_TIMEOUT"), REDIS_OPT_READ_TIMEOUT TSRMLS_CC);
667667
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_TCP_KEEPALIVE"), REDIS_OPT_TCP_KEEPALIVE TSRMLS_CC);
668668
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_COMPRESSION"), REDIS_OPT_COMPRESSION TSRMLS_CC);
669+
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_REPLY_LITERAL"), REDIS_OPT_REPLY_LITERAL);
669670

670671
/* serializer */
671672
zend_declare_class_constant_long(ce, ZEND_STRL("SERIALIZER_NONE"), REDIS_SERIALIZER_NONE TSRMLS_CC);
@@ -3007,12 +3008,12 @@ PHP_METHOD(Redis, pubsub) {
30073008
/* {{{ proto variant Redis::eval(string script, [array keys, long num_keys]) */
30083009
PHP_METHOD(Redis, eval)
30093010
{
3010-
REDIS_PROCESS_KW_CMD("EVAL", redis_eval_cmd, redis_read_variant_reply);
3011+
REDIS_PROCESS_KW_CMD("EVAL", redis_eval_cmd, redis_read_raw_variant_reply);
30113012
}
30123013

30133014
/* {{{ proto variant Redis::evalsha(string sha1, [array keys, long num_keys]) */
30143015
PHP_METHOD(Redis, evalsha) {
3015-
REDIS_PROCESS_KW_CMD("EVALSHA", redis_eval_cmd, redis_read_variant_reply);
3016+
REDIS_PROCESS_KW_CMD("EVALSHA", redis_eval_cmd, redis_read_raw_variant_reply);
30163017
}
30173018

30183019
/* {{{ proto status Redis::script('flush')
@@ -3384,7 +3385,7 @@ PHP_METHOD(Redis, rawcommand) {
33843385
/* Execute our command */
33853386
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
33863387
if (IS_ATOMIC(redis_sock)) {
3387-
redis_read_variant_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,redis_sock,NULL,NULL);
3388+
redis_read_raw_variant_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,redis_sock,NULL,NULL);
33883389
}
33893390
REDIS_PROCESS_RESPONSE(redis_read_variant_reply);
33903391
}

redis_cluster.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,13 +1989,13 @@ PHP_METHOD(RedisCluster, punsubscribe) {
19891989

19901990
/* {{{ proto mixed RedisCluster::eval(string script, [array args, int numkeys) */
19911991
PHP_METHOD(RedisCluster, eval) {
1992-
CLUSTER_PROCESS_KW_CMD("EVAL", redis_eval_cmd, cluster_variant_resp, 0);
1992+
CLUSTER_PROCESS_KW_CMD("EVAL", redis_eval_cmd, cluster_variant_raw_resp, 0);
19931993
}
19941994
/* }}} */
19951995

19961996
/* {{{ proto mixed RedisCluster::evalsha(string sha, [array args, int numkeys]) */
19971997
PHP_METHOD(RedisCluster, evalsha) {
1998-
CLUSTER_PROCESS_KW_CMD("EVALSHA", redis_eval_cmd, cluster_variant_resp, 0);
1998+
CLUSTER_PROCESS_KW_CMD("EVALSHA", redis_eval_cmd, cluster_variant_raw_resp, 0);
19991999
}
20002000
/* }}} */
20012001

@@ -3161,10 +3161,10 @@ PHP_METHOD(RedisCluster, rawcommand) {
31613161

31623162
/* Process variant response */
31633163
if (CLUSTER_IS_ATOMIC(c)) {
3164-
cluster_variant_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
3164+
cluster_variant_raw_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
31653165
} else {
31663166
void *ctx = NULL;
3167-
CLUSTER_ENQUEUE_RESPONSE(c, slot, cluster_variant_resp, ctx);
3167+
CLUSTER_ENQUEUE_RESPONSE(c, slot, cluster_variant_raw_resp, ctx);
31683168
}
31693169

31703170
efree(cmd);

redis_commands.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3856,6 +3856,8 @@ void redis_getoption_handler(INTERNAL_FUNCTION_PARAMETERS,
38563856
RETURN_LONG(redis_sock->tcp_keepalive);
38573857
case REDIS_OPT_SCAN:
38583858
RETURN_LONG(redis_sock->scan);
3859+
case REDIS_OPT_REPLY_LITERAL:
3860+
RETURN_LONG(redis_sock->reply_literal);
38593861
case REDIS_OPT_FAILOVER:
38603862
RETURN_LONG(c->failover);
38613863
default:
@@ -3896,6 +3898,10 @@ void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
38963898
RETURN_TRUE;
38973899
}
38983900
break;
3901+
case REDIS_OPT_REPLY_LITERAL:
3902+
val_long = zval_get_long(val);
3903+
redis_sock->reply_literal = val_long != 0;
3904+
RETURN_TRUE;
38993905
case REDIS_OPT_COMPRESSION:
39003906
val_long = zval_get_long(val);
39013907
if (val_long == REDIS_COMPRESSION_NONE

tests/RedisClusterTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,26 @@ protected function rawCommandArray($key, $args) {
609609
return call_user_func_array([$this->redis, 'rawCommand'], $args);
610610
}
611611

612+
/* Test that rawCommand and EVAL can be configured to return simple string values */
613+
public function testReplyLiteral() {
614+
$this->redis->setOption(Redis::OPT_REPLY_LITERAL, false);
615+
$this->assertTrue($this->redis->rawCommand('foo', 'set', 'foo', 'bar'));
616+
$this->assertTrue($this->redis->eval("return redis.call('set', KEYS[1], 'bar')", ['foo'], 1));
617+
618+
$rv = $this->redis->eval("return {redis.call('set', KEYS[1], 'bar'), redis.call('ping')}", ['foo'], 1);
619+
$this->assertEquals([true, true], $rv);
620+
621+
$this->redis->setOption(Redis::OPT_REPLY_LITERAL, true);
622+
$this->assertEquals('OK', $this->redis->rawCommand('foo', 'set', 'foo', 'bar'));
623+
$this->assertEquals('OK', $this->redis->eval("return redis.call('set', KEYS[1], 'bar')", ['foo'], 1));
624+
625+
$rv = $this->redis->eval("return {redis.call('set', KEYS[1], 'bar'), redis.call('ping')}", ['foo'], 1);
626+
$this->assertEquals(['OK', 'PONG'], $rv);
627+
628+
// Reset
629+
$this->redis->setOption(Redis::OPT_REPLY_LITERAL, false);
630+
}
631+
612632
public function testSession()
613633
{
614634
@ini_set('session.save_handler', 'rediscluster');

tests/RedisTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4825,6 +4825,26 @@ public function testPrefix() {
48254825

48264826
}
48274827

4828+
public function testReplyLiteral() {
4829+
$this->redis->setOption(Redis::OPT_REPLY_LITERAL, false);
4830+
$this->assertTrue($this->redis->rawCommand('set', 'foo', 'bar'));
4831+
$this->assertTrue($this->redis->eval("return redis.call('set', 'foo', 'bar')", [], 0));
4832+
4833+
$rv = $this->redis->eval("return {redis.call('set', KEYS[1], 'bar'), redis.call('ping')}", ['foo'], 1);
4834+
$this->assertEquals([true, true], $rv);
4835+
4836+
$this->redis->setOption(Redis::OPT_REPLY_LITERAL, true);
4837+
$this->assertEquals('OK', $this->redis->rawCommand('set', 'foo', 'bar'));
4838+
$this->assertEquals('OK', $this->redis->eval("return redis.call('set', 'foo', 'bar')", [], 0));
4839+
4840+
// Nested
4841+
$rv = $this->redis->eval("return {redis.call('set', KEYS[1], 'bar'), redis.call('ping')}", ['foo'], 1);
4842+
$this->assertEquals(['OK', 'PONG'], $rv);
4843+
4844+
// Reset
4845+
$this->redis->setOption(Redis::OPT_REPLY_LITERAL, false);
4846+
}
4847+
48284848
public function testReconnectSelect() {
48294849
$key = 'reconnect-select';
48304850
$value = 'Has been set!';

0 commit comments

Comments
 (0)