Skip to content

Enable multiple prefixes per index#471

Merged
vishal-bala merged 3 commits intomainfrom
multiprefix/test
Feb 26, 2026
Merged

Enable multiple prefixes per index#471
vishal-bala merged 3 commits intomainfrom
multiprefix/test

Conversation

@rbs333
Copy link
Collaborator

@rbs333 rbs333 commented Feb 11, 2026

This PR let's you pass prefix as a list. It's not a recommend pattern but a blocker for a key customer. The main place this can cause issues in data loading.

Copilot AI review requested due to automatic review settings February 11, 2026 09:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces two major features to the redisvl library: SQL query support and multi-prefix index capability. The PR bumps the version from 0.13.2 to 0.14.0, reflecting the addition of significant new functionality.

Changes:

  • Adds SQLQuery class to translate SQL SELECT statements into Redis FT.SEARCH/FT.AGGREGATE commands via the sql-redis library
  • Implements multi-prefix index support allowing a single index to monitor multiple key prefixes
  • Adds comprehensive test coverage for both new features

Reviewed changes

Copilot reviewed 15 out of 17 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
pyproject.toml Version bump to 0.14.0, adds sql-redis optional dependency
uv.lock Updates lock file with sql-redis and sqlglot dependencies
redisvl/query/sql.py New SQLQuery class with parameter substitution and Redis command translation
redisvl/query/init.py Exports SQLQuery from the query module
redisvl/index/index.py Adds multi-prefix support and _sql_query method for executing SQL queries
tests/unit/test_sql_parameter_substitution.py Unit tests for SQL parameter substitution edge cases
tests/integration/test_sql_redis_json.py Integration tests for SQL queries against JSON storage
tests/integration/test_sql_redis_hash.py Integration tests for SQL queries against Hash storage
tests/integration/test_multi_prefix.py Integration tests verifying multi-prefix index functionality
examples/multi_prefix_example.py Example demonstrating multi-prefix index usage
docs/api/query.rst API documentation for SQLQuery
docs/user_guide/index.md Adds reference to new SQL query guide
docs/user_guide/01_getting_started.ipynb Updates prefix configuration example
docs/user_guide/02_hybrid_queries.ipynb Re-executed notebook with updated outputs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 9 to 13
import pytest

from redisvl.query.sql import SQLQuery


Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

Import of 'pytest' is not used.

Suggested change
import pytest
from redisvl.query.sql import SQLQuery
from redisvl.query.sql import SQLQuery

Copilot uses AI. Check for mistakes.
@tylerhutcherson
Copy link
Collaborator

@rbs333 Looks like this has leaked commits from the SQL work. Can you pare it back to the multi-prefix additions?

Copy link
Collaborator

@vishal-bala vishal-bala left a comment

Choose a reason for hiding this comment

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

No major comments from me aside a question about whether building the registry/executor for SQL translation is expensive. There are a few Copilot comments that I agreed should be addressed (left a 👍 on them) - aside from those, it generally looks good! Super nice to be able to have SQL queries translated 🙌

@jit-ci
Copy link

jit-ci bot commented Feb 23, 2026

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

Copilot AI review requested due to automatic review settings February 23, 2026 15:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings February 23, 2026 20:40
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

pyproject.toml:72

  • The all extra still pins sql-redis>=0.1.1 while the dedicated sql-redis extra was bumped to >=0.1.2. This makes pip install redisvl[all] potentially pull an older version than intended. Update the all extra to match (or intentionally justify why it should differ).
