[CALCITE-7511] Route RelShuttle dispatch through type-specific visit overloads#4928
[CALCITE-7511] Route RelShuttle dispatch through type-specific visit overloads#4928venkata91 wants to merge 4 commits into
Conversation
0348fb1 to
0df0e15
Compare
mihaibudiu
left a comment
There was a problem hiding this comment.
This looks fine. I wonder whether not handling TableFunctionScan was an omission or was intentional.
Thanks for the review, @mihaibudiu! It looks like an omission, not intentional:
I encountered this while working adding support for Without this fix, any rule that walks a Correlate's right subtree with a RexShuttle to renumber $cor0.X references (e.g. This blocks correct projection pushdown through Correlate-over-TFS shapes such as Flink's UNNEST. |
|
Can you ask in Jira why Window and Snapshot are missing? |
|
Actually, this may be a breaking change for the ones who have implemented visitors with workarounds. |
I think this relates to https://issues.apache.org/jira/browse/CALCITE-7288, I'd like to loop in @dssysolyatin to see if this new example could revive the discussion around CALCITE-7288. It would be great to link the two tickets in Jira too. (I would do it but I am on vacation at the moment with limited connectivity) |
Thanks for looping me in. Feel free to run with it in any direction. I've already shared my opinion in the task and PR discussion (#4620), which should provide the relevant context. Unfortunately, I don't have the bandwidth to revisit/revive the discussion right now; even small Calcite tasks tend to take me about a month to resolve at this point in my life. :) |
|
I have linked this JIRA to CALCITE-7288. However, this issue seems to remain unresolved. We have currently identified two such problems; should we accept a breaking change? I ask because I suspect that, in the short term at least, no one is likely to devise and implement a perfect logical solution. |
|
Thanks @mihaibudiu @asolimando, @xiedeyantu, @dssysolyatin. I read through CALCITE-7288 and the prior discussion on #4620/#4641, and I understand the concern: without a spec + test, every gap fix is a fresh breaking change for consumers with That said, the gap isn't theoretical for my use case, the missing dispatch produces silently incorrect runtime results in Flink's UNNEST projection pushdown. Two options I'd be happy to pursue, both documenting the breaking change in the release notes following the pattern from #4620: A is more efficient if we're accepting the breaking change anyway; B is safer if we want to tackle the Window/Snapshot under the broader CALCITE-7288 effort. Either way, I'd like to keep the discussion of a long-term spec/test on CALCITE-7288 rather than blocking this one. What do you prefer? |
|
I personally would not mind implementing all of them and documenting the breaking change. That's how it's supposed to work. If the upgrade path for users is not difficult, we should describe it for users in the release notes. However, Calcite uses semantic versioning, so this kind of change should be officially prohibited. But I don't see any Calcite 2.0 release on the horizon, so I don't think this can be postponed indefinitely. |
Okay in that case, let me fix it for the other Nodes as well |
|
This is only my preference, other people can weigh on this matter differently. |
0df0e15 to
1701be1
Compare
1aed4e4 to
bfc7b79
Compare
|
@mihaibudiu As suggested, updated the fix to fix other |
|
I personally agree with Mihai's point of view; indefinite postponement is not a good approach. Unless we can reach a different consensus in a short time, I personally suggest that this be stated in the upgrade documentation. |
…e accept(RelShuttle) so dispatch routes through type-specific RelShuttle.visit overloads
bfc7b79 to
ff4a2ec
Compare
Thanks @xiedeyantu. The PR already includes a breaking-change entry under 1.42.0 → Breaking Changes in site/_docs/history.md (link), covering which RelShuttle callers are affected and how to migrate (instanceof branches in visit(RelNode) → type-specific visit(Window) / visit(Snapshot) / visit(TableFunctionScan) overrides). Let me know if you'd like anything added or framed differently there. |
| (1) Callers that implement `RelShuttle` directly must implement the two new methods. | ||
| (2) Callers that subclassed `RelShuttleImpl` and routed `Window` / `Snapshot` / | ||
| `TableFunctionScan` through `visit(RelNode other)` with `instanceof` checks should | ||
| migrate to the type-specific `visit(Window)` / `visit(Snapshot)` / |
There was a problem hiding this comment.
Can this include a pointer to the code that is migrated in this PR?
I guess the commit is not yet final, so you cannot point to a commit. Maybe we have to do this in a subsequent PR.
|
|
||
| /** Pre-existing gaps that predate this safety net. Each should be addressed in its own follow-up | ||
| * JIRA before being removed from this list. */ | ||
| private static final Set<String> KNOWN_UNCOVERED_RELS = |
There was a problem hiding this comment.
Why aren't we fixing these too? Is it too disruptive?
There was a problem hiding this comment.
Yes, I felt it was expanding the scope substantially. On a second thought, I decided to bite the bullet by fixing it for those other UNCOVERED_RELS as well. I will shortly update the PR.
There was a problem hiding this comment.
Updated it for the other UNCOVERED_RELS as well. Please review.
There was a problem hiding this comment.
Before merging this let's send a message to the dev list warning people about it, and giving them a chance to comment. Do you want to send it?
There was a problem hiding this comment.
Yes I can send about this breaking change in dev list.
…, Uncollect, Combine, ConditionalCorrelate, SortExchange, and TableSpool Adds the same dispatch-routing fix to the remaining rel types skip-listed in RelShuttleCoverageTest. Each gets accept(RelShuttle) on its concrete class (or abstract parent where one exists), a matching RelShuttle.visit(X) overload, default visitChildren impl in RelShuttleImpl, and forwarding to visit((RelNode) x) in RelHomogeneousShuttle. ToLogicalConverter.visit(Uncollect) forwards to visit((RelNode) uncollect), mirroring the existing Window override; the instanceof Uncollect branch in visit(RelNode) is preserved. RelShuttleCoverageTest no longer needs the KNOWN_UNCOVERED_RELS skip-list or its reverse-assertion. Also switches SCANNED_PACKAGES to ImmutableSet.of for JDK 8 compatibility.
…ds-incompatible and add migration checklist Restructures the upgrade-doc entry from dense prose into a labeled "Backwards-incompatible." marker plus a "Migration required if:" bulleted checklist covering the three consumer scenarios (direct RelShuttle impls, RelShuttleImpl subclasses with instanceof workarounds, and the abstract-parent vs Logical* dispatch distinction). Adds a TODO comment flagging that the target release version is still pending confirmation with the committer; entry may not land in 1.42.0.
…d by other Breaking Changes entries Drops the inline "Backwards-incompatible." marker and the bulleted "Migration required if:" checklist; restores the established prose style used by past entries (e.g., CALCITE-7029 / CALCITE-7125 / CALCITE-5716 in 1.41.0). The #### Breaking Changes section header already conveys the backwards-incompatible status. Also removes the TODO comment about version assignment; entry stays under 1.42.0 (committer can move it if a later release is targeted).
|
mihaibudiu
left a comment
There was a problem hiding this comment.
Let's wait to merge this until we give a chance to other contributors to comment or at least ack the breaking change.



