rusackas opened a new pull request, #42432:
URL: https://github.com/apache/superset/pull/42432

   ### SUMMARY
   `get_timestamp_expr()` only special-cased `epoch_s`/`epoch_ms` 
`python_date_format` values, converting the raw column into a proper timestamp 
*before* applying a time-grain truncation function. Any other 
`python_date_format` (e.g. `"%Y"`) fell through untouched, so the raw value was 
passed straight into the grain function.
   
   On SQLite that means `DATETIME(year, 'start of year')` receives a bare 
integer like `2013` and interprets it as a **Julian day number**, not a 
calendar year — silently returning `NULL` for every row instead of raising an 
error.
   
   This exact configuration ships in Superset's own `video_game_sales` example 
dataset (`superset/examples/video_game_sales/dataset.yaml`): the `year` column 
is `BIGINT`, `is_dttm: true`, `python_date_format: '%Y'`. So any 
time-grain-truncated chart against it (a Nightingale Rose chart with Time Grain 
set to Year, for instance) silently returns no data, with no error surfaced 
anywhere.
   
   This was found while testing PR #42381 (rebuild of the Nightingale Rose 
chart on ECharts) against a live preview: setting Time Grain on a Rose chart 
using this example dataset produced an empty chart. Removing Time Grain worked, 
which pointed at grain-expression generation rather than the chart itself — 
confirmed by reproducing the same `NULL` result with `post_processing` stripped 
out entirely (i.e. before any chart-specific code runs).
   
   ### FIX
   Add a `year_to_dttm()` hook (mirroring the existing 
`epoch_to_dttm()`/`epoch_ms_to_dttm()` pattern) that converts a bare year into 
a proper date before grain truncation, implemented for SQLite via 
`printf()`-based date construction. Includes an explicit `NULL` guard since 
SQLite's `printf()` otherwise treats a `NULL` argument as `0`, which would turn 
a missing year into `'0000-01-01'` instead of propagating `NULL`.
   
   Scope note: this fixes the confirmed, reproduced case (SQLite + `%Y`). Other 
engines with a similarly non-native `python_date_format` column would need 
their own `year_to_dttm()` override; the base class raises 
`NotImplementedError` by default, same as the existing epoch hooks.
   
   ### TESTING INSTRUCTIONS
   - `pytest tests/unit_tests/db_engine_specs/test_sqlite.py -v` — new 
`test_year_pdf_time_grain` parametrized test creates an in-memory SQLite table 
with a `REAL` "year" column and confirms `get_timestamp_expr(pdf="%Y", 
time_grain=TimeGrain.YEAR)` now truncates correctly (including a `NULL`-year 
row, which must stay `NULL` rather than becoming `'0000-01-01'`).
   - Manually: load the `video_game_sales` example dataset, build any 
time-series chart on it with Time Grain set to Year, and confirm it now returns 
data instead of an empty result.
   
   ### ADDITIONAL INFORMATION
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration
   - [ ] 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