From bdb44a6afb1819baebe0e8e11d1be0d798a42ae1 Mon Sep 17 00:00:00 2001 From: Yury Gerzhedovich Date: Fri, 7 Sep 2018 12:07:28 +0300 Subject: [PATCH 1/9] IGNITE-8386: PK indexes don't use wrapped object for table created from SQL --- .../processors/cache/GridCacheProcessor.java | 9 +- .../processors/query/GridQueryIndexing.java | 2 +- .../processors/query/GridQueryProcessor.java | 32 ++- ...niteClientCacheInitializationFailTest.java | 2 +- .../query/h2/H2TableDescriptor.java | 81 ++++-- .../processors/query/h2/IgniteH2Indexing.java | 5 +- ...mplexPkIndexesForCreateTableAsSQLTest.java | 259 ++++++++++++++++++ 7 files changed, 351 insertions(+), 39 deletions(-) create mode 100644 modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index e0a2420107bc6..23394fd99822b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -1159,7 +1159,7 @@ private void stopCacheOnReconnect(GridCacheContext cctx, List boolean rmvIdx = !cache.context().group().persistenceEnabled(); ctx.query().onCacheStop0(cctx, rmvIdx); - ctx.query().onCacheStart0(cctx, desc.schema()); + ctx.query().onCacheStart0(cctx, desc.schema(), desc.sql()); } } } @@ -1187,10 +1187,11 @@ private void stopCacheOnReconnect(GridCacheContext cctx, List /** * @param cache Cache to start. * @param schema Cache schema. + * @param isSql {@code true} in case create cache initialized from SQL. * @throws IgniteCheckedException If failed to start cache. */ @SuppressWarnings({"TypeMayBeWeakened", "unchecked"}) - private void startCache(GridCacheAdapter cache, QuerySchema schema) throws IgniteCheckedException { + private void startCache(GridCacheAdapter cache, QuerySchema schema, boolean isSql) throws IgniteCheckedException { GridCacheContext cacheCtx = cache.context(); CacheConfiguration cfg = cacheCtx.config(); @@ -1227,7 +1228,7 @@ private void startCache(GridCacheAdapter cache, QuerySchema schema) throws cacheCtx.cache().start(); - ctx.query().onCacheStart(cacheCtx, schema); + ctx.query().onCacheStart(cacheCtx, schema, isSql); cacheCtx.onStarted(); @@ -1980,7 +1981,7 @@ else if (CU.affinityNode(ctx.discovery().localNode(), desc.groupDescriptor().con caches.put(cacheCtx.name(), cache); - startCache(cache, desc.schema() != null ? desc.schema() : new QuerySchema()); + startCache(cache, desc.schema() != null ? desc.schema() : new QuerySchema(), desc.sql()); grp.onCacheStarted(cacheCtx); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java index 7aa4021d7b5a0..c0b515b17ed09 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java @@ -262,7 +262,7 @@ public UpdateSourceIterator prepareDistributedUpdate(GridCacheContext c * @throws IgniteCheckedException If failed. * @return {@code True} if type was registered, {@code false} if for some reason it was rejected. */ - public boolean registerType(GridCacheContext cctx, GridQueryTypeDescriptor desc) throws IgniteCheckedException; + public boolean registerType(GridCacheContext cctx, GridQueryTypeDescriptor desc, boolean isSql) throws IgniteCheckedException; /** * Updates index. Note that key is unique for cache, so if cache contains multiple indexes 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 bd5d91cc653b3..4a6d8c2b3f0a3 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 @@ -678,10 +678,11 @@ public GridQueryIndexing getIndexing() throws IgniteException { * Use with {@link #busyLock} where appropriate. * @param cctx Cache context. * @param schema Initial schema. + * @param isSql {@code true} in case create cache initialized from SQL. * @throws IgniteCheckedException If failed. */ @SuppressWarnings({"deprecation", "ThrowableResultOfMethodCallIgnored"}) - public void onCacheStart0(GridCacheContext cctx, QuerySchema schema) + public void onCacheStart0(GridCacheContext cctx, QuerySchema schema, boolean isSql) throws IgniteCheckedException { cctx.shared().database().checkpointReadLock(); @@ -802,7 +803,7 @@ else if (op0 instanceof SchemaAlterTableDropColumnOperation) { } // Ready to register at this point. - registerCache0(cacheName, schemaName, cctx, cands); + registerCache0(cacheName, schemaName, cctx, cands, isSql); // Warn about possible implicit deserialization. if (!mustDeserializeClss.isEmpty()) { @@ -853,9 +854,10 @@ else if (op0 instanceof SchemaAlterTableDropColumnOperation) { * * @param cctx Cache context. * @param schema Index states. + * @param isSql {@code true} in case create cache initialized from SQL. * @throws IgniteCheckedException If failed. */ - public void onCacheStart(GridCacheContext cctx, QuerySchema schema) throws IgniteCheckedException { + public void onCacheStart(GridCacheContext cctx, QuerySchema schema, boolean isSql) throws IgniteCheckedException { if (idx == null) return; @@ -863,7 +865,7 @@ public void onCacheStart(GridCacheContext cctx, QuerySchema schema) throws Ignit return; try { - onCacheStart0(cctx, schema); + onCacheStart0(cctx, schema, isSql); } finally { busyLock.leaveBusy(); @@ -1587,13 +1589,15 @@ public void dynamicTableDrop(String cacheName, String tblName, boolean ifExists) * @param schemaName Schema name. * @param cctx Cache context. * @param cands Candidates. + * @param isSql {@code true} in case create cache initialized from SQL. * @throws IgniteCheckedException If failed. */ private void registerCache0( String cacheName, String schemaName, GridCacheContext cctx, - Collection cands + Collection cands, + boolean isSql ) throws IgniteCheckedException { synchronized (stateMux) { if (idx != null) @@ -1628,7 +1632,7 @@ private void registerCache0( } if (idx != null) - idx.registerType(cctx, desc); + idx.registerType(cctx, desc, isSql); } cacheNames.add(CU.mask(cacheName)); @@ -2504,15 +2508,15 @@ private void processDynamicAddColumn(QueryTypeDescriptorImpl d, List for (QueryField col : cols) { try { props.add(new QueryBinaryProperty( - ctx, + ctx, col.name(), - null, - Class.forName(col.typeName()), - false, - null, - !col.isNullable(), - null, - col.precision(), + null, + Class.forName(col.typeName()), + false, + null, + !col.isNullable(), + null, + col.precision(), col.scale())); } catch (ClassNotFoundException e) { diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java index b1df28e37f86b..f4c13fed1fa9e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java @@ -329,7 +329,7 @@ private static class FailedIndexing implements GridQueryIndexing { /** {@inheritDoc} */ @Override public boolean registerType(GridCacheContext cctx, - GridQueryTypeDescriptor desc) throws IgniteCheckedException { + GridQueryTypeDescriptor desc, boolean isSql) throws IgniteCheckedException { return false; } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 899bdda0b457a..6da0764d0ef8b 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -17,6 +17,10 @@ package org.apache.ignite.internal.processors.query.h2; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.QueryIndexType; @@ -36,10 +40,7 @@ import org.h2.result.SortOrder; import org.h2.table.Column; import org.h2.table.IndexColumn; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import org.jetbrains.annotations.NotNull; import static org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOnheap.KEY_COL; @@ -47,6 +48,15 @@ * Information about table in database. */ public class H2TableDescriptor implements GridH2SystemIndexFactory { + /** PK index name. */ + public static final String PK_IDX_NAME = "_key_PK"; + + /** PK hashindex name */ + public static final String PK_HASH_IDX_NAME = "_key_PK_hash"; + + /** Affinity key index name */ + public static final String AFFINITY_KEY_IDX_NAME = "AFFINITY_KEY"; + /** Indexing. */ private final IgniteH2Indexing idx; @@ -71,6 +81,9 @@ public class H2TableDescriptor implements GridH2SystemIndexFactory { /** */ private H2PkHashIndex pkHashIdx; + /** Flag of table has been created from SQL*/ + private boolean isSql; + /** * Constructor. * @@ -78,13 +91,15 @@ public class H2TableDescriptor implements GridH2SystemIndexFactory { * @param schema Schema. * @param type Type descriptor. * @param cctx Cache context. + * @param isSql {@code true} in case table has been created from SQL. */ public H2TableDescriptor(IgniteH2Indexing idx, H2Schema schema, GridQueryTypeDescriptor type, - GridCacheContext cctx) { + GridCacheContext cctx, boolean isSql) { this.idx = idx; this.type = type; this.schema = schema; this.cctx = cctx; + this.isSql = isSql; fullTblName = H2Utils.withQuotes(schema.schemaName()) + "." + H2Utils.withQuotes(type.tableName()); } @@ -187,12 +202,12 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { if (affCol != null && H2Utils.equals(affCol, keyCol)) affCol = null; - GridH2RowDescriptor desc = tbl.rowDescriptor(); + List keyCols = extractKeyColumns(tbl, keyCol, affCol); Index hashIdx = createHashIndex( tbl, - "_key_PK_hash", - H2Utils.treeIndexColumns(desc, new ArrayList(2), keyCol, affCol) + PK_HASH_IDX_NAME, + keyCols ); if (hashIdx != null) @@ -200,10 +215,10 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { // Add primary key index. Index pkIdx = idx.createSortedIndex( - "_key_PK", + PK_IDX_NAME, tbl, true, - H2Utils.treeIndexColumns(desc, new ArrayList(2), keyCol, affCol), + keyCols, -1 ); @@ -218,8 +233,6 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { } } - boolean affIdxFound = false; - GridQueryIndexDescriptor textIdx = type.textIndex(); if (textIdx != null) { @@ -233,6 +246,8 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { // Locate index where affinity column is first (if any). if (affCol != null) { + boolean affIdxFound = false; + for (GridQueryIndexDescriptor idxDesc : type.indexes().values()) { if (idxDesc.type() != QueryIndexType.SORTED) continue; @@ -246,17 +261,49 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { affIdxFound |= H2Utils.equals(idxCol, affCol); } - } - // Add explicit affinity key index if nothing alike was found. - if (affCol != null && !affIdxFound) { - idxs.add(idx.createSortedIndex("AFFINITY_KEY", tbl, false, - H2Utils.treeIndexColumns(desc, new ArrayList(2), affCol, keyCol), -1)); + // Add explicit affinity key index if nothing alike was found. + if (!affIdxFound) { + idxs.add(idx.createSortedIndex(AFFINITY_KEY_IDX_NAME, tbl, false, + H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), affCol, keyCol), -1)); + } } return idxs; } + /** + * Create list of affinity and key index columns. Key, if it possible, partitions into simple components. + * + * @param tbl GridH2Table instance + * @param keyCol Key index column. + * @param affCol Affinity index column. + * + * @return List of key and affinity columns. Key's, if it possible, splitted into simple components. + */ + @NotNull private List extractKeyColumns(GridH2Table tbl, IndexColumn keyCol, IndexColumn affCol) { + ArrayList keyCols; + + if (isSql) { + keyCols = new ArrayList<>(type.fields().size() + 1); + for (String propName : type.fields().keySet()) { + Column col = tbl.getColumn(propName); + keyCols.add(tbl.indexColumn(col.getColumnId(), SortOrder.ASCENDING)); + } + } + else { + keyCols = new ArrayList<>(2); + keyCols.add(keyCol); + } + + if (affCol != null && !H2Utils.containsColumn(keyCols, affCol)) + keyCols.add(affCol); + else + keyCols.trimToSize(); + + return Collections.unmodifiableList(keyCols); + } + /** * Get collection of user indexes. * diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 9b71f3751649e..ca138a2470aea 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -2699,9 +2699,10 @@ else if (star > 0) { * This implementation doesn't support type reregistration. * * @param type Type description. + * @param isSql {@code true} in case table has been created from SQL. * @throws IgniteCheckedException In case of error. */ - @Override public boolean registerType(GridCacheContext cctx, GridQueryTypeDescriptor type) + @Override public boolean registerType(GridCacheContext cctx, GridQueryTypeDescriptor type, boolean isSql) throws IgniteCheckedException { validateTypeDescriptor(type); @@ -2709,7 +2710,7 @@ else if (star > 0) { H2Schema schema = schemas.get(schemaName); - H2TableDescriptor tbl = new H2TableDescriptor(this, schema, type, cctx); + H2TableDescriptor tbl = new H2TableDescriptor(this, schema, type, cctx, isSql); try { Connection conn = connectionForThread(schemaName); diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java new file mode 100644 index 0000000000000..a8f1473df2c6d --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java @@ -0,0 +1,259 @@ +/* + * 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.cache.index; + +import java.util.List; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.cache.query.annotations.QuerySqlField; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Test of creating and using PK indexes for tables created through SQL. + */ +@SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) +public class UnfolldingComplexPkIndexesForCreateTableAsSQLTest extends GridCommonAbstractTest { + + /** Counter to generate unique table names. */ + private static int tblCnt = 0; + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + startGrid(0); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + stopAllGrids(); + } + + /** + * Test using PK indexes for complex primary key. + */ + public void testComplexPk() { + String tableName = createTableName(); + + executeSql("CREATE TABLE " + tableName + " (id int, name varchar, age int, company varchar, city varchar, " + + "primary key (id, name, city))"); + + checkUsingIndexes(tableName); + } + + /** + * Test using PK indexes for simple primary key. + */ + public void testSimplePk() { + String tableName = createTableName(); + + executeSql("CREATE TABLE " + tableName + " (id int, name varchar, age int, company varchar, city varchar, " + + "primary key (id))"); + + checkUsingIndexes(tableName); + } + + /** + * Test using PK indexes for wrapped primary key. + */ + public void testWrappedPk() { + String tableName = createTableName(); + + executeSql("CREATE TABLE " + tableName + " (id int, name varchar, age int, company varchar, city varchar, " + + "primary key (id)) WITH \"wrap_key=true\""); + + checkUsingIndexes(tableName); + } + + /** + * Check using PK indexes for few cases. + * + * @param tableName name of table which should be checked to using PK indexes. + */ + private void checkUsingIndexes(String tableName) { + String explainSQL = "explain SELECT * FROM " + tableName + " WHERE "; + + List> results = executeSql(explainSQL + "id=1"); + + assertUsingPkIndex(results); + + results = executeSql(explainSQL + "id=1 and name=''"); + + assertUsingPkIndex(results); + + results = executeSql(explainSQL + "id=1 and name='' and city='' and age=0"); + + assertUsingPkIndex(results); + } + + /** + * Test don't using PK indexes for table created through cache API. + */ + public void testIndexesForCachesCreatedThroughCashApi() { + String tableName = TestValue.class.getSimpleName(); + + CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME); + + ccfg.setSqlSchema("PUBLIC"); + ccfg.setName(tableName); + + QueryEntity qryEntity = new QueryEntity(TestKey.class, TestValue.class); + + ccfg.setQueryEntities(F.asList(qryEntity)); + + node().createCache(ccfg); + + List> results = executeSql("explain SELECT * FROM " + tableName + " WHERE id=1"); + + assertDontUsingPkIndex(results); + } + + /** + * Check that explain plan result shown using PK index and don't use scan. + * + * @param results result of execut explain plan query. + */ + private void assertUsingPkIndex(List> results) { + assertEquals(2, results.size()); + + String explainPlan = (String)results.get(0).get(0); + + assertTrue(explainPlan.contains("\"_key_PK\"")); + + assertFalse(explainPlan.contains("_SCAN_")); + } + + /** + * Check that explain plan result shown don't use PK index and use scan. + * + * @param results result of execut explain plan query. + */ + private void assertDontUsingPkIndex(List> results) { + assertEquals(2, results.size()); + + String explainPlan = (String)results.get(0).get(0); + + System.out.println(explainPlan); + + assertFalse(explainPlan.contains("\"_key_PK\"")); + + assertTrue(explainPlan.contains("_SCAN_")); + } + + /** + * Create unique table name. + * + * @return unique name of table. + */ + private String createTableName() { + return "TST_TABLE_" + tblCnt++; + } + + /** + * Run SQL statement on default node. + * + * @param stmt Statement to run. + * @param args arguments of statements + * @return Run result. + */ + private List> executeSql(String stmt, Object... args) { + return executeSql(node(), stmt, args); + } + + /** + * Run SQL statement on specified node. + * + * @param node node to execute query. + * @param stmt Statement to run. + * @param args arguments of statements + * @return Run result. + */ + private List> executeSql(IgniteEx node, String stmt, Object... args) { + return node.context().query().querySqlFields(new SqlFieldsQuery(stmt).setArgs(args), true).getAll(); + } + + /** + * @return Node to initiate operations from. + */ + private IgniteEx node() { + return grid(0); + } + + static class TestKey { + /** */ + @QuerySqlField + private int id; + + /** + * @param id ID. + */ + public TestKey(int id) { + this.id = id; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + TestKey testKey = (TestKey)o; + + return id == testKey.id; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return id; + } + } + + static class TestValue { + /** */ + @QuerySqlField() + private String name; + @QuerySqlField() + private String company; + @QuerySqlField() + private String city; + @QuerySqlField() + private int age; + + /** + * @param age Age. + * @param name Name. + * @param company Company. + * @param city City. + */ + public TestValue(int age, String name, String company, String city) { + this.age = age; + this.name = name; + this.company = company; + this.city = city; + } + } + + +} From 07c4bd82b934b793603bb9ab98709170d2d2a499 Mon Sep 17 00:00:00 2001 From: Yury Gerzhedovich Date: Fri, 7 Sep 2018 12:38:09 +0300 Subject: [PATCH 2/9] IGNITE-8386: PK indexes don't use wrapped object for table created from SQL --- .../query/h2/H2TableDescriptor.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 6da0764d0ef8b..85276fe73d05d 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -26,6 +26,7 @@ import org.apache.ignite.cache.QueryIndexType; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor; +import org.apache.ignite.internal.processors.query.GridQueryProperty; import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex; import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory; @@ -286,13 +287,34 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { if (isSql) { keyCols = new ArrayList<>(type.fields().size() + 1); - for (String propName : type.fields().keySet()) { - Column col = tbl.getColumn(propName); - keyCols.add(tbl.indexColumn(col.getColumnId(), SortOrder.ASCENDING)); + + String keyFieldName = type.keyFieldName(); + + //Check if key is simple type + if(keyFieldName != null){ + int keyColumnId = tbl.getColumn(keyFieldName).getColumnId(); + + keyCols.add(tbl.indexColumn(keyColumnId, SortOrder.ASCENDING)); + } else { + for (String propName : type.fields().keySet()) { + GridQueryProperty prop = type.property(propName); + + if (prop.key()) { + Column col = tbl.getColumn(propName); + + keyCols.add(tbl.indexColumn(col.getColumnId(), SortOrder.ASCENDING)); + } + } + // If key is object but the user has not specified any particular columns, + // we have to fall back to whole-key index. + if (keyCols.isEmpty()) + keyCols.add(keyCol); } + } else { keyCols = new ArrayList<>(2); + keyCols.add(keyCol); } From b570babde131f838a63c5b7faf4a7e9c55990d59 Mon Sep 17 00:00:00 2001 From: Yury Gerzhedovich Date: Fri, 7 Sep 2018 12:40:35 +0300 Subject: [PATCH 3/9] IGNITE-8386: minor fix --- .../internal/processors/query/h2/H2TableDescriptor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 85276fe73d05d..6bb2389b86ee8 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -292,9 +292,9 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { //Check if key is simple type if(keyFieldName != null){ - int keyColumnId = tbl.getColumn(keyFieldName).getColumnId(); + int keyColId = tbl.getColumn(keyFieldName).getColumnId(); - keyCols.add(tbl.indexColumn(keyColumnId, SortOrder.ASCENDING)); + keyCols.add(tbl.indexColumn(keyColId, SortOrder.ASCENDING)); } else { for (String propName : type.fields().keySet()) { GridQueryProperty prop = type.property(propName); From 20e1e74647a10fbcffccc28c423db785bbff781f Mon Sep 17 00:00:00 2001 From: Yury Gerzhedovich Date: Tue, 18 Sep 2018 17:11:53 +0300 Subject: [PATCH 4/9] IGNITE-8386: fix of determination if key is complex type or not --- .../processors/query/h2/H2TableDescriptor.java | 11 ++++------- ...lldingComplexPkIndexesForCreateTableAsSQLTest.java | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 6bb2389b86ee8..ba1a89d5d22bc 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -28,6 +28,7 @@ import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor; import org.apache.ignite.internal.processors.query.GridQueryProperty; import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; +import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex; import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory; import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; @@ -288,14 +289,10 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { if (isSql) { keyCols = new ArrayList<>(type.fields().size() + 1); - String keyFieldName = type.keyFieldName(); - //Check if key is simple type - if(keyFieldName != null){ - int keyColId = tbl.getColumn(keyFieldName).getColumnId(); - - keyCols.add(tbl.indexColumn(keyColId, SortOrder.ASCENDING)); - } else { + if(QueryUtils.isSqlType(type.keyClass())) + keyCols.add(keyCol); + else { for (String propName : type.fields().keySet()) { GridQueryProperty prop = type.property(propName); diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java index a8f1473df2c6d..0af251f5f6694 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java @@ -138,7 +138,7 @@ private void assertUsingPkIndex(List> results) { String explainPlan = (String)results.get(0).get(0); - assertTrue(explainPlan.contains("\"_key_PK\"")); + assertTrue(explainPlan.contains("\"_key_PK")); assertFalse(explainPlan.contains("_SCAN_")); } From f987371c494f4acb6fccf46371299daedec13bb4 Mon Sep 17 00:00:00 2001 From: devozerov Date: Mon, 29 Oct 2018 17:01:37 +0300 Subject: [PATCH 5/9] Merge. --- .../processors/cache/GridCacheProcessor.java | 5 +++-- .../processors/query/h2/H2TableDescriptor.java | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index 7b5bd4269e713..37932a5fb18bf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -2135,7 +2135,8 @@ private void prepareStartCaches( cacheContexts.get(cacheInfo), cacheInfo.getCacheDescriptor().schema() != null ? cacheInfo.getCacheDescriptor().schema() - : new QuerySchema() + : new QuerySchema(), + cacheInfo.getCacheDescriptor().sql() ); context().exchange().exchangerUpdateHeartbeat(); @@ -2178,7 +2179,7 @@ void prepareCacheStart( ) throws IgniteCheckedException { GridCacheContext cacheCtx = prepareCacheContext(startCfg, desc, reqNearCfg, exchTopVer, disabledAfterStart); - ctx.query().onCacheStart(cacheCtx, desc.schema() != null ? desc.schema() : new QuerySchema()); + ctx.query().onCacheStart(cacheCtx, desc.schema() != null ? desc.schema() : new QuerySchema(), desc.sql()); onCacheStarted(cacheCtx); } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 85ad5fd387ed2..0623df122cf87 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -267,8 +267,13 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { // Add explicit affinity key index if nothing alike was found. if (!affIdxFound) { - idxs.add(idx.createSortedIndex(AFFINITY_KEY_IDX_NAME, tbl, false, true, - H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), affCol, keyCol), -1)); + idxs.add(idx.createSortedIndex( + AFFINITY_KEY_IDX_NAME, + tbl, + false, + true, + H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), affCol, keyCol), -1) + ); } } @@ -367,7 +372,14 @@ public GridH2IndexBase createUserIndex(GridQueryIndexDescriptor idxDesc) { if (idxDesc.type() == QueryIndexType.SORTED) { cols = H2Utils.treeIndexColumns(desc, cols, keyCol, affCol); - return idx.createSortedIndex(idxDesc.name(), tbl, false, false, cols, idxDesc.inlineSize()); + return idx.createSortedIndex( + idxDesc.name(), + tbl, + false, + false, + cols, + idxDesc.inlineSize() + ); } else if (idxDesc.type() == QueryIndexType.GEOSPATIAL) return H2Utils.createSpatialIndex(tbl, idxDesc.name(), cols.toArray(new IndexColumn[cols.size()])); From 4bee027829ac65a81be7107be982bec200e654a0 Mon Sep 17 00:00:00 2001 From: devozerov Date: Mon, 29 Oct 2018 17:04:16 +0300 Subject: [PATCH 6/9] Added test to test suite. --- ...ableAsSQLTest.java => ComplexPrmiaryKeyUnwrapSelfTest.java} | 2 +- .../ignite/testsuites/IgniteCacheQuerySelfTestSuite.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) rename modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/{UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java => ComplexPrmiaryKeyUnwrapSelfTest.java} (98%) diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrmiaryKeyUnwrapSelfTest.java similarity index 98% rename from modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java rename to modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrmiaryKeyUnwrapSelfTest.java index 0af251f5f6694..e3cf890f620c5 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/UnfolldingComplexPkIndexesForCreateTableAsSQLTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrmiaryKeyUnwrapSelfTest.java @@ -30,7 +30,7 @@ * Test of creating and using PK indexes for tables created through SQL. */ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) -public class UnfolldingComplexPkIndexesForCreateTableAsSQLTest extends GridCommonAbstractTest { +public class ComplexPrmiaryKeyUnwrapSelfTest extends GridCommonAbstractTest { /** Counter to generate unique table names. */ private static int tblCnt = 0; diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java index fd71794ea38be..8c3a01189a829 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java @@ -106,6 +106,7 @@ import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest; import org.apache.ignite.internal.processors.cache.encryption.EncryptedSqlTableTest; import org.apache.ignite.internal.processors.cache.index.BasicIndexTest; +import org.apache.ignite.internal.processors.cache.index.ComplexPrmiaryKeyUnwrapSelfTest; import org.apache.ignite.internal.processors.cache.index.DuplicateKeyValueClassesSelfTest; import org.apache.ignite.internal.processors.cache.index.DynamicIndexClientBasicSelfTest; import org.apache.ignite.internal.processors.cache.index.DynamicIndexServerBasicSelfTest; @@ -215,6 +216,8 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite { public static TestSuite suite() throws Exception { IgniteTestSuite suite = new IgniteTestSuite("Ignite Cache Queries Test Suite"); + suite.addTestSuite(ComplexPrmiaryKeyUnwrapSelfTest.class); + suite.addTestSuite(PartitionedSqlTest.class); suite.addTestSuite(ReplicatedSqlTest.class); From a161f4544a933624a8147d812190e6ed0813928f Mon Sep 17 00:00:00 2001 From: devozerov Date: Mon, 29 Oct 2018 17:09:21 +0300 Subject: [PATCH 7/9] WIP. --- .../ignite/internal/processors/query/h2/H2TableDescriptor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 0623df122cf87..889798c063947 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -295,7 +295,7 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { if (isSql) { keyCols = new ArrayList<>(type.fields().size() + 1); - //Check if key is simple type + // Check if key is simple type. if(QueryUtils.isSqlType(type.keyClass())) keyCols.add(keyCol); else { @@ -308,6 +308,7 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { keyCols.add(tbl.indexColumn(col.getColumnId(), SortOrder.ASCENDING)); } } + // If key is object but the user has not specified any particular columns, // we have to fall back to whole-key index. if (keyCols.isEmpty()) From 3cce96ccaca7145a080f92eacaebf918f348e0fa Mon Sep 17 00:00:00 2001 From: Yury Gerzhedovich Date: Tue, 6 Nov 2018 11:54:37 +0300 Subject: [PATCH 8/9] ignite-8386: migration support for unwrapped PK indexes. --- modules/compatibility/pom.xml | 7 + ...gnitePKIndexesMigrationToUnwrapPkTest.java | 247 ++++++++++++++++++ .../testframework/junits/Dependency.java | 28 +- .../IgniteCompatibilityAbstractTest.java | 10 +- .../persistence/tree/io/BPlusMetaIO.java | 20 +- .../query/h2/H2TableDescriptor.java | 16 +- .../processors/query/h2/IgniteH2Indexing.java | 8 +- .../processors/query/h2/database/H2Tree.java | 69 ++++- .../query/h2/database/H2TreeIndex.java | 87 +++++- ...a => ComplexPrimaryKeyUnwrapSelfTest.java} | 122 +++++++-- .../IgniteBinaryCacheQueryTestSuite.java | 11 +- 11 files changed, 565 insertions(+), 60 deletions(-) create mode 100644 modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePKIndexesMigrationToUnwrapPkTest.java rename modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/{ComplexPrmiaryKeyUnwrapSelfTest.java => ComplexPrimaryKeyUnwrapSelfTest.java} (62%) diff --git a/modules/compatibility/pom.xml b/modules/compatibility/pom.xml index 7f24efed3a5cb..68948e0c93578 100644 --- a/modules/compatibility/pom.xml +++ b/modules/compatibility/pom.xml @@ -47,6 +47,13 @@ ${project.version} + + org.apache.ignite + ignite-indexing + ${project.version} + test + + com.google.guava guava diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePKIndexesMigrationToUnwrapPkTest.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePKIndexesMigrationToUnwrapPkTest.java new file mode 100644 index 0000000000000..22ccae0190a51 --- /dev/null +++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePKIndexesMigrationToUnwrapPkTest.java @@ -0,0 +1,247 @@ + +/* + * 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.compatibility.persistence; + +import java.util.Collection; +import java.util.List; +import org.apache.ignite.Ignite; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.compatibility.testframework.junits.Dependency; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.cache.GridCacheAbstractFullApiSelfTest; +import org.apache.ignite.lang.IgniteInClosure; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.jetbrains.annotations.NotNull; + +/** + * Test to check that starting node with PK index of the old format present doesn't break anything. + */ +public class IgnitePKIndexesMigrationToUnwrapPkTest extends IgnitePersistenceCompatibilityAbstractTest { + /** */ + private static String TABLE_NAME = "TEST_IDX_TABLE"; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + new ConfigurationClosure().apply(cfg); + + return cfg; + } + + /** {@inheritDoc} */ + @NotNull @Override protected Collection getDependencies(String igniteVer) { + Collection dependencies = super.getDependencies(igniteVer); + + dependencies.add(new Dependency("indexing", null, "ignite-indexing", igniteVer)); + dependencies.add(new Dependency("h2", "com.h2database", "h2", "1.4.195", true)); + + return dependencies; + } + + /** + * Tests opportunity to read data from previous Ignite DB version. + * + * @throws Exception If failed. + */ + public void testSecondaryIndexesMigration_2_5() throws Exception { + doTestStartupWithOldVersion("2.5.0"); + } + + /** + * Tests opportunity to read data from previous Ignite DB version. + * + * @throws Exception If failed. + */ + public void testSecondaryIndexesMigration_2_4() throws Exception { + doTestStartupWithOldVersion("2.4.0"); + } + + /** + * Tests opportunity to read data from previous Ignite DB version. + * + * @param ver 3-digits version of ignite + * @throws Exception If failed. + */ + @SuppressWarnings("unchecked") + private void doTestStartupWithOldVersion(String ver) throws Exception { + try { + startGrid(1, ver, new ConfigurationClosure(), new PostStartupClosure(true)); + + stopAllGrids(); + + IgniteEx igniteEx = startGrid(0); + + new PostStartupClosure(false).apply(igniteEx); + + igniteEx.active(true); + + assertDontUsingPkIndex(igniteEx, TABLE_NAME); + + String newTblName = TABLE_NAME + "_NEW"; + + initializeTable(igniteEx, newTblName); + + checkUsingIndexes(igniteEx, newTblName); + + igniteEx.active(false); + } + finally { + stopAllGrids(); + } + } + + /** */ + private static class PostStartupClosure implements IgniteInClosure { + + /** */ + boolean createTable; + + /** + * @param createTable {@code true} In case table should be created + */ + public PostStartupClosure(boolean createTable) { + this.createTable = createTable; + } + + /** {@inheritDoc} */ + @Override public void apply(Ignite ignite) { + ignite.active(true); + + IgniteEx igniteEx = (IgniteEx)ignite; + + if (createTable) + initializeTable(igniteEx, TABLE_NAME); + + assertDontUsingPkIndex(igniteEx, TABLE_NAME); + + ignite.active(false); + } + } + + /** + * @param igniteEx Ignite instance. + * @param tblName Table name. + */ + @NotNull private static void initializeTable(IgniteEx igniteEx, String tblName) { + executeSql(igniteEx, "CREATE TABLE " + tblName + " (id int, name varchar, age int, company varchar, city varchar, " + + "primary key (id, name, city))"); + + executeSql(igniteEx, "INSERT INTO " + tblName + " (id, name, age, company, city) VALUES(1,'name',2,'company', 'city')"); + + } + + /** + * Run SQL statement on specified node. + * + * @param node node to execute query. + * @param stmt Statement to run. + * @param args arguments of statements + * @return Run result. + */ + private static List> executeSql(IgniteEx node, String stmt, Object... args) { + return node.context().query().querySqlFields(new SqlFieldsQuery(stmt).setArgs(args), true).getAll(); + } + + /** + * Check using PK indexes for few cases. + * + * @param ignite Ignite instance. + * @param tblName name of table which should be checked to using PK indexes. + */ + private static void checkUsingIndexes(IgniteEx ignite, String tblName) { + String explainSQL = "explain SELECT * FROM " + tblName + " WHERE "; + + List> results = executeSql(ignite, explainSQL + "id=1"); + + assertUsingPkIndex(results); + + results = executeSql(ignite, explainSQL + "id=1 and name='name'"); + + assertUsingPkIndex(results); + + results = executeSql(ignite, explainSQL + "id=1 and name='name' and city='city' and age=2"); + + assertUsingPkIndex(results); + } + + /** + * Check that explain plan result shown using PK index and don't use scan. + * + * @param results Result list of explain of query. + */ + private static void assertUsingPkIndex(List> results) { + assertEquals(2, results.size()); + + String explainPlan = (String)results.get(0).get(0); + + assertTrue(explainPlan.contains("\"_key_PK")); + + assertFalse(explainPlan.contains("_SCAN_")); + } + + /** + * Check that explain plan result shown don't use PK index and use scan. + * + * @param igniteEx Ignite instance. + * @param tblName Name of table. + */ + private static void assertDontUsingPkIndex(IgniteEx igniteEx, String tblName) { + List> results = executeSql(igniteEx, "explain SELECT * FROM " + tblName + " WHERE id=1"); + + assertEquals(2, results.size()); + + String explainPlan = (String)results.get(0).get(0); + + System.out.println(explainPlan); + + assertFalse(explainPlan, explainPlan.contains("\"_key_PK\"")); + + assertTrue(explainPlan, explainPlan.contains("_SCAN_")); + } + + /** */ + private static class ConfigurationClosure implements IgniteInClosure { + /** {@inheritDoc} */ + @Override public void apply(IgniteConfiguration cfg) { + cfg.setLocalHost("127.0.0.1"); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + disco.setIpFinder(GridCacheAbstractFullApiSelfTest.LOCAL_IP_FINDER); + + cfg.setDiscoverySpi(disco); + + cfg.setPeerClassLoadingEnabled(false); + + DataStorageConfiguration memCfg = new DataStorageConfiguration() + .setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true) + .setInitialSize(1024 * 1024 * 10).setMaxSize(1024 * 1024 * 15)) + .setSystemRegionInitialSize(1024 * 1024 * 10) + .setSystemRegionMaxSize(1024 * 1024 * 15); + + cfg.setDataStorageConfiguration(memCfg); + } + } + +} diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/Dependency.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/Dependency.java index 56da0e982bec8..a30fb1e303dde 100644 --- a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/Dependency.java +++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/Dependency.java @@ -40,6 +40,9 @@ public class Dependency { /** Test flag. Test jar should have {@code true} value. Default is {@code false}. */ private boolean test; + /** */ + private String exludePathFromClassPath; + /** * Creates dependency. * @@ -71,12 +74,35 @@ public Dependency(String locModuleName, String artifactName) { * @param version Version. Null means default Ignite version is to be used. M */ public Dependency(String locModuleName, @Nullable String grpName, String artifactName, @Nullable String version) { - this.locModuleName = locModuleName; + this(locModuleName, grpName, artifactName, version, false); + } + + /** + * @param excludeName Local module name or part of exclude path. + * @param grpName Group name. Null means ignite default group name. + * @param artifactName Artifact name (artifact ID) without group na + * @param version Version. Null means default Ignite version is to be used. M + * @param exludeNotLocModule {@code true} In case param @excludeName should exclude path instead of local module. + */ + public Dependency(String excludeName, @Nullable String grpName, String artifactName, @Nullable String version, + boolean exludeNotLocModule) { + if (exludeNotLocModule) + this.exludePathFromClassPath = excludeName; + else + this.locModuleName = excludeName; + this.groupName = grpName; this.artifactName = artifactName; this.version = version; } + /** + * @return Path to exclude form classpath. + */ + public String excludePathFromClassPath() { + return exludePathFromClassPath; + } + /** * @return path based on local module name to exclude from classpath */ diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/IgniteCompatibilityAbstractTest.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/IgniteCompatibilityAbstractTest.java index 2301717b2068b..71ff9ffda80c8 100644 --- a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/IgniteCompatibilityAbstractTest.java +++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testframework/junits/IgniteCompatibilityAbstractTest.java @@ -21,6 +21,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; @@ -168,14 +169,16 @@ protected IgniteEx startGrid(final String igniteInstanceName, final String ver, final Collection dependencies = getDependencies(ver); - Set excluded = dependencies.stream().map(Dependency::localPathTemplate).collect(Collectors.toSet()); + Set excludedModules = dependencies.stream().map(Dependency::localPathTemplate).collect(Collectors.toSet()); + + Set excludedPaths = dependencies.stream().map(Dependency::excludePathFromClassPath).filter(Objects::nonNull).collect(Collectors.toSet()); StringBuilder pathBuilder = new StringBuilder(); for (URL url : CompatibilityTestsUtils.classLoaderUrls(CLASS_LOADER)) { String path = url.getPath(); - if (excluded.stream().noneMatch(path::contains)) + if (excludedModules.stream().noneMatch(path::contains) && excludedPaths.stream().noneMatch(path::contains)) pathBuilder.append(path).append(File.pathSeparator); } @@ -243,6 +246,9 @@ protected long getNodeJoinTimeout() { dependencies.add(new Dependency("core", "ignite-core")); dependencies.add(new Dependency("core", "ignite-core", true)); + //Just to exclude indexing module + dependencies.add(new Dependency("indexing", "ignite-core")); + return dependencies; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java index 623951bafc58d..fef58fd1b7b66 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/BPlusMetaIO.java @@ -28,7 +28,7 @@ public class BPlusMetaIO extends PageIO { /** */ public static final IOVersions VERSIONS = new IOVersions<>( - new BPlusMetaIO(1), new BPlusMetaIO(2) + new BPlusMetaIO(1), new BPlusMetaIO(2), new BPlusMetaIO(3) ); /** */ @@ -40,6 +40,9 @@ public class BPlusMetaIO extends PageIO { /** */ private final int inlineSizeOff; + /** */ + private boolean unwrappedPk; + /** * @param ver Page format version. */ @@ -50,11 +53,19 @@ private BPlusMetaIO(int ver) { case 1: inlineSizeOff = -1; refsOff = LVLS_OFF + 1; + unwrappedPk = false; break; case 2: inlineSizeOff = LVLS_OFF + 1; refsOff = inlineSizeOff + 2; + unwrappedPk = false; + break; + + case 3: + inlineSizeOff = LVLS_OFF + 1; + refsOff = inlineSizeOff + 2; + unwrappedPk = true; break; default: @@ -182,6 +193,13 @@ public int getInlineSize(long pageAddr) { return getVersion() > 1 ? PageUtils.getShort(pageAddr, inlineSizeOff) : 0; } + /** + * @return {@code true} In case use unwrapped PK. + */ + public boolean unwrappedPk() { + return unwrappedPk; + } + /** {@inheritDoc} */ @Override protected void printPage(long addr, int pageSize, GridStringBuilder sb) throws IgniteCheckedException { sb.a("BPlusMeta [\n\tlevelsCnt=").a(getLevelsCount(addr)) diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index 889798c063947..aa66939855425 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -204,12 +204,15 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { if (affCol != null && H2Utils.equals(affCol, keyCol)) affCol = null; - List keyCols = extractKeyColumns(tbl, keyCol, affCol); + List unwrappedKeyCols = extractKeyColumns(tbl, keyCol, affCol); + + List wrappedKeyCols = H2Utils.treeIndexColumns(tbl.rowDescriptor(), + new ArrayList<>(2), keyCol, affCol); Index hashIdx = createHashIndex( tbl, PK_HASH_IDX_NAME, - keyCols + wrappedKeyCols ); if (hashIdx != null) @@ -221,7 +224,8 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { tbl, true, false, - keyCols, + unwrappedKeyCols, + wrappedKeyCols, -1 ); @@ -267,12 +271,15 @@ H2RowFactory rowFactory(GridH2RowDescriptor rowDesc) { // Add explicit affinity key index if nothing alike was found. if (!affIdxFound) { + List columns = H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), affCol, keyCol); idxs.add(idx.createSortedIndex( AFFINITY_KEY_IDX_NAME, tbl, false, true, - H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), affCol, keyCol), -1) + columns, + columns, + -1) ); } } @@ -379,6 +386,7 @@ public GridH2IndexBase createUserIndex(GridQueryIndexDescriptor idxDesc) { false, false, cols, + cols, idxDesc.inlineSize() ); } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 6c07009a46f2f..8ba52ffea15b1 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -992,13 +992,13 @@ private void executeSql(String schemaName, String sql) throws IgniteCheckedExcep * @param tbl Table. * @param pk Primary key flag. * @param affinityKey Affinity key flag. - * @param cols Columns. + * @param unwrappedCols Unwrapped index columns for complex types. + * @param wrappedCols Index columns as is complex types. * @param inlineSize Index inline size. * @return Index. */ GridH2IndexBase createSortedIndex(String name, GridH2Table tbl, boolean pk, boolean affinityKey, - List cols, - int inlineSize) { + List unwrappedCols, List wrappedCols, int inlineSize) { try { GridCacheContext cctx = tbl.cache(); @@ -1009,7 +1009,7 @@ GridH2IndexBase createSortedIndex(String name, GridH2Table tbl, boolean pk, bool H2RowCache cache = rowCache.forGroup(cctx.groupId()); - return new H2TreeIndex(cctx, cache, tbl, name, pk, affinityKey, cols, inlineSize, segments); + return new H2TreeIndex(cctx, cache, tbl, name, pk, affinityKey, unwrappedCols, wrappedCols, inlineSize, segments); } catch (IgniteCheckedException e) { throw new IgniteException(e); diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java index 4c6c0c065f58f..71cea7edbee87 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java @@ -108,6 +108,8 @@ public abstract class H2Tree extends BPlusTree { /** */ private final IgniteLogger log; + private boolean unwrappedPk; + /** * Constructor. * @@ -143,9 +145,8 @@ protected H2Tree( H2RowFactory rowStore, long metaPageId, boolean initNew, - IndexColumn[] cols, - List inlineIdxs, - int inlineSize, + H2TreeIndex.IndexColumnsInfo unwrappedColsInfo, + H2TreeIndex.IndexColumnsInfo wrappedColsInfo, AtomicInteger maxCalculatedInlineSize, boolean pk, boolean affinityKey, @@ -157,15 +158,23 @@ protected H2Tree( super(name, grpId, pageMem, wal, globalRmvId, metaPageId, reuseList, failureProcessor); if (!initNew) { - // Page is ready - read inline size from it. - inlineSize = getMetaInlineSize(); + // Page is ready - read meta information. + MetaPageInfo metaInfo = getMetaInfo(); + + inlineSize = metaInfo.inlineSize(); + + unwrappedPk = metaInfo.useUnwrappedPk(); + } + else { + unwrappedPk = true; + + inlineSize = unwrappedColsInfo.inlineSize(); } this.idxName = idxName; this.cacheName = cacheName; this.tblName = tblName; - this.inlineSize = inlineSize; this.maxCalculatedInlineSize = maxCalculatedInlineSize; this.pk = pk; @@ -176,8 +185,8 @@ protected H2Tree( assert rowStore != null; this.rowStore = rowStore; - this.inlineIdxs = inlineIdxs; - this.cols = cols; + this.inlineIdxs = unwrappedPk ? unwrappedColsInfo.inlineIdx() : wrappedColsInfo.inlineIdx(); + this.cols = unwrappedPk ? unwrappedColsInfo.cols() : wrappedColsInfo.cols(); this.columnIds = new int[cols.length]; @@ -259,7 +268,7 @@ private int inlineSize() { * @return Inline size. * @throws IgniteCheckedException If failed. */ - private int getMetaInlineSize() throws IgniteCheckedException { + private MetaPageInfo getMetaInfo() throws IgniteCheckedException { final long metaPage = acquirePage(metaPageId); try { @@ -271,7 +280,7 @@ private int getMetaInlineSize() throws IgniteCheckedException { try { BPlusMetaIO io = BPlusMetaIO.VERSIONS.forPage(pageAddr); - return io.getInlineSize(pageAddr); + return new MetaPageInfo(io.getInlineSize(pageAddr), io.unwrappedPk()); } finally { readUnlock(metaPageId, metaPage, pageAddr); @@ -500,6 +509,46 @@ private void inlineSizeRecomendation(SearchRow row) { } } + /** + * @return {@code true} In case use unwrapped columns for PK + */ + public boolean unwrappedPk() { + return unwrappedPk; + } + + /** + * + */ + private class MetaPageInfo { + /** */ + int inlineSize; + /** */ + boolean useUnwrappedPk; + + /** + * @param inlineSize Inline size. + * @param useUnwrappedPk {@code true} In case use unwrapped PK for indexes. + */ + public MetaPageInfo(int inlineSize, boolean useUnwrappedPk) { + this.inlineSize = inlineSize; + this.useUnwrappedPk = useUnwrappedPk; + } + + /** + * @return Inline size. + */ + public int inlineSize() { + return inlineSize; + } + + /** + * @return {@code true} In case use unwrapped PK for indexes. + */ + public boolean useUnwrappedPk() { + return useUnwrappedPk; + } + } + /** * @param v1 First value. * @param v2 Second value. diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java index e9cca9ee0381e..b7179b744b22e 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java @@ -93,12 +93,15 @@ public class H2TreeIndex extends GridH2IndexBase { /** * @param cctx Cache context. + * @param rowCache Row cache. * @param tbl Table. * @param idxName Index name. * @param pk Primary key. * @param affinityKey {@code true} for affinity key. - * @param colsList Index columns. + * @param unwrappedColsList Unwrapped index columns for complex types. + * @param wrappedColsList Index columns as is. * @param inlineSize Inline size. + * @param segmentsCnt Count of tree segments. * @throws IgniteCheckedException If failed. */ public H2TreeIndex( @@ -108,7 +111,8 @@ public H2TreeIndex( String idxName, boolean pk, boolean affinityKey, - List colsList, + List unwrappedColsList, + List wrappedColsList, int inlineSize, int segmentsCnt ) throws IgniteCheckedException { @@ -124,12 +128,8 @@ public H2TreeIndex( this.tblName = tbl.getName(); this.idxName = idxName; - IndexColumn[] cols = colsList.toArray(new IndexColumn[colsList.size()]); + this.table = tbl; - IndexColumn.mapColumns(cols, tbl); - - initBaseIndex(tbl, 0, idxName, cols, - pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false)); GridQueryTypeDescriptor typeDesc = tbl.rowDescriptor().type(); @@ -139,9 +139,13 @@ public H2TreeIndex( treeName = BPlusTree.treeName(treeName, "H2Tree"); - if (cctx.affinityNode()) { - inlineIdxs = getAvailableInlineColumns(cols); + IndexColumnsInfo unwrappedColsInfo = new IndexColumnsInfo(unwrappedColsList, inlineSize); + + IndexColumnsInfo wrappedColsInfo = new IndexColumnsInfo(wrappedColsList, inlineSize); + IndexColumn[] cols; + + if (cctx.affinityNode()) { segments = new H2Tree[segmentsCnt]; IgniteCacheDatabaseSharedManager db = cctx.shared().database(); @@ -167,9 +171,8 @@ public H2TreeIndex( tbl.rowFactory(), page.pageId().pageId(), page.isAllocated(), - cols, - inlineIdxs, - computeInlineSize(inlineIdxs, inlineSize), + unwrappedColsInfo, + wrappedColsInfo, maxCalculatedInlineSize, pk, affinityKey, @@ -186,13 +189,28 @@ public H2TreeIndex( db.checkpointReadUnlock(); } } + + boolean useUnwrappedCols = segments[0].unwrappedPk(); + + IndexColumnsInfo colsInfo = useUnwrappedCols ? unwrappedColsInfo : wrappedColsInfo; + + cols = colsInfo.cols(); + + inlineIdxs = colsInfo.inlineIdx(); } else { // We need indexes on the client node, but index will not contain any data. segments = null; inlineIdxs = null; + + cols = unwrappedColsInfo.cols(); } + IndexColumn.mapColumns(cols, tbl); + + initBaseIndex(tbl, 0, idxName, cols, + pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false)); + initDistributedJoinMessaging(tbl); } @@ -540,4 +558,49 @@ private void dropMetaPage(String name, int segIdx) throws IgniteCheckedException for (int pos = 0; pos < inlineHelpers.size(); ++pos) inlineIdxs.set(pos, inlineHelpers.get(pos)); } + + /** + * + */ + public class IndexColumnsInfo { + /** */ + private final int inlineSize; + /** */ + private final IndexColumn[] cols; + /** */ + private final List inlineIdx; + + /** + * @param colsList Index columns list + * @param cfgInlineSize Inline size from cache config. + */ + public IndexColumnsInfo(List colsList, int cfgInlineSize) { + this.cols = colsList.toArray(new IndexColumn[colsList.size()]); + + this.inlineIdx = getAvailableInlineColumns(cols); + + this.inlineSize = computeInlineSize(inlineIdx, cfgInlineSize); + } + + /** + * @return Inline size. + */ + public int inlineSize() { + return inlineSize; + } + + /** + * @return Index columns. + */ + public IndexColumn[] cols() { + return cols; + } + + /** + * @return Inline indexes. + */ + public List inlineIdx() { + return inlineIdx; + } + } } diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrmiaryKeyUnwrapSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java similarity index 62% rename from modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrmiaryKeyUnwrapSelfTest.java rename to modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java index e3cf890f620c5..8f4eaf00f7564 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrmiaryKeyUnwrapSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java @@ -17,7 +17,9 @@ package org.apache.ignite.internal.processors.cache.index; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.cache.query.annotations.QuerySqlField; @@ -30,7 +32,7 @@ * Test of creating and using PK indexes for tables created through SQL. */ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) -public class ComplexPrmiaryKeyUnwrapSelfTest extends GridCommonAbstractTest { +public class ComplexPrimaryKeyUnwrapSelfTest extends GridCommonAbstractTest { /** Counter to generate unique table names. */ private static int tblCnt = 0; @@ -53,55 +55,123 @@ public class ComplexPrmiaryKeyUnwrapSelfTest extends GridCommonAbstractTest { * Test using PK indexes for complex primary key. */ public void testComplexPk() { - String tableName = createTableName(); + String tblName = createTableName(); - executeSql("CREATE TABLE " + tableName + " (id int, name varchar, age int, company varchar, city varchar, " + + executeSql("CREATE TABLE " + tblName + " (id int, name varchar, age int, company varchar, city varchar, " + "primary key (id, name, city))"); - checkUsingIndexes(tableName); + checkUsingIndexes(tblName, "1"); } /** * Test using PK indexes for simple primary key. */ public void testSimplePk() { - String tableName = createTableName(); - - executeSql("CREATE TABLE " + tableName + " (id int, name varchar, age int, company varchar, city varchar, " + - "primary key (id))"); + //ToDo: IGNITE-8386: need to add DATE type into the test. + HashMap types = new HashMap() { + { + put("boolean", "1"); + put("char", "'1'"); + put("varchar", "'1'"); + put("real", "1"); + put("number", "1"); + put("int", "1"); + put("long", "1"); + put("float", "1"); + put("double", "1"); + put("tinyint", "1"); + put("smallint", "1"); + put("bigint", "1"); + put("varchar_ignorecase", "'1'"); + put("time", "'11:11:11'"); + put("timestamp", "'20018-11-02 11:11:11'"); + put("uuid", "'1'"); + } + }; + for (Map.Entry entry : types.entrySet()) { + + String tblName = createTableName(); + + String type = entry.getKey(); + String value = entry.getValue(); + + executeSql("CREATE TABLE " + tblName + + " (id " + type + " , name varchar, age int, company varchar, city varchar," + + " primary key (id))"); + + checkUsingIndexes(tblName, value); + } + } - checkUsingIndexes(tableName); + /** + * Test using PK indexes for simple primary key and affinity key. + */ + public void testSimplePkWithAffinityKey() { + //ToDo: IGNITE-8386: need to add DATE type into the test. + HashMap types = new HashMap() { + { + put("boolean", "1"); + put("char", "'1'"); + put("varchar", "'1'"); + put("real", "1"); + put("number", "1"); + put("int", "1"); + put("long", "1"); + put("float", "1"); + put("double", "1"); + put("tinyint", "1"); + put("smallint", "1"); + put("bigint", "1"); + put("varchar_ignorecase", "'1'"); + put("time", "'11:11:11'"); + put("timestamp", "'20018-11-02 11:11:11'"); + put("uuid", "'1'"); + } + }; + for (Map.Entry entry : types.entrySet()) { + + String tblName = createTableName(); + + String type = entry.getKey(); + String value = entry.getValue(); + + executeSql("CREATE TABLE " + tblName + + " (id " + type + " , name varchar, age int, company varchar, city varchar," + + " primary key (id)) WITH \"affinity_key=id\""); + + checkUsingIndexes(tblName, value); + } } /** * Test using PK indexes for wrapped primary key. */ public void testWrappedPk() { - String tableName = createTableName(); + String tblName = createTableName(); - executeSql("CREATE TABLE " + tableName + " (id int, name varchar, age int, company varchar, city varchar, " + + executeSql("CREATE TABLE " + tblName + " (id int, name varchar, age int, company varchar, city varchar, " + "primary key (id)) WITH \"wrap_key=true\""); - checkUsingIndexes(tableName); + checkUsingIndexes(tblName, "1"); } /** * Check using PK indexes for few cases. * - * @param tableName name of table which should be checked to using PK indexes. + * @param tblName name of table which should be checked to using PK indexes. */ - private void checkUsingIndexes(String tableName) { - String explainSQL = "explain SELECT * FROM " + tableName + " WHERE "; + private void checkUsingIndexes(String tblName, String idValue) { + String explainSQL = "explain SELECT * FROM " + tblName + " WHERE "; - List> results = executeSql(explainSQL + "id=1"); + List> results = executeSql(explainSQL + "id=" + idValue); assertUsingPkIndex(results); - results = executeSql(explainSQL + "id=1 and name=''"); + results = executeSql(explainSQL + "id=" + idValue + " and name=''"); assertUsingPkIndex(results); - results = executeSql(explainSQL + "id=1 and name='' and city='' and age=0"); + results = executeSql(explainSQL + "id=" + idValue + " and name='' and city='' and age=0"); assertUsingPkIndex(results); } @@ -110,12 +180,12 @@ private void checkUsingIndexes(String tableName) { * Test don't using PK indexes for table created through cache API. */ public void testIndexesForCachesCreatedThroughCashApi() { - String tableName = TestValue.class.getSimpleName(); + String tblName = TestValue.class.getSimpleName(); CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME); ccfg.setSqlSchema("PUBLIC"); - ccfg.setName(tableName); + ccfg.setName(tblName); QueryEntity qryEntity = new QueryEntity(TestKey.class, TestValue.class); @@ -123,7 +193,7 @@ public void testIndexesForCachesCreatedThroughCashApi() { node().createCache(ccfg); - List> results = executeSql("explain SELECT * FROM " + tableName + " WHERE id=1"); + List> results = executeSql("explain SELECT * FROM " + tblName + " WHERE id=1"); assertDontUsingPkIndex(results); } @@ -199,6 +269,9 @@ private IgniteEx node() { return grid(0); } + /** + * + */ static class TestKey { /** */ @QuerySqlField @@ -230,14 +303,20 @@ public TestKey(int id) { } } + /** + * + */ static class TestValue { /** */ @QuerySqlField() private String name; + /** */ @QuerySqlField() private String company; + /** */ @QuerySqlField() private String city; + /** */ @QuerySqlField() private int age; @@ -255,5 +334,4 @@ public TestValue(int age, String name, String company, String city) { } } - } diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java index ee82b7a71ee56..2f42b7403cd00 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java @@ -119,6 +119,7 @@ import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest; import org.apache.ignite.internal.processors.cache.encryption.EncryptedSqlTableTest; import org.apache.ignite.internal.processors.cache.index.BasicIndexTest; +import org.apache.ignite.internal.processors.cache.index.ComplexPrimaryKeyUnwrapSelfTest; import org.apache.ignite.internal.processors.cache.index.DuplicateKeyValueClassesSelfTest; import org.apache.ignite.internal.processors.cache.index.DynamicIndexClientBasicSelfTest; import org.apache.ignite.internal.processors.cache.index.DynamicIndexServerBasicSelfTest; @@ -126,10 +127,6 @@ import org.apache.ignite.internal.processors.cache.index.DynamicIndexServerNodeFIlterBasicSelfTest; import org.apache.ignite.internal.processors.cache.index.DynamicIndexServerNodeFilterCoordinatorBasicSelfTest; import org.apache.ignite.internal.processors.cache.index.H2ConnectionLeaksSelfTest; -import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientAtomicPartitionedNoBackupsTest; -import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientTransactionalPartitionedNoBackupsTest; -import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerAtomicPartitionedNoBackupsTest; -import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerTransactionalPartitionedNoBackupsTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicColumnsClientBasicSelfTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicColumnsServerBasicSelfTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicColumnsServerCoordinatorBasicSelfTest; @@ -139,12 +136,16 @@ import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexTransactionalPartitionedNearSelfTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexTransactionalPartitionedSelfTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexTransactionalReplicatedSelfTest; +import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientAtomicPartitionedNoBackupsTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientAtomicPartitionedTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientAtomicReplicatedTest; +import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientTransactionalPartitionedNoBackupsTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientTransactionalPartitionedTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexClientTransactionalReplicatedTest; +import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerAtomicPartitionedNoBackupsTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerAtomicPartitionedTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerAtomicReplicatedTest; +import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerTransactionalPartitionedNoBackupsTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerTransactionalPartitionedTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerTransactionalReplicatedTest; import org.apache.ignite.internal.processors.cache.index.H2DynamicTableSelfTest; @@ -235,6 +236,8 @@ public class IgniteBinaryCacheQueryTestSuite extends TestSuite { public static TestSuite suite() throws Exception { IgniteTestSuite suite = new IgniteTestSuite("Ignite Cache Queries Test Suite"); + suite.addTestSuite(ComplexPrimaryKeyUnwrapSelfTest.class); + suite.addTestSuite(PartitionedSqlTest.class); suite.addTestSuite(ReplicatedSqlTest.class); From 0845235b250f7c156043c9e792a58468a332ffa9 Mon Sep 17 00:00:00 2001 From: Yury Gerzhedovich Date: Tue, 6 Nov 2018 12:11:23 +0300 Subject: [PATCH 9/9] ignite-8386: minor fix after merge. --- .../ignite/internal/processors/cache/GridCacheProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index b575092728224..2544c618b2fdd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -2542,7 +2542,7 @@ private void onCacheStarted(GridCacheContext cacheCtx) throws IgniteCheckedExcep grp.onCacheStarted(cacheCtx); - ctx.query().onCacheStart(cacheCtx, desc.schema() != null ? desc.schema() : new QuerySchema()); + ctx.query().onCacheStart(cacheCtx, desc.schema() != null ? desc.schema() : new QuerySchema(), desc.sql()); if (log.isInfoEnabled()) { log.info("Started cache in recovery mode [name=" + cfg.getName() +