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

   ### SUMMARY
   
   Selecting NULL in a semantic-view filter can silently drop the missing-value 
rows because the provider receives SQL-style equality or membership against 
NULL. Explore and drill-by also send the `<NULL>` sentinel, which needs 
normalization before type coercion.
   
   This PR normalizes those selections in the host and adds a small provider 
contract for the one case that needs an OR group:
   
   - NULL equality and NULL-only membership become `IS NULL`; their negative 
forms become `IS NOT NULL`.
   - Mixed `IN ('a', NULL)` becomes a parenthesized `IN ('a') OR IS NULL`. 
Providers must opt in to `OR_FILTERS` after implementing grouped filters; 
otherwise the host returns a query validation error (HTTP 400) before provider 
execution.
   - Mixed `NOT IN ('a', NULL)` becomes `NOT IN ('a') AND IS NOT NULL`, using 
existing leaf predicates.
   - UI empty-string sentinels are decoded, invalid NULL comparison/LIKE 
operands and empty membership are rejected, and scalar comparison collections 
follow the native datasource's first-value behavior.
   
   The SDK adds a frozen `OrFilter` containing at least two leaves from one 
predicate stage. Query and group-limit filter sets remain AND sets. 
`get_values` keeps its existing leaf-only contract. Main queries, row counts, 
time offsets and group-limit subqueries use the capability gate.
   
   A constant in direct semantic result-cache keys prevents reuse of 
pre-normalization answers during rolling deployment. `UPDATING.md` and provider 
documentation cover SDK union narrowing, guarded loading on older hosts, the 
new validation behavior and cache warming. Adapters still need to implement 
grouped rendering before advertising the capability; this PR does not complete 
adapter adoption.
   
   **Merge coordination:** whichever of this PR and #45100 lands second must 
preserve both cache-key guarantees: the semantic-filter protocol marker **and** 
the metadata cache token. Keep #45100's semantic annotation datasource resolver 
and its source security/version keying; add a regression that pins both direct 
semantic cache-key elements. Do not resolve the overlap by choosing either 
branch's cache implementation wholesale.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   No visual UI change; browser screenshots were not captured.
   
   | Selected values | Before | After |
   | --- | --- | --- |
   | NULL only | Equality/membership can return no matching rows | 
Missing-value rows selected with `IS NULL` |
   | `a` and NULL | NULL rows can be silently omitted | Both selected with 
supported grouped filtering; explicit 400 on a provider without the capability |
   | NOT IN `a` and NULL | SQL UNKNOWN can exclude all rows | Excludes `a` and 
missing values; other rows remain |
   
   ### TESTING INSTRUCTIONS
   
   Automated regression and coverage gate:
   
   ```bash
   TZ=UTC python -m pytest tests/unit_tests/semantic_layers \
     --cov=superset/semantic_layers --cov-branch --cov-fail-under=100
   ```
   
   The tests compare NULL/a/b fact membership, decode Explore/drill-by 
sentinels, reject unsupported groups before table and row-count dispatch, 
retain offset and inner ranking bounds, and separate legacy result-cache keys. 
They also cover duplicate inputs, integer boolean rejection, empty selections 
and NULL comparison operands.
   
   Manual, with `SEMANTIC_LAYERS` enabled and a semantic view containing NULL, 
`a` and `b`:
   
   1. In Explore, select only NULL, then exclude only NULL. Verify missing 
rows, then nonmissing rows.
   2. With a provider supporting `OR_FILTERS`, select `a` plus NULL and verify 
both populations. Without support, verify the explicit validation error rather 
than a partial answer.
   3. Exclude `a` plus NULL and verify only `b` remains. Repeat with a row 
count, a time comparison and a series limit.
   4. Drill by a NULL value and verify it selects missing rows. Check that an 
empty-string choice stays distinct from NULL.
   
   Local validation: 880 semantic tests passed with 100% statement/branch 
coverage. Complete branch-file hooks passed, including MyPy and docs lint. The 
whole unit suite at the final commit reported 22,702 passed, 40 skipped and 2 
xfailed, with only the two documented ARM long-double baseline failures in 
unchanged test files. A docs build, browser round trip and live provider 
validation were not run locally.
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue:
   - [x] Required feature flags: `SEMANTIC_LAYERS`
   - [ ] 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
   - [x] Introduces new feature or API: optional grouped-filter SDK contract
   - [ ] Removes existing feature or API
   
   @aminghadersohi @rebenitez1802 — could you review the NULL normalization and 
optional provider contract? This is a draft while adapter adoption and the 
cache-key merge coordination are pending.
   
   Generated with OpenAI Codex.
   


-- 
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