Skip to content

Commit f5ca307

Browse files
GETKEYSANDFLAGS sub-command, new module apis, and key-spec flags changes (redis#1784)
doc changes for redis/redis#10237 Co-authored-by: Itamar Haber <[email protected]>
1 parent dfc60e5 commit f5ca307

File tree

5 files changed

+110
-30
lines changed

5 files changed

+110
-30
lines changed

commands.json

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,8 @@
582582
},
583583
"RW": true,
584584
"access": true,
585-
"update": true
585+
"update": true,
586+
"variable_flags": true
586587
}
587588
],
588589
"arguments": [
@@ -2854,6 +2855,21 @@
28542855
"stale"
28552856
]
28562857
},
2858+
"COMMAND GETKEYSANDFLAGS": {
2859+
"summary": "Extract keys given a full Redis command",
2860+
"since": "7.0.0",
2861+
"group": "server",
2862+
"complexity": "O(N) where N is the number of arguments to the command",
2863+
"acl_categories": [
2864+
"@slow",
2865+
"@connection"
2866+
],
2867+
"arity": -4,
2868+
"command_flags": [
2869+
"loading",
2870+
"stale"
2871+
]
2872+
},
28572873
"COMMAND HELP": {
28582874
"summary": "Show helpful text about the different subcommands",
28592875
"since": "5.0.0",
@@ -4244,7 +4260,7 @@
42444260
"arity": 3,
42454261
"arguments": [
42464262
{
4247-
"name": "function-name",
4263+
"name": "library-name",
42484264
"type": "string"
42494265
}
42504266
],
@@ -11111,7 +11127,8 @@
1111111127
},
1111211128
"RW": true,
1111311129
"access": true,
11114-
"update": true
11130+
"update": true,
11131+
"variable_flags": true
1111511132
}
1111611133
],
1111711134
"arguments": [

commands/command-getkeys.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ Returns @array-reply of keys from a full Redis command.
33
`COMMAND GETKEYS` is a helper command to let you find the keys
44
from a full Redis command.
55

6-
`COMMAND` shows some commands as having movablekeys meaning
7-
the entire command must be parsed to discover storage or retrieval
8-
keys. You can use `COMMAND GETKEYS` to discover key positions
9-
directly from how Redis parses the commands.
6+
`COMMAND` provides information on how to find the key names of each command (see `firstkey`, [key specifications](/topics/key-specs#logical-operation-flags), and `movablekeys`),
7+
but in some cases it's not possible to find keys of certain commands and then the entire command must be parsed to discover some / all key names.
8+
You can use `COMMAND GETKEYS` or `COMMAND GETKEYSANDFLAGS` to discover key names directly from how Redis parses the commands.
109

1110

1211
@return
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Returns @array-reply of keys from a full Redis command and their usage flags.
2+
3+
`COMMAND GETKEYSANDFLAGS` is a helper command to let you find the keys from a full Redis command together with flags indicating what each key is used for.
4+
5+
`COMMAND` provides information on how to find the key names of each command (see `firstkey`, [key specifications](/topics/key-specs#logical-operation-flags), and `movablekeys`),
6+
but in some cases it's not possible to find keys of certain commands and then the entire command must be parsed to discover some / all key names.
7+
You can use `COMMAND GETKEYS` or `COMMAND GETKEYSANDFLAGS` to discover key names directly from how Redis parses the commands.
8+
9+
Refer to [key specifications](/topics/key-specs#logical-operation-flags) for information about the meaning of the key flags.
10+
11+
@return
12+
13+
@array-reply: list of keys from your command.
14+
Each element of the array is an array containing key name in the first entry, and flags in the second.
15+
16+
@examples
17+
18+
```cli
19+
COMMAND GETKEYS MSET a b c d e f
20+
COMMAND GETKEYS EVAL "not consulted" 3 key1 key2 key3 arg1 arg2 arg3 argN
21+
COMMAND GETKEYSANDFLAGS LMOST mylist1 mylist2 left left
22+
```

topics/key-specs.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ Key specifications may have the following flags:
156156
* **channel:** this flag indicates that the specification isn't about keys at all.
157157
Instead, the specification relates to the name of a sharded Pub/Sub channel.
158158
Please refer to the `SPUBLISH` command for further details about sharded Pub/Sub.
159-
* **incomplete:** this flag is explained in the following section.
159+
* **incomplete:** this flag is explained below.
160+
* **variable_flags:** this flag is explained below.
160161

161162
### incomplete
162163

@@ -180,6 +181,13 @@ The difficulty arises, for example, because the string _"STORE"_ is both a keywo
180181
the only commands with _incomplete_ key specifications are `SORT` and `MIGRATE`.
181182
We don't expect the addition of such commands in the future.
182183

184+
### variable_flags
185+
186+
In some commands, the flags for the same key name argument can depend on other arguments.
187+
For example, consider the `SET` command and its optional _GET_ argument.
188+
Without the _GET_ argument, `SET` is write-only, but it becomes a read and write command with it.
189+
When this flag is present, it means that the key specification flags cover all possible options, but the effective flags depend on other arguments.
190+
183191
## Examples
184192

185193
### `SET`'s key specifications

topics/modules-api-ref.md

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -152,28 +152,42 @@ Return non-zero if a module command, that was declared with the
152152
flag "getkeys-api", is called in a special way to get the keys positions
153153
and not to get executed. Otherwise zero is returned.
154154

155-
<span id="RedisModule_KeyAtPos"></span>
155+
<span id="RedisModule_KeyAtPosWithFlags"></span>
156156

157-
### `RedisModule_KeyAtPos`
157+
### `RedisModule_KeyAtPosWithFlags`
158158

159-
void RedisModule_KeyAtPos(RedisModuleCtx *ctx, int pos);
160-
161-
**Available since:** 4.0.0
159+
void RedisModule_KeyAtPosWithFlags(RedisModuleCtx *ctx, int pos, int flags);
162160

163161
When a module command is called in order to obtain the position of
164162
keys, since it was flagged as "getkeys-api" during the registration,
165163
the command implementation checks for this special call using the
166164
[`RedisModule_IsKeysPositionRequest()`](#RedisModule_IsKeysPositionRequest) API and uses this function in
167-
order to report keys, like in the following example:
165+
order to report keys.
166+
167+
The supported flags are the ones used by [`RedisModule_SetCommandInfo`](#RedisModule_SetCommandInfo), see `REDISMODULE_CMD_KEY_`*.
168+
169+
170+
The following is an example of how it could be used:
168171

169172
if (RedisModule_IsKeysPositionRequest(ctx)) {
170-
RedisModule_KeyAtPos(ctx,1);
171-
RedisModule_KeyAtPos(ctx,2);
173+
RedisModule_KeyAtPosWithFlags(ctx, 2, REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS);
174+
RedisModule_KeyAtPosWithFlags(ctx, 1, REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE | REDISMODULE_CMD_KEY_ACCESS);
172175
}
173176

174-
Note: in the example below the get keys API would not be needed since
175-
keys are at fixed positions. This interface is only used for commands
176-
with a more complex structure.
177+
Note: in the example above the get keys API could have been handled by key-specs (preferred).
178+
Implementing the getkeys-api is required only when is it not possible to declare key-specs that cover all keys.
179+
180+
<span id="RedisModule_KeyAtPos"></span>
181+
182+
### `RedisModule_KeyAtPos`
183+
184+
void RedisModule_KeyAtPos(RedisModuleCtx *ctx, int pos);
185+
186+
**Available since:** 4.0.0
187+
188+
This API existed before [`RedisModule_KeyAtPosWithFlags`](#RedisModule_KeyAtPosWithFlags) was added, now deprecated and
189+
can be used for compatibility with older versions, before key-specs and flags
190+
were introduced.
177191

178192
<span id="RedisModule_CreateCommand"></span>
179193

@@ -408,8 +422,9 @@ All fields except `version` are optional. Explanation of the fields:
408422
versions where RM_SetCommandInfo is not available.
409423

410424
Note that key-specs don't fully replace the "getkeys-api" (see
411-
RM_CreateCommand, RM_IsKeysPositionRequest and RM_KeyAtPos) so it may be
412-
a good idea to supply both key-specs and a implement the getkeys-api.
425+
RM_CreateCommand, RM_IsKeysPositionRequest and RM_KeyAtPosWithFlags) so
426+
it may be a good idea to supply both key-specs and implement the
427+
getkeys-api.
413428

414429
A key-spec has the following structure:
415430

@@ -6472,21 +6487,24 @@ such as:
64726487

64736488
If `old_value` is non-NULL, the old value is returned by reference.
64746489

6475-
<span id="RedisModule_GetCommandKeys"></span>
6476-
6477-
### `RedisModule_GetCommandKeys`
6490+
<span id="RedisModule_GetCommandKeysWithFlags"></span>
64786491

6479-
int *RedisModule_GetCommandKeys(RedisModuleCtx *ctx,
6480-
RedisModuleString **argv,
6481-
int argc,
6482-
int *num_keys);
6492+
### `RedisModule_GetCommandKeysWithFlags`
64836493

6484-
**Available since:** 6.0.9
6494+
int *RedisModule_GetCommandKeysWithFlags(RedisModuleCtx *ctx,
6495+
RedisModuleString **argv,
6496+
int argc,
6497+
int *num_keys,
6498+
int **out_flags);
64856499

64866500
For a specified command, parse its arguments and return an array that
64876501
contains the indexes of all key name arguments. This function is
64886502
essentially a more efficient way to do `COMMAND GETKEYS`.
64896503

6504+
The `out_flags` argument is optional, and can be set to NULL.
6505+
When provided it is filled with `REDISMODULE_CMD_KEY_` flags in matching
6506+
indexes with the key indexes of the returned array.
6507+
64906508
A NULL return value indicates the specified command has no keys, or
64916509
an error condition. Error conditions are indicated by setting errno
64926510
as follows:
@@ -6496,7 +6514,21 @@ as follows:
64966514

64976515
NOTE: The returned array is not a Redis Module object so it does not
64986516
get automatically freed even when auto-memory is used. The caller
6499-
must explicitly call [`RedisModule_Free()`](#RedisModule_Free) to free it.
6517+
must explicitly call [`RedisModule_Free()`](#RedisModule_Free) to free it, same as the `out_flags` pointer if
6518+
used.
6519+
6520+
<span id="RedisModule_GetCommandKeys"></span>
6521+
6522+
### `RedisModule_GetCommandKeys`
6523+
6524+
int *RedisModule_GetCommandKeys(RedisModuleCtx *ctx,
6525+
RedisModuleString **argv,
6526+
int argc,
6527+
int *num_keys);
6528+
6529+
**Available since:** 6.0.9
6530+
6531+
Identinal to [`RedisModule_GetCommandKeysWithFlags`](#RedisModule_GetCommandKeysWithFlags) when flags are not needed.
65006532

65016533
<span id="RedisModule_GetCurrentCommandName"></span>
65026534

@@ -6762,6 +6794,7 @@ There is no guarantee that this info is always available, so this may return -1.
67626794
* [`RedisModule_GetClusterSize`](#RedisModule_GetClusterSize)
67636795
* [`RedisModule_GetCommand`](#RedisModule_GetCommand)
67646796
* [`RedisModule_GetCommandKeys`](#RedisModule_GetCommandKeys)
6797+
* [`RedisModule_GetCommandKeysWithFlags`](#RedisModule_GetCommandKeysWithFlags)
67656798
* [`RedisModule_GetContextFlags`](#RedisModule_GetContextFlags)
67666799
* [`RedisModule_GetContextFlagsAll`](#RedisModule_GetContextFlagsAll)
67676800
* [`RedisModule_GetCurrentCommandName`](#RedisModule_GetCurrentCommandName)
@@ -6814,6 +6847,7 @@ There is no guarantee that this info is always available, so this may return -1.
68146847
* [`RedisModule_IsModuleNameBusy`](#RedisModule_IsModuleNameBusy)
68156848
* [`RedisModule_IsSubEventSupported`](#RedisModule_IsSubEventSupported)
68166849
* [`RedisModule_KeyAtPos`](#RedisModule_KeyAtPos)
6850+
* [`RedisModule_KeyAtPosWithFlags`](#RedisModule_KeyAtPosWithFlags)
68176851
* [`RedisModule_KeyExists`](#RedisModule_KeyExists)
68186852
* [`RedisModule_KeyType`](#RedisModule_KeyType)
68196853
* [`RedisModule_KillForkChild`](#RedisModule_KillForkChild)

0 commit comments

Comments
 (0)