IGNITE-5327: Introduced PARTITIONED and REPLICATED cache templates for CREATE TABLE command. This closes #2056.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3d7b15b1 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3d7b15b1 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3d7b15b1 Branch: refs/heads/ignite-5075 Commit: 3d7b15b1a3e025fafd44035ff33d714e3d2d87eb Parents: e4580b8 Author: Alexander Paschenko <[email protected]> Authored: Fri Jun 2 17:40:12 2017 +0300 Committer: devozerov <[email protected]> Committed: Fri Jun 2 17:40:12 2017 +0300 ---------------------------------------------------------------------- .../processors/query/GridQueryProcessor.java | 35 ++++++----- .../internal/processors/query/QueryUtils.java | 6 ++ .../query/h2/sql/GridSqlQueryParser.java | 25 ++------ .../cache/index/H2DynamicTableSelfTest.java | 65 +++++++++++++++++++- .../query/h2/sql/GridQueryParsingTest.java | 5 +- 5 files changed, 95 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/3d7b15b1/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- 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 1c1fa34..62d826d 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 @@ -1290,30 +1290,33 @@ public class GridQueryProcessor extends GridProcessorAdapter { assert !F.isEmpty(templateName); assert backups >= 0; - CacheConfiguration<?, ?> templateCfg = ctx.cache().getConfigFromTemplate(templateName); + CacheConfiguration<?, ?> ccfg = ctx.cache().getConfigFromTemplate(templateName); - if (templateCfg == null) - throw new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, templateName); + if (ccfg == null) { + if (QueryUtils.TEMPLATE_PARTITIONED.equalsIgnoreCase(templateName)) + ccfg = new CacheConfiguration<>().setCacheMode(CacheMode.PARTITIONED); + else if (QueryUtils.TEMPLATE_REPLICÃTED.equalsIgnoreCase(templateName)) + ccfg = new CacheConfiguration<>().setCacheMode(CacheMode.REPLICATED); + else + throw new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, templateName); + } - if (!F.isEmpty(templateCfg.getQueryEntities())) - throw new SchemaOperationException("Template cannot contain query entities [template=" + - templateName + ']'); + if (!F.isEmpty(ccfg.getQueryEntities())) + throw new SchemaOperationException("Template cache already contains query entities which it should not: " + + templateName); - CacheConfiguration<?, ?> newCfg = new CacheConfiguration<>(templateCfg); + ccfg.setName(entity.getTableName()); if (atomicityMode != null) - newCfg.setAtomicityMode(atomicityMode); - - newCfg.setBackups(backups); + ccfg.setAtomicityMode(atomicityMode); - newCfg.setName(entity.getTableName()); - newCfg.setQueryEntities(Collections.singleton(entity)); - newCfg.setSqlSchema(schemaName); + ccfg.setBackups(backups); - // Preserve user specified names as they are. - newCfg.setSqlEscapeAll(true); + ccfg.setSqlSchema(schemaName); + ccfg.setSqlEscapeAll(true); + ccfg.setQueryEntities(Collections.singleton(entity)); - boolean res = ctx.grid().getOrCreateCache0(newCfg, true).get2(); + boolean res = ctx.grid().getOrCreateCache0(ccfg, true).get2(); if (!res && !ifNotExists) throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_EXISTS, entity.getTableName()); http://git-wip-us.apache.org/repos/asf/ignite/blob/3d7b15b1/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java ---------------------------------------------------------------------- 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 51648e5..748768e 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 @@ -75,6 +75,12 @@ public class QueryUtils { /** Version field name. */ public static final String VER_FIELD_NAME = "_VER"; + /** Well-known template name for PARTITIONED cache. */ + public static final String TEMPLATE_PARTITIONED = "PARTITIONED"; + + /** Well-known template name for REPLICATED cache. */ + public static final String TEMPLATE_REPLICÃTED = "REPLICATED"; + /** Discovery history size. */ private static final int DISCO_HIST_SIZE = getInteger(IGNITE_INDEXING_DISCOVERY_HISTORY_SIZE, 1000); http://git-wip-us.apache.org/repos/asf/ignite/blob/3d7b15b1/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java index 573384a..fdb908e 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java @@ -30,7 +30,6 @@ import java.util.Map; import javax.cache.CacheException; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.CacheAtomicityMode; -import org.apache.ignite.cache.CacheMode; import org.apache.ignite.cache.QueryIndex; import org.apache.ignite.cache.QueryIndexType; import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode; @@ -405,11 +404,6 @@ public class GridSqlQueryParser { /** */ private static final String PARAM_ATOMICITY = "ATOMICITY"; - /** Names of the params that need to be present in WITH clause of CREATE TABLE. */ - private static final String[] MANDATORY_CREATE_TABLE_PARAMS = { - PARAM_TEMPLATE - }; - /** */ private final IdentityHashMap<Object, Object> h2ObjToGridObj = new IdentityHashMap<>(); @@ -847,6 +841,8 @@ public class GridSqlQueryParser { private GridSqlCreateTable parseCreateTable(CreateTable createTbl) { GridSqlCreateTable res = new GridSqlCreateTable(); + res.templateName(QueryUtils.TEMPLATE_PARTITIONED); + Query qry = CREATE_TABLE_QUERY.get(createTbl); if (qry != null) @@ -945,11 +941,8 @@ public class GridSqlQueryParser { throw new IgniteSQLException("No cache value related columns found"); res.columns(cols); - res.primaryKeyColumns(pkCols); - res.tableName(data.tableName); - res.ifNotExists(CREATE_TABLE_IF_NOT_EXISTS.get(createTbl)); List<String> extraParams = data.tableEngineParams != null ? new ArrayList<String>() : null; @@ -960,9 +953,9 @@ public class GridSqlQueryParser { res.params(extraParams); - Map<String, String> params = new HashMap<>(); - if (!F.isEmpty(extraParams)) { + Map<String, String> params = new HashMap<>(); + for (String p : extraParams) { String[] parts = p.split(PARAM_NAME_VALUE_SEPARATOR); @@ -981,17 +974,11 @@ public class GridSqlQueryParser { if (params.put(name, val) != null) throw new IgniteSQLException("Duplicate parameter: " + p, IgniteQueryErrorCode.PARSING); } - } - for (String paramName : MANDATORY_CREATE_TABLE_PARAMS) { - if (!params.containsKey(paramName)) - throw new IgniteSQLException("Mandatory parameter is missing: " + paramName, - IgniteQueryErrorCode.PARSING); + for (Map.Entry<String, String> e : params.entrySet()) + processExtraParam(e.getKey(), e.getValue(), res); } - for (Map.Entry<String, String> e : params.entrySet()) - processExtraParam(e.getKey(), e.getValue(), res); - return res; } http://git-wip-us.apache.org/repos/asf/ignite/blob/3d7b15b1/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java index b43d3f2..d97d1eb 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java @@ -97,9 +97,64 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest { * @throws Exception if failed. */ public void testCreateTable() throws Exception { + doTestCreateTable(CACHE_NAME, null); + } + + /** + * Test that {@code CREATE TABLE} with reserved template cache name actually creates new {@code REPLICATED} cache, + * H2 table and type descriptor on all nodes. + * @throws Exception if failed. + */ + public void testCreateTableReplicated() throws Exception { + doTestCreateTable("REPLICATED", CacheMode.REPLICATED); + } + + /** + * Test that {@code CREATE TABLE} with reserved template cache name actually creates new {@code PARTITIONED} cache, + * H2 table and type descriptor on all nodes. + * @throws Exception if failed. + */ + public void testCreateTablePartitioned() throws Exception { + doTestCreateTable("PARTITIONED", CacheMode.PARTITIONED); + } + + /** + * Test that {@code CREATE TABLE} with reserved template cache name actually creates new {@code REPLICATED} cache, + * H2 table and type descriptor on all nodes. + * @throws Exception if failed. + */ + public void testCreateTableReplicatedCaseInsensitive() throws Exception { + doTestCreateTable("replicated", CacheMode.REPLICATED); + } + + /** + * Test that {@code CREATE TABLE} with reserved template cache name actually creates new {@code PARTITIONED} cache, + * H2 table and type descriptor on all nodes. + * @throws Exception if failed. + */ + public void testCreateTablePartitionedCaseInsensitive() throws Exception { + doTestCreateTable("partitioned", CacheMode.PARTITIONED); + } + + /** + * Test that {@code CREATE TABLE} with reserved template cache name actually creates new {@code PARTITIONED} cache, + * H2 table and type descriptor on all nodes, when no cache template name is given. + * @throws Exception if failed. + */ + public void testCreateTableNoTemplate() throws Exception { + doTestCreateTable(null, CacheMode.PARTITIONED); + } + + /** + * Test that {@code CREATE TABLE} with given template cache name actually creates new cache, + * H2 table and type descriptor on all nodes, optionally with cache type check. + * @param tplCacheName Template cache name. + * @param mode Expected cache mode, or {@code null} if no check is needed. + */ + private void doTestCreateTable(String tplCacheName, CacheMode mode) { executeDdl("CREATE TABLE \"Person\" (\"id\" int, \"city\" varchar," + " \"name\" varchar, \"surname\" varchar, \"age\" int, PRIMARY KEY (\"id\", \"city\")) WITH " + - "\"template=cache,backups=10\",\"atomicity=atomic\""); + (F.isEmpty(tplCacheName) ? "" : "\"template=" + tplCacheName + "\",") + "\"backups=10,atomicity=atomic\""); for (int i = 0; i < 4; i++) { IgniteEx node = grid(i); @@ -110,12 +165,18 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest { assertNotNull(cacheDesc); - assertEquals(10, cacheDesc.cacheConfiguration().getBackups()); + if (mode == CacheMode.REPLICATED) + assertEquals(Integer.MAX_VALUE, cacheDesc.cacheConfiguration().getBackups()); + else + assertEquals(10, cacheDesc.cacheConfiguration().getBackups()); assertEquals(CacheAtomicityMode.ATOMIC, cacheDesc.cacheConfiguration().getAtomicityMode()); assertTrue(cacheDesc.sql()); + if (mode != null) + assertEquals(mode, cacheDesc.cacheConfiguration().getCacheMode()); + QueryTypeDescriptorImpl desc = typeExisting(node, "Person", "Person"); assertEquals(Object.class, desc.keyClass()); http://git-wip-us.apache.org/repos/asf/ignite/blob/3d7b15b1/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java index 8f9db2e..329e580 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java @@ -598,10 +598,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest { assertParseThrows("create table Person (id int primary key)", IgniteSQLException.class, "No cache value related columns found"); - assertParseThrows("create table Person (id int primary key, age int null)", - IgniteSQLException.class, "Mandatory parameter is missing: TEMPLATE"); - - assertParseThrows("create table Person (id int primary key, age int not null) WITH \"template=cache\"", + assertParseThrows("create table Person (id int primary key, age int not null) WITH \"cacheTemplate=cache\"", IgniteSQLException.class, "Non nullable columns are forbidden"); assertParseThrows("create table Person (id int primary key, age int unique) WITH \"template=cache\"",
