calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject [2/3] calcite git commit: [CALCITE-1864] Allow NULL literal as argument
Date Tue, 04 Jul 2017 23:14:31 GMT
[CALCITE-1864] Allow NULL literal as argument


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/ccaa700a
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/ccaa700a
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/ccaa700a

Branch: refs/heads/master
Commit: ccaa700a0126cbca993217192df2bfe3fa4bce1a
Parents: df82643
Author: Julian Hyde <jhyde@apache.org>
Authored: Thu Jun 29 12:32:43 2017 -0700
Committer: Julian Hyde <jhyde@apache.org>
Committed: Mon Jul 3 21:32:03 2017 -0700

----------------------------------------------------------------------
 .../calcite/rel/type/RelDataTypeFactory.java    |  8 ++++++
 .../org/apache/calcite/sql/SqlOperator.java     |  2 +-
 .../sql/type/SameOperandTypeChecker.java        |  8 ------
 .../calcite/sql/type/SqlTypeFactoryImpl.java    | 29 ++++++++++++-------
 .../apache/calcite/sql/type/SqlTypeUtil.java    |  8 +++++-
 .../calcite/sql/validate/SqlValidatorImpl.java  |  6 ++--
 .../calcite/sql/test/SqlOperatorBaseTest.java   | 30 +++++++++++++++++---
 .../apache/calcite/test/SqlValidatorTest.java   |  5 +---
 core/src/test/resources/sql/misc.iq             | 11 +++++++
 9 files changed, 76 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java
index 1b3a1be..c7f2539 100644
--- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java
+++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactory.java
@@ -207,6 +207,14 @@ public interface RelDataTypeFactory {
   RelDataType createSqlType(SqlTypeName typeName);
 
   /**
+   * Creates a SQL type that represents the "unknown" type.
+   * It is only equal to itself, and is distinct from the NULL type.
+
+   * @return unknown type
+   */
+  RelDataType createUnknownType();
+
+  /**
    * Creates a SQL type with length (precision) but no scale.
    *
    * @param typeName  Name of the type, for example {@link SqlTypeName#VARCHAR}.

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
index 8a7f345..c979c01 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
@@ -579,10 +579,10 @@ public abstract class SqlOperator {
       if (operand.getKind() == SqlKind.ROW && convertRowArgToColumnList) {
         RelDataTypeFactory typeFactory = validator.getTypeFactory();
         nodeType = typeFactory.createSqlType(SqlTypeName.COLUMN_LIST);
+        ((SqlValidatorImpl) validator).setValidatedNodeType(operand, nodeType);
       } else {
         nodeType = validator.deriveType(operandScope, operand);
       }
-      ((SqlValidatorImpl) validator).setValidatedNodeType(operand, nodeType);
       argTypeBuilder.add(nodeType);
     }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/main/java/org/apache/calcite/sql/type/SameOperandTypeChecker.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SameOperandTypeChecker.java b/core/src/main/java/org/apache/calcite/sql/type/SameOperandTypeChecker.java
index 7b4248b..ddd2bd7 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SameOperandTypeChecker.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SameOperandTypeChecker.java
@@ -85,14 +85,6 @@ public class SameOperandTypeChecker implements SqlSingleOperandTypeChecker
{
     final List<Integer> operandList =
         getOperandList(operatorBinding.getOperandCount());
     for (int i : operandList) {
-      if (operatorBinding.isOperandNull(i, false)) {
-        if (throwOnFailure) {
-          throw callBinding.getValidator().newValidationError(
-              callBinding.operand(i), RESOURCE.nullIllegal());
-        } else {
-          return false;
-        }
-      }
       types[i] = operatorBinding.getOperandType(i);
     }
     int prev = -1;

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
index 9f7dc51..e512333 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
@@ -42,7 +42,6 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
 
   //~ Methods ----------------------------------------------------------------
 
-  // implement RelDataTypeFactory
   public RelDataType createSqlType(SqlTypeName typeName) {
     if (typeName.allowsPrec()) {
       return createSqlType(typeName, typeSystem.getDefaultPrecision(typeName));
@@ -52,7 +51,6 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     return canonize(newType);
   }
 
-  // implement RelDataTypeFactory
   public RelDataType createSqlType(
       SqlTypeName typeName,
       int precision) {
@@ -71,7 +69,6 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     return canonize(newType);
   }
 
-  // implement RelDataTypeFactory
   public RelDataType createSqlType(
       SqlTypeName typeName,
       int precision,
@@ -89,7 +86,10 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     return canonize(newType);
   }
 
-  // implement RelDataTypeFactory
+  public RelDataType createUnknownType() {
+    return canonize(new UnknownSqlType(this));
+  }
+
   public RelDataType createMultisetType(
       RelDataType type,
       long maxCardinality) {
@@ -113,7 +113,6 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     return canonize(newType);
   }
 
-  // implement RelDataTypeFactory
   public RelDataType createSqlIntervalType(
       SqlIntervalQualifier intervalQualifier) {
     RelDataType newType =
@@ -121,7 +120,6 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     return canonize(newType);
   }
 
-  // implement RelDataTypeFactory
   public RelDataType createTypeWithCharsetAndCollation(
       RelDataType type,
       Charset charset,
@@ -147,8 +145,7 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     return canonize(newType);
   }
 
-  // implement RelDataTypeFactory
-  public RelDataType leastRestrictive(List<RelDataType> types) {
+  @Override public RelDataType leastRestrictive(List<RelDataType> types) {
     assert types != null;
     assert types.size() >= 1;
 
@@ -193,8 +190,7 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     }
   }
 
-  // implement RelDataTypeFactory
-  public RelDataType createTypeWithNullability(
+  @Override public RelDataType createTypeWithNullability(
       final RelDataType type,
       final boolean nullable) {
     RelDataType newType;
@@ -563,6 +559,19 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
     }
     return type;
   }
+
+  /** The unknown type. Similar to the NULL type, but is only equal to
+   * itself. */
+  private static class UnknownSqlType extends BasicSqlType {
+    UnknownSqlType(RelDataTypeFactory typeFactory) {
+      super(typeFactory.getTypeSystem(), SqlTypeName.NULL);
+    }
+
+    @Override protected void generateTypeString(StringBuilder sb,
+        boolean withDetail) {
+      sb.append("UNKNOWN");
+    }
+  }
 }
 
 // End SqlTypeFactoryImpl.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
