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: Further to [CALCITE-1510] INSERT/UPSERT should allow fewer values than columns, check for default value only when target field is null (Rajeshbabu Chintaguntla)
Date Tue, 28 Feb 2017 03:15:25 GMT
Further to [CALCITE-1510] INSERT/UPSERT should allow fewer values than columns, check for default
value only when target field is null (Rajeshbabu Chintaguntla)

Close apache/calcite#383


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

Branch: refs/heads/master
Commit: 2218343fcc7b7d75811f7014645a4b2fbea95a24
Parents: 4ba9d1b
Author: Rajeshbabu Chintaguntla <rajeshbabu@apache.org>
Authored: Sat Feb 25 01:11:35 2017 +0530
Committer: Julian Hyde <jhyde@apache.org>
Committed: Mon Feb 27 13:38:33 2017 -0800

----------------------------------------------------------------------
 .../calcite/sql/validate/SqlValidatorImpl.java  |  6 +--
 .../apache/calcite/test/MockCatalogReader.java  | 39 +++++++++++++++++++-
 .../apache/calcite/test/SqlValidatorTest.java   | 36 ++++++++++++++++++
 3 files changed, 77 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/2218343f/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 66c467e..d270f57 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
@@ -3808,9 +3808,9 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
       if (!field.getType().isNullable()) {
         final RelDataTypeField targetField =
             logicalTargetRowType.getField(field.getName(), true, false);
-        final boolean haveDefaultValue =
-            table.columnHasDefaultValue(table.getRowType(), field.getIndex());
-        if (targetField == null && !haveDefaultValue) {
+        if (targetField == null
+            && !table.columnHasDefaultValue(table.getRowType(),
+                field.getIndex())) {
           throw newValidationError(node,
               RESOURCE.columnNotNullable(field.getName()));
         }

http://git-wip-us.apache.org/repos/asf/calcite/blob/2218343f/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
index 9d84d9f..420354d 100644
--- a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
+++ b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
@@ -62,6 +62,7 @@ import org.apache.calcite.schema.Wrapper;
 import org.apache.calcite.schema.impl.AbstractSchema;
 import org.apache.calcite.sql.SqlAccessType;
 import org.apache.calcite.sql.SqlCollation;
+import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlIntervalQualifier;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -99,6 +100,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Mock implementation of {@link SqlValidatorCatalogReader} which returns tables
@@ -153,9 +155,15 @@ public class MockCatalogReader extends CalciteCatalogReader {
     MockSchema salesSchema = new MockSchema("SALES");
     registerSchema(salesSchema);
 
+    // Register "EMP" table with customer InitializerExpressionFactory
+    // to check whether newDefaultValue method called or not.
+    final InitializerExpressionFactory countingInitializerExpressionFactory =
+        new CountingFactory(typeFactory);
+
     // Register "EMP" table.
     final MockTable empTable =
-        MockTable.create(this, salesSchema, "EMP", false, 14);
+        MockTable.create(this, salesSchema, "EMP", false, 14, null,
+            countingInitializerExpressionFactory);
     empTable.addColumn("EMPNO", f.intType, true);
     empTable.addColumn("ENAME", f.varchar20Type);
     empTable.addColumn("JOB", f.varchar10Type);
@@ -1321,6 +1329,35 @@ public class MockCatalogReader extends CalciteCatalogReader {
                 new RelDataTypeFieldImpl("STATE", 3, varchar20Type)),
             RelDataTypeComparability.NONE);
   }
+
+  /** To check whether {@link #newColumnDefaultValue} is called. */
+  public static class CountingFactory
+      extends NullInitializerExpressionFactory {
+    static final ThreadLocal<AtomicInteger> THREAD_CALL_COUNT =
+        new ThreadLocal<AtomicInteger>() {
+          protected AtomicInteger initialValue() {
+            return new AtomicInteger();
+          }
+        };
+
+    CountingFactory(RelDataTypeFactory typeFactory) {
+      super(typeFactory);
+    }
+
+    @Override public RexNode newColumnDefaultValue(RelOptTable table,
+        int iColumn) {
+      THREAD_CALL_COUNT.get().incrementAndGet();
+      return super.newColumnDefaultValue(table, iColumn);
+    }
+
+    @Override public RexNode newAttributeInitializer(RelDataType type,
+        SqlFunction constructor, int iAttribute,
+        List<RexNode> constructorArgs) {
+      THREAD_CALL_COUNT.get().incrementAndGet();
+      return super.newAttributeInitializer(type, constructor, iAttribute,
+         constructorArgs);
+    }
+  }
 }
 
 // End MockCatalogReader.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/2218343f/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 26bde91..09a6077 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -8112,6 +8112,42 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
     pragmaticTester.checkQuery(sql2);
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-1510">[CALCITE-1510]
+   * INSERT/UPSERT should allow fewer values than columns</a>,
+   * check for default value only when target field is null. */
+  @Test public void testInsertShouldNotCheckForDefaultValue() {
+    final int c =
+        MockCatalogReader.CountingFactory.THREAD_CALL_COUNT.get().get();
+    final SqlTester pragmaticTester =
+        tester.withConformance(SqlConformanceEnum.PRAGMATIC_2003);
+    final String sql1 = "insert into emp values(1, 'nom', 'job', 0, "
+        + "timestamp '1970-01-01 00:00:00', 1, 1, 1, false)";
+    pragmaticTester.checkQuery(sql1);
+    assertThat("Should not check for default value if column is in INSERT",
+        MockCatalogReader.CountingFactory.THREAD_CALL_COUNT.get().get(), is(c));
+
+    // Now add a list of target columns, keeping the query otherwise the same.
+    final String sql2 = "insert into emp (empno, ename, job, mgr, hiredate,\n"
+        + "  sal, comm, deptno, slacker)\n"
+        + "values(1, 'nom', 'job', 0,\n"
+        + "  timestamp '1970-01-01 00:00:00', 1, 1, 1, false)";
+    pragmaticTester.checkQuery(sql2);
+    assertThat("Should not check for default value if column is in INSERT",
+        MockCatalogReader.CountingFactory.THREAD_CALL_COUNT.get().get(), is(c));
+
+    // Now remove SLACKER, which is NOT NULL, from the target list.
+    final String sql3 = "insert into ^emp^ (empno, ename, job, mgr, hiredate,\n"
+        + "  sal, comm, deptno)\n"
+        + "values(1, 'nom', 'job', 0,\n"
+        + "  timestamp '1970-01-01 00:00:00', 1, 1, 1)";
+    pragmaticTester.checkQueryFails(sql3,
+        "Column 'SLACKER' has no default value and does not allow NULLs");
+    assertThat("Missing non-NULL column generates a call to factory",
+        MockCatalogReader.CountingFactory.THREAD_CALL_COUNT.get().get(),
+        is(c + 1));
+  }
+
   @Test public void testInsertView() {
     tester.checkQuery("insert into empnullables_20 (ename, empno, comm)\n"
         + "values ('Karl', 1, 1)");


Mime
View raw message