feat: add max-time-range limit for SELECT queries#27557
Conversation
Add a max-time-range coordinator config option that rejects a SELECT whose time range spans more than the configured duration. A value of 0 disables the limit, so behavior is unchanged by default.
There was a problem hiding this comment.
Pull request overview
Adds a coordinator-level max-time-range configuration to reject SELECT queries whose effective time span exceeds a configured duration (0 disables the check), with enforcement implemented during query preparation.
Changes:
- Introduces
MaxTimeRange time.Durationtoquery.SelectOptionsand propagates it from coordinator config through the statement executor. - Tracks whether a SELECT originally had an open upper bound and enforces the configured max-time-range limit in
compiledStatement.Prepare. - Adds tests covering bounded, unbounded, now()-relative, and aggregate query scenarios; documents the new TOML option in the sample config.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| query/select.go | Adds MaxTimeRange to SelectOptions for downstream enforcement. |
| query/compile.go | Tracks open upper bound and enforces MaxTimeRange during Prepare. |
| query/compile_test.go | Adds test coverage for max-time-range enforcement scenarios. |
| etc/config.sample.toml | Documents the new max-time-range coordinator option. |
| coordinator/statement_executor.go | Plumbs coordinator-configured max-time-range into query SelectOptions. |
| coordinator/config.go | Adds TOML config field + diagnostics exposure for max-time-range. |
| coordinator/config_test.go | Verifies TOML parsing of max-time-range. |
| cmd/influxd/run/server.go | Wires coordinator config value into StatementExecutor.MaxTimeRange. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Enforce the maximum time range a query may span, if configured. The range | ||
| // is measured against the shard-mapping time range so that an aggregate | ||
| // query whose open lower bound has already been constrained by the bucket | ||
| // limit above is measured by its effective window rather than by all of | ||
| // time. An open upper bound (no explicit end time) is measured up to now(), | ||
| // matching how aggregate queries default their max time; the query still | ||
| // scans any data beyond now(). A query with no lower bound that the bucket | ||
| // limit did not constrain spans the full possible range and is therefore | ||
| // rejected when this limit is set. | ||
| if sopt.MaxTimeRange > 0 { | ||
| maxT := timeRange.MaxTime() | ||
| if c.OpenUpperBound { | ||
| maxT = c.Options.Now | ||
| } | ||
| if d := maxT.Sub(timeRange.MinTime()); d > sopt.MaxTimeRange { | ||
| return nil, fmt.Errorf("max-time-range limit exceeded: (%s/%s)", d, sopt.MaxTimeRange) | ||
| } | ||
| } |
There was a problem hiding this comment.
Using extra intervals in the computation will seem confusing to the user who submitted the query; they have a range limit of 3 days, the query covers 3 days, but for the computation 3 days and one hour are queried, so their query is rejected. We can't expect the user to know the details of how many extra intervals specific functions add, and the bounds are better when cognitively simpler.
Add a max-time-range coordinator config option that rejects a SELECT whose time range spans more than the configured duration. A value of 0 disables the limit, so behavior is unchanged by default.
Closes https://github.com/influxdata/feature-requests/issues/142