-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Added support for GET option in SET command #322
Conversation
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.
Thanks for the changes @yaten2302, have left a few comments.
core/eval.go
Outdated
} else { | ||
return RespNIL | ||
} |
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.
You still need to Put() the key even if it did not previously exist when using the GET option.
core/eval.go
Outdated
@@ -193,6 +197,23 @@ func evalSET(args []string) []byte { | |||
} | |||
case constants.KEEPTTL, constants.Keepttl: | |||
keepttl = true | |||
case "GET": | |||
// Get the key from the hash table | |||
obj := Get(key) |
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.
An error is returned and SET aborted if the value stored at key is not a string.
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.
@JyotinderSingh , I've a doubt, that by default dice stores everything as a string only, right? Then why this error is being shown?
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.
The behavior should be correct from the implementation perspective. So we should do the check on our side.
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.
Oh! Okay 👍
BTW @JyotinderSingh , I wanted to ask that could you please provide a sample test case like when the test is failing? like I've a doubt that how can I set the value to int or something else (anything other than string)?
If possible, may I give it a try please, which is causing this problem! (like if the value is not string and then it's creating a problem). Like, if anyone else is already working on it, then I can collaborate with them 🙏 ?
tests/set_test.go
Outdated
@@ -113,6 +113,11 @@ func TestSetWithOptions(t *testing.T) { | |||
commands: []string{"SET k v XX EX 1", "GET k", "SLEEP 2", "GET k", "SET k v XX EX 1", "GET k"}, | |||
expected: []interface{}{"(nil)", "(nil)", "OK", "(nil)", "(nil)", "(nil)"}, | |||
}, | |||
{ |
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.
Add test cases for the following:
- Validate that SET succeeds with GET option even if the key does not exist.
- Validate error is returned when using SET with GET option if the previously stored value was not a string.
- Validate previous value is returned when using SET with the GET option.
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.
Sure, I'll add these test cases 👍
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.
@JyotinderSingh , actually, I've some doubts:
-
like for the 1st one, in redis it's given that if the key doesn't exists, then it should return
(nil)
?
-
Also, could you please guide that how can I validate that if the previous values was a string or not? Because dice stores everything as string, am I right? Like
2
will be stored as"2"
? -
I've got the 3rd point. I'll add that 👍
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.
- Even though it returns nil, the key is still set in the background. You return nil since there was no existing value, however, the new value will still be set.
- Add the validation regardless.
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.
I remember there were few comments had posted on last PR for the same issue, can you please mention if they've been fixed?
Linter is still failing :( will look into it. |
@lucifercr07 , yes, I've made all the changes in the PR which were suggested previously, but I haven't made this change, because the tests were failing if I remove the else block. |
Can you detail on why it's failing? Any reasons |
Sure @lucifercr07 , here is the error on removing the |
We need to remove the
|
@lucifercr07 , @JyotinderSingh , I've pushed some changes. could you please review those 👍 |
Lint checks are passing now since you merged with master. |
core/eval.go
Outdated
@@ -193,6 +197,23 @@ func evalSET(args []string) []byte { | |||
} | |||
case constants.KEEPTTL, constants.Keepttl: | |||
keepttl = true | |||
case "GET": | |||
// Get the key from the hash table | |||
obj := Get(key) |
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.
The behavior should be correct from the implementation perspective. So we should do the check on our side.
tests/set_test.go
Outdated
@@ -113,6 +113,11 @@ func TestSetWithOptions(t *testing.T) { | |||
commands: []string{"SET k v XX EX 1", "GET k", "SLEEP 2", "GET k", "SET k v XX EX 1", "GET k"}, | |||
expected: []interface{}{"(nil)", "(nil)", "OK", "(nil)", "(nil)", "(nil)"}, | |||
}, | |||
{ |
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.
- Even though it returns nil, the key is still set in the background. You return nil since there was no existing value, however, the new value will still be set.
- Add the validation regardless.
core/eval.go
Outdated
} else if nxOption { | ||
//store.Put(key, store.NewObj(value, exDurationMs, oType, oEnc)) | ||
if obj == nil { | ||
return Encode(obj.Value, false) |
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.
Shouldn't this return RespNIL?
If key k
doesn't exit and you fire SET k v NX GET
the result will be (nil)
.
redis> SET k v NX GET
(nil)
Also, add a test for this once fixed.
core/eval.go
Outdated
return Encode(obj.Value, false) | ||
} | ||
|
||
return RespNIL |
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.
If the object is not nil, you should return obj.Value
.
redis> SET k v1
"OK"
redis> SET k v2 NX GET
"v1"
Please rebase the PR, we just had a large change go in which might've introduced conflicts. |
@yaten2302 can you rebase this? we would like to close this as soon as possible. Do you need any help? |
Fixes #207