Fixed SET and BITFIELD commands being wrongly marked movablekeys (#10837)
The SET and BITFIELD command were added `get_keys_function` in #10148, causing them to be wrongly marked movablekeys in `populateCommandMovableKeys`. This was an unintended side effect introduced in #10148 (7.0 RC1) which could cause some clients an extra round trip for these commands in cluster mode. Since we define movablekeys as a way to determine if the legacy range [first, last, step] doesn't find all keys, then we need a completely different approach. The right approach should be to check if the legacy range covers all key-specs, and if none of the key-specs have the INCOMPLETE flag. This way, we don't need to look at getkeys_proc of VARIABLE_FLAG at all. Probably with the exception of modules, who may still not be using key-specs. In this PR, we removed `populateCommandMovableKeys` and put its logic in `populateCommandLegacyRangeSpec`. In order to properly serve both old and new modules, we must probably keep relying CMD_MODULE_GETKEYS, but do that only for modules that don't declare key-specs. For ones that do, we need to take the same approach we take with native redis commands. This approach was proposed by Oran. Fixes #10833 Co-authored-by: Oran Agra <oran@redislabs.com>
This commit is contained in:
@@ -31,6 +31,20 @@ start_server {tags {"modules"}} {
|
||||
assert_equal [r command getkeys kspec.tworanges foo bar baz quux] {foo bar}
|
||||
}
|
||||
|
||||
test "Module key specs: Two ranges with gap" {
|
||||
set reply [lindex [r command info kspec.tworangeswithgap] 0]
|
||||
# Verify (first, last, step) and movablekeys
|
||||
assert_equal [lindex $reply 2] {module movablekeys}
|
||||
assert_equal [lindex $reply 3] 1
|
||||
assert_equal [lindex $reply 4] 1
|
||||
assert_equal [lindex $reply 5] 1
|
||||
# Verify key-specs
|
||||
set keyspecs [lindex $reply 8]
|
||||
assert_equal [lindex $keyspecs 0] {flags {RO access} begin_search {type index spec {index 1}} find_keys {type range spec {lastkey 0 keystep 1 limit 0}}}
|
||||
assert_equal [lindex $keyspecs 1] {flags {RW update} begin_search {type index spec {index 3}} find_keys {type range spec {lastkey 0 keystep 1 limit 0}}}
|
||||
assert_equal [r command getkeys kspec.tworangeswithgap foo bar baz quux] {foo baz}
|
||||
}
|
||||
|
||||
test "Module key specs: Keyword-only spec clears the legacy triple" {
|
||||
set reply [lindex [r command info kspec.keyword] 0]
|
||||
# Verify (first, last, step) and movablekeys
|
||||
@@ -79,7 +93,7 @@ start_server {tags {"modules"}} {
|
||||
test "Module command list filtering" {
|
||||
;# Note: we piggyback this tcl file to test the general functionality of command list filtering
|
||||
set reply [r command list filterby module keyspecs]
|
||||
assert_equal [lsort $reply] {kspec.complex1 kspec.complex2 kspec.keyword kspec.none kspec.tworanges}
|
||||
assert_equal [lsort $reply] {kspec.complex1 kspec.complex2 kspec.keyword kspec.none kspec.nonewithgetkeys kspec.tworanges kspec.tworangeswithgap}
|
||||
assert_equal [r command getkeys kspec.complex2 foo bar 2 baz quux banana STORE dst dummy MOREKEYS hey ho] {dst foo bar baz quux hey ho}
|
||||
}
|
||||
|
||||
@@ -108,6 +122,20 @@ start_server {tags {"modules"}} {
|
||||
assert_equal "This user has no permissions to access the 'write' key" [r ACL DRYRUN testuser kspec.tworanges write rw]
|
||||
}
|
||||
|
||||
foreach cmd {kspec.none kspec.tworanges} {
|
||||
test "$cmd command will not be marked with movablekeys" {
|
||||
set info [lindex [r command info $cmd] 0]
|
||||
assert_no_match {*movablekeys*} [lindex $info 2]
|
||||
}
|
||||
}
|
||||
|
||||
foreach cmd {kspec.keyword kspec.complex1 kspec.complex2 kspec.nonewithgetkeys} {
|
||||
test "$cmd command is marked with movablekeys" {
|
||||
set info [lindex [r command info $cmd] 0]
|
||||
assert_match {*movablekeys*} [lindex $info 2]
|
||||
}
|
||||
}
|
||||
|
||||
test "Unload the module - keyspecs" {
|
||||
assert_equal {OK} [r module unload keyspecs]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user