-
Notifications
You must be signed in to change notification settings - Fork 24.4k
hrandfield and zrandmember with count should return emptyarray when key does not exist. #9178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@oranagra This one is small and looks like a bug |
zuiderkwast
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sure looks like a bugfix. The docs say an empty array should be returned.
LGTM, but we need test cases to cover this.
|
@zuiderkwast It's a bit embarrassing..., I don't know how to judge empty array in single test |
|
In TCL? I don't know either. :-) But there must be some way, maybe using lower level protocol or a redis-cli test case(?) |
|
In other test cases, they just check that it's an empty string, such as here: |
|
@zuiderkwast Yes. The original code test case is also check the empty string. Not an empty array |
|
regarding the tests, TCL doesn't really have any types other than strings, so there's not much we can do.
|
|
considering this a breaking change in a command that was recently introduced, in theory there's a question of whether to fix it and also backport the fix to 6.2. |
|
For the test, I think we should take 2 or 3. Or at least one way to check. 2 we can change the whole point, including changing the previous ones and maybe simpler I think i will try method 2 first and see how the changes are... |
|
I suggest 4: Use redis-cli and check that the output is "(empty array)". Very similar to this: https://github.com/redis/redis/blob/unstable/tests/integration/redis-cli.tcl#L170 integration/redis-cli.tcl might not be the right place to test these corner cases. With a little refactoring (move some helper functions such as open_cli into tests/support/cli.tcl) we can use cli also in other test suites with very little effort. [Edit] But on the other hand, one purpose is to check that redis-cli outputs "(empty array)" for empty arrays, so therefore we can put the test cases in the redis-cli test suite. :-) |
|
i don't think we should abuse redis-cli for these tests (they don't intend to test redis-cli). option 3 is useful so that it's easy to use and will also fail tests that actually expect an empty array (so we don't wanna change the test), if for some reason redis one day responds with null (we'll be able to catch a regression). and i think that option 4 is an important tool to have in our toolbox, to be able to read RESP directly from the tests if we want. i was considering to post my POC here and let you take it to completion, but if we wanna do both 3 and 4 anyway, that raw mode can come in a different PR. the only question is if there's any reason not to do 3? |
|
Raw mode (3) or cli (4) both do the job AFAICT. If 3 is easy enough to do, then no need for 4. (The only option I don't love is option 2 since {nil} in TCL is a list of one element. Also it still doesn't allow distinguish between empty string and null. And in the docs, nil is used for null, not for empty arrays.) |
|
@zuiderkwast do you mean that the string we choose: proc ::redis::redis_multi_bulk_read {id fd} {
set count [redis_read_line $fd]
- if {$count == -1} return {}
+ if {$count == -1} return {nil}can be confused with a normal response containing the string "nil" (i.e. regarding the terms "nil" or "null" and consistency with the docs, i don't think it matters, we can take either one as long as the tests are consistent with their infra. the only concern i have is if this kind of change causes more damage than good. and if we apply similar logic in other places (for constancy), it may cause more damage than good. |
That's the ambiguity, yes, but I don't think there's a real risk either. But even redis-cli prints "(nil)" for null, so I think "nil" for an empty array is a bad choice. If we do 2 ("corner case mode"), how about returning special strings for these corner cases:
|
|
maybe we can try being consistent with the codebase: shared.null[2] = createObject(OBJ_STRING,sdsnew("$-1\r\n"));
shared.null[3] = createObject(OBJ_STRING,sdsnew("_\r\n"));
shared.nullarray[2] = createObject(OBJ_STRING,sdsnew("*-1\r\n"));
shared.nullarray[3] = createObject(OBJ_STRING,sdsnew("_\r\n"));and also make it clear that this is a special hack string, and make it easy to grep for it and find the other mentions of it. |
|
Here's what i came up with: #9193 |
…ey does not exist.
Co-authored-by: Oran Agra <oran@redislabs.com>
Co-authored-by: Oran Agra <oran@redislabs.com>
yossigo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@oranagra I agree, we've already discussed this a few times and agreed this kind of bugs are fixed (and backported) regardless of the breaking impact. The major decision was already taken IMHO.
|
ohh, i missed one... (waiting to get feedback from Yossi, hope to merge soon) |
…ey does not exist. (#9178) due to a copy-paste bug, it used to reply with null response rather than empty array. this commit includes new tests that are looking at the RESP response directly in order to be able to tell the difference between them. Co-authored-by: Oran Agra <oran@redislabs.com> (cherry picked from commit a418a2d)
…ey does not exist. (redis#9178) due to a copy-paste bug, it used to reply with null response rather than empty array. this commit includes new tests that are looking at the RESP response directly in order to be able to tell the difference between them. Co-authored-by: Oran Agra <oran@redislabs.com>
we treat non-existing key as an empty hash or zset
Before:
After:
also can check https://redis.io/commands/hrandfield
Also add test to check emptyarray.