[ 
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)

Reply via email to