Conversation
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.
Why
workload/tpch_deequ.yamlcarries two data-quality cells,U-P4dandU-P4l,that express distributional checks as Pearson correlation. Both failed to lower:
DataFusion plans
corr(x, y)fine;lower_agg_intentrejected it, becauseAggSemantichas no correlation. The planner therefore could not see these twocells at all. Getting
corrinto the IR is the precondition for any later workon it.
What
The SQL frontend now lowers
corr(x, y)to anAggIntent::Extension, and theaggregate's output column is typed
Float64/ nullable instead of the genericUtf8placeholder.Corpus lowering goes from 39/50 to 41/50. Scope is deliberately limited to
translation plus surviving the optimization pipeline: this PR produces no new
optimization, and is not intended to.
How
lower_corrmirrorslower_arg_selectorand runs before thelookup_nativecall.
corrdiffers fromargMaxin one way — it is a real native DataFusionaggregate — but the reason it needs handling here is identical:
lookup_nativehas nothing to return for it.
It lowers to
Extensionrather than a new core variant. Every coreAggIntentreducer folds one column (
col: Option<C>); correlation reads two and would bethe first binary core variant.
AggIntent::Extensionstates its own admissionbar — core only grows for intents that at least two deployment models actually
use — and a repo-wide search found no second model wanting correlation; PromQL
has none. This is the same judgement
lower_arg_selectorrecords forargMax/argMin(issue #232).Both columns are stored in
payloadas validated bare-columnColumnRefs,under
x_col/y_col, in written order. Order is load-bearing: a laterrewrite into co-moments has to tell x from y.
The output type is settled in one place.
argMaxmust be patched at bothquery_expr.rscall sites because its type follows the selected column;corris alwaysFloat64regardless of schema, sooutput_columnresolves itdirectly.
nullable: truebecausecorris NULL on zero variance or fewer thantwo contributing rows.
Before this PR
U-P4dandU-P4lwere rejected at lowering and never reached the planner.After this PR
Both cells lower and appear in the exported graph as independent nodes.
The 9 remaining failures are 8
Date32and 1IntervalMonthDayNano— untouchedby this branch and expected; they belong to
feat/type-extension.Developers can now write
corrin a workload and have the planner carry itend to end. It realizes through
CostModel::realize_extension, which stilldefaults to
PassThrough— the seam is left in the right place, not used.Evidence
Execution example — before/after on the same workload.
The three
corrintents inpost.jsonare distinct and are not folded.U-P4dandU-P4luse different column pairs, so collapsing them would meanthe payload never entered the hash. It did not:
Column pairs and their order match the SQL as written.
The single
SketchApproximationnote inpost.jsonis attributed tocount,not to
corr— consistent withcorrtaking the defaultPassThroughpath.Performance measurement: not applicable — no optimization is produced and no
hot path changed.
Screenshot: not applicable — no visual output.
Diagram: not applicable — the design document already carries the
Extensionseam discussion.Verification
Unit tests (
crates/frontend-sql/tests/sql_lowering.rs, 4 new):corr_lowers_to_an_extension_intent—corr(x, y)producesExtension { ext_kind: "corr" }rather than a lowering error.corr_payload_preserves_both_column_names— both columns survive inpayload, underx_col/y_col, in written order.corr_over_an_expression_binds_the_derived_column— an expression argumentis carried, not dropped: the planner materializes it into the Project below
the Aggregate and the payload names that derived column.
corr_output_column_is_a_nullable_float— the aggregate's output column isFloat64and nullable, not theUtf8placeholder.All 4 pass. Each was written against the design before the implementation
landed; they were not verified to fail against an unmodified tree as part of
this run, since this is new behavior rather than a correctness fix.
Regression suites:
cargo test -p asap-frontend-sql -p asap-types—321 tests, 0 failures.
End-to-end:
run_dag_export.pyover the full 50-cell corpus, both thepre-ASAP and
--post-asapruns, no error and no panic. Numbers above.Other checks:
cargo fmt --checkclean;cargo clippy -p asap-frontend-sql -p asap-types --all-targetsclean (exit 0, no warnings).Corpus test / ratchet: deliberately absent. See Limitations.
Architectural decisions
Extensionover a new coreAggIntentvariant. Rejected adding a binarycore variant: correlation would be the first reducer reading two columns, and
Extension's stated bar is two or more deployment models wanting the intent.PromQL has no correlation, so
corrdoes not clear it today.argMaxis thematching precedent.
Output type resolved in
output_column, not patched at the call sites.Rejected the
argMaxpattern of patchingquery_expr.rsat both sites, sincethat pattern exists only because the arg selectors' output type follows the
selected column.
corris schema-independent, so one site suffices. Corealready recognizes specific
ext_kinds inarg_selector_columns, so this isnot a new kind of coupling.
Columns kept unresolved in
payload.Extensionhas no typed column field,so core carries the two
ColumnRefs without resolving them, perreducer_col'sbare-column rule (issue #115).
Limitations and follow-up
realize_extensionstill defaults toPassThrough. Overriding it is deferred.Extensionpath can only return one candidate. Core cannot enumeratealternatives for an opaque shape, so even after
realize_extensionisoverridden there will be no "KLL or DDSketch" choice space for
corr. This isa known property of the seam, not a regression.
agg_is_mergeablereturnstrueforExtension, soSharedSubtreeStrategycould in principle share twoidentical
corrintents. The corpus has no identical pair — all three columnpairs differ — so the corpus exercises nothing here and
1 sharedis unchangedfrom the baseline.
tests/data_quality_check/tpch_deequ.rsand its
.sqlare created byfeat/type-extension, which has not landed; twoPRs creating the same files would conflict.
corrcoverage is backed by theunit tests above, and the corpus still records the two cells on the failing
side.
ratchet from 48 to 50. Note that on
dev/dqcthe ratchet becomes actually 50while pinned at 48 — it must be updated in place on merge or the test goes red.
realize_extensiontogive
corra real implementation form, and add a rewrite strategy matchingext_kind == "corr"that decomposes it into six mergeable sums(
Sx, Sy, Sxy, Sxx, Syy, n), modelled onAvgToSumOverCountStrategy. Matchingan
Extensionshape is as feasible as matching a core variant, so this choicedoes not block that path — it only costs one payload decode.
Human review — do not complete with an agent