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

tledkov pushed a commit to branch sql-calcite
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/sql-calcite by this push:
     new 42820f7  IGNITE-15123 Calcite. Multi-tuple insert fails on validation 
(#9266)
42820f7 is described below

commit 42820f7ccbc163c99ebdc4291a632a382db9cbb8
Author: korlov42 <[email protected]>
AuthorDate: Tue Jul 20 19:31:28 2021 +0300

    IGNITE-15123 Calcite. Multi-tuple insert fails on validation (#9266)
---
 .../query/calcite/prepare/IgniteSqlValidator.java  | 28 ++++++++++++++++++++++
 .../integration/TableDmlIntegrationTest.java       | 13 ++++++++++
 2 files changed, 41 insertions(+)

diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
index e85dc53..d605da0 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
@@ -23,6 +23,7 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.prepare.CalciteCatalogReader;
 import org.apache.calcite.prepare.Prepare;
@@ -61,6 +62,7 @@ import 
org.apache.ignite.internal.processors.query.calcite.util.IgniteResource;
 import org.apache.ignite.internal.util.typedef.F;
 import org.jetbrains.annotations.Nullable;
 
+import static java.util.Objects.requireNonNull;
 import static org.apache.calcite.util.Static.RESOURCE;
 
 /** Validator. */
@@ -196,6 +198,32 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
         super.validateNamespace(namespace, targetRowType);
     }
 
+    /** {@inheritDoc} */
+    @Override protected void inferUnknownTypes(RelDataType inferredType, 
SqlValidatorScope scope, SqlNode node) {
+        requireNonNull(node, "node");
+
+        // Type inference for NULL literal is ommitted here to avoid 
validation problem later
+        // since NULL type could be easilly cast to any other type. Otherwise 
the
+        // validation error could be raised in case VALUES node contains 
several tuples
+        // with differen values of different types (still compatible through 
the cast) and NULL literal.
+        // I.e:
+        //      CREATE TABLE ... (d DATE);
+        //      INSERT INTO ... VALUES ('2000-10-10'), (NULL);
+        //
+        // In this case the field's type of the first tuple is CHAR, field's 
type of the second
+        // tuple is DATE (derived from table's row type), and the problem is 
that both types
+        // belong to the different type families, thus validation will fail.
+        if (SqlUtil.isNullLiteral(node, false)) {
+            RelDataType nullType = typeFactory.createSqlType(SqlTypeName.NULL);
+
+            setValidatedNodeType(node, nullType);
+
+            return;
+        }
+
+        super.inferUnknownTypes(inferredType, scope, node);
+    }
+
     /**
      * @param n Node to check limit.
      * @param nodeName Node name.
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java
index 42bf2e6..ffbadd1 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java
@@ -272,6 +272,19 @@ public class TableDmlIntegrationTest extends 
GridCommonAbstractTest {
         assertNull(row);
     }
 
+    /**
+     * Test verifies that a type inference works properly in case of
+     * multiple values list consisting of least restrictive type
+     * comparing to table field type and NULL literal.
+     */
+    @Test
+    public void testInsertMultipleValuesWithNullAndImplicitTypeConversion() {
+        executeSql("CREATE TABLE test (d DATE)");
+        executeSql("INSERT INTO test VALUES ('2000-10-10'), (null)");
+
+        assertEquals(2L, executeSql("select count(*) from 
test").get(0).get(0));
+    }
+
     /** */
     private List<List<?>> executeSql(String sql, Object... args) {
         List<FieldsQueryCursor<List<?>>> cur = queryProcessor().query(null, 
"PUBLIC", sql, args);

Reply via email to