You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2019/02/07 12:36:13 UTC

[ignite] branch master updated: IGNITE-11219: SQL: Fixed affinity mapper resolution for CREATE TABLE templates. This closes #6046.

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

vozerov 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 2a19e3f  IGNITE-11219: SQL: Fixed affinity mapper resolution for CREATE TABLE templates. This closes #6046.
2a19e3f is described below

commit 2a19e3f2789320b6b45dcd5fb91e82fd8bdcc1a1
Author: Max-Pudov <pu...@gmail.com>
AuthorDate: Thu Feb 7 15:36:00 2019 +0300

    IGNITE-11219: SQL: Fixed affinity mapper resolution for CREATE TABLE templates. This closes #6046.
---
 .../binary/CacheObjectBinaryProcessorImpl.java     |   7 +-
 .../processors/query/GridQueryProcessor.java       |   3 +
 .../internal/processors/query/QueryUtils.java      |  12 ++
 .../query/IgniteSqlCreateTableTemplateTest.java    | 159 +++++++++++++++++++++
 .../IgniteBinaryCacheQueryTestSuite2.java          |   3 +
 5 files changed, 178 insertions(+), 6 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index 8ac9810..5e43dd3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -948,11 +948,6 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
 
         AffinityKeyMapper cacheAffMapper = ccfg.getAffinityMapper();
 
-        boolean customAffMapper =
-            cacheAffMapper != null &&
-            !(cacheAffMapper instanceof CacheDefaultBinaryAffinityKeyMapper) &&
-            !(cacheAffMapper instanceof GridCacheDefaultAffinityKeyMapper);
-
         AffinityKeyMapper dfltAffMapper = binaryEnabled ?
             new CacheDefaultBinaryAffinityKeyMapper(ccfg.getKeyConfiguration()) :
             new GridCacheDefaultAffinityKeyMapper();
