Unverified Commit 70ff26b4 authored by yoav-steinberg's avatar yoav-steinberg Committed by GitHub
Browse files

Multiparam config get. (#9914)

Support doing `CONFIG GET <x> <y> <z>`, each of them can also be
a pattern with wildcards.

This avoids duplicates in the result by looping over the configs and for
each once checking all the patterns, once a match is found for a pattern
we move on to the next config.
parent 28b5a653
This diff is collapsed.
......@@ -4,13 +4,13 @@
"complexity": "O(N) when N is the number of configuration parameters provided",
"group": "server",
"since": "2.0.0",
"arity": 3,
"arity": -3,
"container": "CONFIG",
"function": "configGetCommand",
"history": [
[
"7.0.0",
"Added the ability to pass multiple pattern parameters in one"
"Added the ability to pass multiple pattern parameters in one call"
]
],
"command_flags": [
......
......@@ -810,37 +810,34 @@ end:
*----------------------------------------------------------------------------*/
void configGetCommand(client *c) {
robj *o = c->argv[2];
void *replylen = addReplyDeferredLen(c);
char *pattern = o->ptr;
int matches = 0;
serverAssertWithInfo(c,o,sdsEncodedObject(o));
int i;
for (standardConfig *config = configs; config->name != NULL; config++) {
/* Hidden configs require an exact match (not a pattern) */
if (config->flags & HIDDEN_CONFIG) {
if (!strcasecmp(pattern, config->name)) {
int matched_conf = 0;
int matched_alias = 0;
for (i = 0; i < c->argc - 2 && (!matched_conf || !matched_alias); i++) {
robj *o = c->argv[2+i];
char *pattern = o->ptr;
/* Note that hidden configs require an exact match (not a pattern) */
if (!matched_conf &&
(((config->flags & HIDDEN_CONFIG) && !strcasecmp(pattern, config->name)) ||
(!(config->flags & HIDDEN_CONFIG) && stringmatch(pattern, config->name, 1)))) {
addReplyBulkCString(c, config->name);
addReplyBulkSds(c, config->interface.get(config->data));
matches++;
break;
} else if (config->alias && !strcasecmp(pattern, config->alias)) {
addReplyBulkCString(c, config->alias);
addReplyBulkSds(c, config->interface.get(config->data));
matches++;
break;
}
continue;
matched_conf = 1;
}
if (stringmatch(pattern,config->name,1)) {
addReplyBulkCString(c,config->name);
if (!matched_alias && config->alias &&
(((config->flags & HIDDEN_CONFIG) && !strcasecmp(pattern, config->alias)) ||
(!(config->flags & HIDDEN_CONFIG) && stringmatch(pattern, config->alias, 1)))) {
addReplyBulkCString(c, config->alias);
addReplyBulkSds(c, config->interface.get(config->data));
matches++;
matched_alias = 1;
}
if (config->alias && stringmatch(pattern,config->alias,1)) {
addReplyBulkCString(c,config->alias);
addReplyBulkSds(c, config->interface.get(config->data));
matches++;
}
}
......
......@@ -412,6 +412,22 @@ start_server {tags {"introspection"}} {
assert {[dict exists [r config get $hidden_config] "$hidden_config"]}
}
test {CONFIG GET multiple args} {
set res [r config get maxmemory maxmemory* bind *of]
# Verify there are no duplicates in the result
assert_equal [expr [llength [dict keys $res]]*2] [llength $res]
# Verify we got both name and alias in result
assert {[dict exists $res slaveof] && [dict exists $res replicaof]}
# Verify pattern found multiple maxmemory* configs
assert {[dict exists $res maxmemory] && [dict exists $res maxmemory-samples] && [dict exists $res maxmemory-clients]}
# Verify we also got the explicit config
assert {[dict exists $res bind]}
}
# Config file at this point is at a weird state, and includes all
# known keywords. Might be a good idea to avoid adding tests here.
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment