Repository navigation
fix(partition-mapping): stop epoch partition mirroring from dropping rows on hourly/daily keys - #45846
Open
hughhhh wants to merge 13 commits into
Open
fix(partition-mapping): stop epoch partition mirroring from dropping rows on hourly/daily keys#45846hughhhh wants to merge 13 commits into
hughhhh wants to merge 13 commits into
Conversation
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #45846 +/- ##
==========================================
+ Coverage 84.73% 84.75% +0.01%
==========================================
Files 3069 3071 +2
Lines 205781 206128 +347
Branches 48391 48511 +120
==========================================
+ Hits 174366 174696 +330
- Misses 28122 28132 +10
- Partials 3293 3300 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
hughhhh
force-pushed
the
plan/sc-130257-partition-followup
branch
2 times, most recently
from
October 29, 2026 19:20
f83cdd6 to
54a8442
Compare
…keted epoch keys Hive/Impala suggested `unix_timestamp(:value)` as the partition transform. On hour- or day-bucketed epoch keys it yields the raw instant rather than the bucket boundary, so mirrored predicates silently excluded matching rows. - Remove the Hive/Impala default; decline mirroring for the bare expression on temporal-to-numeric mappings and surface the refusal in the editor. - Add an explicit "Validate against data" check that compares the transform of sampled business values with the same rows' stored partition keys. - Label expression-only preview as evaluated, not verified. - Document bucket, timezone and validation semantics. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atement Direct sqlglot use is disallowed here, and it let a tokenizer error from a half-typed transform escape the dataset summary. Compare projections via SQLStatement, which already maps tokenizer errors to parse errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…etected epoch spellings An empty metrics list made the sample a GROUP BY over the whole partition before LIMIT. Docs now say which spellings the refusal does not catch, replace raw-instant examples with bucketed ones, and warn about non-UTC sessions such as IST. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tants The text match caught only the bare former default; CAST(...), + 0, * 1, floor(...) and STRING timestamp columns still mirrored raw instants onto hour/day keys and dropped rows. Probe two canary instants 2843 seconds apart for temporal-to-numeric mappings and decline when the answers keep that distance. The canaries are a separate, cached probe, so filter-value probes and their cache keys are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Elsewhere a raw epoch column is an ordinary index to prune on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hughhhh
force-pushed
the
plan/sc-130257-partition-followup
branch
from
October 29, 2026 19:55
54a8442 to
30f0769
Compare
QA's rerun on Hive 4.0.1 and Impala 4.4.1 found three ways a raw-instant transform still mirrored and dropped rows: - a STRING timestamp column left at the default is_dttm=false was never checked; - microsecond instants (`* 1000000`, Impala's `utc_to_unix_micros`) were not recognised; - text in ISO layout with a `T` was asked only with a space, answered NULL, and skipped the check. Text columns are now asked in each common layout plus their own python_date_format, flagged temporal or not, and the step matches seconds through nanoseconds. If an engine raises on one layout, each pair is probed alone. The dataset API reports a refusal that a probe has already cached, so safety_refusal stops reading null for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From QA's rerun of #45846 on Hive and Impala: - N-FIX-02: an ordinary comment in a transform (`-- hourly`) made every probe decline with a "not a plain projection" warning. The probe gate rejects any comment in the compiled SQL, since that is how a bound value hides what follows it. Comments the owner wrote are now removed with the engine's own lexer before the probe compiles. A `:value` inside a comment is still refused as stored. - A transform the mapping refuses could get a green "Matched" from Validate when the chosen keys only held hour-boundary rows. Validate now reports it as refused and reads no rows. - VAL-2: an inconclusive result names the partition keys at fault. - VAL-4: partition keys must be 64-bit integers. A trailing newline no longer passes the `$` anchor, and the UI and the API agree on length. - VAL-5: a disabled Validate button says why, and "1 partition" is singular. - VAL-6: a refused mapping no longer says its filters are mirrored above "Filters will not be mirrored". - O-REG-01: Validate is not offered for a text partition key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The dataset editor crashed on load: the build lowers `**` to `Math.pow`, which throws on BigInt operands, so the 64-bit key bounds are now spelled out as literals. Jest keeps the native operator, so only the served bundle showed it. - A rejected partition key was reported one character at a time: marshmallow treats a lazy string as a list of messages. The message is now a plain string, and the test checks the message, not only that it raised. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Ask the column's python_date_format canary pair only when its text round-trips as a literal, the same gate every filter value passes. The format is the dataset owner's text; on Hive a backslash closes the literal SQLAlchemy rendered. - strip_comments returns "" for comment-only input, and its re-lex refusal branches are tested, restoring 100% coverage on superset/sql. - Document the refused status and inconclusive_keys in the validation response, and regenerate openapi.json. - The panel says a rejected transform is not mirrored rather than refused, since an operator or engine reason is not a refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ition-followup # Conflicts: # UPDATING.md # superset/translations/de/LC_MESSAGES/messages.po
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SUMMARY
Charts on Hive/Impala datasets were silently dropping rows when a partition filter mapping used the suggested transform
unix_timestamp(:value). If the partition key stores hour- or day-start epoch seconds, that transform turns a filter bound like10:47:23into the raw instant rather than its bucket boundary, so the mirrored partition predicate excludes rows the original filter keeps. QA reproduced this on Hive 4.0.1 and Impala 4.4.1.The fix:
CAST(unix_timestamp(:value) AS BIGINT),+ 0,* 1,floor(unix_timestamp(:value))and STRING timestamp columns. A key that really stores raw epoch seconds is declined too: full scan, correct rows. Other engines are unaffected, since a raw epoch column there is an ordinary index.LIMIT 50select (no GROUP BY) throughQueryContextwithraise_for_access()and RLS, with noCOUNT(*)and no time filter. Probe caches and mirror verdicts are bypassed. A sampled match is reported as exactly that, not as proof for the whole dataset.UPDATING.mdgive correct hourly/daily floor recipes and explain timezone and validation semantics.Operator widening and the existing timezone normalization (
adjust_time_bounds) are unchanged.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
unix_timestamp(:value)→ no suggestion; placeholder asks for the expression that populates the key.unix_timestamp(:value)on an hourly key: predicates mirrored, rows lost → not mirrored, with a warning explaining the missing bucket.TESTING INSTRUCTIONS
Proof: backend unit tests for
sql/parse,connectors/sqla,datasets, partition mirroring and the Hive/Impala specs pass (3,938 total). JestPartitionFilterMapping/passes (119). Staged-file pre-commit passes, including mypy, pylint and the frontend type check. New tests execute generated SQL and compare mirrored and unmirrored row identities for hourly and daily keys across=,IN, ranges and inequalities. They also confirm that the sampling query keeps RLS and partition restrictions and issues noCOUNT(*). A further executed-SQL test runs five raw-instant spellings on TIMESTAMP and STRING sources: they are declined on Hive and still mirror on SQLite. With the check disabled, 9 of the 10 cases fail. QA ran an earlier head (2b4db94) on real Hive 4.0.1 and Impala 4.4.1: all 8 story scenarios returned correct counts. QA's remaining High (the raw-instant spellings above) is addressed by the later commits, which have not yet been re-run on live engines.With
PARTITION_FILTER_MAPPINGenabled on a Hive or Impala dataset with a TIMESTAMP column mapped to an hour-start BIGINT partition key:unix_timestamp(:value), save, and reopen. Expect a "not mirrored" warning, and no partition predicate in View query.CAST(floor(unix_timestamp(:value) / 3600) * 3600 AS BIGINT)and validate again. Expect "Matched N sampled rows across M partitions".=,INand partial-hour ranges with and without the mapping. They should be equal.ADDITIONAL INFORMATION
PARTITION_FILTER_MAPPINGvalidation_partition_valueson the partition-mapping preview endpoint,data_validationin its response,safety_refusalin the dataset's partition summarypartition_value_transform_default(the response field stays, nownull)Reviewed with sol-loop: 4 rounds with Claude Opus (GPT Sol unavailable: Codex usage limit). Verdict: the last finding (reverting a failure cache that could have switched the check off for 24 hours) is fixed as requested.
🤖 Generated with Claude Code