@@ -962,7 +957,7 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
         return new CacheObjectContext(ctx,
             ccfg.getName(),
             dfltAffMapper,
-            customAffMapper,
+            QueryUtils.isCustomAffinityMapper(ccfg.getAffinityMapper()),
             ccfg.isCopyOnRead(),
             storeVal,
             ctx.config().isPeerClassLoadingEnabled() && !isBinaryEnabled(ccfg),
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 94ad17d..e5f323d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -1567,6 +1567,9 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         ccfg.setSqlEscapeAll(true);
         ccfg.setQueryEntities(Collections.singleton(entity));
 
+        if (!QueryUtils.isCustomAffinityMapper(ccfg.getAffinityMapper()))
+            ccfg.setAffinityMapper(null);
+
         if (affinityKey != null)
             ccfg.setKeyConfiguration(new CacheKeyConfiguration(entity.getKeyType(), affinityKey));
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
index 316cf4c..e15687e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
@@ -1396,6 +1396,18 @@ public class QueryUtils {
     }
 
     /**
+     * Checks whether affinity key mapper is custom or default.
+     *
+     * @param affinityKeyMapper Affinity key mapper.
+     * @return {@code true} if affinity key mapper is custom.
+     */
+    public static boolean isCustomAffinityMapper(AffinityKeyMapper affinityKeyMapper) {
+        return affinityKeyMapper != null &&
+                !(affinityKeyMapper instanceof CacheDefaultBinaryAffinityKeyMapper) &&
+                !(affinityKeyMapper instanceof GridCacheDefaultAffinityKeyMapper);
+    }
+
+    /**
      * Checks if given column can be removed from table using its {@link QueryEntity}.
      *
      * @param entity Query entity.
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCreateTableTemplateTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCreateTableTemplateTest.java
new file mode 100644
index 0000000..a1b8b92
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCreateTableTemplateTest.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryObjectBuilder;
+import org.apache.ignite.cache.affinity.AffinityKeyMapper;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest;
+import org.junit.Test;
+
+/**
+ * Ensures that SQL queries work for tables created dynamically based on a template.
+ */
+public class IgniteSqlCreateTableTemplateTest extends AbstractIndexingCommonTest {
+    /** {@inheritDoc} */
+    @Override public IgniteConfiguration getConfiguration(String name) throws Exception {
+        IgniteConfiguration configuration = new IgniteConfiguration();
+        configuration.setIgniteInstanceName(name);
+
+        CacheConfiguration defaultCacheConfiguration = new CacheConfiguration();
+
+        defaultCacheConfiguration.setName("DEFAULT_TEMPLATE*");
+
+        CacheConfiguration customCacheConfiguration = new CacheConfiguration();
+
+        customCacheConfiguration.setName("CUSTOM_TEMPLATE*");
+
+        MockAffinityKeyMapper customAffinityMapper = new MockAffinityKeyMapper();
+
+        customCacheConfiguration.setAffinityMapper(customAffinityMapper);
+
+        configuration.setCacheConfiguration(defaultCacheConfiguration, customCacheConfiguration);
+
+        return configuration;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("deprecation")
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGrid();
+    }
+
+    /**
+     * Tests select statement works on a table with BinaryObject as a primary key.
+     */
+    @Test
+    public void testSelectForTableWithDataInsertedWithKeyValueAPI() {
+        Ignite ignite = grid();
+        IgniteCache cache = ignite.getOrCreateCache("test");
+
+        createTable(cache, "PERSON", "DEFAULT_TEMPLATE");
+
+        createTable(cache, "ORGANIZATION", "DEFAULT_TEMPLATE");
+
+        BinaryObjectBuilder keyBuilder = ignite.binary().builder("PERSON_KEY");
+
+        keyBuilder.setField("ID", 1);
+        keyBuilder.setField("AFF_PERSON", 2);
+
+        BinaryObjectBuilder valueBuilder = ignite.binary().builder("PERSON_VALUE");
+        valueBuilder.setField("NAME", "test");
+
+        ignite.cache("PERSON_CACHE").withKeepBinary().put(keyBuilder.build(), valueBuilder.build());
+
+        keyBuilder = ignite.binary().builder("ORGANIZATION_KEY");
+
+        keyBuilder.setField("ID", 1);
+        keyBuilder.setField("AFF_ORGANIZATION", 2);
+
+        valueBuilder = ignite.binary().builder("ORGANIZATION_VALUE");
+
+        valueBuilder.setField("NAME", "test");
+
+        ignite.cache("ORGANIZATION_CACHE").withKeepBinary().put(keyBuilder.build(), valueBuilder.build());
+
+        assertEquals(1, ignite.cache("PERSON_CACHE").query(
+            new SqlFieldsQuery("Select NAME from PERSON where ID = 1")).getAll().size()
+        );
+
+        assertEquals(1, ignite.cache("PERSON_CACHE").query(
+            new SqlFieldsQuery("Select NAME from PERSON where AFF_PERSON = 2")).getAll().size()
+        );
+
+        assertEquals(1, ignite.cache("ORGANIZATION_CACHE").query(
+            new SqlFieldsQuery("Select NAME from ORGANIZATION where AFF_ORGANIZATION = 2")).getAll().size()
+        );
+
+    }
+
+    /**
+     * Creates table based on a template.
+     *
+     * @param cache Cache.
+     */
+    private void createTable(IgniteCache cache, String tableName, String template) {
+        String sql = String.format(
+                "CREATE TABLE IF NOT EXISTS %1$s(\n" +
+                "  ID                INT        NOT NULL,\n" +
+                "  AFF_%1$s        INT        NOT NULL,\n" +
+                "  NAME              VARCHAR2(100),\n" +
+                "  PRIMARY KEY (ID, AFF_%1$s)\n" +
+                ") with \"TEMPLATE=%2$s,KEY_TYPE=%1$s_KEY, AFFINITY_KEY=AFF_%1$s, CACHE_NAME=%1$s_CACHE, " +
+                    "VALUE_TYPE=%1$s_VALUE, ATOMICITY=TRANSACTIONAL\";", tableName, template);
+
+        cache.query(new SqlFieldsQuery(sql).setSchema("PUBLIC"));
+    }
+
+    /**
+     * When template has custom affinity mapper.
+     * then cache created via CREATE TABLE command should have the same affinity mapper.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCustomAffinityKeyMapperIsNotOverwritten() {
+        Ignite ignite = grid();
+
+        IgniteCache cache = ignite.getOrCreateCache("test");
+
+        createTable(cache, "CUSTOM", "CUSTOM_TEMPLATE");
+
+        assertTrue(ignite.getOrCreateCache("CUSTOM_CACHE").getConfiguration(
+            CacheConfiguration.class).getAffinityMapper() instanceof MockAffinityKeyMapper);
+    }
+
+    /**
+     * Mock affinity mapper implementation.
+     */
+    @SuppressWarnings("deprecation")
+    private static class MockAffinityKeyMapper implements AffinityKeyMapper {
+        /** {@inheritDoc} */
+        @Override public Object affinityKey(Object key) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void reset() {
+            // no-op
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
index a9c52c8..0476f47 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
@@ -50,6 +50,7 @@ import org.apache.ignite.internal.processors.query.IgniteCacheGroupsCompareQuery
 import org.apache.ignite.internal.processors.query.IgniteCacheGroupsSqlDistributedJoinSelfTest;
 import org.apache.ignite.internal.processors.query.IgniteCacheGroupsSqlSegmentedIndexMultiNodeSelfTest;
 import org.apache.ignite.internal.processors.query.IgniteCacheGroupsSqlSegmentedIndexSelfTest;
+import org.apache.ignite.internal.processors.query.IgniteSqlCreateTableTemplateTest;
 import org.apache.ignite.internal.processors.query.SqlLocalQueryConnectionAndStatementTest;
 import org.apache.ignite.internal.processors.query.h2.CacheQueryEntityWithDateTimeApiFieldsTest;
 import org.apache.ignite.internal.processors.query.h2.twostep.CacheQueryMemoryLeakTest;
@@ -130,6 +131,8 @@ import org.junit.runners.Suite;
     SqlLocalQueryConnectionAndStatementTest.class,
 
     NoneOrSinglePartitionsQueryOptimizationsTest.class,
+
+    IgniteSqlCreateTableTemplateTest.class,
 })
 public class IgniteBinaryCacheQueryTestSuite2 {
 }