Skip to content

Commit

Permalink
Fix commands H*EXPIRE* and H*TTL to include FIELDS constant (#13270)
Browse files Browse the repository at this point in the history
The same goes to: HPEXPIRE, HEXPIREAT, HPEXPIREAT, HEXPIRETIME,
HPEXPIRETIME, HPTTL, HTTL, HPERSIST
  • Loading branch information
moticless committed May 16, 2024
1 parent 80be2cc commit 7167651
Show file tree
Hide file tree
Showing 16 changed files with 276 additions and 216 deletions.
31 changes: 20 additions & 11 deletions src/commands.def

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions src/commands/hexpire.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HEXPIRE": {
"summary": "Set expiry for hash field using relative time to expire (seconds)",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -5,
"since": "7.4.0",
"arity": -6,
"function": "hexpireCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -106,6 +106,10 @@
}
]
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
10 changes: 7 additions & 3 deletions src/commands/hexpireat.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HEXPIREAT": {
"summary": "Set expiry for hash field using an absolute Unix timestamp (seconds)",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -5,
"since": "7.4.0",
"arity": -6,
"function": "hexpireatCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -106,6 +106,10 @@
}
]
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
10 changes: 7 additions & 3 deletions src/commands/hexpiretime.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HEXPIRETIME": {
"summary": "Returns the expiration time of a hash field as a Unix timestamp, in seconds.",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -4,
"since": "7.4.0",
"arity": -5,
"function": "hexpiretimeCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -75,6 +75,10 @@
"name": "numfields",
"type": "integer"
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "field",
"type": "string",
Expand Down
4 changes: 2 additions & 2 deletions src/commands/hgetf.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"HGETF": {
"summary": "For each specified field: get its value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"since": "7.4.0",
"arity": -5,
"function": "hgetfCommand",
"history": [],
Expand Down
10 changes: 7 additions & 3 deletions src/commands/hpersist.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HPERSIST": {
"summary": "Removes the expiration time for each specified field",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -4,
"since": "7.4.0",
"arity": -5,
"function": "hpersistCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -70,6 +70,10 @@
"type": "key",
"key_spec_index": 0
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
10 changes: 7 additions & 3 deletions src/commands/hpexpire.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HPEXPIRE": {
"summary": "Set expiry for hash field using relative time to expire (milliseconds)",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -5,
"since": "7.4.0",
"arity": -6,
"function": "hpexpireCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -106,6 +106,10 @@
}
]
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
10 changes: 7 additions & 3 deletions src/commands/hpexpireat.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HPEXPIREAT": {
"summary": "Set expiry for hash field using an absolute Unix timestamp (milliseconds)",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -5,
"since": "7.4.0",
"arity": -6,
"function": "hpexpireatCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -106,6 +106,10 @@
}
]
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
10 changes: 7 additions & 3 deletions src/commands/hpexpiretime.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HPEXPIRETIME": {
"summary": "Returns the expiration time of a hash field as a Unix timestamp, in msec.",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -4,
"since": "7.4.0",
"arity": -5,
"function": "hpexpiretimeCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -75,6 +75,10 @@
"name": "numfields",
"type": "integer"
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "field",
"type": "string",
Expand Down
12 changes: 8 additions & 4 deletions src/commands/hpttl.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HPTTL": {
"summary": "Returns the TTL in milliseconds of a hash field.",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -4,
"since": "7.4.0",
"arity": -5,
"function": "hpttlCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -41,7 +41,7 @@
"type": "null"
},
{
"description": "The keyname, popped member, and its score.",
"description": "Array of results",
"type": "array",
"minItems": 1,
"maxItems": 4294967295,
Expand Down Expand Up @@ -71,6 +71,10 @@
"type": "key",
"key_spec_index": 0
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
4 changes: 2 additions & 2 deletions src/commands/hsetf.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"HSETF": {
"summary": "For each specified field value pair: set field to value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"since": "7.4.0",
"arity": -6,
"function": "hsetfCommand",
"history": [],
Expand Down
10 changes: 7 additions & 3 deletions src/commands/httl.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"HTTL": {
"summary": "Returns the TTL in seconds of a hash field.",
"complexity": "O(N) where N is the number of arguments to the command",
"complexity": "O(N) where N is the number of specified fields",
"group": "hash",
"since": "8.0.0",
"arity": -4,
"since": "7.4.0",
"arity": -5,
"function": "httlCommand",
"history": [],
"command_flags": [
Expand Down Expand Up @@ -71,6 +71,10 @@
"type": "key",
"key_spec_index": 0
},
{
"name": "FIELDS",
"type": "string"
},
{
"name": "numfields",
"type": "integer"
Expand Down
39 changes: 27 additions & 12 deletions src/t_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -2719,19 +2719,24 @@ static ExpireMeta *hashGetExpireMeta(const eItem hash) {
serverPanic("Unknown encoding: %d", hashObj->encoding);
}
}

/* HTTL key <FIELDS count field [field ...]> */
static void httlGenericCommand(client *c, const char *cmd, long long basetime, int unit) {
UNUSED(cmd);
robj *hashObj;
long numFields = 0, numFieldsAt = 2;
long numFields = 0, numFieldsAt = 3;

/* Read the hash object */
if ((hashObj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL ||
checkType(c, hashObj, OBJ_HASH)) return;

if (strcasecmp(c->argv[numFieldsAt-1]->ptr, "FIELDS")) {
addReplyError(c, "Mandatory argument FIELDS is missing or not at the right position");
return;
}

/* Read number of fields */
if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX,
&numFields, "Parameter `numFileds` should be greater than 0") != C_OK)
&numFields, "Number of fields must be a positive integer") != C_OK)
return;

/* Verify `numFields` is consistent with number of arguments */
Expand All @@ -2745,7 +2750,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i

addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3+i]->ptr;
sds field = c->argv[numFieldsAt+1+i]->ptr;
void *fptr = lpFirst(lp);
if (fptr != NULL)
fptr = lpFind(lp, fptr, (unsigned char *) field, sdslen(field), 1);
Expand All @@ -2762,7 +2767,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) {
long long expire;
sds field = c->argv[3+i]->ptr;
sds field = c->argv[numFieldsAt+1+i]->ptr;
void *fptr = lpFirst(lpt->lp);
if (fptr != NULL)
fptr = lpFind(lpt->lp, fptr, (unsigned char *) field, sdslen(field), 2);
Expand Down Expand Up @@ -2800,7 +2805,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i

addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3+i]->ptr;
sds field = c->argv[numFieldsAt+1+i]->ptr;
dictEntry *de = dictFind(d, field);
if (de == NULL) {
addReplyLongLong(c, HFE_GET_NO_FIELD);
Expand Down Expand Up @@ -2840,7 +2845,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
*
* Additional flags are supported and parsed via parseExtendedExpireArguments */
static void hexpireGenericCommand(client *c, const char *cmd, long long basetime, int unit) {
long numFields = 0, numFieldsAt = 3;
long numFields = 0, numFieldsAt = 4;
long long expire; /* unix time in msec */
int expireSetCond = 0;
robj *hashObj, *keyArg = c->argv[1], *expireArg = c->argv[2];
Expand Down Expand Up @@ -2890,6 +2895,11 @@ static void hexpireGenericCommand(client *c, const char *cmd, long long basetime
expireSetCond = HFE_LT; ++numFieldsAt;
}

if (strcasecmp(c->argv[numFieldsAt-1]->ptr, "FIELDS")) {
addReplyError(c, "Mandatory argument FIELDS is missing or not at the right position");
return;
}

/* Read number of fields */
if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX,
&numFields, "Parameter `numFields` should be greater than 0") != C_OK)
Expand Down Expand Up @@ -2961,16 +2971,21 @@ void hpexpiretimeCommand(client *c) {
/* HPERSIST key <FIELDS count field [field ...]> */
void hpersistCommand(client *c) {
robj *hashObj;
long numFields = 0, numFieldsAt = 2;
long numFields = 0, numFieldsAt = 3;
int changed = 0; /* Used to determine whether to send a notification. */

/* Read the hash object */
if ((hashObj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL ||
checkType(c, hashObj, OBJ_HASH)) return;

if (strcasecmp(c->argv[numFieldsAt-1]->ptr, "FIELDS")) {
addReplyError(c, "Mandatory argument FIELDS is missing or not at the right position");
return;
}

/* Read number of fields */
if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX,
&numFields, "Parameter `numFileds` should be greater than 0") != C_OK)
&numFields, "Number of fields must be a positive integer") != C_OK)
return;

/* Verify `numFields` is consistent with number of arguments */
Expand All @@ -2982,7 +2997,7 @@ void hpersistCommand(client *c) {
if (hashObj->encoding == OBJ_ENCODING_LISTPACK) {
addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3 + i]->ptr;
sds field = c->argv[numFieldsAt + 1 + i]->ptr;
unsigned char *fptr, *zl = hashObj->ptr;

fptr = lpFirst(zl);
Expand All @@ -3002,7 +3017,7 @@ void hpersistCommand(client *c) {

addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3 + i]->ptr;
sds field = c->argv[numFieldsAt + 1 + i]->ptr;

fptr = lpFirst(lpt->lp);
if (fptr != NULL)
Expand Down Expand Up @@ -3040,7 +3055,7 @@ void hpersistCommand(client *c) {

addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3+i]->ptr;
sds field = c->argv[numFieldsAt + 1 + i]->ptr;
dictEntry *de = dictFind(d, field);
if (de == NULL) {
addReplyLongLong(c, HFE_PERSIST_NO_FIELD);
Expand Down

0 comments on commit 7167651

Please sign in to comment.