Skip to content

feat(time-series): add TS.NRANGE and TS.NREVRANGE multi-key pivot commands - #3337

Merged
nkaradzhov merged 3 commits into
masterfrom
nrange
Jul 15, 2026
Merged

nkaradzhov merged 3 commits into
masterfrom
nrange

Conversation

@nkaradzhov

@nkaradzhov nkaradzhov commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

This pull request adds the TS.NRANGE and TS.NREVRANGE RedisTimeSeries commands (Redis 8.10). Both query an explicit list of time series keys over a timestamp range and return timestamp-major pivot rows { timestamp, values }, where values preserves the input key order and missing cells surface as NaN (indistinguishable from a stored/aggregated NaN, matching the server contract). TS.NRANGE returns rows in increasing-timestamp order; TS.NREVRANGE in decreasing order, reusing the same argument builder and reply parser without re-sorting server rows.

Key behaviors:

  • numkeys is derived from the key list and duplicate keys are preserved (duplicates map to repeated value columns).
  • Full TS.RANGE-style option set: LATEST, FILTER_BY_TS, FILTER_BY_VALUE, COUNT, ALIGN, AGGREGATION, BUCKETTIMESTAMP, EMPTY.
  • Aggregation takes one aggregator per key emitted as separate tokens (AGGREGATION first max min ...), never the comma-joined form.
  • Single-shard, key-routed (no multi_shard policy); same-slot key requirement documented in JSDoc.

Exposed as NRANGE/nRange and NREVRANGE/nRevRange. A shared pivot-row reply transform lives in helpers.ts. Behavior verified against a live Redis 8.10 instance.

🤖 Generated with Claude Code


Note

Low Risk
Additive read-only commands plus a small dedupe refactor of range argument parsing; behavior covered by unit and integration tests against Redis 8.10.

Overview
Adds Redis 8.10 client support for TS.NRANGE and TS.NREVRANGE, exposed as nRange / nRevRange. Both take an explicit key list (with numkeys from length, duplicates preserved), a time range, and optional TS.RANGE-style filters; replies are timestamp-major pivot rows { timestamp, values[] } aligned to key order, with missing cells as NaN via transformPivotSamplesReply.

TS.NRANGE builds wire args including one aggregator token per key under AGGREGATION (not the comma-joined form used by single-key multi-agg). TS.NREVRANGE reuses the same argument builder and reply parser, only changing the command name.

Refactor: shared range preamble (LATEST, FILTER_BY_TS, FILTER_BY_VALUE, COUNT) moves into parseRangeCommonArguments / TsRangeCommonOptions in helpers.ts, used by existing RANGE and RANGE_MULTIAGGR parsers without changing their aggregation wire format.

Reviewed by Cursor Bugbot for commit 02a9e8c. Bugbot is set up for automated code reviews on this repo. Configure here.

nkaradzhov and others added 3 commits July 14, 2026 13:17
…mands

Add the TS.NRANGE and TS.NREVRANGE RedisTimeSeries commands (Redis 8.10).
Both query an explicit list of keys over a timestamp range and return
timestamp-major pivot rows { timestamp, values } where values preserve the
input key order and missing cells surface as NaN. NRANGE returns rows in
increasing-timestamp order, NREVRANGE in decreasing order, reusing the same
argument builder and reply parser without re-sorting server rows.

- numkeys derived from the key list; duplicate keys preserved
- full TS.RANGE option set (LATEST, FILTER_BY_TS, FILTER_BY_VALUE, COUNT,
  ALIGN, AGGREGATION, BUCKETTIMESTAMP, EMPTY)
- one aggregator per key emitted as separate tokens, never comma-joined
- single-shard, key-routed; same-slot key requirement documented

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…y NRANGE reply

Apply code-review fixes to the TS.NRANGE/TS.NREVRANGE feature with no
change to serialized wire arguments or reply shape:

- Extract shared parseRangeCommonArguments + TsRangeCommonOptions into
  helpers.ts; RANGE, RANGE_MULTIAGGR, and NRANGE now emit the common
  option prefix from one place instead of three copies.
- Reference transformPivotSamplesReply directly in NRANGE.transformReply,
  dropping redundant wrapper closures and unused imports.
- Fold single-row transformPivotSampleReply into transformPivotSamplesReply.
- Trim verbose registry JSDoc to match sibling range commands.
- Add RESP2 test asserting a missing pivot cell surfaces as NaN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ale TODO

Add "Added since Redis 8.10." to the NRANGE/NREVRANGE registry JSDoc,
matching the version-annotation style used in the client command index,
and remove the copied "use double type mapping instead" TODO from the
pivot RESP2 transform.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nkaradzhov
nkaradzhov marked this pull request as ready for review July 14, 2026 10:45
@nkaradzhov
nkaradzhov requested a review from PavelPashov July 14, 2026 10:45
@nkaradzhov
nkaradzhov merged commit faf83f2 into master Jul 15, 2026
15 checks passed
@nkaradzhov
nkaradzhov deleted the nrange branch July 15, 2026 15:33
nkaradzhov added a commit that referenced this pull request Jul 28, 2026
…TS.NREVRANGE (#3360)

RedisTimeSeries#2079 finalized the semantics: one AGGREGATION token per key,
each holding one or more comma-separated aggregators (e.g. `avg,max sum`). The
merged implementation (#3337) only exposed a single aggregator per key.

Change `AGGREGATION.types` from a flat `TimeSeriesAggregationTypeList` to
`TimeSeriesAggregationTypeGroups` (one group per key); emit each group as a
single comma-joined token. The shared `TimeSeriesAggregationTypeList` used by
single-key TS.RANGE is left untouched.

BREAKING (vs unreleased #3337): flat `types: [MAX, MIN]` becomes grouped
`types: [[MAX], [MIN]]`. Wire output for single-aggregator usage is unchanged.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants