Skip to content

feat(time-series): add TS.QUERYLABELS (LABELS and VALUES forms)#3354

Open
nkaradzhov wants to merge 1 commit into
redis:masterfrom
nkaradzhov:querylabels
Open

feat(time-series): add TS.QUERYLABELS (LABELS and VALUES forms)#3354
nkaradzhov wants to merge 1 commit into
redis:masterfrom
nkaradzhov:querylabels

Conversation

@nkaradzhov

@nkaradzhov nkaradzhov commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

This pull request adds client support for TS.QUERYLABELS, introduced in RedisTimeSeries 8.10. The command returns label metadata for time series matching a filter: the set of all label names (LABELS), or the set of all values of one label name (VALUES label). It completes the Grafana-style drill-down flow alongside the existing TS.QUERYINDEX.

Two methods are exposed so the mandatory label argument of the VALUES form is enforced by the signature:

  • client.ts.queryLabels(filter?)TS.QUERYLABELS LABELS [FILTER ...]
  • client.ts.queryLabelValues(label, filter?)TS.QUERYLABELS VALUES label [FILTER ...]

The command is keyless and read-only; in cluster mode the receiving shard performs the cluster-wide fan-out and returns a single merged, deduplicated reply, so clients use default keyless routing with no client-side aggregation. Filter expressions reuse the existing TS.QUERYINDEX filter representation and are sent verbatim (not parsed, reordered, or deduplicated). The reply is a flat array under RESP2 and a set under RESP3; an empty reply is a valid success.

Behavior notes:

  • FILTER is optional in both forms; omitting it queries all indexed series.
  • Passing an explicitly empty filter array raises a local usage error rather than silently widening to all series (a bare FILTER token is rejected by the server).
  • The reply is unordered and already deduplicated; documented and tested as such.
  • Not eligible for client-side caching (server advertises the dont_cache tip).

New QUERYLABELS.ts / QUERYLABELS_VALUES.ts (+ co-located specs), a shared parseQueryLabelsFilterArgument helper in helpers.ts, and registry entries with JSDoc in commands/index.ts.

🤖 Generated with Claude Code


Note

Low Risk
Additive read-only command bindings and tests only; no changes to existing command behavior.

Overview
Adds client support for RedisTimeSeries 8.10 TS.QUERYLABELS, exposing queryLabels(filter?) (LABELS — distinct label names) and queryLabelValues(label, filter?) (VALUES — distinct values for one label). Both are keyless, read-only commands with RESP2 array / RESP3 set replies, matching the existing QUERYINDEX pattern.

Optional filters reuse the same expression style as TS.QUERYINDEX and are appended via a new shared parseQueryLabelsFilterArgument helper; an explicitly empty filter array throws locally instead of widening to all series. Registry entries and integration tests cover argument encoding, filtered/unfiltered queries, empty results, and RESP2.

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

Add client support for TS.QUERYLABELS, introduced in RedisTimeSeries 8.10.
The command returns label metadata for time series matching a filter: the
set of all label names (LABELS), or the set of all values of one label name
(VALUES label). It completes the drill-down flow alongside TS.QUERYINDEX.

Two methods are exposed so the mandatory label argument of the VALUES form
is enforced by the signature:
- queryLabels(filter?) -> TS.QUERYLABELS LABELS [FILTER ...]
- queryLabelValues(label, filter?) -> TS.QUERYLABELS VALUES label [FILTER ...]

The command is keyless and read-only; FILTER is optional in both forms and
omitting it queries all indexed series. Filter expressions reuse the existing
TS.QUERYINDEX representation and are sent verbatim. The reply is a flat array
under RESP2 and a set under RESP3; an empty reply is a valid success. Not
eligible for client-side caching (server advertises the dont_cache tip).

Passing an explicitly empty filter array raises a local usage error rather
than silently widening to all series.

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.

1 participant