Skip to content

Resolve dynamic date parameters on the backend so scheduled queries can use them - #7809

Open
ekanshul wants to merge 1 commit into
getredash:masterfrom
ekanshul:fix-dynamic-date-parameters
Open

Resolve dynamic date parameters on the backend so scheduled queries can use them#7809
ekanshul wants to merge 1 commit into
getredash:masterfrom
ekanshul:fix-dynamic-date-parameters

Conversation

@ekanshul

@ekanshul ekanshul commented Sep 10, 2026

Copy link
Copy Markdown

What type of PR is this?

  • Bug Fix

Description

Fixes #7710 and #4514.

Dynamic date and date range values (d_last_7_days, d_this_month, d_now, …) are only evaluated by the frontend, right before it runs a query (DateRangeParameter.js, DateParameter.js). Everything that runs a query without a browser gets the raw d_* string instead, so for a query whose parameter defaults to a dynamic value:

Just accepting the strings in _is_date_range (as tried in #7710) isn't enough: mustache then renders {{ range.start }} as an empty string and missing_params reports range.start.

Changes

  • ParameterizedQuery.apply() now resolves dynamic values into the same concrete values the frontend would send, based on each parameter's type from the schema (YYYY-MM-DD, YYYY-MM-DD HH:mm or YYYY-MM-DD HH:mm:ss, as {start, end} for ranges). The presets mirror the frontend definitions one to one, including the "until now" ranges and calendar periods (weeks start on Sunday, like moment's default locale). Values are evaluated in UTC. Unknown d_* values and presets used on the wrong parameter type are still rejected by the existing validation, and non-date parameters are untouched.
  • Since the rendered text of such a query changes from one run to the next, the hash stored when the query was last saved doesn't necessarily match the text refresh_queries is about to run, and Query.update_latest_result() would leave the query's latest_query_data untouched even though the run succeeded. refresh_queries now refreshes the stored hash right before enqueueing (Query.update_query_hash(), the same thing a save does, without touching updated_at), so the result is attached through the existing hash match and dashboards and alerts on that query see the fresh data. Editing the query while a run is in flight keeps today's semantics: the hash changes with the edit, so the stale result isn't attached.

The presets are resolved wherever the parameter definitions are known: scheduled refreshes, the query hash, and API executions that go through the saved query (/api/queries/<id>/results). /api/queries/<id>/refresh intentionally builds its ParameterizedQuery without the schema (#3383), so it is unchanged. No change to how query hashes are calculated either, so this doesn't conflict with the larger rework proposed in #6960; it makes the existing scheduling path work for these queries in the meantime.

How is this tested?

  • Unit tests (pytest, jest)

  • Manually

  • New tests in tests/models/test_parameterized_query.py cover every preset against a fixed now (including leap-year month boundaries and week boundaries), each datetime format, unknown/mismatched presets and non-date parameters.

  • tests/tasks/test_refresh_queries.py: a scheduled query with a d_last_7_days default is enqueued with the resolved dates, and its stored hash is refreshed to match that text without touching updated_at.

  • Full backend suite run in the CI image (docker compose build … && docker compose run redash tests tests/): 942 passed, 1 skipped.

Related Tickets & Documents

#7710, #4514, #6960

Mobile & Desktop Screenshots/Recordings (if there are UI changes)

N/A

🤖 Generated with Claude Code

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR resolves supported dynamic date presets in backend parameterized-query paths and synchronizes scheduled queries’ stored hashes with the rendered query text.

  • Adds UTC-based resolution for date and date-range presets using parameter schema types.
  • Updates scheduled refreshes to persist the hash of the concrete rendered query before enqueueing.
  • Adds unit coverage for presets, date formats, validation, scheduled rendering, and hash synchronization.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
redash/models/parameterized_query.py Adds schema-aware UTC resolution of supported dynamic date and date-range values before validation and rendering.
redash/tasks/queries/maintenance.py Synchronizes scheduled queries’ stored hashes with their dynamically rendered text before enqueueing.
tests/models/test_parameterized_query.py Covers supported presets, formatting variants, calendar boundaries, validation, and unchanged non-date values.
tests/tasks/test_refresh_queries.py Verifies scheduled dynamic-date rendering and stored-hash synchronization without changing updated_at.

Sequence Diagram

sequenceDiagram
    participant Scheduler
    participant ParameterizedQuery
    participant QueryRecord
    participant Executor
    Scheduler->>ParameterizedQuery: Apply stored parameters and schema
    ParameterizedQuery->>ParameterizedQuery: Resolve supported dynamic date presets
    ParameterizedQuery-->>Scheduler: Concrete rendered query text
    Scheduler->>QueryRecord: Synchronize rendered query hash
    Scheduler->>Executor: Enqueue rendered query
    Executor-->>QueryRecord: Attach matching latest result
Loading

Reviews (2): Last reviewed commit: "Resolve dynamic date parameters on the b..." | Re-trigger Greptile

Comment thread redash/models/parameterized_query.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 5 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread redash/tasks/queries/execution.py Outdated
Comment thread redash/models/parameterized_query.py
…an use them

Dynamic date and date range values ("d_last_7_days", "d_now", ...) are only
evaluated by the frontend right before it runs a query. Everything that runs a
query without a browser gets the raw "d_*" string instead: scheduled refreshes
fail parameter validation (logging "Could not enqueue query ... due to
InvalidParameterError" and sending failure e-mails every cycle) and saving the
query logs "Unable to update hash for query ...".

ParameterizedQuery.apply() now resolves those values into the same concrete
values the frontend would send, using the definitions from
client/app/services/parameters/DateParameter.js and DateRangeParameter.js
(evaluated in UTC; weeks start on Sunday like moment's default locale).
Unknown "d_*" values are still rejected by the existing validation.

Because the rendered text of such a query changes from run to run, the hash
stored when the query was last saved doesn't necessarily match the text that
refresh_queries is about to run, and Query.update_latest_result() would leave
the query's latest result untouched. refresh_queries() therefore refreshes the
stored hash right before enqueueing, the same way a save does.

Fixes getredash#7710
Fixes getredash#4514

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ekanshul
ekanshul force-pushed the fix-dynamic-date-parameters branch from 149284f to 25edfc2 Compare September 10, 2026 20:33
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.

Invalid parameters on scheduled query date range

1 participant