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