feat(string): support IFEQ/IFNE/IFDEQ/IFDNE in SET command (#3311)#3393
feat(string): support IFEQ/IFNE/IFDEQ/IFDNE in SET command (#3311)#3393kirito632 wants to merge 8 commits intoapache:unstablefrom
Conversation
|
Thanks for the pointer. I used AI tools to assist with the initial implementation draft and test scaffolding. I reviewed the logic myself against the Redis 8.x documentation, caught and fixed a wrong test assertion (GET+IFEQ condition-not-met should return the old value, not nil), and cleaned up non-ASCII comments to match kvrocks conventions. I understand the implementation and can explain any part of it. |
|
Hi @PragmaTwice @jihuayu , I have addressed the review comments and fixed the clang-tidy / Go test issues in my latest commit . I also updated the branch to resolve the out-of-date issue. |
|
Hi @kirito632. You need to ensure the CI passes before we start the review. |
When GET is combined with IFEQ/IFNE/IFDEQ/IFDNE and the condition is not met, return the previous value (not nil), consistent with how Redis handles GET+NX/XX and the official Redis 8.x documentation.
When GET is combined with a conditional SET (IFEQ/IFNE/IFDEQ/IFDNE), the previous value is always returned regardless of whether the condition was met. The Go test incorrectly expected nil when the condition was not met; fix it to expect the old value. Also replace non-ASCII arrow characters in C++ test comments with plain ASCII equivalents to match kvrocks coding conventions.
…dling - Change StringSetArgs parameter to const reference in Set() declaration and definition to satisfy clang-tidy performance-unnecessary-value-param - Fix Go tests: use .Val() instead of .Result() when nil response is expected, since go-redis treats nil as redis.Nil error in .Result() - Fix missing-cmp_value error message check: actual error is 'ERR no more item to parse', not a syntax error
- Return WRONGTYPE when IFEQ/IFNE/IFDEQ/IFDNE is used on non-string keys - Treat NX with wrong type as "key exists" so the condition is not met - Keep other behaviors unchanged
7fdd1fe to
d0343e5
Compare
|
@jihuayu All CI checks pass locally now: Lint & Format:
C++ Unit Tests:
Go Integration Tests:
The WRONGTYPE handling fix is in the last commit. Ready for review. |
|
@kirito632 Could you please tell me your clang-format and clang-tidy versions? |
jihuayu
left a comment
There was a problem hiding this comment.
Thanks for you work! Looks good overall, just a few things to fix up:
- This PR is too large. We prefer one command per PR—please split this into 2–4 smaller PRs.
- Only add C++ tests if the Go tests can't cover the logic. Please double-check if these are necessary.
- Please add the following test cases for failure scenarios:
t.Run("DelEX IFDEQ and IFDNE reject invalid digest length", func(t *testing.T) {
key := "test-string-key-invalid-digest"
value := "Hello world"
require.NoError(t, rdb.Del(ctx, key).Err())
require.NoError(t, rdb.Set(ctx, key, value, 0).Err())
require.ErrorContains(t, rdb.Do(ctx, "DelEX", key, "ifdeq", "123456789012345").Err(),
"exactly 16 hexadecimal characters")
require.Equal(t, value, rdb.Get(ctx, key).Val())
require.ErrorContains(t, rdb.Do(ctx, "DelEX", key, "ifdne", "123456789012345").Err(),
"exactly 16 hexadecimal characters")
require.Equal(t, value, rdb.Get(ctx, key).Val())
})
t.Run("Extended SET GET and NX option on wrong type", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "listkey").Err())
require.NoError(t, rdb.LPush(ctx, "listkey", "v1").Err())
require.ErrorContains(t, rdb.Do(ctx, "SET", "listkey", "v", "NX", "GET").Err(), "WRONGTYPE")
})
|



What this PR does / why we need it
This PR implements the
IFEQ,IFNE,IFDEQ, andIFDNEoptions for theSETcommand, resolving #3311.IFEQ <value>: only set if key exists and current value equals<value>IFNE <value>: only set if key does not exist, or current value differs from<value>IFDEQ <digest>: only set if key exists and digest of current value equals<digest>IFDNE <digest>: only set if key does not exist, or digest of current value differs from<digest>Which issue(s) this PR fixes
Closes #3311
Test coverage
GETandTTLcombinationsTestSetConditionalcovering syntax errors,basic behavior, GET/EX combinations, and 10 property-based tests
AI assistance
AI tools were used for the initial implementation draft and test scaffolding.
Logic was reviewed manually against the Redis 8.x documentation and kvrocks
coding conventions.