sql-redis = [
    "sql-redis>=0.1.2",
]
all = [
    "mistralai>=1.0.0",
    "openai>=1.1.0",
    "nltk>=3.8.1,<4",
    "cohere>=4.44",
    "voyageai>=0.2.2",
    "sentence-transformers>=3.4.0,<4",
    "langcache>=0.11.0",
    "google-cloud-aiplatform>=1.26,<2.0.0",
    "protobuf>=5.28.0,<6.0.0",
    "boto3>=1.36.0,<2",
    "urllib3<2.2.0",
    "pillow>=11.3.0",
    "sql-redis>=0.1.1",
]

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1 to +10
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Write SQL Queries for Redis\n",
"\n",
"While Redis does not natively support SQL, RedisVL provides a `SQLQuery` class that translates SQL-like queries into Redis queries.\n",
"\n",
"The `SQLQuery` class wraps the [`sql-redis`](https://pypi.org/project/sql-redis/) package. This package is not installed by default, so install it with:\n",
"\n",
"```bash\n",
"pip install redisvl[sql-redis]\n",
"```\n",
"\n",
"## Prerequisites\n",
"\n",
"Before you begin, ensure you have:\n",
"- Installed RedisVL with SQL support: `pip install redisvl[sql-redis]`\n",
"- A running Redis instance ([Redis 8+](https://redis.io/downloads/) or [Redis Cloud](https://redis.io/cloud))\n",
"\n",
"## What You'll Learn\n",
"\n",
"By the end of this guide, you will be able to:\n",
"- Write SQL-like queries for Redis using `SQLQuery`\n",
"- Translate SELECT, WHERE, and ORDER BY clauses to Redis queries\n",
"- Combine SQL queries with vector search\n",
"- Use aggregate functions and grouping"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create an index to search"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:01.542482Z",
"iopub.status.busy": "2026-02-16T15:20:01.542270Z",
"iopub.status.idle": "2026-02-16T15:20:19.311130Z",
"shell.execute_reply": "2026-02-16T15:20:19.310567Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/tyler.hutcherson/Documents/AppliedAI/redis-vl-python/.venv/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm\n"
]
}
],
"source": [
"from redisvl.utils.vectorize import HFTextVectorizer\n",
"\n",
"hf = HFTextVectorizer()\n",
"\n",
"schema = {\n",
" \"index\": {\n",
" \"name\": \"user_simple\",\n",
" \"prefix\": \"user_simple_docs\",\n",
" \"storage_type\": \"json\",\n",
" },\n",
" \"fields\": [\n",
" {\"name\": \"user\", \"type\": \"tag\"},\n",
" {\"name\": \"region\", \"type\": \"tag\"},\n",
" {\"name\": \"job\", \"type\": \"tag\"},\n",
" {\"name\": \"job_description\", \"type\": \"text\"},\n",
" {\"name\": \"age\", \"type\": \"numeric\"},\n",
" {\n",
" \"name\": \"job_embedding\",\n",
" \"type\": \"vector\",\n",
" \"attrs\": {\n",
" \"dims\": len(hf.embed(\"get embed length\")),\n",
" \"distance_metric\": \"cosine\",\n",
" \"algorithm\": \"flat\",\n",
" \"datatype\": \"float32\"\n",
" }\n",
" }\n",
" ]\n",
"}"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create sample dataset"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.312894Z",
"iopub.status.busy": "2026-02-16T15:20:19.312512Z",
"iopub.status.idle": "2026-02-16T15:20:19.621061Z",
"shell.execute_reply": "2026-02-16T15:20:19.620563Z"
}
},
"outputs": [],
"source": [
"data = [\n",
" {\n",
" 'user': 'john',\n",
" 'age': 34,\n",
" 'job': 'software engineer',\n",
" 'region': 'us-west',\n",
" 'job_description': 'Designs, develops, and maintains software applications and systems.'\n",
" },\n",
" {\n",
" 'user': 'bill',\n",
" 'age': 54,\n",
" 'job': 'engineer',\n",
" 'region': 'us-central',\n",
" 'job_description': 'Applies scientific and mathematical principles to solve technical problems.'\n",
" },\n",
" {\n",
" 'user': 'mary',\n",
" 'age': 24,\n",
" 'job': 'doctor',\n",
" 'region': 'us-central',\n",
" 'job_description': 'Diagnoses and treats illnesses, injuries, and other medical conditions in the healthcare field.'\n",
" },\n",
" {\n",
" 'user': 'joe',\n",
" 'age': 27,\n",
" 'job': 'dentist',\n",
" 'region': 'us-east',\n",
" 'job_description': 'Provides oral healthcare including diagnosing and treating teeth and gum issues.'\n",
" },\n",
" {\n",
" 'user': 'stacy',\n",
" 'age': 61,\n",
" 'job': 'project manager',\n",
" 'region': 'us-west',\n",
" 'job_description': 'Plans, organizes, and oversees projects from inception to completion.'\n",
" }\n",
"]\n",
"\n",
"data = [\n",
" { \n",
" **d,\n",
" \"job_embedding\": hf.embed(f\"{d['job_description']=} {d['job']=}\"),\n",
" } \n",
" for d in data\n",
"]"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create a `SearchIndex`\n",
"\n",
"With the schema and sample dataset ready, create a `SearchIndex`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Bring your own Redis connection instance\n",
"\n",
"This is ideal in scenarios where you have custom settings on the connection instance or if your application will share a connection pool:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.622451Z",
"iopub.status.busy": "2026-02-16T15:20:19.622366Z",
"iopub.status.idle": "2026-02-16T15:20:19.630721Z",
"shell.execute_reply": "2026-02-16T15:20:19.630403Z"
}
},
"outputs": [],
"source": [
"from redisvl.index import SearchIndex\n",
"from redis import Redis\n",
"\n",
"client = Redis.from_url(\"redis://localhost:6379\")\n",
"index = SearchIndex.from_dict(schema, redis_client=client, validate_on_load=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Let the index manage the connection instance\n",
"\n",
"This is ideal for simple cases:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.632020Z",
"iopub.status.busy": "2026-02-16T15:20:19.631934Z",
"iopub.status.idle": "2026-02-16T15:20:19.633821Z",
"shell.execute_reply": "2026-02-16T15:20:19.633429Z"
}
},
"outputs": [],
"source": [
"index = SearchIndex.from_dict(schema, redis_url=\"redis://localhost:6379\", validate_on_load=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create the index\n",
"\n",
"Now that we are connected to Redis, we need to run the create command."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.634818Z",
"iopub.status.busy": "2026-02-16T15:20:19.634741Z",
"iopub.status.idle": "2026-02-16T15:20:19.640648Z",
"shell.execute_reply": "2026-02-16T15:20:19.640244Z"
}
},
"outputs": [],
"source": [
"index.create(overwrite=True, drop=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load Data to `SearchIndex`\n",
"\n",
"Load the sample dataset to Redis.\n",
"\n",
"### Validate data entries on load\n",
"RedisVL uses pydantic validation under the hood to ensure loaded data is valid and confirms to your schema. This setting is optional and can be configured in the `SearchIndex` class."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.641629Z",
"iopub.status.busy": "2026-02-16T15:20:19.641563Z",
"iopub.status.idle": "2026-02-16T15:20:19.751366Z",
"shell.execute_reply": "2026-02-16T15:20:19.750887Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['user_simple_docs:01KHKJGG26AR3VW2RJA381R8YK', 'user_simple_docs:01KHKJGG2R8EZP6H15MG1V4E53', 'user_simple_docs:01KHKJGG369F5R0R51PW2HP8MV', 'user_simple_docs:01KHKJGG3MGVPAZ6XEQVEWXZFC', 'user_simple_docs:01KHKJGG44ZEKJVRQJ0EF72PV7']\n"
]
}
],
"source": [
"keys = index.load(data)\n",
"\n",
"print(keys)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create a `SQLQuery` Object\n",
"\n",
"First, let's test a simple select statement such as the one below."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.752548Z",
"iopub.status.busy": "2026-02-16T15:20:19.752471Z",
"iopub.status.idle": "2026-02-16T15:20:19.754355Z",
"shell.execute_reply": "2026-02-16T15:20:19.753935Z"
}
},
"outputs": [],
"source": [
"from redisvl.query import SQLQuery\n",
"\n",
"sql_str = \"\"\"\n",
" SELECT user, region, job, age\n",
" FROM user_simple\n",
" WHERE age > 17\n",
" \"\"\"\n",
"\n",
"sql_query = SQLQuery(sql_str) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Check the created query string"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:19.755445Z",
"iopub.status.busy": "2026-02-16T15:20:19.755366Z",
"iopub.status.idle": "2026-02-16T15:20:20.018643Z",
"shell.execute_reply": "2026-02-16T15:20:20.018223Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'FT.SEARCH user_simple \"@age:[(17 +inf]\" RETURN 4 user region job age'"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sql_query.redis_query_string(redis_url=\"redis://localhost:6379\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Executing the query"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:20.019728Z",
"iopub.status.busy": "2026-02-16T15:20:20.019644Z",
"iopub.status.idle": "2026-02-16T15:20:20.026215Z",
"shell.execute_reply": "2026-02-16T15:20:20.025841Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[{'user': 'john',\n",
" 'region': 'us-west',\n",
" 'job': 'software engineer',\n",
" 'age': '34'},\n",
" {'user': 'bill', 'region': 'us-central', 'job': 'engineer', 'age': '54'},\n",
" {'user': 'mary', 'region': 'us-central', 'job': 'doctor', 'age': '24'},\n",
" {'user': 'joe', 'region': 'us-east', 'job': 'dentist', 'age': '27'},\n",
" {'user': 'stacy', 'region': 'us-west', 'job': 'project manager', 'age': '61'}]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results = index.query(sql_query)\n",
"results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Additional query support\n",
"\n",
"### Conditional operators"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:20.027232Z",
"iopub.status.busy": "2026-02-16T15:20:20.027154Z",
"iopub.status.idle": "2026-02-16T15:20:20.036830Z",
"shell.execute_reply": "2026-02-16T15:20:20.036450Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Resulting redis query: FT.SEARCH user_simple \"@age:[(17 +inf] @region:{us\\-west}\" RETURN 4 user region job age\n"
]
},
{
"data": {
"text/plain": [
"[{'user': 'john',\n",
" 'region': 'us-west',\n",
" 'job': 'software engineer',\n",
" 'age': '34'},\n",
" {'user': 'stacy', 'region': 'us-west', 'job': 'project manager', 'age': '61'}]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sql_str = \"\"\"\n",
" SELECT user, region, job, age\n",
" FROM user_simple\n",
" WHERE age > 17 and region = 'us-west'\n",
"\"\"\"\n",
"\n",
"sql_query = SQLQuery(sql_str)\n",
"redis_query = sql_query.redis_query_string(redis_url=\"redis://localhost:6379\")\n",
"print(\"Resulting redis query: \", redis_query)\n",
"results = index.query(sql_query)\n",
"results"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:20.037744Z",
"iopub.status.busy": "2026-02-16T15:20:20.037670Z",
"iopub.status.idle": "2026-02-16T15:20:20.047532Z",
"shell.execute_reply": "2026-02-16T15:20:20.047144Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Resulting redis query: FT.SEARCH user_simple \"((@region:{us\\-west})|(@region:{us\\-central}))\" RETURN 4 user region job age\n"
]
},
{
"data": {
"text/plain": [
"[{'user': 'john',\n",
" 'region': 'us-west',\n",
" 'job': 'software engineer',\n",
" 'age': '34'},\n",
" {'user': 'bill', 'region': 'us-central', 'job': 'engineer', 'age': '54'},\n",
" {'user': 'stacy', 'region': 'us-west', 'job': 'project manager', 'age': '61'},\n",
" {'user': 'mary', 'region': 'us-central', 'job': 'doctor', 'age': '24'}]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sql_str = \"\"\"\n",
" SELECT user, region, job, age\n",
" FROM user_simple\n",
" WHERE region = 'us-west' or region = 'us-central'\n",
" \"\"\"\n",
"\n",
"sql_query = SQLQuery(sql_str)\n",
"redis_query = sql_query.redis_query_string(redis_url=\"redis://localhost:6379\")\n",
"print(\"Resulting redis query: \", redis_query)\n",
"results = index.query(sql_query)\n",
"results"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:20.048481Z",
"iopub.status.busy": "2026-02-16T15:20:20.048419Z",
"iopub.status.idle": "2026-02-16T15:20:20.057250Z",
"shell.execute_reply": "2026-02-16T15:20:20.056891Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Resulting redis query: FT.SEARCH user_simple \"@job:{software engineer|engineer|pancake tester}\" RETURN 4 user region job age\n"
]
},
{
"data": {
"text/plain": [
"[{'user': 'john',\n",
" 'region': 'us-west',\n",
" 'job': 'software engineer',\n",
" 'age': '34'},\n",
" {'user': 'bill', 'region': 'us-central', 'job': 'engineer', 'age': '54'}]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# job is a tag field therefore this syntax works\n",
"sql_str = \"\"\"\n",
" SELECT user, region, job, age\n",
" FROM user_simple\n",
" WHERE job IN ('software engineer', 'engineer', 'pancake tester')\n",
" \"\"\"\n",
"\n",
"sql_query = SQLQuery(sql_str)\n",
"redis_query = sql_query.redis_query_string(redis_url=\"redis://localhost:6379\")\n",
"print(\"Resulting redis query: \", redis_query)\n",
"results = index.query(sql_query)\n",
"results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Text based searches\n",
"\n",
"See [the docs](https://redis.io/docs/latest/develop/ai/search-and-query/query/full-text/) for available text queries in Redis.\n",
"\n",
"For more on exact matching see [here](https://redis.io/docs/latest/develop/ai/search-and-query/query/exact-match/)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"execution": {
"iopub.execute_input": "2026-02-16T15:20:20.058215Z",
"iopub.status.busy": "2026-02-16T15:20:20.058144Z",
"iopub.status.idle": "2026-02-16T15:20:20.067897Z",
"shell.execute_reply": "2026-02-16T15:20:20.067471Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Resulting redis query: FT.SEARCH user_simple \"@job_description:sci*\" RETURN 5 user region job job_description age\n"
]
},
{
"data": {
"text/plain": [
"[{'user': 'bill',\n",
" 'region': 'us-central',\n",
" 'job': 'engineer',\n",
" 'job_description': 'Applies scientific and mathematical principles to solve technical problems.',\n",
" 'age': '54'}]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Write SQL Queries for Redis\n",
"\n",
"While Redis does not natively support SQL, RedisVL provides a `SQLQuery` class that translates SQL-like queries into Redis queries.\n",
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

This notebook was re-serialized with different JSON indentation/formatting, causing an enormous diff that’s hard to review and makes future git blame noisy. Other notebooks in docs/user_guide/ use a consistent 2-space JSON style; consider re-saving with the repo’s standard notebook serialization (or reverting this reformat-only change) so the PR stays focused on the multi-prefix feature.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 25, 2026 13:24
@rbs333 rbs333 marked this pull request as ready for review February 25, 2026 13:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@vishal-bala vishal-bala left a comment

Choose a reason for hiding this comment

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

LGTM!

return prefix[0] if isinstance(prefix, list) else prefix

@property
def prefixes(self) -> List[str]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a need for any extra validation here (e.g. if a prefix happens to be an empty string, etc.), or is that better left to raise an error somewhere else?

"sql_str = \"\"\"\n",
" SELECT user, region, job, age\n",
" FROM user_simple\n",
" WHERE job IN ('software engineer', 'engineer', 'pancake tester')\n",
Copy link
Collaborator

Choose a reason for hiding this comment

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

A comment highlighting that there's a syntactic difference in the Redis translation of region = 'a' OR region = 'b' and region IN ('a', 'b') could be worthwhile (but not critical).

@vishal-bala vishal-bala added auto:minor Increment the minor version when merged auto:dependencies Update one or more dependencies version labels Feb 26, 2026
@tylerhutcherson tylerhutcherson changed the title Multiprefix/test Enable multiple prefixes per index Feb 26, 2026
@vishal-bala vishal-bala merged commit 9f3319e into main Feb 26, 2026
55 checks passed
@vishal-bala vishal-bala removed the auto:dependencies Update one or more dependencies version label Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto:minor Increment the minor version when merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants