Ian Bertolacci created CALCITE-5387:
---------------------------------------

             Summary: type-mismatch on nullability in 
JOIN_PUSH_TRANSITIVE_PREDICATES
                 Key: CALCITE-5387
                 URL: https://issues.apache.org/jira/browse/CALCITE-5387
             Project: Calcite
          Issue Type: Bug
            Reporter: Ian Bertolacci


If the the join operands have the same core type, but different nulabilities, 
then an exception is thrown during CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES 
because the types "mismatch".

For example:
{{`select * from Query.Test as t join (select * from QUERY.JoinTable as j where 
j.ID > 10) as j on j.ID = t.C2`}}

Here, ID is {{`BIGINT NOT NULL`}} and C2 is {{`BIGINT`}}

Initial plan:
{code}
14:LogicalProject(ID=[$0], C1=[$1], C2=[$2], C3=[$3], C4=[$4], C5=[$5], 
C6=[$6], C7=[$7], ID0=[$8], C10=[$9])
  13:LogicalJoin(condition=[=($8, $2)], joinType=[inner])
    9:QueryTableScan(table=[[QUERY, Test]], fields=[[0, 1, 2, 3, 4, 5, 6, 7]])
    12:LogicalProject(ID=[$0], C1=[$1])
      11:LogicalFilter(condition=[>($0, 10)])
        10:QueryTableScan(table=[[QUERY, JoinTable]], fields=[[0, 1]])
{code}

Exception and stack-trace:
{code}
type mismatch:
ref:
BIGINT NOT NULL
input:
BIGINT
java.lang.AssertionError: type mismatch:
ref:
BIGINT NOT NULL
input:
BIGINT
        at org.apache.calcite.util.Litmus$1.fail(Litmus.java:32)
        at org.apache.calcite.plan.RelOptUtil.eq(RelOptUtil.java:2211)
        at org.apache.calcite.rex.RexChecker.visitInputRef(RexChecker.java:129)
        at org.apache.calcite.rex.RexChecker.visitInputRef(RexChecker.java:61)
        at org.apache.calcite.rex.RexInputRef.accept(RexInputRef.java:114)
        at org.apache.calcite.rex.RexChecker.visitCall(RexChecker.java:144)
        at org.apache.calcite.rex.RexChecker.visitCall(RexChecker.java:61)
        at org.apache.calcite.rex.RexCall.accept(RexCall.java:189)
        at org.apache.calcite.rel.core.Filter.isValid(Filter.java:125)
        at org.apache.calcite.rel.core.Filter.<init>(Filter.java:81)
        at 
org.apache.calcite.rel.logical.LogicalFilter.<init>(LogicalFilter.java:69)
        at 
org.apache.calcite.rel.logical.LogicalFilter.create(LogicalFilter.java:114)
        at 
org.apache.calcite.rel.core.RelFactories$FilterFactoryImpl.createFilter(RelFactories.java:345)
        at org.apache.calcite.tools.RelBuilder.filter(RelBuilder.java:1737)
        at org.apache.calcite.tools.RelBuilder.filter(RelBuilder.java:1697)
        at 
org.apache.calcite.rel.rules.JoinPushTransitivePredicatesRule.onMatch(JoinPushTransitivePredicatesRule.java:88)
        at 
org.apache.calcite.plan.AbstractRelOptPlanner.fireRule(AbstractRelOptPlanner.java:337)
        at org.apache.calcite.plan.hep.HepPlanner.applyRule(HepPlanner.java:556)
        at 
org.apache.calcite.plan.hep.HepPlanner.applyRules(HepPlanner.java:420)
        at 
org.apache.calcite.plan.hep.HepPlanner.executeRuleCollection(HepPlanner.java:286)
        at 
org.apache.calcite.plan.hep.HepInstruction$RuleCollection$State.execute(HepInstruction.java:105)
        at 
org.apache.calcite.plan.hep.HepPlanner.lambda$executeProgram$0(HepPlanner.java:211)
        at 
com.google.common.collect.ImmutableList.forEach(ImmutableList.java:406)
        at 
org.apache.calcite.plan.hep.HepPlanner.executeProgram(HepPlanner.java:210)
        at 
org.apache.calcite.plan.hep.HepProgram$State.execute(HepProgram.java:118)
        at 
org.apache.calcite.plan.hep.HepPlanner.executeProgram(HepPlanner.java:205)
        at 
org.apache.calcite.plan.hep.HepPlanner.findBestExp(HepPlanner.java:191)
{code}

My thinking is that checking if the two types are equal is not meaningful.
Instead what should happen is that the whole expression is type checked from 
scratch using the new operand type.
Even if the new and original operant types are different (in any ways) so long 
as the expression successfully type-checks, then the expression is safe to use.

Or maybe I'm just using the rule wrong.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to