sadpandajoe opened a new pull request, #44254:
URL: https://github.com/apache/superset/pull/44254
fix(query): resolve sub-day "Last <unit>" time_range shorthand
### SUMMARY
Sub-day relative `time_range` shorthand ("Last hour", "Last minute", "Last
second",
"Last N minutes/hours") raised `ValueError: From date cannot be larger than
to date`
on almost every request, at any time other than the first moments after local
midnight.
Two related defects in `superset/utils/date_parser.py::get_since_until()`:
1. The separator-less `"Last <unit>"` / `"Next <unit>"` shorthand rewrite
always
defaulted the *other* bound to the literal `"today"` (which resolves to
midnight),
regardless of whether the matched unit is granular (second/minute/hour,
which
`get_relative_base()` anchors to `"now"`) or broad
(day/week/month/quarter/year,
anchored to `"today"`). For a granular unit this paired a
`"now"`-anchored `since`
against a midnight-anchored `until`, so `since > until` any time after
local
midnight.
2. `hour` was missing from the unit alternation in the `time_range_lookup`
regex that
recognizes `"(this|last|next|prior) [N] <unit>"` phrases, even though the
`DATEADD(...)` grammar, `get_relative_base()`, and the file's other two
unit
regexes already treat `hour` as an ordinary granular unit. So `"Last N
hours"`
(N > 1) never reached the deterministic `handle_scope_and_unit()` path at
all — it
fell through to a fuzzy `parsedatetime` fallback that resolved in the
wrong
direction (added N hours instead of subtracting).
The fix adds a small helper, `get_default_bound_for_shorthand()`, that picks
the same
`"now"`/`"today"` anchor `get_relative_base()` would pick for the matched
unit, and
uses it for the previously-hardcoded default; plus a one-token regex fix
adding
`hour` to the existing alternation.
This also corrects a related, previously-silent issue: separator-less `"Next
<granular-unit>"` (e.g. "Next hour") anchored its `since` on midnight rather
than
`"now"`, silently producing an oversized range (e.g. "today so far, plus the
next
hour") instead of "the next hour starting now". It never raised, so it went
unnoticed; the same anchor fix corrects it, and both directions now have
exact
regression coverage.
`superset/mcp_service/common/time_range_validation.py` carries a
pre-existing,
narrower workaround for the exact same mismatch
(`_normalize_sub_day_last()`), used
by MCP tools that accept free-form `time_range` strings. It's left in place
(its
explicit `DATEADD(...)` output is asserted verbatim by two other MCP test
files) but
its test now also pins that it stays equivalent to the corrected central
parser,
rather than asserting the old exception.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A — backend-only change, no UI surface.
### TESTING INSTRUCTIONS
- `pytest tests/unit_tests/utils/date_parser_tests.py` — includes the new
`test_get_since_until_sub_day_shorthand`, which exercises the real
(unmocked)
`get_since_until()` under `freezegun.freeze_time(...)` frozen at a
non-midnight
instant, asserting exact `(since, until)` values for `Last`/`Next`
second/minute/hour/N-minutes/N-hours. The existing `test_get_since_until`
(mocked,
covering `Last week/quarter/5 months`, `Next 5 months`, explicit
`relative_start`/`relative_end` overrides, etc.) is unchanged.
- `pytest tests/unit_tests/mcp_service/common/test_time_range_validation.py`
—
updated to assert the MCP normalization path stays equivalent to the
now-fixed
central parser instead of asserting the old crash.
- Manually: with the fix applied, a chart/dashboard/native-filter time range
of
"Last hour" (or "Last N minutes", "Last N hours") resolves instead of
erroring.
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]