[
https://issues.apache.org/jira/browse/CALCITE-6501?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17868668#comment-17868668
]
kate edited comment on CALCITE-6501 at 7/25/24 2:43 PM:
--------------------------------------------------------
Apologies, I would like to express my thoughts in more detail.
In the case above, for example, in JoinOnLeftCalcToJoinUnifyRule, we want to
add a Calc to the MV to make the MV equivalent to a query. In this scenario,
the compensated Calc is made up of the query's Calc plus the query's RAny
collocation (the Project of the Calc is not modified in any way).
However, in the case of a RightJoin, if there is a non-null field in the Calc,
after the Join operator, the type of this operator is inferred to be nullable
because it is on the null-producing side of the Join. Therefore, if we still
use the original logic to construct the Calc, an assertion error will occur
during type checking due to the type mismatch.
!image-2024-07-25-22-05-23-957.png|width=417,height=208!
We should not modify the RexProgram.create method, as the type checking in this
method is reasonable. Instead, we need to perform checks in advance to avoid
such situations. A simple solution is to return null when there is a non-null
field in the Calc of the query and it involves a RightJoin.
While this approach may miss some rewrite opportunities, it prevents assertions
from being generated when the above situation occurs. Of course, this is a
one-size-fits-all and conservative approach.
That's why I'm conflating the two, because it's not necessarily the best
solution to this problem, and in my opinion, the optimal approach would be to
consider when to fix null to ensure rewrites, since fixing null for some cases
could result in an error. For example, consider SELECT CASE WHEN a is null THEN
1 ELSE 0 END as a1. Allowing for such rewrites may produce incorrect results.
I'd like to see what you guys think about this, and for the latter, I think
it's an interesting exploration
was (Author: JIRAUSER301334):
[~asolimando] Yes, I agree that we shouldn't be discussing this together. For
the Assert part, I think we should return null before the assert occurs, for
the case above, the root cause is the mismatch of the null value, and if one
wishes to avoid this, the approach can be to reject the Right Join in
JoinOnLeftCalcToJoin, and to reject the Right Join in JoinOnRIghtCalcToJoin
rejects Left Join. Of course, this would be a missed opportunity for some
rewrites, even if it is rewritable.
> Assertion Error in JoinUnifyRule Due to Type Mismatch
> -----------------------------------------------------
>
> Key: CALCITE-6501
> URL: https://issues.apache.org/jira/browse/CALCITE-6501
> Project: Calcite
> Issue Type: Bug
> Components: core
> Reporter: kate
> Priority: Minor
> Attachments: image-2024-07-25-22-05-23-957.png
>
>
> In some cases, there is an assertion failure during the unifyRule rewriting
> process due to a type mismatch. If we can't rewrite it, we'd better return
> null instead of assert.
> example:
> {code:java}
> @Test
> public void testJoinOnCalcToJoin3011()
> {
> String mv = ""
> + "select \"emps\".\"empid\", \"emps\".\"deptno\", \"depts\".\"deptno\"
> from\n"
> + "\"emps\" right join \"depts\"\n"
> + "on \"emps\".\"deptno\" = \"depts\".\"deptno\"";
> String query = ""
> + "select \"A\".\"empid\", \"A\".\"a\", \"A\".\"deptno\",
> \"depts\".\"deptno\" from\n"
> + " (select \"empid\", \"deptno\", \"deptno\" \"a\" from \"emps\") A"
> + " right join \"depts\"\n"
> + "on \"A\".\"deptno\" = \"depts\".\"deptno\"";
> sql(mv, query).noMat();
> } {code}
> Trace:
> {code:java}
> type mismatch:type1:JavaType(int) NOT NULLtype2:JavaType(class
> java.lang.Integer)java.lang.AssertionError: type mismatch:type1:JavaType(int)
> NOT NULLtype2:JavaType(class java.lang.Integer) at
> org.apache.calcite.util.Litmus.lambda$static$0(Litmus.java:31) at
> org.apache.calcite.plan.RelOptUtil.eq(RelOptUtil.java:2204) at
> org.apache.calcite.rex.RexProgramBuilder$RegisterInputShuttle.visitInputRef(RexProgramBuilder.java:949)
> at
> org.apache.calcite.rex.RexProgramBuilder$RegisterInputShuttle.visitInputRef(RexProgramBuilder.java:927)
> at org.apache.calcite.rex.RexInputRef.accept(RexInputRef.java:125) at
> org.apache.calcite.rex.RexProgramBuilder.registerInput(RexProgramBuilder.java:303)
> at
> org.apache.calcite.rex.RexProgramBuilder.addProject(RexProgramBuilder.java:213)
> at org.apache.calcite.rex.RexProgram.create(RexProgram.java:235) at
> org.apache.calcite.rex.RexProgram.create(RexProgram.java:204) at
> org.apache.calcite.plan.SubstitutionVisitor$JoinOnLeftCalcToJoinUnifyRule.apply(SubstitutionVisitor.java:1265)
> at
> org.apache.calcite.plan.SubstitutionVisitor.go(SubstitutionVisitor.java:589)
> at
> org.apache.calcite.plan.SubstitutionVisitor.go(SubstitutionVisitor.java:523)
> at
> org.apache.calcite.test.MaterializedViewSubstitutionVisitorTest$1.optimize(MaterializedViewSubstitutionVisitorTest.java:88)
> at
> org.apache.calcite.test.MaterializedViewTester.checkNoMaterialize(MaterializedViewTester.java:94)
> at
> org.apache.calcite.test.MaterializedViewFixture.noMat(MaterializedViewFixture.java:60)
> at {code}
>
>
>
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)