-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[CALCITE-7753] CorrelateProjectExtractor corrupts plans with nested Correlates that reuse the same correlation id
#5231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2548,4 +2548,43 @@ private RelNode decorrelateSql(String sql) { | |
| + " LogicalTableScan(table=[[bookstore, authors]])\n"; | ||
| assertThat(after, hasTree(planAfter)); | ||
| } | ||
|
|
||
| /** Test case for | ||
| * <a href="https://issues.apache.org/jira/browse/CALCITE-7753">[CALCITE-7753] | ||
| * CorrelateProjectExtractor corrupts plans with nested Correlates that reuse | ||
| * the same correlation id</a>. */ | ||
| @Test void testNestedCorrelatesSharingCorrelationId() { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in jira: it is not reproducible with pure SQL in Calcite
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the bug requires two nested Correlates that share the same correlation id, and pure SQL (in Calcite) never produces that shape: Calcite's SqlToRelConverter gives every correlated subquery scope its own id. |
||
| final RelBuilder builder = RelBuilder.create(config().build()) | ||
| .transform(c -> c.withSimplify(false)); | ||
| final Holder<@Nullable RexCorrelVariable> v = Holder.empty(); | ||
| builder.scan("EMP").variable(v::set); | ||
| final RelNode emp = builder.build(); | ||
|
|
||
| final RelNode inner = builder | ||
| .scan("EMP") | ||
| .scan("EMP") | ||
| .filter(builder.equals(builder.field(v.get(), "DEPTNO"), builder.field("DEPTNO"))) | ||
| .correlate(JoinRelType.INNER, v.get().id, builder.field(2, 0, "DEPTNO")) | ||
| .filter(builder.isNull(builder.field(v.get(), "COMM"))) | ||
| .build(); | ||
|
|
||
| final RelNode before = builder | ||
| .push(emp) | ||
| .push(inner) | ||
| .correlate(JoinRelType.LEFT, v.get().id, builder.field(2, 0, "COMM")) | ||
| .build(); | ||
| final String planBefore = "" | ||
| + "LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{6}])\n" | ||
| + " LogicalTableScan(table=[[scott, EMP]])\n" | ||
| + " LogicalFilter(condition=[IS NULL($cor0.COMM)])\n" | ||
| + " LogicalCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{7}])\n" | ||
| + " LogicalTableScan(table=[[scott, EMP]])\n" | ||
| + " LogicalFilter(condition=[=($cor0.DEPTNO, $7)])\n" | ||
| + " LogicalTableScan(table=[[scott, EMP]])\n"; | ||
| assertThat(before, hasTree(planBefore)); | ||
|
|
||
| RelDecorrelator.decorrelateQuery(before, builder, | ||
| RuleSets.ofList(Collections.emptyList()), | ||
| RuleSets.ofList(Collections.emptyList())); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if its possible to plug the fix in
findCorrelationDependentCallsto avoid traversing again a potentially large sub plan? How about stopping traversal inside findCorrelationDependentCalls if we encounter a correlate with the same id?