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]

Reply via email to