Arvid Heise created CALCITE-1721:
------------------------------------

             Summary: RexImpTable translates NOT to expression that can never 
evaluate to true
                 Key: CALCITE-1721
                 URL: https://issues.apache.org/jira/browse/CALCITE-1721
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.11.0
            Reporter: Arvid Heise
            Assignee: Julian Hyde


When compiling a query of the form "<cond1> AND NOT <cond2>", where cond1 
returns a nullable boolean and cond2 is non-nullable, RexImpTable does not 
handle the NOT operator properly.

Given some query, such as "uri = 'google.de' AND NOT blacklisted"
The resulting code does not contain any true branch.
{code:java}
public Object[] apply(Object root0) {
  final String inp61_ = ((Object[]) ((org.apache.calcite.DataContext) 
root0).get("inputRecord"))[61] == null ? (String) null : ((Object[]) 
((org.apache.calcite.DataContext) root0).get("inputRecord"))[61].toString();
  return new Object[] {
(      inp61_ == null || org.apache.calcite.runtime.SqlFunctions.eq(inp61_, 
"google.de")) && !org.apache.calcite.runtime.SqlFunctions.toBoolean(((Object[]) 
((org.apache.calcite.DataContext) root0).get("inputRecord"))[136]) ? (Boolean) 
null : Boolean.FALSE};
}
{code}

If we look at the unoptizimed code, we can quickly see the root cause:
{code:Java}
final org.apache.calcite.DataContext root = (org.apache.calcite.DataContext) 
root0;
final String inp61_ = ((Object[]) root.get("inputRecord"))[61] == null ? 
(String) null : ((Object[]) root.get("inputRecord"))[61].toString();
final boolean inp61__unboxed = inp61_ == null;
final boolean v = inp61__unboxed || 
org.apache.calcite.runtime.SqlFunctions.eq(inp61_"google.de");
final boolean inp136_ = 
org.apache.calcite.runtime.SqlFunctions.toBoolean(((Object[]) 
root.get("inputRecord"))[136]);
final boolean v0 = !inp136_;
final boolean inp61__unboxed0 = inp61_ == null;
final boolean v1 = !false;
final Boolean v2 = !(v && v0) ? Boolean.FALSE : inp61__unboxed0 || v1 ? 
(Boolean) null : Boolean.TRUE;
return new Object[] {v2};
{code}

v1 is always true, which triggers the NULL path of the second condition.

I suspect that the NOT handler of RexImpTable should have a special branch for 
IS_NULL where the negation is not applied
https://github.com/apache/calcite/blob/master/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java#L592



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to