index 5b4c070..0bdcea4 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
@@ -1240,12 +1240,18 @@ public abstract class SqlTypeUtil {
       return true;
     }
 
-    // If one of the operators is of type 'ANY', return true.
+    // If one of the arguments is of type 'ANY', return true.
     if (family1 == SqlTypeFamily.ANY
         || family2 == SqlTypeFamily.ANY) {
       return true;
     }
 
+    // If one of the arguments is of type 'NULL', return true.
+    if (family1 == SqlTypeFamily.NULL
+        || family2 == SqlTypeFamily.NULL) {
+      return true;
+    }
+
     // We can implicitly convert from character to date
     if (family1 == SqlTypeFamily.CHARACTER
         && canConvertStringInCompare(family2)

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index dc0b229..d445050 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -236,6 +236,8 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
 
   private int nextGeneratedId;
   protected final RelDataTypeFactory typeFactory;
+
+  /** The type of dynamic parameters until a type is imposed on them. */
   protected final RelDataType unknownType;
   private final RelDataType booleanType;
 
@@ -297,9 +299,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
     this.typeFactory = Preconditions.checkNotNull(typeFactory);
     this.conformance = Preconditions.checkNotNull(conformance);
 
-    // NOTE jvs 23-Dec-2003:  This is used as the type for dynamic
-    // parameters and null literals until a real type is imposed for them.
-    unknownType = typeFactory.createSqlType(SqlTypeName.NULL);
+    unknownType = typeFactory.createUnknownType();
     booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
 
     rewriteCalls = true;

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index 916cd39..b1d7cde 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -2929,6 +2929,29 @@ public abstract class SqlOperatorBaseTest {
         "DATE NOT NULL");
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-1864">[CALCITE-1864]
+   * Allow NULL literal as argument</a>. */
+  @Test public void testNullOperand() {
+    checkNullOperand(tester, "=");
+    checkNullOperand(tester, ">");
+    checkNullOperand(tester, "<");
+    checkNullOperand(tester, "<=");
+    checkNullOperand(tester, ">=");
+    checkNullOperand(tester, "<>");
+
+    // "!=" is allowed under ORACLE_10 SQL conformance level
+    final SqlTester tester1 =
+        tester.withConformance(SqlConformanceEnum.ORACLE_10);
+    checkNullOperand(tester1, "<>");
+  }
+
+  private void checkNullOperand(SqlTester tester, String op) {
+    tester.checkBoolean("1 " + op + " null", null);
+    tester.checkBoolean("null " + op + " -3", null);
+    tester.checkBoolean("null " + op + " null", null);
+  }
+
   @Test public void testNotEqualsOperator() {
     tester.setFor(SqlStdOperatorTable.NOT_EQUALS);
     tester.checkBoolean("1<>1", Boolean.FALSE);
@@ -2945,10 +2968,9 @@ public abstract class SqlOperatorBaseTest {
     final SqlTester tester1 =
         tester.withConformance(SqlConformanceEnum.ORACLE_10);
 
-    tester1
-        .checkBoolean("1 <> 1", Boolean.FALSE);
-    tester1
-        .checkBoolean("1 != 1", Boolean.FALSE);
+    tester1.checkBoolean("1 <> 1", Boolean.FALSE);
+    tester1.checkBoolean("1 != 1", Boolean.FALSE);
+    tester1.checkBoolean("1 != null", null);
   }
 
   @Test public void testNotEqualsOperatorIntervals() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index d262fa6..a61e7e8 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -891,10 +891,7 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
     checkExp("1 in (1, null, 2)");
     checkExp("1 in (null, 1, null, 2)");
     checkExp("1 in (cast(null as integer), null)");
-
-    // Expression is illegal, but error message is not perfect.
-    checkWholeExpFails("1 in (null, null)",
-        "Values passed to IN operator must have compatible types");
+    checkExp("1 in (null, null)");
   }
 
   @Test public void testNullCast() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/ccaa700a/core/src/test/resources/sql/misc.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
index 73bb0f0..de9e2dc 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -1030,6 +1030,17 @@ Expression 'DEPTNO' is not being grouped
 
 !use scott
 
+# [CALCITE-1864] Allow NULL literal as argument
+select count(*) as c from "scott".emp where empno > null;
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+
 # [CALCITE-613] Implicitly convert strings in comparisons
 select * from "scott".emp where hiredate < '1981-01-02';
 +-------+-------+-------+------+------------+--------+------+--------+


Mime
View raw message