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

Skip to content

Commit 3b0d8b7

Browse files
Refactor XINFO handler
Fixes #2119
1 parent 525958e commit 3b0d8b7

5 files changed

Lines changed: 46 additions & 35 deletions

File tree

redis_cluster.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ public function xdel(string $key, array $ids): int;
344344

345345
public function xgroup(string $operation, string $key = null, string $arg1 = null, string $arg2 = null, bool $arg3 = false): mixed;
346346

347-
public function xinfo(string $operation, string $arg1 = null, string $arg2 = null): mixed;
347+
public function xinfo(string $operation, ?string $arg1 = null, ?string $arg2 = null, int $count = -1): mixed;
348348

349349
public function xlen(string $key): int;
350350

redis_cluster_arginfo.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 39c0741e5bf358e116f5ed2caa35c1ca226fd593 */
2+
* Stub hash: 396a72b8937928cf3ed504a2a8063f5090e7196b */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -742,8 +742,9 @@ ZEND_END_ARG_INFO()
742742

743743
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_xinfo, 0, 1, IS_MIXED, 0)
744744
ZEND_ARG_TYPE_INFO(0, operation, IS_STRING, 0)
745-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg1, IS_STRING, 0, "null")
746-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_STRING, 0, "null")
745+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg1, IS_STRING, 1, "null")
746+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_STRING, 1, "null")
747+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, count, IS_LONG, 0, "-1")
747748
ZEND_END_ARG_INFO()
748749

749750
#define arginfo_class_RedisCluster_xlen arginfo_class_RedisCluster_decr

redis_cluster_legacy_arginfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 39c0741e5bf358e116f5ed2caa35c1ca226fd593 */
2+
* Stub hash: 396a72b8937928cf3ed504a2a8063f5090e7196b */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_INFO(0, name)
@@ -644,6 +644,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_xinfo, 0, 0, 1)
644644
ZEND_ARG_INFO(0, operation)
645645
ZEND_ARG_INFO(0, arg1)
646646
ZEND_ARG_INFO(0, arg2)
647+
ZEND_ARG_INFO(0, count)
647648
ZEND_END_ARG_INFO()
648649

649650
#define arginfo_class_RedisCluster_xlen arginfo_class_RedisCluster__prefix

redis_commands.c

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5624,42 +5624,38 @@ int redis_xgroup_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
56245624
int redis_xinfo_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
56255625
char **cmd, int *cmd_len, short *slot, void **ctx)
56265626
{
5627-
char *op, *key, *arg = NULL;
5628-
size_t oplen, keylen, arglen;
5627+
zend_string *op = NULL, *key = NULL, *arg = NULL;
5628+
smart_string cmdstr = {0};
56295629
zend_long count = -1;
5630-
int argc = ZEND_NUM_ARGS();
5631-
char fmt[] = "skssl";
5632-
5633-
if (argc > 4 || zend_parse_parameters(ZEND_NUM_ARGS(), "s|ssl",
5634-
&op, &oplen, &key, &keylen, &arg,
5635-
&arglen, &count) == FAILURE)
5636-
{
5637-
return FAILURE;
5638-
}
56395630

5640-
/* Handle everything except XINFO STREAM */
5641-
if (strncasecmp(op, "STREAM", 6) != 0) {
5642-
fmt[argc] = '\0';
5643-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "XINFO", fmt, op, oplen, key, keylen,
5644-
arg, arglen);
5645-
return SUCCESS;
5646-
}
5631+
ZEND_PARSE_PARAMETERS_START(1, 4)
5632+
Z_PARAM_STR(op)
5633+
Z_PARAM_OPTIONAL
5634+
Z_PARAM_STR_OR_NULL(key)
5635+
Z_PARAM_STR_OR_NULL(arg)
5636+
Z_PARAM_LONG(count)
5637+
ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
56475638

5648-
/* 'FULL' is the only legal option to XINFO STREAM */
5649-
if (argc > 2 && strncasecmp(arg, "FULL", 4) != 0) {
5650-
php_error_docref(NULL, E_WARNING, "'%s' is not a valid option for XINFO STREAM", arg);
5639+
if ((arg != NULL && key == NULL) || (count != -1 && (key == NULL || arg == NULL))) {
5640+
php_error_docref(NULL, E_WARNING, "Cannot pass a non-null optional argument after a NULL one.");
56515641
return FAILURE;
56525642
}
56535643

5654-
/* If we have a COUNT bump the argument count to account for the 'COUNT' literal */
5655-
if (argc == 4) argc++;
5644+
REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 1 + (key != NULL) + (arg != NULL) + (count > -1 ? 2 : 0), "XINFO");
5645+
redis_cmd_append_sstr_zstr(&cmdstr, op);
56565646

5657-
fmt[argc] = '\0';
5647+
if (key != NULL)
5648+
redis_cmd_append_sstr_key(&cmdstr, ZSTR_VAL(key), ZSTR_LEN(key), redis_sock, slot);
5649+
if (arg != NULL)
5650+
redis_cmd_append_sstr_zstr(&cmdstr, arg);
56585651

5659-
/* Build our XINFO STREAM variant */
5660-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "XINFO", fmt, "STREAM", 6, key, keylen,
5661-
"FULL", 4, "COUNT", 5, count);
5652+
if (count > -1) {
5653+
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "COUNT");
5654+
redis_cmd_append_sstr_long(&cmdstr, count);
5655+
}
56625656

5657+
*cmd = cmdstr.c;
5658+
*cmd_len = cmdstr.len;
56635659
return SUCCESS;
56645660
}
56655661

tests/RedisTest.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6742,9 +6742,9 @@ public function testXClaim() {
67426742

67436743
public function testXInfo()
67446744
{
6745-
if (!$this->minVersionCheck("5.0")) {
6746-
return $this->markTestSkipped();
6747-
}
6745+
if (!$this->minVersionCheck("5.0"))
6746+
$this->markTestSkipped();
6747+
67486748
/* Create some streams and groups */
67496749
$stream = 's';
67506750
$groups = ['g1' => 0, 'g2' => 0];
@@ -6767,6 +6767,12 @@ public function testXInfo()
67676767
$this->assertTrue(is_array($info[$key]));
67686768
}
67696769

6770+
/* Ensure that default/NULL arguments are ignored */
6771+
$info = $this->redis->xInfo('STREAM', $stream, NULL);
6772+
$this->assertTrue(is_array($info));
6773+
$info = $this->redis->xInfo('STREAM', $stream, NULL, -1);
6774+
$this->assertTrue(is_array($info));
6775+
67706776
/* XINFO STREAM FULL [COUNT N] Requires >= 6.0.0 */
67716777
if (!$this->minVersionCheck("6.0"))
67726778
return;
@@ -6791,6 +6797,13 @@ public function testXInfo()
67916797
$n = isset($info['entries']) ? count($info['entries']) : 0;
67926798
$this->assertEquals($n, $this->redis->xLen($stream));
67936799
}
6800+
6801+
/* Make sure we can't erroneously send non-null args after null ones */
6802+
$this->redis->clearLastError();
6803+
$this->assertFalse(@$this->redis->xInfo('FOO', NULL, 'fail', 25));
6804+
$this->assertEquals(NULL, $this->redis->getLastError());
6805+
$this->assertFalse(@$this->redis->xInfo('FOO', NULL, NULL, -2));
6806+
$this->assertEquals(NULL, $this->redis->getLastError());
67946807
}
67956808

67966809
/* Regression test for issue-1831 (XINFO STREAM on an empty stream) */

0 commit comments

Comments
 (0)