This is an automated email from the ASF dual-hosted git repository.

danny0405 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new 65043f2  [CALCITE-3433] EQUALS operator between date/timestamp types 
returns false if the type is nullable (DonnyZone)
65043f2 is described below

commit 65043f290a7be45a668cf941ab48ee3c30efbe4e
Author: wellfengzhu <[email protected]>
AuthorDate: Mon Oct 28 17:12:25 2019 +0800

    [CALCITE-3433] EQUALS operator between date/timestamp types returns false 
if the type is nullable (DonnyZone)
    
    When checking equals or not-equals on two primitive boxing classes
    (i.e. Long x, Long y), we should fall back to call `SqlFunctions.eq(x, y)`
    and `SqlFunctions.ne(x, y)`, rather than `x == y`.
    
    close apache/calcite#1540
---
 .../apache/calcite/adapter/enumerable/RexImpTable.java   | 16 ++++++++++++++++
 core/src/test/java/org/apache/calcite/test/JdbcTest.java | 16 ++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 95bfac6..a19fd13 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -2273,6 +2273,12 @@ public class RexImpTable {
             SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
             SqlStdOperatorTable.GREATER_THAN,
             SqlStdOperatorTable.GREATER_THAN_OR_EQUAL);
+
+    private static final List<SqlBinaryOperator> EQUALS_OPERATORS =
+        ImmutableList.of(
+            SqlStdOperatorTable.EQUALS,
+            SqlStdOperatorTable.NOT_EQUALS);
+
     public static final String METHOD_POSTFIX_FOR_ANY_TYPE = "Any";
 
     private final ExpressionType expressionType;
@@ -2319,6 +2325,16 @@ public class RexImpTable {
           return Expressions.call(SqlFunctions.class, backupMethodName,
               expressions);
         }
+        // When checking equals or not equals on two primitive boxing classes
+        // (i.e. Long x, Long y), we should fall back to call 
`SqlFunctions.eq(x, y)`
+        // or `SqlFunctions.ne(x, y)`, rather than `x == y`
+        final Primitive boxPrimitive0 = Primitive.ofBox(type0);
+        final Primitive boxPrimitive1 = Primitive.ofBox(type1);
+        if (EQUALS_OPERATORS.contains(op)
+            && boxPrimitive0 != null && boxPrimitive1 != null) {
+          return Expressions.call(SqlFunctions.class, backupMethodName,
+              expressions);
+        }
       }
 
       final Type returnType =
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java 
b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 5fb8f71..e34effb 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -5943,6 +5943,22 @@ public class JdbcTest {
         .returnsUnordered("EMPNO=7876", "EMPNO=7499", "EMPNO=7698");
   }
 
+  @Test public void testTimestampEqualsComparison() {
+    CalciteAssert.that()
+        .query("select time0 = time1, time0 <> time1"
+            + " from ("
+            + "  select timestamp'2000-12-30 21:07:32'as time0,"
+            + "         timestamp'2000-12-30 21:07:32'as time1 "
+            + "  union all"
+            + "  select cast(null as timestamp) as time0,"
+            + "         cast(null as timestamp) as time1"
+            + ") calcs")
+        .planContains("org.apache.calcite.runtime.SqlFunctions.eq(inp0_, 
inp1_)")
+        .planContains("org.apache.calcite.runtime.SqlFunctions.ne(inp0_, 
inp1_)")
+        .returns("EXPR$0=true; EXPR$1=false\n"
+            + "EXPR$0=null; EXPR$1=null\n");
+  }
+
   @Test public void testUnicode() throws Exception {
     CalciteAssert.AssertThat with =
         CalciteAssert.that().with(CalciteAssert.Config.FOODMART_CLONE);

Reply via email to