[
https://issues.apache.org/jira/browse/CALCITE-5289?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17627130#comment-17627130
]
Mou Wu edited comment on CALCITE-5289 at 11/1/22 12:12 PM:
-----------------------------------------------------------
I found the root cause, for example: there is a left join query, the row-type
of join's right expression should be nullable, so JavaType should be boxed,
e.g. 'int' will be 'Integer', and then, the MultiJoinOptimizeBushyRule will
check the relNode's row-type should be same with original relNode, so throw the
type not-matched exception.
was (Author: JIRAUSER290047):
I found the root cause, for example: there is a left join query, the row-type
of join's right expression should be nullable, e.g. 'int' will be 'Integer',
and then, the MultiJoinOptimizeBushyRule will check the relNode's row-type
should be same with original relNode, so throw the type not-matched exception.
> 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
> Assignee: Mou Wu
> 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)