[
https://issues.apache.org/jira/browse/CALCITE-5289?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mihai Budiu updated CALCITE-5289:
---------------------------------
Description:
The reproduction is easy: just modify the following test case from
PlannerTest.java:
--- a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
{{{{@@ -1005,7 +1005,7 @@ private void checkJoinNWay(int n) throws Exception
{}}}}
{{private void checkHeuristic(String sql, String expected) throws Exception {}}
{{ Planner planner = getPlanner(null,}}
{{- Programs.heuristicJoinOrder(Programs.RULE_SET, false, 0));}}
{{+ Programs.heuristicJoinOrder(Programs.RULE_SET, true, 0));}}
{{ SqlNode parse = planner.parse(sql);}}
{{ SqlNode validate = planner.validate(parse);}}
{{ {{ RelNode convert = planner.rel(validate).rel;}}}}
Then the test fails with the exception shown below. This happens with the
latest version of calcite, the main branch.
It looks like the rule does not account for the fact that outer joins can
produce results with a different nullability than the input relations.
The exception can be triggered even for very simple outer join queries, e.g.:
SELECT T1.COL3 FROM T AS T1 LEFT JOIN T AS T2 ON T1.COL1 = T2.COL5
The only workaround I found is to make sure this rule is never applied when a
query contains an outer join.
Here is the Java stack trace:
{{java.lang.RuntimeException: Error while applying rule
MultiJoinOptimizeBushyRule, args
[rel#44:MultiJoin.NONE.[](input#0=RelSubset#42,input#1=RelSubset#43,joinFilter=true,isFullOuterJoin=false,joinTypes=[RIGHT,
INNER],outerJoinConditions=[=($0, $10), NULL],projFields=[ALL, ALL])]}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:250)}}
{{ at
org.apache.calcite.plan.volcano.IterativeRuleDriver.drive(IterativeRuleDriver.java:59)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:523)}}
{{ at
org.apache.calcite.tools.Programs$RuleSetProgram.run(Programs.java:318)}}
{{ at
org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:337)}}
{{ at
org.apache.calcite.tools.Programs.lambda$heuristicJoinOrder$1(Programs.java:223)}}
{{ at
org.apache.calcite.prepare.PlannerImpl.transform(PlannerImpl.java:373)}}
{{ at
org.apache.calcite.tools.PlannerTest.checkHeuristic(PlannerTest.java:1014)}}
{{ at
org.apache.calcite.tools.PlannerTest.testHeuristicRightJoin(PlannerTest.java:1003)}}
{{ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)}}
{{ at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)}}
{{ at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)}}
{{ at java.lang.reflect.Method.invoke(Method.java:498)}}
{{ at
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)}}
{{ at
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)}}
{{ at
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)}}
{{ at
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)}}
{{ at
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
{{ at
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
{{ at java.util.ArrayList.forEach(ArrayList.java:1257)}}
{{ at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
{{ at
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
{{ at java.util.ArrayList.forEach(ArrayList.java:1257)}}
{{ at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
{{ at
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
{{ at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)}}
{{ at
org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)}}
{{ at
org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)}}
{{ at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)}}
{{ at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)}}
{{ at
org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)}}
{{ at
org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)}}
{{ at
com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)}}
{{ at
com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)}}
{{ at
com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)}}
{{ at
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)}}
{{ at
com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)}}
{{ at
com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)}}
{{Caused by: java.lang.RuntimeException: Error occurred while applying rule
MultiJoinOptimizeBushyRule}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.transformTo(VolcanoRuleCall.java:157)}}
{{ at
org.apache.calcite.plan.RelOptRuleCall.transformTo(RelOptRuleCall.java:269)}}
{{ at
org.apache.calcite.plan.RelOptRuleCall.transformTo(RelOptRuleCall.java:284)}}
{{ at
org.apache.calcite.rel.rules.MultiJoinOptimizeBushyRule.onMatch(MultiJoinOptimizeBushyRule.java:292)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:223)}}
{{ ... 77 more}}
{{Caused by: java.lang.IllegalArgumentException: Type mismatch:}}
{{rel rowtype: RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL
deptno, JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
JavaType(class java.lang.Integer) commission, JavaType(int) NOT NULL deptno0,
JavaType(class java.lang.String) name0, RecordType(JavaType(int) NOT NULL
empid, JavaType(int) NOT NULL deptno, JavaType(class java.lang.String) name,
JavaType(float) NOT NULL salary, JavaType(class java.lang.Integer) commission)
NOT NULL ARRAY NOT NULL employees, JavaType(int) NOT NULL x, JavaType(int) NOT
NULL y, JavaType(int) NOT NULL empid0, JavaType(class java.lang.String) name1)
NOT NULL}}
{{equiv rowtype: RecordType(JavaType(class java.lang.Integer) empid,
JavaType(class java.lang.Integer) deptno, JavaType(class java.lang.String)
name, JavaType(class java.lang.Float) salary, JavaType(class java.lang.Integer)
commission, JavaType(class java.lang.Integer) deptno0, JavaType(class
java.lang.String) name0, RecordType(JavaType(int) NOT NULL empid, JavaType(int)
NOT NULL deptno, JavaType(class java.lang.String) name, JavaType(float) NOT
NULL salary, JavaType(class java.lang.Integer) commission) NOT NULL ARRAY
employees, JavaType(class java.lang.Integer) x, JavaType(class
java.lang.Integer) y, JavaType(int) NOT NULL empid0, JavaType(class
java.lang.String) name1) NOT NULL}}
{{Difference:}}
{{empid: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{deptno: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{salary: JavaType(float) NOT NULL -> JavaType(class java.lang.Float)}}
{{deptno0: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{employees: RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL
deptno, JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
JavaType(class java.lang.Integer) commission) NOT NULL ARRAY NOT NULL ->
RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL deptno,
JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
JavaType(class java.lang.Integer) commission) NOT NULL ARRAY}}
{{x: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{y: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:592)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:613)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.transformTo(VolcanoRuleCall.java:144)}}
{{ ... 81 more}}
was:
The reproduction is easy: just modify the following test case from
PlannerTest.java:
{{{}--- a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
{}}}{{{}+++ b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
{}}}{{{}@@ -1005,7 +1005,7 @@ private void checkJoinNWay(int n) throws
Exception {{}}}
{{private void checkHeuristic(String sql, String expected) throws Exception {
}}{{{} Planner planner = getPlanner(null,
{}}}{{{}- Programs.heuristicJoinOrder(Programs.RULE_SET, false, 0));
{}}}{{{}+ Programs.heuristicJoinOrder(Programs.RULE_SET, true, 0));
{}}}{{ SqlNode parse = planner.parse(sql);
}}{{ SqlNode validate = planner.validate(parse);
}}{{ RelNode convert = planner.rel(validate).rel;}}
Then the test fails with the exception shown below. This happens with the
latest version of calcite, the main branch.
It looks like the rule does not account for the fact that outer joins can
produce results with a different nullability than the input relations.
The exception can be triggered even for very simple outer join queries, e.g.:
SELECT T1.COL3 FROM T AS T1 LEFT JOIN T AS T2 ON T1.COL1 = T2.COL5
The only workaround I found is to make sure this rule is never applied when a
query contains an outer join.
Here is the Java stack trace:
{{java.lang.RuntimeException: Error while applying rule
MultiJoinOptimizeBushyRule, args
[rel#44:MultiJoin.NONE.[](input#0=RelSubset#42,input#1=RelSubset#43,joinFilter=true,isFullOuterJoin=false,joinTypes=[RIGHT,
INNER],outerJoinConditions=[=($0, $10), NULL],projFields=[ALL, ALL])]}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:250)}}
{{ at
org.apache.calcite.plan.volcano.IterativeRuleDriver.drive(IterativeRuleDriver.java:59)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:523)}}
{{ at
org.apache.calcite.tools.Programs$RuleSetProgram.run(Programs.java:318)}}
{{ at
org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:337)}}
{{ at
org.apache.calcite.tools.Programs.lambda$heuristicJoinOrder$1(Programs.java:223)}}
{{ at
org.apache.calcite.prepare.PlannerImpl.transform(PlannerImpl.java:373)}}
{{ at
org.apache.calcite.tools.PlannerTest.checkHeuristic(PlannerTest.java:1014)}}
{{ at
org.apache.calcite.tools.PlannerTest.testHeuristicRightJoin(PlannerTest.java:1003)}}
{{ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)}}
{{ at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)}}
{{ at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)}}
{{ at java.lang.reflect.Method.invoke(Method.java:498)}}
{{ at
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)}}
{{ at
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)}}
{{ at
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)}}
{{ at
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)}}
{{ at
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)}}
{{ at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)}}
{{ at
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)}}
{{ at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
{{ at
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
{{ at java.util.ArrayList.forEach(ArrayList.java:1257)}}
{{ at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
{{ at
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
{{ at java.util.ArrayList.forEach(ArrayList.java:1257)}}
{{ at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
{{ at
org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
{{ at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
{{ at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
{{ at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)}}
{{ at
org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)}}
{{ at
org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)}}
{{ at
org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)}}
{{ at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)}}
{{ at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)}}
{{ at
org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)}}
{{ at
org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)}}
{{ at
com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)}}
{{ at
com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)}}
{{ at
com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)}}
{{ at
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)}}
{{ at
com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)}}
{{ at
com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)}}
{{Caused by: java.lang.RuntimeException: Error occurred while applying rule
MultiJoinOptimizeBushyRule}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.transformTo(VolcanoRuleCall.java:157)}}
{{ at
org.apache.calcite.plan.RelOptRuleCall.transformTo(RelOptRuleCall.java:269)}}
{{ at
org.apache.calcite.plan.RelOptRuleCall.transformTo(RelOptRuleCall.java:284)}}
{{ at
org.apache.calcite.rel.rules.MultiJoinOptimizeBushyRule.onMatch(MultiJoinOptimizeBushyRule.java:292)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:223)}}
{{ ... 77 more}}
{{Caused by: java.lang.IllegalArgumentException: Type mismatch:}}
{{rel rowtype: RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL
deptno, JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
JavaType(class java.lang.Integer) commission, JavaType(int) NOT NULL deptno0,
JavaType(class java.lang.String) name0, RecordType(JavaType(int) NOT NULL
empid, JavaType(int) NOT NULL deptno, JavaType(class java.lang.String) name,
JavaType(float) NOT NULL salary, JavaType(class java.lang.Integer) commission)
NOT NULL ARRAY NOT NULL employees, JavaType(int) NOT NULL x, JavaType(int) NOT
NULL y, JavaType(int) NOT NULL empid0, JavaType(class java.lang.String) name1)
NOT NULL}}
{{equiv rowtype: RecordType(JavaType(class java.lang.Integer) empid,
JavaType(class java.lang.Integer) deptno, JavaType(class java.lang.String)
name, JavaType(class java.lang.Float) salary, JavaType(class java.lang.Integer)
commission, JavaType(class java.lang.Integer) deptno0, JavaType(class
java.lang.String) name0, RecordType(JavaType(int) NOT NULL empid, JavaType(int)
NOT NULL deptno, JavaType(class java.lang.String) name, JavaType(float) NOT
NULL salary, JavaType(class java.lang.Integer) commission) NOT NULL ARRAY
employees, JavaType(class java.lang.Integer) x, JavaType(class
java.lang.Integer) y, JavaType(int) NOT NULL empid0, JavaType(class
java.lang.String) name1) NOT NULL}}
{{Difference:}}
{{empid: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{deptno: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{salary: JavaType(float) NOT NULL -> JavaType(class java.lang.Float)}}
{{deptno0: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{employees: RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL
deptno, JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
JavaType(class java.lang.Integer) commission) NOT NULL ARRAY NOT NULL ->
RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL deptno,
JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
JavaType(class java.lang.Integer) commission) NOT NULL ARRAY}}
{{x: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{y: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:592)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:613)}}
{{ at
org.apache.calcite.plan.volcano.VolcanoRuleCall.transformTo(VolcanoRuleCall.java:144)}}
{{ ... 81 more}}
> Assertion failure in MultiJoinOptimizeBushyRule
> -----------------------------------------------
>
> Key: CALCITE-5289
> URL: https://issues.apache.org/jira/browse/CALCITE-5289
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.32.0
> Reporter: Mihai Budiu
> Priority: Minor
>
> The reproduction is easy: just modify the following test case from
> PlannerTest.java:
>
> --- a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
> +++ b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
> {{{{@@ -1005,7 +1005,7 @@ private void checkJoinNWay(int n) throws Exception
> {}}}}
> {{private void checkHeuristic(String sql, String expected) throws Exception
> {}}
> {{ Planner planner = getPlanner(null,}}
> {{- Programs.heuristicJoinOrder(Programs.RULE_SET, false, 0));}}
> {{+ Programs.heuristicJoinOrder(Programs.RULE_SET, true, 0));}}
> {{ SqlNode parse = planner.parse(sql);}}
> {{ SqlNode validate = planner.validate(parse);}}
> {{ {{ RelNode convert = planner.rel(validate).rel;}}}}
>
> Then the test fails with the exception shown below. This happens with the
> latest version of calcite, the main branch.
> It looks like the rule does not account for the fact that outer joins can
> produce results with a different nullability than the input relations.
> The exception can be triggered even for very simple outer join queries, e.g.:
> SELECT T1.COL3 FROM T AS T1 LEFT JOIN T AS T2 ON T1.COL1 = T2.COL5
>
> The only workaround I found is to make sure this rule is never applied when a
> query contains an outer join.
>
> Here is the Java stack trace:
> {{java.lang.RuntimeException: Error while applying rule
> MultiJoinOptimizeBushyRule, args
> [rel#44:MultiJoin.NONE.[](input#0=RelSubset#42,input#1=RelSubset#43,joinFilter=true,isFullOuterJoin=false,joinTypes=[RIGHT,
> INNER],outerJoinConditions=[=($0, $10), NULL],projFields=[ALL, ALL])]}}
>
> {{ at
> org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:250)}}
> {{ at
> org.apache.calcite.plan.volcano.IterativeRuleDriver.drive(IterativeRuleDriver.java:59)}}
> {{ at
> org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:523)}}
> {{ at
> org.apache.calcite.tools.Programs$RuleSetProgram.run(Programs.java:318)}}
> {{ at
> org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:337)}}
> {{ at
> org.apache.calcite.tools.Programs.lambda$heuristicJoinOrder$1(Programs.java:223)}}
> {{ at
> org.apache.calcite.prepare.PlannerImpl.transform(PlannerImpl.java:373)}}
> {{ at
> org.apache.calcite.tools.PlannerTest.checkHeuristic(PlannerTest.java:1014)}}
> {{ at
> org.apache.calcite.tools.PlannerTest.testHeuristicRightJoin(PlannerTest.java:1003)}}
> {{ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method)}}
> {{ at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)}}
> {{ at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)}}
> {{ at java.lang.reflect.Method.invoke(Method.java:498)}}
> {{ at
> org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)}}
> {{ at
> org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)}}
> {{ at
> org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)}}
> {{ at
> org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)}}
> {{ at
> org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)}}
> {{ at
> org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)}}
> {{ at
> org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)}}
> {{ at
> org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)}}
> {{ at
> org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)}}
> {{ at
> org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)}}
> {{ at
> org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)}}
> {{ at
> org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)}}
> {{ at
> org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)}}
> {{ at
> org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)}}
> {{ at
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)}}
> {{ at
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)}}
> {{ at
> org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
> {{ at java.util.ArrayList.forEach(ArrayList.java:1257)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
> {{ at java.util.ArrayList.forEach(ArrayList.java:1257)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)}}
> {{ at
> org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)}}
> {{ at
> org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)}}
> {{ at
> org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)}}
> {{ at
> org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)}}
> {{ at
> org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)}}
> {{ at
> org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)}}
> {{ at
> org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)}}
> {{ at
> org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)}}
> {{ at
> org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)}}
> {{ at
> org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)}}
> {{ at
> com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)}}
> {{ at
> com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)}}
> {{ at
> com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)}}
> {{ at
> com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)}}
> {{ at
> com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)}}
> {{ at
> com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)}}
> {{Caused by: java.lang.RuntimeException: Error occurred while applying rule
> MultiJoinOptimizeBushyRule}}
> {{ at
> org.apache.calcite.plan.volcano.VolcanoRuleCall.transformTo(VolcanoRuleCall.java:157)}}
> {{ at
> org.apache.calcite.plan.RelOptRuleCall.transformTo(RelOptRuleCall.java:269)}}
> {{ at
> org.apache.calcite.plan.RelOptRuleCall.transformTo(RelOptRuleCall.java:284)}}
> {{ at
> org.apache.calcite.rel.rules.MultiJoinOptimizeBushyRule.onMatch(MultiJoinOptimizeBushyRule.java:292)}}
> {{ at
> org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:223)}}
> {{ ... 77 more}}
> {{Caused by: java.lang.IllegalArgumentException: Type mismatch:}}
> {{rel rowtype: RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT
> NULL deptno, JavaType(class java.lang.String) name, JavaType(float) NOT NULL
> salary, JavaType(class java.lang.Integer) commission, JavaType(int) NOT NULL
> deptno0, JavaType(class java.lang.String) name0, RecordType(JavaType(int) NOT
> NULL empid, JavaType(int) NOT NULL deptno, JavaType(class java.lang.String)
> name, JavaType(float) NOT NULL salary, JavaType(class java.lang.Integer)
> commission) NOT NULL ARRAY NOT NULL employees, JavaType(int) NOT NULL x,
> JavaType(int) NOT NULL y, JavaType(int) NOT NULL empid0, JavaType(class
> java.lang.String) name1) NOT NULL}}
> {{equiv rowtype: RecordType(JavaType(class java.lang.Integer) empid,
> JavaType(class java.lang.Integer) deptno, JavaType(class java.lang.String)
> name, JavaType(class java.lang.Float) salary, JavaType(class
> java.lang.Integer) commission, JavaType(class java.lang.Integer) deptno0,
> JavaType(class java.lang.String) name0, RecordType(JavaType(int) NOT NULL
> empid, JavaType(int) NOT NULL deptno, JavaType(class java.lang.String) name,
> JavaType(float) NOT NULL salary, JavaType(class java.lang.Integer)
> commission) NOT NULL ARRAY employees, JavaType(class java.lang.Integer) x,
> JavaType(class java.lang.Integer) y, JavaType(int) NOT NULL empid0,
> JavaType(class java.lang.String) name1) NOT NULL}}
> {{Difference:}}
> {{empid: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
> {{deptno: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
> {{salary: JavaType(float) NOT NULL -> JavaType(class java.lang.Float)}}
> {{deptno0: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
> {{employees: RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL
> deptno, JavaType(class java.lang.String) name, JavaType(float) NOT NULL
> salary, JavaType(class java.lang.Integer) commission) NOT NULL ARRAY NOT NULL
> -> RecordType(JavaType(int) NOT NULL empid, JavaType(int) NOT NULL deptno,
> JavaType(class java.lang.String) name, JavaType(float) NOT NULL salary,
> JavaType(class java.lang.Integer) commission) NOT NULL ARRAY}}
> {{x: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
> {{y: JavaType(int) NOT NULL -> JavaType(class java.lang.Integer)}}
>
> {{ at
> org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:592)}}
> {{ at
> org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:613)}}
> {{ at
> org.apache.calcite.plan.volcano.VolcanoRuleCall.transformTo(VolcanoRuleCall.java:144)}}
> {{ ... 81 more}}
>
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)