Skip to content

[vector sets] VRANGE implementation#14235

Merged
sundb merged 8 commits into
redis:unstablefrom
antirez:vrange
Oct 9, 2025
Merged

[vector sets] VRANGE implementation#14235
sundb merged 8 commits into
redis:unstablefrom
antirez:vrange

Conversation

@antirez

@antirez antirez commented Jul 30, 2025

Copy link
Copy Markdown
Contributor

This is basically the Vector Set iteration primitive.
It exploits the underlying radix tree implementation.
The usage pattern is strongly reminiscent of other Redis commands doing similar things.

The command usage is straightforward:

> VRANGE word_embeddings_int8 [Redis + 10
 1) "Redis"
 2) "Rediscover"
 3) "Rediscover_Ashland"
 4) "Rediscover_Northern_Ireland"
 5) "Rediscovered"
 6) "Rediscovered_Bookshop"
 7) "Rediscovering"
 8) "Rediscovering_God"
 9) "Rediscovering_Lost"
10) "Rediscovers"

The above command returns 10 (or less, if less are available in the specified range) elements from "Redis" (inclusive) to the maximum possible element. The comparison is performed byte by byte, as memcmp() would do, in this way the elements have a total order. The start and end range can be either a string, prefixed
by [ or ( (the prefix is mandatory) to tell the command if the range is inclusive or exclusive, or can be the special symbols - and + that means the maximum and minimum element.

More info can be found in the implementation itself and in the README file change.

@snyk-io

snyk-io Bot commented Jul 30, 2025

Copy link
Copy Markdown

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

@kaplanben

Copy link
Copy Markdown

Logo
Checkmarx One – Scan Summary & Details5b97af55-1d4d-430e-998b-28633b25d8a5

New Issues (7)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3676
detailsThe buffer buf created in /src/redis-cli.c at line 3676 is written to a buffer in /deps/hiredis/sds.c at line 234 by newsh, but an error in calc...
ID: MB1M%2FHPv8FdnbXxmZA9TAV1%2BzTs%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3676
detailsThe buffer buf created in /src/redis-cli.c at line 3676 is written to a buffer in /deps/hiredis/sds.c at line 234 by hdrlen, but an error in cal...
ID: MqnP7QsVuVyOykiPzdkQCxsw7H4%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /deps/linenoise/linenoise.c: 1200
detailsThe buffer buf created in /deps/linenoise/linenoise.c at line 1200 is written to a buffer in /deps/hiredis/sds.c at line 97 by sh, but an error i...
ID: L1dS1AWIau3DXfxVZMTussbT9bE%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 10588
detailsThe buffer argv created in /src/redis-cli.c at line 10588 is written to a buffer in /deps/hiredis/sds.c at line 97 by sh, but an error in calcul...
ID: vC%2FFYG%2FXR4U4ciJLaAPiJS9TD80%3D
Attack Vector
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /deps/linenoise/linenoise.c: 1166
detailsThe buffer fgetc created in /deps/linenoise/linenoise.c at line 1166 is written to a buffer in /deps/hiredis/sds.c at line 97 by sh, but an error...
ID: GntXTIkoxcin9A6wr5%2FfrOjRD7o%3D
Attack Vector
MEDIUM Divide_By_Zero /deps/fpconv/fpconv_dtoa.c: 183
detailsThe application performs an illegal operation in generate_digits, in /deps/fpconv/fpconv_dtoa.c. In line 183, the program attempts to divide by...
ID: f6%2Fo%2FUFMnQCQOzVpdP%2Bi6jAlAds%3D
Attack Vector
MEDIUM Divide_By_Zero /src/redis-cli.c: 6037
detailsThe application performs an illegal operation in clusterManagerNodeMasterRandom, in /src/redis-cli.c. In line 6050, the program attempts to divi...
ID: Ez8UONVHfwHV2ShayzJB8j%2B6jPI%3D
Attack Vector
Fixed Issues (4)

Great job! The following issues were fixed in this Pull Request

Severity Issue Source File / Package
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677
CRITICAL Buffer_Overflow_Wrong_Buffer_Size /src/redis-cli.c: 3677

@GuyAv46 GuyAv46 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Are tests not running on CI? Coverage is 0
  2. Are we set on VRANGE as the command name? IMO it's confusing with vector range queries. Maybe VLEXRANGE?

Comment thread modules/vector-sets/vset.c Outdated
Comment on lines +1876 to +1877
void *data;
while ((key_data = RedisModule_DictNextC(iter, &key_len, &data)) != NULL) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not using data, and it's an optional parameter of the API. Consider removing

Suggested change
void *data;
while ((key_data = RedisModule_DictNextC(iter, &key_len, &data)) != NULL) {
while ((key_data = RedisModule_DictNextC(iter, &key_len, NULL)) != NULL) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment thread modules/vector-sets/tests/vrange.py Outdated
result = self.redis.execute_command('VRANGE', self.test_key, '(apple', '[cherry', '10')
result = [r.decode() for r in result]
assert 'apple' not in result, "Exclusive boundary should not include 'apple'"
assert 'apricot' in result and 'banana' in result and 'cherry' in result, "Should include elements after apple up to cherry"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider asserting the full reply

Comment thread modules/vector-sets/tests/vrange.py Outdated
result = self.redis.execute_command('VRANGE', self.test_key, '[banana', '(cherry', '10')
result = [r.decode() for r in result]
assert 'banana' in result, "Should include banana"
assert 'cherry' not in result, "Exclusive end should not include cherry"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider asserting the full reply.
The same comment applies to the cases listed below.

Comment thread modules/vector-sets/tests/vrange.py Outdated

# Test 8: Count of 0 returns empty array
result = self.redis.execute_command('VRANGE', self.test_key, '-', '+', '0')
assert len(result) == 0, "Count of 0 should return empty array"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider asserting the returned value, and not its size. If something breaks, we won't know what we have got.

Suggested change
assert len(result) == 0, "Count of 0 should return empty array"
assert result == [], "Count of 0 should return empty array"

Same comment for the other cases below

@sundb sundb removed this from Redis 8.2 Aug 19, 2025
@sundb sundb added this to Redis 8.4 Aug 19, 2025
@antirez

antirez commented Sep 9, 2025

Copy link
Copy Markdown
Contributor Author

Thank you @GuyAv46 I improved the PR with your suggestions.

@GuyAv46 GuyAv46 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the plan for vector range queries? My only question is whether VRANGE should be kept for that command, and we should call this new command VLEXRANGE or another name indicating lexicographic ranges and not of embedding distances

@antirez

antirez commented Sep 18, 2025

Copy link
Copy Markdown
Contributor Author

@GuyAv46 thank you for the question. No problem for range queries: there is no plan for fetching ranges from vectors, as any total order of vectors in a high dimensional space is basically meaningless, more or less, and the "range" that is useful is basically VSIM: the subset of vectors near something. So it is worth to simplify naming for the range of vector sets. In the past, the names of certain Redis commands were probably a bit too fancy, but at least for a good reason. Here there are no such concerns.

@antirez

antirez commented Sep 18, 2025

Copy link
Copy Markdown
Contributor Author

I'm rebasing the changes so that the PR applies again cleanly.

@antirez

antirez commented Sep 18, 2025

Copy link
Copy Markdown
Contributor Author

Rebased and force-pushed.

Comment thread modules/vector-sets/commands.json Outdated
"summary": "Return elements in a lexicographical range",
"complexity": "O(log(K)+M) where K is the number of elements in the start prefix, and M is the number of elements returned. In practical terms, the command is just O(M)",
"group": "vector_set",
"since": "8.3.0",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the next version be 8.4?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, fixing, thanks.

Comment thread modules/vector-sets/vset.c Outdated
@sundb sundb merged commit 3de2fda into redis:unstable Oct 9, 2025
22 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Redis 8.4 Oct 9, 2025
@sundb sundb added the release-notes indication that this issue needs to be mentioned in the release notes label Oct 9, 2025
sundb added a commit that referenced this pull request Oct 10, 2025
In #14235 we forgot to skip vset
module command `VRANGE` for schema validator.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes indication that this issue needs to be mentioned in the release notes

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants