From 67720b5d8c71f6b4065721ba445ad4eb12c0279f Mon Sep 17 00:00:00 2001 From: Rajeshbabu Chintaguntla Date: Sat, 25 Feb 2017 01:11:35 +0530 Subject: [PATCH] CALCITE-1510 Addendum check for default value only when target field is null --- .../sql/validate/SqlValidatorImpl.java | 10 +++--- .../calcite/test/MockCatalogReader.java | 31 ++++++++++++++++++- .../apache/calcite/test/SqlValidatorTest.java | 13 ++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) 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 66c467e9f3ee..3aa05ae00d5a 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,11 +3808,11 @@ private void checkFieldCount( 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) { - throw newValidationError(node, - RESOURCE.columnNotNullable(field.getName())); + if (targetField == null) { + if (!table.columnHasDefaultValue(table.getRowType(), field.getIndex())) { + throw newValidationError(node, + RESOURCE.columnNotNullable(field.getName())); + } } } } 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 9d84d9f5acd8..68e2915a46c2 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.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; @@ -153,9 +154,15 @@ public MockCatalogReader init() { MockSchema salesSchema = new MockSchema("SALES"); registerSchema(salesSchema); + // Register "EMP" table with customer InitializerExpressionFactory + // to check whether newDefaultValue method called or not. + final InitializerExpressionFactory customInitializerExpressionFactory = + new CustomInitializerExpressionFactory(typeFactory); + // Register "EMP" table. final MockTable empTable = - MockTable.create(this, salesSchema, "EMP", false, 14); + MockTable.create(this, salesSchema, "EMP", false, 14, null, + customInitializerExpressionFactory); empTable.addColumn("EMPNO", f.intType, true); empTable.addColumn("ENAME", f.varchar20Type); empTable.addColumn("JOB", f.varchar10Type); @@ -1321,6 +1328,28 @@ private class Fixture { new RelDataTypeFieldImpl("STATE", 3, varchar20Type)), RelDataTypeComparability.NONE); } + + /** To check whether newColumnDefaultValue is called or not. */ + public static class CustomInitializerExpressionFactory extends NullInitializerExpressionFactory { + public static boolean methodCalled = false; + + public CustomInitializerExpressionFactory(RelDataTypeFactory typeFactory) { + super(typeFactory); + } + + @Override public RexNode newColumnDefaultValue(RelOptTable table, int iColumn) { + methodCalled = true; + return super.newColumnDefaultValue(table, iColumn); + } + + @Override public RexNode newAttributeInitializer(RelDataType type, + SqlFunction constructor, int iAttribute, + List constructorArgs) { + methodCalled = true; + return super.newAttributeInitializer(type, constructor, iAttribute, + constructorArgs); + } + } } // End MockCatalogReader.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 26bde91bf402..a0ad67e13db2 100644 --- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java +++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java @@ -36,6 +36,7 @@ import org.apache.calcite.sql.validate.SqlMonotonicity; import org.apache.calcite.sql.validate.SqlValidator; import org.apache.calcite.sql.validate.SqlValidatorUtil; +import org.apache.calcite.test.MockCatalogReader.CustomInitializerExpressionFactory; import org.apache.calcite.util.Bug; import org.apache.calcite.util.ImmutableBitSet; @@ -61,6 +62,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -8112,6 +8114,17 @@ public int compare(SqlOperator o1, SqlOperator o2) { pragmaticTester.checkQuery(sql2); } + @Test public void testInsertShouldNotCheckForDefaultValue() { + CustomInitializerExpressionFactory.methodCalled = false; + 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); + assertFalse("Should not check for default value when column value present in insert.", + CustomInitializerExpressionFactory.methodCalled); + } + @Test public void testInsertView() { tester.checkQuery("insert into empnullables_20 (ename, empno, comm)\n" + "values ('Karl', 1, 1)");