Feature/date support#12
Conversation
There was a problem hiding this comment.
Pull request overview
Adds DATE/DATETIME support to sql-redis by parsing ISO 8601 date literals into Unix timestamps and translating SQL date-part/format functions into RediSearch FT.AGGREGATE APPLY + FILTER expressions.
Changes:
- Parse ISO 8601 date/datetime literals in
WHERE(includingBETWEEN) and convert them to Unix timestamps. - Parse date-part and formatting functions (e.g.,
YEAR(),MONTH(),DATE_FORMAT()) and translate them into RediSearchAPPLY(andFILTERwhen used inWHERE). - Add analyzer support for date-function field resolution / GROUP BY alias handling, plus new tests and README documentation.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Bumps lockfile revision and package version to reflect the new feature release. |
sql_redis/parser.py |
Adds ISO 8601 literal detection + parsing, plus date-function parsing into ParsedQuery.date_functions and date-function operators in conditions. |
sql_redis/translator.py |
Adds FT.AGGREGATE generation for date functions and date-function WHERE conditions via APPLY + FILTER. |
sql_redis/analyzer.py |
Incorporates date functions into field reference analysis and treats computed/date aliases as valid GROUP BY targets. |
tests/test_date_fields.py |
New tests validating date literal parsing and translation to numeric range queries. |
tests/test_date_functions.py |
New tests validating date function parsing and translation to APPLY/FILTER/GROUPBY. |
README.md |
Documents date literal handling, supported formats, and date functions mapping. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Adds DATE/DATETIME support to sql-redis by parsing ISO-8601 literals into Unix timestamps and translating SQL date functions into RediSearch FT.AGGREGATE APPLY/FILTER expressions.
Changes:
- Extend the parser/analyzer/translator pipeline to support date literals and date-part/formatting functions (
YEAR,MONTH,DAY,DATE_FORMAT, etc.). - Add new test suites for date literal parsing and date function translation, plus small test cleanups.
- Document date behavior in README and bump the package version in the lockfile.
Reviewed changes
Copilot reviewed 12 out of 14 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
sql_redis/parser.py |
Adds ISO-8601 detection + timestamp conversion and parses date functions into a new date_functions structure. |
sql_redis/analyzer.py |
Tracks date functions and handles GROUP BY aliases for computed/date fields. |
sql_redis/translator.py |
Emits FT.AGGREGATE with APPLY/FILTER for date functions and routes date-function WHERE clauses to FILTER. |
tests/test_date_fields.py |
New tests for date literal parsing and numeric filter translation. |
tests/test_date_functions.py |
New tests for date function parsing and translation (APPLY/FILTER/GROUP BY shape). |
README.md |
Adds DATE/DATETIME usage + function mapping documentation. |
tests/test_translator.py |
Updates GROUPBY assertion to expect @category. |
tests/test_sql_queries.py |
Minor assertion formatting changes. |
tests/test_sql_parser.py |
Removes a test for SELECT without FROM. |
tests/test_redis_queries.py |
Minor assertion formatting + removes unused import. |
tests/test_executor.py |
Removes unused import. |
tests/test_analyzer.py |
Removes unused import. |
tests/conftest.py |
Formatting-only changes in key strings. |
uv.lock |
Bumps editable package version to 0.2.0. |
.ipynb_checkpoints/geo_examples_consolidated-checkpoint.ipynb |
Adds a Jupyter checkpoint artifact (likely unintended). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Adds DATE/DATETIME capabilities to sql-redis, enabling ISO-8601 date literals in WHERE clauses and date-part extraction/formatting via SQL functions that translate to RediSearch FT.AGGREGATE (APPLY/FILTER) expressions.
Changes:
- Parse ISO-8601 date/datetime literals and (currently) convert them to Unix timestamps during parsing.
- Add support for date functions (e.g.,
YEAR,MONTH,DATE_FORMAT) in SELECT and WHERE, translating to RedisAPPLYandFILTER. - Extend analyzer + add new tests and README documentation for date support.
Reviewed changes
Copilot reviewed 12 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
sql_redis/parser.py |
Adds date literal detection + date function parsing into ParsedQuery. |
sql_redis/analyzer.py |
Tracks date functions and improves GROUP BY alias handling. |
sql_redis/translator.py |
Generates FT.AGGREGATE pipelines for date functions + date-function WHERE filtering. |
tests/test_date_fields.py |
New tests for ISO-8601 literal conversion + numeric range translation. |
tests/test_date_functions.py |
New tests for parsing/translating date functions in SELECT/WHERE/GROUP BY. |
tests/test_translator.py |
Updates GROUP BY expectation to use @field syntax. |
tests/test_sql_parser.py |
Removes/adjusts parser test coverage around FROM-less SELECT. |
tests/test_redis_queries.py |
Minor import cleanup. |
tests/test_executor.py |
Import cleanup. |
tests/test_analyzer.py |
Import cleanup. |
tests/conftest.py |
Minor formatting cleanup in f-strings. |
README.md |
Adds DATE/DATETIME docs + supported function mapping/limitations. |
uv.lock |
Bumps project version to 0.2.0 (lock revision update). |
.gitignore |
Adds nitin_docs/ ignore entry. |
.ipynb_checkpoints/geo_examples_consolidated-checkpoint.ipynb |
Adds a notebook checkpoint artifact (likely unintended). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
5c3d942 to
5af9148
Compare
There was a problem hiding this comment.
Pull request overview
Adds DATE/DATETIME capabilities to sql-redis, including ISO-8601 date literal conversion in WHERE clauses and support for date-part extraction/formatting functions that translate to RediSearch FT.AGGREGATE APPLY/FILTER.
Changes:
- Add ISO-8601 DATE/DATETIME literal detection and conversion to Unix timestamps during parsing.
- Add parsing/analysis/translation support for date functions (e.g.,
YEAR,MONTH,DATE_FORMAT) usingFT.AGGREGATEAPPLYandFILTER. - Add new test suites for date literals and date functions, plus documentation updates in
README.md.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
sql_redis/parser.py |
Adds date literal parsing + date function parsing; updates function-name handling in SELECT/WHERE. |
sql_redis/analyzer.py |
Tracks date functions and adjusts field resolution/alias handling for GROUP BY. |
sql_redis/translator.py |
Switches to FT.AGGREGATE for date functions/conditions; generates APPLY and FILTER for date functions. |
tests/test_date_fields.py |
New integration-style tests for date literal parsing + translation to numeric ranges. |
tests/test_date_functions.py |
New tests for date functions parsing + translation (APPLY, FILTER, GROUP BY). |
README.md |
Documents supported date literals/functions and limitations. |
tests/test_sql_queries.py |
Minor assertion formatting. |
tests/test_redis_queries.py |
Minor assertion formatting. |
.gitignore |
Adds (duplicated) Jupyter checkpoint ignore entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Adds DATE/DATETIME support to sql-redis, enabling ISO 8601 date literal filtering (translated to Unix timestamps) and date-part extraction/formatting via Redis FT.AGGREGATE APPLY + FILTER.
Changes:
- Parse ISO 8601 date/datetime literals and translate them into NUMERIC timestamp filters when the schema field type is
NUMERIC. - Add parsing/analyzing/translating for date functions (
YEAR,MONTH,DAY,DAYOFWEEK,DAYOFYEAR,HOUR,MINUTE,DATE_FORMAT) usingAPPLYandFILTER. - Add integration tests and update README documentation for date usage and limitations.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
sql_redis/parser.py |
Adds ISO 8601 detection/parsing helpers, date-function specs, and parsing support for date functions in SELECT/WHERE. |
sql_redis/analyzer.py |
Tracks date function source fields and handles GROUP BY aliases for computed/date fields. |
sql_redis/translator.py |
Converts date literals for NUMERIC fields; emits APPLY/FILTER for date functions and rejects OR with date-function predicates. |
tests/test_date_fields.py |
Adds tests for preserving date literals in parsing and timestamp conversion during translation for NUMERIC fields. |
tests/test_date_functions.py |
Adds tests for date-function parsing and FT.AGGREGATE translation behavior (APPLY, FILTER, GROUPBY). |
README.md |
Documents new date literal behavior, date functions, and limitations. |
.gitignore |
Minor change (duplicate entry added). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| # Handle tuple values (e.g., BETWEEN) - try date conversion for each | ||
| low, high = condition.value | ||
| low_val = self._convert_to_numeric(low) | ||
| high_val = self._convert_to_numeric(high) |
|
|
||
| - `NOT YEAR(field) = 2024` is not supported (raises `ValueError`) | ||
| - `DATE_FORMAT()` is only supported in SELECT, not in WHERE (raises `ValueError`) | ||
| - Date functions with `OR` require careful handling |
| if date_func.function == "DATE_FORMAT" and date_func.format_string: | ||
| # DATE_FORMAT(field, format) -> timefmt(@field, format) | ||
| expression = ( | ||
| f'{redis_func}(@{date_func.field}, "{date_func.format_string}")' | ||
| ) |
| # Quote string values for FILTER | ||
| return f'"{value}"' |
- Parse DATE/DATETIME literals in WHERE clauses (ISO 8601 format) - Add date functions: YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), DAYOFWEEK(), DAYOFYEAR() - Add DATE_FORMAT() for custom formatting via Redis timefmt() - Translate to FT.AGGREGATE with APPLY/FILTER clauses - Defer date-to-timestamp conversion to translator (field-type aware) - Escape special characters in format strings and filter values - Validate: reject OR/NOT with date functions, require literal format in DATE_FORMAT
- Test date literal parsing and preservation - Test datetime with various formats (T separator, space, Z suffix, timezones) - Test BETWEEN with date ranges - Test date function extraction (YEAR, MONTH, DAY, etc.) - Test DATE_FORMAT translation to timefmt() - Test date function conditions in WHERE clauses - Test validation errors for OR/NOT with date functions
- Document date function syntax and examples - Document DATE_FORMAT with Redis timefmt() mapping - Add limitations section for date functions - Add .ipynb_checkpoints to gitignore
1a47f93 to
5025eb5
Compare
Add DATE/DATETIME Support
Summary
Adds DATE/DATETIME support to sql-redis, enabling date filtering with ISO 8601 literals and date part extraction using SQL functions.
New Features
1. Date Literal Parsing (Phase 1)
Use ISO 8601 date strings directly in WHERE clauses:
2. Date Extraction Functions (Phase 2)
Extract date parts using SQL functions that map to Redis APPLY expressions:
YEAR(field)year(@field)MONTH(field)monthofyear(@field)DAY(field)dayofmonth(@field)HOUR(field)hour(@field)MINUTE(field)minute(@field)DAYOFWEEK(field)dayofweek(@field)DAYOFYEAR(field)dayofyear(@field)3. Date Formatting (Phase 3)
Format timestamps as human-readable strings:
Maps to Redis's
timefmt(@field, format)function.4. GROUP BY Date Parts
Aggregate data by date components:
Files Changed
sql_redis/parser.pysql_redis/translator.pysql_redis/analyzer.pytests/test_date_fields.pytests/test_date_functions.pyREADME.mdWhat's NOT Supported (and Why)
DATE_ADD / DATE_SUB
Why: Redis RediSearch has no native date arithmetic functions. This would require:
NOW()at query timeINTERVALsyntax to seconds@field + 604800Workaround: Compute the timestamp in application code:
SECOND()
Why: Redis RediSearch doesn't have a
second()function. The available time functions are:hour()- rounds to hourminute()- rounds to minuteNo sub-minute extraction is available.
NOW() / CURRENT_TIMESTAMP
Why: These are dynamic values that must be evaluated at query time. Redis queries are static - there's no concept of "current time" in the query language.
Workaround: Pass the current timestamp from application code:
Redis Implementation Details
Storage Format
Dates are stored as Unix timestamps in NUMERIC fields:
Query Routing
FT.SEARCHwith numeric rangeFT.AGGREGATEwith APPLYFT.AGGREGATEwith APPLY + FILTERFT.AGGREGATEwith GROUPBYMONTH Returns 0-11
Important: Redis's
monthofyear()returns 0-11, not 1-12:Usage Examples
Date Literals
Date Functions in SELECT
Date Functions in WHERE
Aggregations
Combined with Other Filters