sadpandajoe opened a new pull request, #42054:
URL: https://github.com/apache/superset/pull/42054
### SUMMARY
A time-series chart using a relative time-comparison offset with **no time
grain** returns HTTP 400 `Time Grain must be specified when using Time
Comparison.` instead of rendering. The validation was introduced as a side
effect of #39344, which turned a previously-dead guard into a live one. Before
that change, grain-less comparisons didn't error — but they weren't correct
either: the join matched current timestamps against historic ones, so the
comparison series was silently empty.
This PR replaces the error with an exact alignment, so saved charts that
started 400-ing render again — and now with a *correct* comparison series:
- **Grain-less relative offsets are aligned exactly.** The main series'
timestamps are shifted by the offset delta (e.g. `-1 year` for "1 year ago")
and joined against the offset series' raw timestamps — the same convention
`generate_join_column` uses for the grain path, just without truncation.
Timestamps with no exact counterpart yield nulls, mirroring the grain-based
join. The join uses stringified values so an empty offset series (which
materializes join keys as NaN floats) can't crash the merge on a dtype mismatch.
- **`normalize_time_delta` converts quarters to months** (`"1 quarter ago"`
→ `{"months": -3}`), since `pd.DateOffset` rejects a `quarters` argument. This
also fixes a pre-existing crash for grain-based quarter offsets in
`generate_join_column`.
- **Free-form offsets** (e.g. `"one year ago"`) that don't match
`normalize_time_delta`'s digit-only grammar are shifted per-row with
`get_past_or_future` — the same parser that shifted the offset query's time
range — instead of silently degrading. If the offset can't be interpreted at
all, the join falls back to the raw keys and logs a warning.
- **The query's x-axis label selects the temporal join key**, rather than
whichever datetime column happens to come first, so results with multiple
datetime columns align on the actual temporal axis.
- **Column order is preserved** for grain-less joins. `left_join_df`'s
`set_index().join().reset_index()` round-trip moves join keys to the front; the
original order is restored so chart payloads and CSV exports don't reorder
dimensions.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Before: a time-series chart with Time Comparison enabled (e.g. "1 year ago")
and Time Grain cleared fails with `Time Grain must be specified when using Time
Comparison.`
After: the chart renders with the comparison series aligned to the shifted
timestamps.
### TESTING INSTRUCTIONS
1. Create a time-series chart (e.g. ECharts Time-series Line) with a
temporal x-axis.
2. Set Time Grain to "None" (clear it).
3. Enable a Time Comparison / time shift of "1 year ago" (any relative
offset).
4. On master this returns a 400 error; with this PR the chart renders and
the comparison series aligns with the main series wherever shifted timestamps
match exactly.
5. Unit coverage: `pytest tests/unit_tests/common/test_time_shifts.py
tests/unit_tests/utils/date_parser_tests.py`
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
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]