-
Notifications
You must be signed in to change notification settings - Fork 23.9k
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
Improve GETRANGE command behavior #12272
Conversation
I think i don't like |
It use to solve a problem about
If we use sentence like follow, I think it may ambiguous, so use empty
Maybe there is another way to solve it, please give any ideas. |
1. Change the end inclusive to exclusive. 2. If it exceeds the valid index range, the valid index range will be extended to all integers, and elements smaller than or larger than the valid range will be considered empty elements. 3. The end can be empty, that means the default end will take max length of key.
1. Change the end inclusive to exclusive. 2. If it exceeds the valid index range, the valid index range will be extended to all integers, and elements smaller than or larger than the valid range will be considered empty elements. 3. The end can be empty, that means the default end will take max length of key.
IMHO, I'm not a fan of 1 and 3. As mentioned in this comment: #11738 (comment) diff --git a/src/t_string.c b/src/t_string.c
index 2bce3acc..2ef6e339 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -527,8 +527,11 @@ void getrangeCommand(client *c) {
}
if (start < 0) start = strlen+start;
if (end < 0) end = strlen+end;
+ if (end < 0) {
+ addReply(c,shared.emptybulk);
+ return;
+ }
if (start < 0) start = 0;
- if (end < 0) end = 0;
if ((unsigned long long)end >= strlen) end = strlen-1; |
Yes, your idea is more simple. Let me make a quick change. |
Outright changing the meaning of a parameter (1) is a complete no-go. That's a hard break. If there is a valid reason, a valid suggestion might be to allow a syntax to optionally change it, i.e. like the |
Change the end to non-inclusive.
@linzihao1999 I think you misunderstood non-inclusive, what I meant was that it shouldn't be set to Another thought: diff --git a/src/t_string.c b/src/t_string.c
index 2bce3acc8..8b887a8e9 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -520,20 +520,14 @@ void getrangeCommand(client *c) {
strlen = sdslen(str);
}
- /* Convert negative indexes */
- if (start < 0 && end < 0 && start > end) {
- addReply(c,shared.emptybulk);
- return;
- }
if (start < 0) start = strlen+start;
if (end < 0) end = strlen+end;
if (start < 0) start = 0;
- if (end < 0) end = 0;
if ((unsigned long long)end >= strlen) end = strlen-1;
/* Precondition: end >= 0 && end < strlen, so the only condition where
* nothing can be returned is: start > end. */
- if (start > end || strlen == 0) {
+ if ((unsigned long long)start >= strlen || end < 0 || start > end || strlen == 0) {
addReply(c,shared.emptybulk);
} else {
addReplyBulkCBuffer(c,(char*)str+start,end-start+1); |
@sundb Thanks for patient guidance! |
@linzihao1999 please also update the top comment with a brief description of break changes. |
Hi @sundb top comment updated |
@linzihao1999 thanks. i think it was me that suggested that all the headache with this command comes from the fact in any case, we can't completely change the meaning of the command arguments, if we wanna do that we need to deprecate the old command and invent a new one. looking at the recent revision in the code, i understand that you didn't change the meaning of the arguments, and the behavior change here is minimal. i.e. it'll only change behavior when the user used a very specific unlikely scenario when both start and end are <=0 and end >= start. i also see the top comment still mention something about changing start and end to non-inclusive. is that a relic from a previous revision? it's confusing... |
we discussed this in a core-team meeting, we do agree it is worth fixing. (as a breaking change to be released in 8.0). @linzihao1999 please ack on my previous message and see if you can make the top comment clearer. |
@oranagra the comment has been updated. |
is the behavior change only when |
all the changes were made for it and judge if it was out of range before set |
Fixed the issue about GETRANGE and SUBSTR command return unexpected result caused by the `start` and `end` out of definition range of string. --- ## break change Before this PR, when negative `end` was out of range (i.e., end < -strlen), we would fix it to 0 to get the substring, which also resulted in the first character still being returned for this kind of out of range. After this PR, we ensure that `GETRANGE` returns an empty bulk when the negative end index is out of range. Closes redis#11738 --------- Co-authored-by: debing.sun <[email protected]>
### New Features in binary distributions - 7 new data structures: JSON, Time series, Bloom filter, Cuckoo filter, Count-min sketch, Top-k, t-digest - Redis scalable query engine (including vector search) ### Potentially breaking changes - #12272 `GETRANGE` returns an empty bulk when the negative end index is out of range - #12395 Optimize `SCAN` command when matching data type ### Bug fixes - #13510 Fix `RM_RdbLoad` to enable AOF after RDB loading is completed - #13489 `ACL CAT` - return module commands - #13476 Fix a race condition in the `cache_memory` of `functionsLibCtx` - #13473 Fix incorrect lag due to trimming stream via `XTRIM` command - #13338 Fix incorrect lag field in `XINFO` when tombstone is after the `last_id` of the consume group - #13470 On `HDEL` of last field - update the global hash field expiration data structure - #13465 Cluster: Pass extensions to node if extension processing is handled by it - #13443 Cluster: Ensure validity of myself when loading cluster config - #13422 Cluster: Fix `CLUSTER SHARDS` command returns empty array ### Modules API - #13509 New API calls: `RM_DefragAllocRaw`, `RM_DefragFreeRaw`, and `RM_RegisterDefragCallbacks` - defrag API to allocate and free raw memory ### Performance and resource utilization improvements - #13503 Avoid overhead of comparison function pointer calls in listpack `lpFind` - #13505 Optimize `STRING` datatype write commands - #13499 Optimize `SMEMBERS` command - #13494 Optimize `GEO*` commands reply - #13490 Optimize `HELLO` command - #13488 Optimize client query buffer - #12395 Optimize `SCAN` command when matching data type - #13529 Optimize `LREM`, `LPOS`, `LINSERT`, and `LINDEX` commands - #13516 Optimize `LRANGE` and other commands that perform several writes to client buffers per call - #13431 Avoid `used_memory` contention when updating from multiple threads ### Other general improvements - #13495 Reply `-LOADING` on replica while flushing the db ### CLI tools - #13411 redis-cli: Fix wrong `dbnum` showed after the client reconnected ### Notes - No backward compatibility for replication or persistence. - Additional distributions, upgrade paths, features, and improvements will be introduced in upcoming pre-releases. - With the GA release of 8.0 we will deprecate Redis Stack.
Although the commit #6ceadfb58 improves GETRANGE command behavior, we can't accept it as we should avoid a breaking change for non-critical bug fixes. This reverts commit 6ceadfb.
Although the commit #6ceadfb58 improves GETRANGE command behavior, we can't accept it as we should avoid breaking changes for non-critical bug fixes. This reverts commit 6ceadfb.
Although the commit #6ceadfb58 improves GETRANGE command behavior, we can't accept it as we should avoid breaking changes for non-critical bug fixes. This reverts commit 6ceadfb.
Notice: this change was reverted in 0aeb86d
we concluded we can't accept it as we should avoid breaking changes for non-critical bug fixes.
Improve GETRANGE command behavior
A breaking change. Fixed the issue about GETRANGE and SUBSTR command return unexpected result caused by the
start
andend
out of definition range of string.break change
Before this PR, when negative
end
was out of range (i.e., end < -strlen), we would fix it to 0 to get the substring, which also resulted in the first character still being returned for this kind of out of range.After this PR, we ensure that
GETRANGE
returns an empty bulk when the negative end index is out of range.Closes #11738
After change (all return empty string)
Before