peter-toth commented on PR #57753:
URL: https://github.com/apache/spark/pull/57753#issuecomment-5207280556

   No problem at all, and thanks — this review was greatly appreciated. It 
found real gaps, including a couple I'd have shipped. Everything is in 
`97d5247`.
   
   **What changed**
   
   - **Transform comparison (`:858`).** This was the big one. 
`TransformExpression` is a plain case class, so `canonicalized ==` compares the 
`BoundFunction` instance, and `V2ExpressionUtils` binds afresh on every 
derivation — so two identical `bucket(4, id)` reports compared unequal and 
every transform-partitioned source declined the merge. Both dimensions now 
compare with `isSameFunction`, recursively, so a nested transform's children 
don't fall back to the instance comparison either. One fixture trap worth 
flagging: Spark's `UnboundBucketFunction.bind` returns a singleton, so an 
in-repo bucket test passes with or without the fix — the new test uses a 
`FunctionCatalog` that binds a fresh instance per call, like a real connector, 
and it fails without the fix.
   - **Report checked per build attempt (`:831`, `:806`).** The check moved out 
of `tryBuildMergedDSv2Scan` to its callers, and now runs per attempt. A 
degradation is no longer indistinguishable from a filter-enforcement failure, 
so the build's `None` again means only "strict filters not re-enforceable" — 
which restores the `tryBuildFilterDSv2ScanChild` contract you flagged — and a 
source that reports per scan still gets its chance from the strict-only attempt.
   - **Coverage (`:877`, `:2622`).** You were right that the ordering check 
never fired with a non-empty requirement; I measured it — replacing 
`merged.ordering.getOrElse(Nil)` with `Nil` left all 82 tests green. 
`TestV2Table` can now report an ordering or a bucket partitioning, and there 
are four new tests: the two ordering ones, the bucket-transform one, and the 
incompatible-inputs-with-the-config-on case, which was indeed uncovered.
   - **Configs (`:7297`, `:7298`).** Both renamed to end in `.enabled`, and 
both docs now mention the decline that happens before any rebuild. I dropped 
the redundant `allow` while renaming, because 
`allowKeyGroupedPartitioningDegradation.enabled` came to 94 chars — one over 
the line limit, so it would have been the only key in `SQLConf` split across 
two literals, and not greppable from a log.
   - **Comments and names (`:724`, `:841`, `:2603`).** All fixed, plus two more 
the same pass turned up: the `(Filter, Filter)` call site still claimed strict 
filters were the only reason to decline, and `DSv2DeferredScan`'s `@param`s 
named the configs by their old keys.
   - **Nits (`:179`, `:104`).** The `withSQLConf` was decorative as you say — 
rather than drop it I made it matter, by also asserting the merged scan reports 
`KeyedPartitioning` on the partition column in the physical plan (AQE off so 
the plan is walkable). The fixture is down to one `createTable` and one 
`capabilities()`.
   
   **Where I'd push back a little**
   
   - `:872`, second half — emptying the requirement at line 730 is a no-op 
rather than a lost check: reaching `getOrElse(Nil)` with a `None` implies that 
dimension's config is on, and `mergeDegradesReporting` already short-circuits 
on it.
   - `:872`, first half — a *gained* report is real (the partitioning pass is 
reference-subset guarded, so `{c1,c3}` + `{c2,c3}` does give the merged scan 
`Some([c1,c2])`), but I read it as the win rather than a hazard: the source 
reported that partitioning for the table, and an input dropped it only because 
a pruned column left it inexpressible. I've documented it so it reads as 
deliberate.
   - `:867` — agreed the check sees only the expressions, and that limitation 
is now written down. `keyGroupedPartitioning` is `Option[Seq[Expression]]`, so 
split counts and partition values aren't visible at that layer, and planning 
input partitions in the optimizer to compare them seems worse than the gap. It 
isn't specific to the `.orElse` either — the first build can prune differently 
from either input too.
   - `:802` — a zero-key `KeyGroupedPartitioning` does now reach the merged 
scan as `Some(Nil)`. But the two unmerged scans would each have carried the 
same `Some(Nil)` and collapsed the same way, so it's not worse than not merging 
— the old `None` was accidentally better than the original plan. Commented 
rather than changed.
   - `:2622`, first half — I couldn't reproduce this one: setting the equality 
to `false`, and deleting the np-side `mapAttributes`, both fail 
`DSv2PlanMergingSuite`'s new end-to-end test. The two subquery relations carry 
different exprIds, so the remap is what makes the two reports comparable at 
all. Both do stay green if `MergeSubplansSuite` runs alone.
   - `:877`, second half — picking the weaker side is green only for two 
non-empty orderings; flipping the empty-side branches along with it fails the 
existing single-side decline test. The new test covers the non-empty case.
   
   **Two follow-ups I'd rather not fold in here**
   
   - `TransformExpression`'s equality is the root cause and it reaches past 
this rule: `PartitioningPreservingUnaryExecNode.projectKeyedPartitionings` puts 
kGP expressions in an `ExpressionSet` (so dedup silently fails and the 
cross-product can hit `aliasCandidateLimit`), `BatchScanExec.equals` compares 
`keyGroupedPartitioning` directly, and `DataSourceV2ScanRelation`'s canonical 
form does too, so `PlanMerger.checkIdenticalPlans` can miss two identical 
subqueries. Overriding `equals`/`hashCode` in terms of `canonicalName()` would 
fix all of them and let me delete the helper this PR adds. I'll file a JIRA.
   - The strict-only retry in `tryBuildFilterDSv2ScanChild` is untested — 
deleting the `.orElse` leaves everything green — because the fixture is 
all-or-nothing on filters, so both attempts fail together. That predates this 
PR (SPARK-40259); it needs a source that pushes a batch or nothing.
   


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