From d9ef807b1cae1c29ca07a0511e2d152e50e80228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Fern=C3=A1ndez?= Date: Tue, 7 Feb 2017 22:43:10 +0100 Subject: [PATCH 1/4] Failing test case when running LUA with bulk empty response --- tests/RedisClusterTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/RedisClusterTest.php b/tests/RedisClusterTest.php index 1ccbf47b59..1253de6320 100644 --- a/tests/RedisClusterTest.php +++ b/tests/RedisClusterTest.php @@ -346,6 +346,20 @@ public function testEvalSHA() { $this->assertTrue(1 === $this->redis->evalsha($sha,Array($str_key), 1)); } + public function testEvalBulkEmptyResponse() { + $str_key1 = uniqid() . '-' . rand(1,1000) . '{hash}'; + $str_key2 = uniqid() . '-' . rand(1,1000) . '{hash}'; + + $this->redis->script($str_key1, 'flush'); + $this->redis->script($str_key2, 'flush'); + + $scr = "for _,key in ipairs(KEYS) do redis.call('SET', key, 'value') end"; + + $result = $this->redis->eval($scr,Array($str_key1, $str_key2), 2); + + $this->assertTrue(null === $result); + } + /* Cluster specific introspection stuff */ public function testIntrospection() { $arr_masters = $this->redis->_masters(); From cac14f411040883054069a8c4e1555a39b9a7ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Fern=C3=A1ndez?= Date: Tue, 7 Feb 2017 22:43:21 +0100 Subject: [PATCH 2/4] Fix issue when parsing bulk array response from eval commands --- cluster_library.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cluster_library.c b/cluster_library.c index 280d94bbcf..12bd2decc3 100644 --- a/cluster_library.c +++ b/cluster_library.c @@ -1870,7 +1870,11 @@ PHP_REDIS_API void cluster_variant_resp(INTERNAL_FUNCTION_PARAMETERS, redisClust RETVAL_TRUE; break; case TYPE_BULK: - RETVAL_STRINGL(r->str, r->len); + if (r->len > -1) { + RETVAL_STRINGL(r->str, r->len); + } else { + RETVAL_NULL(); + } break; case TYPE_MULTIBULK: array_init(z_arr); From 1872f918b03748b65e900e1159b1d2c8b9038595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Fern=C3=A1ndez?= Date: Wed, 8 Feb 2017 20:28:28 +0100 Subject: [PATCH 3/4] Added test for bulk LUA responses and changed condition --- cluster_library.c | 2 +- tests/RedisClusterTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cluster_library.c b/cluster_library.c index 12bd2decc3..21e83eacba 100644 --- a/cluster_library.c +++ b/cluster_library.c @@ -1870,7 +1870,7 @@ PHP_REDIS_API void cluster_variant_resp(INTERNAL_FUNCTION_PARAMETERS, redisClust RETVAL_TRUE; break; case TYPE_BULK: - if (r->len > -1) { + if (r->len > 0) { RETVAL_STRINGL(r->str, r->len); } else { RETVAL_NULL(); diff --git a/tests/RedisClusterTest.php b/tests/RedisClusterTest.php index 1253de6320..37f423be9c 100644 --- a/tests/RedisClusterTest.php +++ b/tests/RedisClusterTest.php @@ -345,6 +345,21 @@ public function testEvalSHA() { $this->assertTrue(1 === $this->redis->eval($scr,Array($str_key), 1)); $this->assertTrue(1 === $this->redis->evalsha($sha,Array($str_key), 1)); } + + public function testEvalBulkResponse() { + $str_key1 = uniqid() . '-' . rand(1,1000) . '{hash}'; + $str_key2 = uniqid() . '-' . rand(1,1000) . '{hash}'; + + $this->redis->script($str_key1, 'flush'); + $this->redis->script($str_key2, 'flush'); + + $scr = "return {KEYS[1],KEYS[2]}"; + + $result = $this->redis->eval($scr,Array($str_key1, $str_key2), 2); + + $this->assertTrue($str_key1 === $result[0]); + $this->assertTrue($str_key2 === $result[1]); + } public function testEvalBulkEmptyResponse() { $str_key1 = uniqid() . '-' . rand(1,1000) . '{hash}'; From e380ec2f143be70faaaa5ec924024687ef0f0c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Fern=C3=A1ndez?= Date: Thu, 9 Feb 2017 13:31:42 +0100 Subject: [PATCH 4/4] Added multi tests and fixes in C code format --- cluster_library.c | 14 +++++++++----- tests/RedisClusterTest.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/cluster_library.c b/cluster_library.c index 21e83eacba..923dda4e45 100644 --- a/cluster_library.c +++ b/cluster_library.c @@ -1870,10 +1870,10 @@ PHP_REDIS_API void cluster_variant_resp(INTERNAL_FUNCTION_PARAMETERS, redisClust RETVAL_TRUE; break; case TYPE_BULK: - if (r->len > 0) { - RETVAL_STRINGL(r->str, r->len); - } else { + if (r->len < 0) { RETVAL_NULL(); + } else { + RETVAL_STRINGL(r->str, r->len); } break; case TYPE_MULTIBULK: @@ -1900,8 +1900,12 @@ PHP_REDIS_API void cluster_variant_resp(INTERNAL_FUNCTION_PARAMETERS, redisClust add_next_index_bool(&c->multi_resp, 1); break; case TYPE_BULK: - add_next_index_stringl(&c->multi_resp, r->str, r->len); - efree(r->str); + if (r->len < 0) { + add_next_index_null(&c->multi_resp); + } else { + add_next_index_stringl(&c->multi_resp, r->str, r->len); + efree(r->str); + } break; case TYPE_MULTIBULK: cluster_mbulk_variant_resp(r, &c->multi_resp); diff --git a/tests/RedisClusterTest.php b/tests/RedisClusterTest.php index 37f423be9c..36f65f84a6 100644 --- a/tests/RedisClusterTest.php +++ b/tests/RedisClusterTest.php @@ -361,6 +361,24 @@ public function testEvalBulkResponse() { $this->assertTrue($str_key2 === $result[1]); } + public function testEvalBulkResponseMulti() { + $str_key1 = uniqid() . '-' . rand(1,1000) . '{hash}'; + $str_key2 = uniqid() . '-' . rand(1,1000) . '{hash}'; + + $this->redis->script($str_key1, 'flush'); + $this->redis->script($str_key2, 'flush'); + + $scr = "return {KEYS[1],KEYS[2]}"; + + $this->redis->multi(); + $this->redis->eval($scr,Array($str_key1, $str_key2), 2); + + $result = $this->redis->exec(); + + $this->assertTrue($str_key1 === $result[0][0]); + $this->assertTrue($str_key2 === $result[0][1]); + } + public function testEvalBulkEmptyResponse() { $str_key1 = uniqid() . '-' . rand(1,1000) . '{hash}'; $str_key2 = uniqid() . '-' . rand(1,1000) . '{hash}'; @@ -375,6 +393,22 @@ public function testEvalBulkEmptyResponse() { $this->assertTrue(null === $result); } + public function testEvalBulkEmptyResponseMulti() { + $str_key1 = uniqid() . '-' . rand(1,1000) . '{hash}'; + $str_key2 = uniqid() . '-' . rand(1,1000) . '{hash}'; + + $this->redis->script($str_key1, 'flush'); + $this->redis->script($str_key2, 'flush'); + + $scr = "for _,key in ipairs(KEYS) do redis.call('SET', key, 'value') end"; + + $this->redis->multi(); + $this->redis->eval($scr,Array($str_key1, $str_key2), 2); + $result = $this->redis->exec(); + + $this->assertTrue(null === $result[0]); + } + /* Cluster specific introspection stuff */ public function testIntrospection() { $arr_masters = $this->redis->_masters();