Jira Link
CALCITE-7511
Changes Proposed
Adds
accept(RelShuttle)overrides on rel classes that previously fell throughAbstractRelNode.accept(RelShuttle)tovisit(RelNode), plus matching type-specificRelShuttle.visit(X)overloads (with default impls inRelShuttleImpland forwardingoverrides in
RelHomogeneousShuttle). Mirrors the existing pattern onTableScan.Affected rel classes (10):
TableFunctionScan,Window,Snapshot,Collect,Sample,Uncollect,Combine,ConditionalCorrelate,SortExchange,TableSpoolaccept(RelShuttle)override is placed on the abstract parent where one exists,so all subclasses (not just
Logical*) dispatch through the type-specific overload.For example,
EnumerableTableFunctionScannow also routes throughvisit(TableFunctionScan).Also adds the previously-missing
RelHomogeneousShuttle.visit(LogicalAsofJoin)forwardingoverride; subclasses that relied on
LogicalAsofJoinnot being routed through theirvisit(RelNode)override will now see it routed there, matching every other rel typein the homogeneous shuttle.
Migrates
SqlHintsConverterTest.HintCollectorandToLogicalConverteroffinstanceofworkarounds inside
visit(RelNode)for the affected types where applicable.Adds
RelShuttleCoverageTestas a regression guard: reflectively scans concrete rels inorg.apache.calcite.rel.core/.logicaland asserts every one is covered by anon-
visit(RelNode)overload onRelShuttle. Also asserts everyRelShuttle.visit(X)parameter type declares its own
accept(RelShuttle).Documented as a breaking change in
site/_docs/history.md(see prior discussion onCALCITE-7288 / #4620): callers implementing
RelShuttledirectly must add the newmethods; subclasses of
RelShuttleImplthat handled any of these types viainstanceofchecks in
visit(RelNode)should migrate to the type-specific overrides.