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 {
}