[ 
https://issues.apache.org/jira/browse/CALCITE-980?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15029666#comment-15029666
 ] 

Julian Hyde commented on CALCITE-980:
-------------------------------------

Anyway, I'm not going to veto your change. You're welcome to move the tests 
into another Java class, or keep them in JdbcTest. Or SqlOperatorBaseTest, 
which some nice facilities for running the same tests against different 
engines. I don't think there's a "right answer" but I wanted to make you aware 
of the alternatives.

Yes, it's hard to test the nullable and non-nullable combinations, especially 
when you include all of the other operators, such as CASE and IN and NOT.

Regarding boxed return type. When a boolean is used in a WHERE clause it is 
implicitly wrapped in "IS TRUE" i.e. null is treated as false, so we take great 
pains to keep booleans primitive. That optimization is great for end users, but 
makes it more difficult to test for null behavior.

> Not (C='a' or C='b') as well as Not (C='a' and C='b') causes NPE
> ----------------------------------------------------------------
>
>                 Key: CALCITE-980
>                 URL: https://issues.apache.org/jira/browse/CALCITE-980
>             Project: Calcite
>          Issue Type: Bug
>    Affects Versions: 1.4.0-incubating
>            Reporter: liyang
>            Assignee: Julian Hyde
>
> A where clause like Not (C='a' or C='b') causes NPE if C has NULL value.
> The generated code snippet looks like:
> {code}
> /*  65 */           public boolean moveNext() {
> /*  66 */             while (inputEnumerator.moveNext()) {
> /*  67 */               final Object[] current = (Object[]) 
> inputEnumerator.current();
> /*  68 */               final String inp21_ = current[21] == null ? (String) 
> null : current[21].toString();
> /*  69 */               final Boolean v = inp21_ == null ? (Boolean) null : 
> Boolean.valueOf(org.apache.calcite.runtime.SqlFunctions.eq(inp21_, "A"));
> /*  70 */               final Boolean v0 = inp21_ == null ? (Boolean) null : 
> Boolean.valueOf(org.apache.calcite.runtime.SqlFunctions.eq(inp21_, "B"));
> /*  71 */               if (!(v == null ? (v0 == null || !v0 ? (Boolean) null 
> : Boolean.TRUE) : v ? Boolean.TRUE : v0)) {
> /*  72 */                 return true;
> /*  73 */               }
> /*  74 */             }
> /*  75 */             return false;
> /*  76 */           }
> {code}
> And NPE is thrown at line #71 if inp21_ is null.
> Stacktrace:
> {code}
> Caused by: java.lang.NullPointerException
>       at Baz$1$1.moveNext(ANONYMOUS.java:71)
>       at 
> org.apache.calcite.linq4j.EnumerableDefaults.groupBy_(EnumerableDefaults.java:737)
>       at 
> org.apache.calcite.linq4j.EnumerableDefaults.groupBy(EnumerableDefaults.java:677)
>       at 
> org.apache.calcite.linq4j.DefaultEnumerable.groupBy(DefaultEnumerable.java:301)
>       at Baz.bind(Baz.java:95)
>       at 
> org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:281)
>       at 
> org.apache.calcite.jdbc.CalciteConnectionImpl.enumerable(CalciteConnectionImpl.java:235)
>       at 
> org.apache.calcite.jdbc.CalciteMetaImpl.createIterable(CalciteMetaImpl.java:533)
>       at 
> org.apache.calcite.avatica.AvaticaResultSet.execute(AvaticaResultSet.java:184)
>       at 
> org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:63)
>       at 
> org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:42)
>       at 
> org.apache.calcite.avatica.AvaticaConnection$1.execute(AvaticaConnection.java:473)
>       at 
> org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:566)
>       at 
> org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:477)
>       at 
> org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:109)
>       ... 29 more
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to