You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tl...@apache.org on 2021/04/29 10:57:33 UTC

[ignite] branch master updated: IGNITE-14661 validate parts of compound PK for NOT NULL constraint (#9053)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4ffbf5d  IGNITE-14661 validate parts of compound PK for NOT NULL constraint (#9053)
4ffbf5d is described below

commit 4ffbf5dc4958942269b624d8f7dcbf4ab3920e24
Author: korlov42 <ko...@gridgain.com>
AuthorDate: Thu Apr 29 13:57:14 2021 +0300

    IGNITE-14661 validate parts of compound PK for NOT NULL constraint (#9053)
---
 .../processors/query/QueryTypeDescriptorImpl.java  |  4 +-
 .../IgniteCacheSqlInsertValidationSelfTest.java    | 47 +++++++++++++++++++++-
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
index 3be9063..1bfff1a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
@@ -426,8 +426,8 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
         if (uppercaseProps.put(name.toUpperCase(), prop) != null && failOnDuplicate)
             throw new IgniteCheckedException("Property with upper cased name '" + name + "' already exists.");
 
-        if ((prop.notNull() && !prop.key() && !prop.name().equals(VAL_FIELD_NAME)) || prop.precision() != -1 ||
-            coCtx.kernalContext().config().getSqlConfiguration().isValidationEnabled()) {
+        if ((prop.notNull() && !prop.name().equals(KEY_FIELD_NAME) && !prop.name().equals(VAL_FIELD_NAME))
+            || prop.precision() != -1 || coCtx.kernalContext().config().getSqlConfiguration().isValidationEnabled()) {
             if (validateProps == null)
                 validateProps = new ArrayList<>();
 
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheSqlInsertValidationSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheSqlInsertValidationSelfTest.java
index 00f6f25..a966d97 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheSqlInsertValidationSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheSqlInsertValidationSelfTest.java
@@ -24,7 +24,9 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
@@ -43,6 +45,9 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
  * Tests for validation of inserts sql queries.
  */
 public class IgniteCacheSqlInsertValidationSelfTest extends AbstractIndexingCommonTest {
+    /** Name of the class that actually not in class path. */
+    private static final String TEST_CLASS_NAME = "MyClass";
+
     /** Entry point for sql api. Contains table configurations too. */
     private static IgniteCache<Object, Object> cache;
 
@@ -101,7 +106,9 @@ public class IgniteCacheSqlInsertValidationSelfTest extends AbstractIndexingComm
                         .addQueryField("fv2", "java.lang.Long", null)
                         .setTableName("INT_KEY_TAB"),
                     new QueryEntity(SuperKey.class, String.class)
-                        .setTableName("SUPER_TAB")
+                        .setTableName("SUPER_TAB"),
+                    new QueryEntity(String.class.getName(), TEST_CLASS_NAME)
+                        .setTableName("MY_CLASS")
                 )), "testCache");
     }
 
@@ -204,6 +211,44 @@ public class IgniteCacheSqlInsertValidationSelfTest extends AbstractIndexingComm
     }
 
     /**
+     * Check we can't insert null as column value of a compound PK that has NOT NULL constraint.
+     */
+    @Test
+    public void testValidationOfCompoundKey() {
+        execute("CREATE TABLE PUBLIC.TBL (id1 BIGINT, id2 BIGINT NOT NULL, val BIGINT, PRIMARY KEY(id1, id2))");
+
+        GridTestUtils.assertThrows(log(),
+            () -> execute("INSERT INTO PUBLIC.TBL VALUES (1, null, 3)"),
+            IgniteSQLException.class,
+            "Null value is not allowed for column 'ID2'");
+    }
+
+    /**
+     * Check that raw _KEY and _VAL skipped on validation, hence exception
+     * is not thrown when their classes is not in class path.
+     */
+    @Test
+    public void testValidationSkippedForRawKeyVal() {
+        String key = "foo";
+
+        BinaryObject bo = grid(0).binary().builder(TEST_CLASS_NAME)
+            .setField(key, "bar")
+            .build();
+
+        IgniteCache<Object, Object> binCache = cache.withKeepBinary();
+
+        binCache.put(key, bo);
+
+        List<List<?>> res = binCache.query(new SqlFieldsQuery("SELECT _val FROM MY_CLASS WHERE _key = ?")
+            .setArgs(key)).getAll();
+
+        assertEquals(1, res.size());
+        assertEquals(1, res.get(0).size());
+        assertTrue(res.get(0).get(0) instanceof BinaryObject);
+        assertEquals(bo.field(key), ((BinaryObject)res.get(0).get(0)).field(key));
+    }
+
+    /**
      * Execute native sql.
      *
      * @param sql query.