http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java ---------------------------------------------------------------------- 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 937363a..e726857 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 @@ -62,6 +62,7 @@ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObjectValueContext; import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheContextInfo; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.QueryCursorImpl; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture; @@ -73,7 +74,6 @@ import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot; import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; -import org.apache.ignite.internal.processors.query.h2.affinity.PartitionInfo; import org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager; import org.apache.ignite.internal.processors.cache.query.GridCacheQueryMarshallable; import org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery; @@ -100,7 +100,9 @@ import org.apache.ignite.internal.processors.query.QueryIndexDescriptorImpl; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.processors.query.SqlClientContext; import org.apache.ignite.internal.processors.query.UpdateSourceIterator; +import org.apache.ignite.internal.processors.query.h2.affinity.PartitionInfo; import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory; +import org.apache.ignite.internal.processors.query.h2.database.H2TreeClientIndex; import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex; import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasInnerIO; import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasLeafIO; @@ -751,16 +753,20 @@ public class IgniteH2Indexing implements GridQueryIndexing { GridH2IndexBase createSortedIndex(String name, GridH2Table tbl, boolean pk, boolean affinityKey, List<IndexColumn> unwrappedCols, List<IndexColumn> wrappedCols, int inlineSize) { try { - GridCacheContext cctx = tbl.cache(); + GridCacheContextInfo cacheInfo = tbl.cacheInfo(); if (log.isDebugEnabled()) - log.debug("Creating cache index [cacheId=" + cctx.cacheId() + ", idxName=" + name + ']'); + log.debug("Creating cache index [cacheId=" + cacheInfo.cacheId() + ", idxName=" + name + ']'); - final int segments = tbl.rowDescriptor().context().config().getQueryParallelism(); + if (cacheInfo.affinityNode()) { + final int segments = tbl.rowDescriptor().context().config().getQueryParallelism(); - H2RowCache cache = rowCache.forGroup(cctx.groupId()); + H2RowCache cache = rowCache.forGroup(cacheInfo.groupId()); - return new H2TreeIndex(cctx, cache, tbl, name, pk, affinityKey, unwrappedCols, wrappedCols, inlineSize, segments); + return new H2TreeIndex(cacheInfo.gridCacheContext(), cache, tbl, name, pk, affinityKey, unwrappedCols, wrappedCols, inlineSize, segments); + } + else + return new H2TreeClientIndex(tbl, name, pk, unwrappedCols); } catch (IgniteCheckedException e) { throw new IgniteException(e); @@ -1379,7 +1385,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { if (o instanceof GridSqlAlias) o = GridSqlAlias.unwrap((GridSqlAst) o); if (o instanceof GridSqlTable && ((GridSqlTable) o).dataTable() != null) { - GridCacheContext cctx = ((GridSqlTable) o).dataTable().cache(); + GridCacheContext cctx = ((GridSqlTable)o).dataTable().cacheContext(); if (mvccEnabled == null) { mvccEnabled = cctx.mvccEnabled(); @@ -2335,31 +2341,12 @@ public class IgniteH2Indexing implements GridQueryIndexing { * @return H2 prepared statement. */ private PreparedStatement prepareStatementAndCaches(Connection c, String sqlQry) { - boolean cachesCreated = false; - - while (true) { - try { - return prepareStatement(c, sqlQry, true); - } - catch (SQLException e) { - if (!cachesCreated && ( - e.getErrorCode() == ErrorCode.SCHEMA_NOT_FOUND_1 || - e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1 || - e.getErrorCode() == ErrorCode.INDEX_NOT_FOUND_1) - ) { - try { - ctx.cache().createMissingQueryCaches(); - } - catch (IgniteCheckedException ignored) { - throw new CacheException("Failed to create missing caches.", e); - } - - cachesCreated = true; - } - else - throw new IgniteSQLException("Failed to parse query. " + e.getMessage(), - IgniteQueryErrorCode.PARSING, e); - } + try { + return prepareStatement(c, sqlQry, true); + } + catch (SQLException e) { + throw new IgniteSQLException("Failed to parse query. " + e.getMessage(), + IgniteQueryErrorCode.PARSING, e); } } @@ -2445,19 +2432,20 @@ public class IgniteH2Indexing implements GridQueryIndexing { * * This implementation doesn't support type reregistration. * + * @param cacheInfo Cache context info. * @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, boolean isSql) + @Override public boolean registerType(GridCacheContextInfo cacheInfo, GridQueryTypeDescriptor type, boolean isSql) throws IgniteCheckedException { validateTypeDescriptor(type); - String schemaName = schema(cctx.name()); + String schemaName = schema(cacheInfo.name()); H2Schema schema = schemas.get(schemaName); - H2TableDescriptor tbl = new H2TableDescriptor(this, schema, type, cctx, isSql); + H2TableDescriptor tbl = new H2TableDescriptor(this, schema, type, cacheInfo, isSql); try { Connection conn = connMgr.connectionForThread(schemaName); @@ -2596,6 +2584,16 @@ public class IgniteH2Indexing implements GridQueryIndexing { dataTables.remove(h2Tbl.identifier(), h2Tbl); } + /** {@inheritDoc} */ + public GridCacheContextInfo registeredCacheInfo(String cacheName) { + for (GridH2Table value : dataTables.values()) { + if (value.cacheName().equals(cacheName)) + return value.cacheInfo(); + } + + return null; + } + /** * Find table for index. * @@ -2675,7 +2673,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { List<H2TableDescriptor> tbls = new ArrayList<>(); for (H2TableDescriptor tbl : s.tables()) { - if (F.eq(tbl.cache().name(), cacheName)) + if (F.eq(tbl.cacheName(), cacheName)) tbls.add(tbl); } @@ -3044,9 +3042,25 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** {@inheritDoc} */ - @Override public void registerCache(String cacheName, String schemaName, GridCacheContext<?, ?> cctx) + @Override public boolean initCacheContext(GridCacheContext cacheCtx) { + GridCacheContextInfo cacheInfo = registeredCacheInfo(cacheCtx.name()); + + if (cacheInfo != null) { + assert !cacheInfo.isCacheContextInited() : cacheInfo.name(); + assert cacheInfo.name().equals(cacheCtx.name()) : cacheInfo.name() + " != " + cacheCtx.name(); + + cacheInfo.initCacheContext(cacheCtx); + + return true; + } + + return false; + } + + /** {@inheritDoc} */ + @Override public void registerCache(String cacheName, String schemaName, GridCacheContextInfo<?, ?> cacheInfo) throws IgniteCheckedException { - rowCache.onCacheRegistered(cctx); + rowCache.onCacheRegistered(cacheInfo); synchronized (schemaMux) { createSchemaIfNeeded(schemaName, false); @@ -3054,14 +3068,14 @@ public class IgniteH2Indexing implements GridQueryIndexing { cacheName2schema.put(cacheName, schemaName); - createSqlFunctions(schemaName, cctx.config().getSqlFunctionClasses()); + createSqlFunctions(schemaName, cacheInfo.config().getSqlFunctionClasses()); } /** {@inheritDoc} */ - @Override public void unregisterCache(GridCacheContext cctx, boolean rmvIdx) { - rowCache.onCacheUnregistered(cctx); + @Override public void unregisterCache(GridCacheContextInfo cacheInfo, boolean rmvIdx) { + rowCache.onCacheUnregistered(cacheInfo); - String cacheName = cctx.name(); + String cacheName = cacheInfo.name(); String schemaName = schema(cacheName); @@ -3078,7 +3092,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { Collection<H2TableDescriptor> rmvTbls = new HashSet<>(); for (H2TableDescriptor tbl : schema.tables()) { - if (F.eq(tbl.cache().name(), cacheName)) { + if (F.eq(tbl.cacheName(), cacheName)) { try { tbl.table().setRemoveIndexOnDestroy(rmvIdx); @@ -3297,6 +3311,8 @@ public class IgniteH2Indexing implements GridQueryIndexing { GridH2Table tbl = dataTable(tblKey); if (tbl != null) { + H2Utils.checkAndStartNotStartedCache(tbl); + int cacheId = tbl.cacheId(); caches0.add(cacheId);
http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeClientIndex.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeClientIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeClientIndex.java new file mode 100644 index 0000000..a0bab43 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeClientIndex.java @@ -0,0 +1,114 @@ +/* + * 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.h2.database; + +import java.util.List; +import org.apache.ignite.internal.processors.query.IgniteSQLException; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; +import org.h2.engine.Session; +import org.h2.index.Cursor; +import org.h2.index.IndexType; +import org.h2.result.SearchRow; +import org.h2.table.IndexColumn; + +/** + * We need indexes on an not affinity nodes. The index shouldn't contains any data. + */ +public class H2TreeClientIndex extends H2TreeIndexBase { + + /** + * + */ + public static final IgniteSQLException SHOULDNT_BE_INVOKED_EXCEPTION = new IgniteSQLException("Shouldn't be invoked, due to it's not affinity node"); + + /** + * @param tbl Table. + * @param name Index name. + * @param pk Primary key. + * @param colsList Index columns. + */ + public H2TreeClientIndex( + GridH2Table tbl, + String name, + boolean pk, + List<IndexColumn> colsList + ) { + IndexColumn[] cols = colsList.toArray(new IndexColumn[colsList.size()]); + + IndexColumn.mapColumns(cols, tbl); + + initBaseIndex(tbl, 0, name, cols, + pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false)); + } + + /** {@inheritDoc} */ + @Override public void refreshColumnIds() { + //do nothing. + } + + /** {@inheritDoc} */ + @Override public void destroy(boolean rmvIndex) { + //do nothing. + } + + /** {@inheritDoc} */ + @Override protected int segmentsCount() { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public GridH2Row put(GridH2Row row) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public boolean putx(GridH2Row row) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public GridH2Row remove(SearchRow row) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public boolean removex(SearchRow row) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public long getRowCount(Session ses) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override public Cursor findFirstOrLast(Session session, boolean b) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } + + /** {@inheritDoc} */ + @Override protected H2Tree treeForRead(int segment) { + throw SHOULDNT_BE_INVOKED_EXCEPTION; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java ---------------------------------------------------------------------- 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 b7179b7..2c0a9d8 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 @@ -18,7 +18,6 @@ package org.apache.ignite.internal.processors.query.h2.database; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.apache.ignite.IgniteCheckedException; @@ -35,7 +34,6 @@ import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.h2.H2Cursor; import org.apache.ignite.internal.processors.query.h2.H2RowCache; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Cursor; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; import org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; @@ -52,10 +50,7 @@ import org.h2.index.IndexType; import org.h2.index.SingleRowCursor; import org.h2.message.DbException; import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.table.Column; import org.h2.table.IndexColumn; -import org.h2.table.TableFilter; import org.h2.value.Value; import org.jetbrains.annotations.Nullable; @@ -63,7 +58,7 @@ import org.jetbrains.annotations.Nullable; * H2 Index over {@link BPlusTree}. */ @SuppressWarnings({"TypeMayBeWeakened", "unchecked"}) -public class H2TreeIndex extends GridH2IndexBase { +public class H2TreeIndex extends H2TreeIndexBase { /** Default value for {@code IGNITE_MAX_INDEX_PAYLOAD_SIZE} */ public static final int IGNITE_MAX_INDEX_PAYLOAD_SIZE_DEFAULT = 10; @@ -145,66 +140,59 @@ public class H2TreeIndex extends GridH2IndexBase { IndexColumn[] cols; - if (cctx.affinityNode()) { - segments = new H2Tree[segmentsCnt]; - - IgniteCacheDatabaseSharedManager db = cctx.shared().database(); - - AtomicInteger maxCalculatedInlineSize = new AtomicInteger(); - - for (int i = 0; i < segments.length; i++) { - db.checkpointReadLock(); - - try { - RootPage page = getMetaPage(treeName, i); - - segments[i] = new H2Tree( - treeName, - idxName, - tblName, - tbl.cacheName(), - cctx.offheap().reuseListForIndex(treeName), - cctx.groupId(), - cctx.dataRegion().pageMemory(), - cctx.shared().wal(), - cctx.offheap().globalRemoveId(), - tbl.rowFactory(), - page.pageId().pageId(), - page.isAllocated(), - unwrappedColsInfo, - wrappedColsInfo, - maxCalculatedInlineSize, - pk, - affinityKey, - cctx.mvccEnabled(), - rowCache, - cctx.kernalContext().failure(), - log) { - @Override public int compareValues(Value v1, Value v2) { - return v1 == v2 ? 0 : table.compareTypeSafe(v1, v2); - } - }; - } - finally { - db.checkpointReadUnlock(); - } + assert cctx.affinityNode(); + + segments = new H2Tree[segmentsCnt]; + + IgniteCacheDatabaseSharedManager db = cctx.shared().database(); + + AtomicInteger maxCalculatedInlineSize = new AtomicInteger(); + + for (int i = 0; i < segments.length; i++) { + db.checkpointReadLock(); + + try { + RootPage page = getMetaPage(treeName, i); + + segments[i] = new H2Tree( + treeName, + idxName, + tblName, + tbl.cacheName(), + cctx.offheap().reuseListForIndex(treeName), + cctx.groupId(), + cctx.dataRegion().pageMemory(), + cctx.shared().wal(), + cctx.offheap().globalRemoveId(), + tbl.rowFactory(), + page.pageId().pageId(), + page.isAllocated(), + unwrappedColsInfo, + wrappedColsInfo, + maxCalculatedInlineSize, + pk, + affinityKey, + cctx.mvccEnabled(), + rowCache, + cctx.kernalContext().failure(), + log) { + @Override public int compareValues(Value v1, Value v2) { + return v1 == v2 ? 0 : table.compareTypeSafe(v1, v2); + } + }; } + finally { + db.checkpointReadUnlock(); + } + } - boolean useUnwrappedCols = segments[0].unwrappedPk(); - - IndexColumnsInfo colsInfo = useUnwrappedCols ? unwrappedColsInfo : wrappedColsInfo; + boolean useUnwrappedCols = segments[0].unwrappedPk(); - cols = colsInfo.cols(); + IndexColumnsInfo colsInfo = useUnwrappedCols ? unwrappedColsInfo : wrappedColsInfo; - inlineIdxs = colsInfo.inlineIdx(); - } - else { - // We need indexes on the client node, but index will not contain any data. - segments = null; - inlineIdxs = null; + cols = colsInfo.cols(); - cols = unwrappedColsInfo.cols(); - } + inlineIdxs = colsInfo.inlineIdx(); IndexColumn.mapColumns(cols, tbl); @@ -371,17 +359,6 @@ public class H2TreeIndex extends GridH2IndexBase { } /** {@inheritDoc} */ - @Override public double getCost(Session ses, int[] masks, TableFilter[] filters, int filter, SortOrder sortOrder, HashSet<Column> allColumnsSet) { - long rowCnt = getRowCountApproximation(); - - double baseCost = getCostRangeIndex(masks, rowCnt, filters, filter, sortOrder, false, allColumnsSet); - - int mul = getDistributedMultiplier(ses, filters, filter); - - return mul * baseCost; - } - - /** {@inheritDoc} */ @Override public long getRowCount(Session ses) { try { int seg = threadLocalSegment(); @@ -398,16 +375,6 @@ public class H2TreeIndex extends GridH2IndexBase { } /** {@inheritDoc} */ - @Override public long getRowCountApproximation() { - return 10_000; // TODO - } - - /** {@inheritDoc} */ - @Override public boolean canGetFirstOrLast() { - return true; - } - - /** {@inheritDoc} */ @Override public Cursor findFirstOrLast(Session session, boolean b) { try { H2Tree tree = treeForRead(threadLocalSegment()); http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexBase.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexBase.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexBase.java new file mode 100644 index 0000000..e6dda14 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexBase.java @@ -0,0 +1,53 @@ +/* + * 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.h2.database; + +import java.util.HashSet; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; +import org.h2.engine.Session; +import org.h2.result.SortOrder; +import org.h2.table.Column; +import org.h2.table.TableFilter; + +/** + * H2 tree index base. + */ +public abstract class H2TreeIndexBase extends GridH2IndexBase { + /** {@inheritDoc} */ + @Override public double getCost(Session ses, int[] masks, TableFilter[] filters, int filter, SortOrder sortOrder, + HashSet<Column> allColumnsSet) { + long rowCnt = getRowCountApproximation(); + + double baseCost = getCostRangeIndex(masks, rowCnt, filters, filter, sortOrder, false, allColumnsSet); + + int mul = getDistributedMultiplier(ses, filters, filter); + + return mul * baseCost; + } + + /** {@inheritDoc} */ + @Override public boolean canGetFirstOrLast() { + return true; + } + + /** {@inheritDoc} */ + @Override public long getRowCountApproximation() { + return 10_000; // TODO + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java index b99d7dc..6308eab 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java @@ -129,7 +129,7 @@ public class DdlStatementsProcessor { if (cmd instanceof SqlCreateIndexCommand) { SqlCreateIndexCommand cmd0 = (SqlCreateIndexCommand)cmd; - GridH2Table tbl = dataTableWithRetry(cmd0.schemaName(), cmd0.tableName()); + GridH2Table tbl = idx.dataTable(cmd0.schemaName(), cmd0.tableName()); if (tbl == null) throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd0.tableName()); @@ -167,7 +167,7 @@ public class DdlStatementsProcessor { else if (cmd instanceof SqlDropIndexCommand) { SqlDropIndexCommand cmd0 = (SqlDropIndexCommand)cmd; - GridH2Table tbl = dataTableForIndexWithRetry(cmd0.schemaName(), cmd0.indexName()); + GridH2Table tbl = idx.dataTableForIndex(cmd0.schemaName(), cmd0.indexName()); if (tbl != null) { isDdlSupported(tbl); @@ -186,7 +186,7 @@ public class DdlStatementsProcessor { else if (cmd instanceof SqlAlterTableCommand) { SqlAlterTableCommand cmd0 = (SqlAlterTableCommand)cmd; - GridH2Table tbl = dataTableWithRetry(cmd0.schemaName(), cmd0.tableName()); + GridH2Table tbl = idx.dataTable(cmd0.schemaName(), cmd0.tableName()); if (tbl == null) { throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, @@ -270,7 +270,7 @@ public class DdlStatementsProcessor { isDdlOnSchemaSupported(cmd.schemaName()); - GridH2Table tbl = dataTableWithRetry(cmd.schemaName(), cmd.tableName()); + GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName()); if (tbl == null) throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName()); @@ -309,7 +309,7 @@ public class DdlStatementsProcessor { isDdlOnSchemaSupported(cmd.schemaName()); - GridH2Table tbl = dataTableForIndexWithRetry(cmd.schemaName(), cmd.indexName()); + GridH2Table tbl = idx.dataTableForIndex(cmd.schemaName(), cmd.indexName()); if (tbl != null) { isDdlSupported(tbl); @@ -332,7 +332,7 @@ public class DdlStatementsProcessor { isDdlOnSchemaSupported(cmd.schemaName()); - GridH2Table tbl = dataTableWithRetry(cmd.schemaName(), cmd.tableName()); + GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName()); if (tbl != null) { if (!cmd.ifNotExists()) @@ -365,7 +365,7 @@ public class DdlStatementsProcessor { isDdlOnSchemaSupported(cmd.schemaName()); - GridH2Table tbl = dataTableWithRetry(cmd.schemaName(), cmd.tableName()); + GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName()); if (tbl == null) { if (!cmd.ifExists()) @@ -380,7 +380,7 @@ public class DdlStatementsProcessor { isDdlOnSchemaSupported(cmd.schemaName()); - GridH2Table tbl = dataTableWithRetry(cmd.schemaName(), cmd.tableName()); + GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName()); if (tbl == null) { if (!cmd.ifTableExists()) @@ -423,7 +423,7 @@ public class DdlStatementsProcessor { assert tbl.rowDescriptor() != null; if (!allFieldsNullable) - QueryUtils.checkNotNullAllowed(tbl.cache().config()); + QueryUtils.checkNotNullAllowed(tbl.cacheContext().config()); fut = ctx.query().dynamicColumnAdd(tbl.cacheName(), cmd.schemaName(), tbl.rowDescriptor().type().tableName(), cols, cmd.ifTableExists(), cmd.ifNotExists()); @@ -435,7 +435,7 @@ public class DdlStatementsProcessor { isDdlOnSchemaSupported(cmd.schemaName()); - GridH2Table tbl = dataTableWithRetry(cmd.schemaName(), cmd.tableName()); + GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName()); if (tbl == null) { if (!cmd.ifTableExists()) @@ -445,7 +445,7 @@ public class DdlStatementsProcessor { else { assert tbl.rowDescriptor() != null; - if (tbl.cache().mvccEnabled()) + if (tbl.cacheContext().mvccEnabled()) throw new IgniteSQLException("Cannot drop column(s) with enabled MVCC. " + "Operation is unsupported at the moment.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION); @@ -511,46 +511,6 @@ public class DdlStatementsProcessor { } /** - * Get table by name optionally creating missing query caches. - * - * @param schemaName Schema name. - * @param tableName Table name. - * @return Table or {@code null} if none found. - * @throws IgniteCheckedException If failed. - */ - private GridH2Table dataTableWithRetry(String schemaName, String tableName) throws IgniteCheckedException { - GridH2Table tbl = idx.dataTable(schemaName, tableName); - - if (tbl == null) { - ctx.cache().createMissingQueryCaches(); - - tbl = idx.dataTable(schemaName, tableName); - } - - return tbl; - } - - /** - * Get table by name optionally creating missing query caches. - * - * @param schemaName Schema name. - * @param indexName Index name. - * @return Table or {@code null} if none found. - * @throws IgniteCheckedException If failed. - */ - private GridH2Table dataTableForIndexWithRetry(String schemaName, String indexName) throws IgniteCheckedException { - GridH2Table tbl = idx.dataTableForIndex(schemaName, indexName); - - if (tbl == null) { - ctx.cache().createMissingQueryCaches(); - - tbl = idx.dataTableForIndex(schemaName, indexName); - } - - return tbl; - } - - /** * Check if schema supports DDL statement. * * @param schemaName Schema name. @@ -567,7 +527,7 @@ public class DdlStatementsProcessor { * @param tbl Table. */ private static void isDdlSupported(GridH2Table tbl) { - GridCacheContext cctx = tbl.cache(); + GridCacheContext cctx = tbl.cacheContext(); assert cctx != null; @@ -683,11 +643,10 @@ public class DdlStatementsProcessor { scale.put(e.getKey(), col.getScale()); } - if (col.getType() == Value.STRING || - col.getType() == Value.STRING_FIXED || - col.getType() == Value.STRING_IGNORECASE) { + if (col.getType() == Value.STRING || + col.getType() == Value.STRING_FIXED || + col.getType() == Value.STRING_IGNORECASE) precision.put(e.getKey(), (int)col.getPrecision()); - } } if (!F.isEmpty(dfltValues)) http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java index 0f8b6d8..fc3514b 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlan.java @@ -535,7 +535,7 @@ public final class UpdatePlan { * @return Cache context. */ public GridCacheContext cacheContext() { - return tbl.cache(); + return tbl.cacheContext(); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java index 477f22a..f1826a1 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java @@ -22,6 +22,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -39,6 +40,7 @@ import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.processors.query.h2.DmlStatementsProcessor; +import org.apache.ignite.internal.processors.query.h2.H2Utils; import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; @@ -93,6 +95,7 @@ public final class UpdatePlanBuilder { * @param fieldsQry Original query. * @return Update plan. */ + @SuppressWarnings("ConstantConditions") public static UpdatePlan planForStatement(Prepared prepared, boolean loc, IgniteH2Indexing idx, @Nullable Connection conn, @Nullable SqlFieldsQuery fieldsQry, @Nullable Integer errKeysPos, boolean dmlInsideTxAllowed) @@ -103,15 +106,60 @@ public final class UpdatePlanBuilder { GridSqlStatement stmt = parser.parse(prepared); - boolean mvccEnabled = false; + + List<GridH2Table> tbls = extractTablesParticipateAtQuery(parser); GridCacheContext prevCctx = null; + boolean mvccEnabled = false; - for (Object o : parser.objectsMap().values()) { - if (o instanceof GridSqlInsert) - o = ((GridSqlInsert)o).into(); - else if (o instanceof GridSqlMerge) + for (GridH2Table h2tbl : tbls) { + H2Utils.checkAndStartNotStartedCache(h2tbl); + + if (prevCctx == null) { + prevCctx = h2tbl.cacheContext(); + + assert prevCctx != null : h2tbl.cacheName() + " is not initted"; + + mvccEnabled = prevCctx.mvccEnabled(); + + if (!mvccEnabled && !dmlInsideTxAllowed && prevCctx.cache().context().tm().inUserTx()) { + throw new IgniteSQLException("DML statements are not allowed inside a transaction over " + + "cache(s) with TRANSACTIONAL atomicity mode (change atomicity mode to " + + "TRANSACTIONAL_SNAPSHOT or disable this error message with system property " + + "\"IGNITE_ALLOW_DML_INSIDE_TRANSACTION\" [cacheName=" + prevCctx.name() + ']'); + } + } + else if (h2tbl.cacheContext().mvccEnabled() != mvccEnabled) + MvccUtils.throwAtomicityModesMismatchException(prevCctx, h2tbl.cacheContext()); + } + + if (stmt instanceof GridSqlMerge || stmt instanceof GridSqlInsert) + return planForInsert(stmt, loc, idx, mvccEnabled, conn, fieldsQry); + else if (stmt instanceof GridSqlUpdate || stmt instanceof GridSqlDelete) + return planForUpdate(stmt, loc, idx, mvccEnabled, conn, fieldsQry, errKeysPos); + else + throw new IgniteSQLException("Unsupported operation: " + prepared.getSQL(), + IgniteQueryErrorCode.UNSUPPORTED_OPERATION); + } + + /** + * Extract all tables participate at query + * + * @param parser Parser related to the query. + * @return List of tables participate at query. + * @throws IgniteSQLException in case query contains virtual tables. + */ + private static List<GridH2Table> extractTablesParticipateAtQuery(GridSqlQueryParser parser) throws IgniteSQLException { + Collection<?> parserObjects = parser.objectsMap().values(); + + List<GridH2Table> tbls = new ArrayList<>(parserObjects.size()); + + // check all involved caches + for (Object o : parserObjects) { + if (o instanceof GridSqlMerge) o = ((GridSqlMerge)o).into(); + else if (o instanceof GridSqlInsert) + o = ((GridSqlInsert)o).into(); else if (o instanceof GridSqlUpdate) o = ((GridSqlUpdate)o).target(); else if (o instanceof GridSqlDelete) @@ -121,39 +169,18 @@ public final class UpdatePlanBuilder { o = GridSqlAlias.unwrap((GridSqlAst)o); if (o instanceof GridSqlTable) { - if (((GridSqlTable)o).dataTable() == null) { // Check for virtual tables. + GridH2Table h2tbl = ((GridSqlTable)o).dataTable(); + + if (h2tbl == null) { // Check for virtual tables. throw new IgniteSQLException("Operation not supported for table '" + ((GridSqlTable)o).tableName() + "'", IgniteQueryErrorCode.UNSUPPORTED_OPERATION); } - if (prevCctx == null) { - prevCctx = (((GridSqlTable)o).dataTable()).cache(); - - mvccEnabled = prevCctx.mvccEnabled(); - - if (!mvccEnabled && !dmlInsideTxAllowed && prevCctx.cache().context().tm().inUserTx()) { - throw new IgniteSQLException("DML statements are not allowed inside a transaction over " + - "cache(s) with TRANSACTIONAL atomicity mode (change atomicity mode to " + - "TRANSACTIONAL_SNAPSHOT or disable this error message with system property " + - "\"IGNITE_ALLOW_DML_INSIDE_TRANSACTION\" [cacheName=" + prevCctx.name() + ']'); - } - } - else { - GridCacheContext cctx = ((GridSqlTable)o).dataTable().cache(); - - if (cctx.mvccEnabled() != mvccEnabled) - MvccUtils.throwAtomicityModesMismatchException(prevCctx, cctx); - } + tbls.add(h2tbl); } } - if (stmt instanceof GridSqlMerge || stmt instanceof GridSqlInsert) - return planForInsert(stmt, loc, idx, mvccEnabled, conn, fieldsQry); - else if (stmt instanceof GridSqlUpdate || stmt instanceof GridSqlDelete) - return planForUpdate(stmt, loc, idx, mvccEnabled, conn, fieldsQry, errKeysPos); - else - throw new IgniteSQLException("Unsupported operation: " + prepared.getSQL(), - IgniteQueryErrorCode.UNSUPPORTED_OPERATION); + return tbls; } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java index 9c4941d..ddfc437 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java @@ -29,6 +29,7 @@ import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheContextInfo; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; import org.apache.ignite.internal.processors.query.GridQueryProperty; import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; @@ -57,6 +58,7 @@ import org.h2.value.ValueString; import org.h2.value.ValueTime; import org.h2.value.ValueTimestamp; import org.h2.value.ValueUuid; +import org.jetbrains.annotations.Nullable; import static org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOnheap.DEFAULT_COLUMNS_COUNT; import static org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOnheap.KEY_COL; @@ -171,12 +173,22 @@ public class GridH2RowDescriptor { return type; } + + /** + * Gets cache context info for this row descriptor. + * + * @return Cache context info. + */ + public GridCacheContextInfo<?, ?> cacheInfo() { + return tbl.cacheInfo(); + } + /** * Gets cache context for this row descriptor. * * @return Cache context. */ - public GridCacheContext<?, ?> context() { + @Nullable public GridCacheContext<?, ?> context() { return tbl.cache(); } http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SystemIndexFactory.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SystemIndexFactory.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SystemIndexFactory.java index f150b6a..fa1e5cb 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SystemIndexFactory.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SystemIndexFactory.java @@ -17,19 +17,17 @@ package org.apache.ignite.internal.processors.query.h2.opt; -import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex; -import org.h2.index.Index; - import java.util.ArrayList; +import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase; +import org.h2.index.Index; /** * Factory for system table indexes. */ public interface GridH2SystemIndexFactory { /** - * Create list of indexes. First must be primary key, after that all unique indexes and - * only then non-unique indexes. - * All indexes must be subtypes of {@link H2TreeIndex}. + * Create list of indexes. First must be primary key, after that all unique indexes and only then non-unique + * indexes. All indexes must be subtypes of {@link H2TreeIndexBase}. * * @param tbl Table to create indexes for. * @return List of indexes. http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java index b2da670..ef31f20 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java @@ -31,12 +31,13 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteInterruptedException; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheContextInfo; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; import org.apache.ignite.internal.processors.cache.query.QueryTable; import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.internal.processors.query.QueryField; import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory; -import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex; +import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase; import org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor; import org.apache.ignite.internal.util.typedef.F; import org.h2.command.ddl.CreateTableData; @@ -69,8 +70,8 @@ public class GridH2Table extends TableBase { /** Insert hack flag. */ private static final ThreadLocal<Boolean> INSERT_HACK = new ThreadLocal<>(); - /** Cache context. */ - private final GridCacheContext cctx; + /** Cache context info. */ + private final GridCacheContextInfo cacheInfo; /** */ private final GridH2RowDescriptor desc; @@ -124,16 +125,16 @@ public class GridH2Table extends TableBase { * @param desc Row descriptor. * @param rowFactory Row factory. * @param idxsFactory Indexes factory. - * @param cctx Cache context. + * @param cacheInfo Cache context info. */ public GridH2Table(CreateTableData createTblData, GridH2RowDescriptor desc, H2RowFactory rowFactory, - GridH2SystemIndexFactory idxsFactory, GridCacheContext cctx) { + GridH2SystemIndexFactory idxsFactory, GridCacheContextInfo cacheInfo) { super(createTblData); assert idxsFactory != null; this.desc = desc; - this.cctx = cctx; + this.cacheInfo = cacheInfo; if (desc.context() != null && !desc.context().customAffinityMapper()) { boolean affinityColExists = true; @@ -200,7 +201,7 @@ public class GridH2Table extends TableBase { * @return {@code true} If this is a partitioned table. */ public boolean isPartitioned() { - return desc != null && desc.context().config().getCacheMode() == PARTITIONED; + return desc != null && desc.cacheInfo().config().getCacheMode() == PARTITIONED; } /** @@ -226,21 +227,35 @@ public class GridH2Table extends TableBase { * @return Cache name. */ public String cacheName() { - return cctx.name(); + return cacheInfo.name(); } /** * @return Cache ID. */ public int cacheId() { - return cctx.cacheId(); + return cacheInfo.cacheId(); + } + + /** + * @return Cache context info. + */ + public GridCacheContextInfo cacheInfo() { + return cacheInfo; + } + + /** + * @return {@code true} If Cache is lazy (not full inited). + */ + public boolean isCacheLazy() { + return cacheInfo.gridCacheContext() == null; } /** * @return Cache context. */ - public GridCacheContext cache() { - return cctx; + @Nullable public GridCacheContext cacheContext() { + return cacheInfo.gridCacheContext(); } /** {@inheritDoc} */ @@ -854,7 +869,7 @@ public class GridH2Table extends TableBase { * @return Proxy index. */ private Index createDuplicateIndexIfNeeded(Index target) { - if (!(target instanceof H2TreeIndex) && !(target instanceof SpatialIndex)) + if (!(target instanceof H2TreeIndexBase) && !(target instanceof SpatialIndex)) return null; IndexColumn[] cols = target.getIndexColumns(); @@ -1064,4 +1079,4 @@ public class GridH2Table extends TableBase { return true; } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/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 122a9f7..34e223c 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 @@ -1728,7 +1728,11 @@ public class GridSqlQueryParser { GridH2Table tbl = ((GridSqlTable)o).dataTable(); if (tbl != null) { - GridCacheContext cctx = tbl.cache(); + //It's not affinity cache. Can't be local. + if (tbl.cacheContext() == null) + return false; + + GridCacheContext cctx = tbl.cacheContext(); if (cctx.mvccEnabled()) return false; @@ -1759,8 +1763,8 @@ public class GridSqlQueryParser { if (o instanceof GridSqlTable) { GridH2Table tbl = ((GridSqlTable)o).dataTable(); - if (tbl != null && tbl.cache().isPartitioned()) - return tbl.cache(); + if (tbl != null && tbl.cacheContext().isPartitioned()) + return tbl.cacheContext(); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/main/java/org/apache/ignite/internal/visor/verify/ValidateIndexesClosure.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/visor/verify/ValidateIndexesClosure.java b/modules/indexing/src/main/java/org/apache/ignite/internal/visor/verify/ValidateIndexesClosure.java index b6909e3..6e27ca2 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/visor/verify/ValidateIndexesClosure.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/visor/verify/ValidateIndexesClosure.java @@ -61,7 +61,7 @@ import org.apache.ignite.internal.processors.query.GridQueryProcessor; import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.QueryTypeDescriptorImpl; import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing; -import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex; +import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; @@ -229,7 +229,7 @@ public class ValidateIndexesClosure implements IgniteCallable<VisorValidateIndex ArrayList<Index> indexes = gridH2Tbl.getIndexes(); for (Index idx : indexes) - if (idx instanceof H2TreeIndex) + if (idx instanceof H2TreeIndexBase) idxArgs.add(new T2<>(ctx, idx)); } } @@ -517,7 +517,7 @@ public class ValidateIndexesClosure implements IgniteCallable<VisorValidateIndex ArrayList<Index> indexes = gridH2Tbl.getIndexes(); for (Index idx : indexes) { - if (!(idx instanceof H2TreeIndex)) + if (!(idx instanceof H2TreeIndexBase)) continue; try { http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientPersistentTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientPersistentTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientPersistentTest.java new file mode 100644 index 0000000..ab93a4c --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientPersistentTest.java @@ -0,0 +1,44 @@ +/* + * 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; + +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.WALMode; + +/** + * Test lazy cache start on client nodes with persistence cache. + */ +public class GridCacheDynamicLoadOnClientPersistentTest extends GridCacheDynamicLoadOnClientTest { + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + DataStorageConfiguration dsCfg = new DataStorageConfiguration() + .setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setMaxSize(200 * 1024 * 1024).setPersistenceEnabled(true)) + .setWalMode(WALMode.LOG_ONLY); + + cfg.setDataStorageConfiguration(dsCfg); + + return cfg; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientTest.java new file mode 100644 index 0000000..5cc559e --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDynamicLoadOnClientTest.java @@ -0,0 +1,304 @@ +/* + * 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; + +import java.io.Serializable; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collection; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.cache.query.SqlQuery; +import org.apache.ignite.cache.query.annotations.QuerySqlField; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.odbc.ClientListenerProcessor; +import org.apache.ignite.internal.processors.port.GridPortRecord; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Assert; + +/** + * Test lazy cache start on client nodes with inmemory cache. + */ +public class GridCacheDynamicLoadOnClientTest extends GridCommonAbstractTest { + /** Cache name. */ + private static final String PERSON_CACHE = "Person"; + + /** SQL schema name. */ + private static final String PERSON_SCHEMA = "test"; + + /** Number of element to add into cache. */ + private static final int CACHE_ELEMENT_COUNT = 10; + + /** Full table name. */ + private static final String FULL_TABLE_NAME = PERSON_SCHEMA + "." + PERSON_CACHE; + + /** Number of nodes. */ + private static final int NODES = 2; + + /** Client or server mode for configuration. */ + protected boolean client; + + /** Instance of client node. */ + private static IgniteEx clientNode; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName).setClientMode(client); + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + client = false; + + startGridsMultiThreaded(NODES - 1); + + client = true; + + clientNode = startGrid(NODES - 1); + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + clientNode.destroyCache(PERSON_CACHE); + + createAndFillServerCache(); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + stopAllGrids(); + } + + /** + * Test from client node batch merge through JDBC. + * + * @throws Exception If failure. + */ + public void testBatchMerge() throws Exception { + final int BATCH_SIZE = 7; + + try (Connection con = connect(clientNode); + Statement stmt = con.createStatement()) { + for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) { + stmt.addBatch("merge into " + FULL_TABLE_NAME + " (_key, name, orgId) values (" + + (100 + idx) + "," + + "'" + "batch-" + idx + "'" + "," + + idx + + ")"); + } + + int[] updCnts = stmt.executeBatch(); + + assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length); + } + } + + /** + * Test from client node to delete cache elements through JDBC. + * + * @throws Exception If failure. + */ + public void testClientJdbcDelete() throws Exception { + try (Connection con = connect(clientNode); + Statement stmt = con.createStatement()) { + int cnt = stmt.executeUpdate(("DELETE " + FULL_TABLE_NAME + " WHERE _key=1")); + + Assert.assertEquals(1, cnt); + } + + SqlFieldsQuery qry = new SqlFieldsQuery("SELECT * FROM " + FULL_TABLE_NAME); + + Assert.assertEquals(CACHE_ELEMENT_COUNT - 1, clientNode.cache(PERSON_CACHE).query(qry).getAll().size()); + } + + /** + * Test from client node to insert into cache through JDBC. + * + * @throws Exception If failure. + */ + public void testClientJdbcInsert() throws Exception { + try (Connection con = connect(clientNode); + Statement stmt = con.createStatement()) { + int cnt = stmt.executeUpdate( + "INSERT INTO " + FULL_TABLE_NAME + "(_key, name, orgId) VALUES(1000,'new_name', 10000)"); + + Assert.assertEquals(1, cnt); + } + + SqlFieldsQuery qry = new SqlFieldsQuery("SELECT * FROM " + FULL_TABLE_NAME); + + Assert.assertEquals(CACHE_ELEMENT_COUNT + 1, clientNode.cache(PERSON_CACHE).query(qry).getAll().size()); + } + + /** + * Test from client node to update cache elements through JDBC. + * + * @throws Exception If failure. + */ + public void testClientJdbcUpdate() throws Exception { + try (Connection con = connect(clientNode); + Statement stmt = con.createStatement()) { + int cnt = stmt.executeUpdate(("UPDATE " + FULL_TABLE_NAME + " SET name = 'new_name'")); + + Assert.assertEquals(CACHE_ELEMENT_COUNT, cnt); + } + + SqlFieldsQuery qry = new SqlFieldsQuery("SELECT * FROM " + FULL_TABLE_NAME + " WHERE name = 'new_name'"); + + Assert.assertEquals(CACHE_ELEMENT_COUNT, clientNode.cache(PERSON_CACHE).query(qry).getAll().size()); + } + + /** + * Test from client node to get cache elements through JDBC. + * + * @throws Exception If failure. + */ + public void testClientJdbc() throws Exception { + try (Connection con = connect(clientNode); + Statement st = con.createStatement()) { + ResultSet rs = st.executeQuery("SELECT count(*) FROM " + FULL_TABLE_NAME); + + rs.next(); + + Assert.assertEquals(CACHE_ELEMENT_COUNT, rs.getInt(1)); + } + } + + /** + * Test from client node to put cache elements through cache API. + */ + public void testClientPut() { + clientNode.cache(PERSON_CACHE).put(-100, new Person(-100, "name-")); + + Assert.assertEquals(CACHE_ELEMENT_COUNT + 1, clientNode.cache(PERSON_CACHE).size()); + } + + /** + * Test from client node to get cache elements through cache API. + */ + public void testClientSqlFieldsQuery() { + SqlFieldsQuery qry = new SqlFieldsQuery("SELECT * FROM " + FULL_TABLE_NAME); + + Assert.assertEquals(CACHE_ELEMENT_COUNT, clientNode.cache(PERSON_CACHE).query(qry).getAll().size()); + } + + /** + * Test from client node to get cache elements through cache API. + */ + public void testClientSqlQuery() { + SqlQuery<Integer, Person> qry = new SqlQuery<>(PERSON_CACHE, "FROM " + PERSON_CACHE); + + Assert.assertEquals(CACHE_ELEMENT_COUNT, + clientNode.cache(PERSON_CACHE).query(qry).getAll().size()); + } + + /** + * Create cache at server node and put some values into the cache. + */ + private void createAndFillServerCache() { + IgniteEx srvNode = grid(0); + + srvNode.createCache(cacheConfiguration()); + + for (int i = 0; i < CACHE_ELEMENT_COUNT; i++) + srvNode.cache(PERSON_CACHE).put(i, new Person(i, "name-" + i)); + } + + /** + * @return Cache configuration. + */ + private CacheConfiguration<?, ?> cacheConfiguration() { + CacheConfiguration ccfg = new CacheConfiguration(PERSON_CACHE); + + ccfg.setSqlSchema(PERSON_SCHEMA); + ccfg.setCacheMode(CacheMode.PARTITIONED); + + QueryEntity person = new QueryEntity(); + person.setKeyType(Integer.class.getName()); + person.setValueType(Person.class.getName()); + person.addQueryField("orgId", Integer.class.getName(), null); + person.addQueryField("id", Integer.class.getName(), null); + person.addQueryField("name", String.class.getName(), null); + person.setIndexes(F.asList(new QueryIndex("orgId"), new QueryIndex("id"), new QueryIndex("name"))); + + ccfg.setQueryEntities(F.asList(person)); + + return ccfg; + } + + /** + * Create SQL connection to node specified as argument + * + * @param node Node to connect. + * @return Connection. + * @throws SQLException In case of failure. + */ + private static Connection connect(IgniteEx node) throws SQLException { + Collection<GridPortRecord> recs = node.context().ports().records(); + + GridPortRecord cliLsnrRec = null; + + for (GridPortRecord rec : recs) { + if (rec.clazz() == ClientListenerProcessor.class) { + cliLsnrRec = rec; + + break; + } + } + + String connStr = "jdbc:ignite:thin://127.0.0.1:" + cliLsnrRec.port(); + + return DriverManager.getConnection(connStr); + } + + /** + * Test object to keep in cache. + */ + private static class Person implements Serializable { + /** */ + @QuerySqlField + int orgId; + + /** */ + @QuerySqlField + String name; + + /** + * @param orgId Organization ID. + * @param name Name. + */ + public Person(int orgId, String name) { + this.orgId = orgId; + this.name = name; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/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 07c0ede..5634748 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 @@ -725,6 +725,28 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest { } /** + * Test that {@code DROP TABLE} executed at client node actually removes specified cache and type descriptor on all nodes. + * @throws Exception if failed. + */ + public void testDropTableFromClient() throws Exception { + execute(grid(0),"CREATE TABLE IF NOT EXISTS \"Person\" (\"id\" int, \"city\" varchar," + + " \"name\" varchar, \"surname\" varchar, \"age\" int, PRIMARY KEY (\"id\", \"city\")) WITH " + + "\"template=cache\""); + + execute(client(), "DROP TABLE \"Person\""); + + for (int i = 0; i < 4; i++) { + IgniteEx node = grid(i); + + assertNull(node.cache("Person")); + + QueryTypeDescriptorImpl desc = type(node, "Person", "Person"); + + assertNull(desc); + } + } + + /** * Test that {@code DROP TABLE} actually removes specified cache and type descriptor on all nodes. * @throws Exception if failed. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/SchemaExchangeSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/SchemaExchangeSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/SchemaExchangeSelfTest.java index c7709f2..bd2b578 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/SchemaExchangeSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/SchemaExchangeSelfTest.java @@ -17,6 +17,9 @@ package org.apache.ignite.internal.processors.cache.index; +import java.util.Collections; +import java.util.Map; +import junit.framework.AssertionFailedError; import org.apache.ignite.IgniteClientDisconnectedException; import org.apache.ignite.IgniteException; import org.apache.ignite.Ignition; @@ -26,18 +29,18 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.cache.GridCacheAdapter; +import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.query.QueryTypeDescriptorImpl; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.util.lang.GridAbsPredicate; import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.GridTestUtils; -import java.util.Collections; -import java.util.Map; - import static org.apache.ignite.internal.IgniteClientReconnectAbstractTest.TestTcpDiscoverySpi; import static org.apache.ignite.internal.IgniteClientReconnectAbstractTest.reconnectClientNode; @@ -171,11 +174,13 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { assertTypes(node1, ValueClass.class); assertTypes(node2, ValueClass.class); + assertCacheStarted(CACHE_NAME, node1, node2); - assertTypes(node3); + assertTypes(node3, ValueClass.class); + assertCacheNotStarted(CACHE_NAME, node3); node3.cache(CACHE_NAME); - assertTypes(node3, ValueClass.class); + assertCacheStarted(CACHE_NAME, node3); // Check restarts from the first node. destroySqlCache(node1); @@ -193,11 +198,14 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { assertTypes(node1, ValueClass.class, ValueClass2.class); assertTypes(node2, ValueClass.class, ValueClass2.class); + assertTypes(node3, ValueClass.class, ValueClass2.class); - assertTypes(node3); + assertCacheStarted(CACHE_NAME, node1, node2); + + assertCacheNotStarted(CACHE_NAME, node3); node3.cache(CACHE_NAME); - assertTypes(node3, ValueClass.class, ValueClass2.class); + assertCacheStarted(CACHE_NAME, node3); // Check restarts from the second node. node2.destroyCache(CACHE_NAME); @@ -215,16 +223,20 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { assertTypes(node1, ValueClass.class, ValueClass2.class); assertTypes(node2, ValueClass.class, ValueClass2.class); + assertTypes(node3, ValueClass.class, ValueClass2.class); + assertTypes(node4, ValueClass.class, ValueClass2.class); - assertTypes(node3); + assertCacheStarted(CACHE_NAME, node1, node2); + + assertCacheNotStarted(CACHE_NAME, node3); node3.cache(CACHE_NAME); - assertTypes(node3, ValueClass.class, ValueClass2.class); + assertCacheStarted(CACHE_NAME, node3); - assertTypes(node4); + assertCacheNotStarted(CACHE_NAME, node4); node4.cache(CACHE_NAME); - assertTypes(node4, ValueClass.class, ValueClass2.class); + assertCacheStarted(CACHE_NAME, node4); // Make sure that joining node observes correct state. assertTypes(start(5), ValueClass.class, ValueClass2.class); @@ -234,10 +246,13 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { IgniteEx node8 = startClientNoCache(8); - assertTypes(node8); + assertTypes(node8, ValueClass.class, ValueClass2.class); + + assertCacheNotStarted(CACHE_NAME, node8); node8.cache(CACHE_NAME); - assertTypes(node8, ValueClass.class, ValueClass2.class); + + assertCacheStarted(CACHE_NAME, node8); } /** @@ -292,10 +307,15 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { assertTypes(node2, ValueClass.class); assertTypes(node3, ValueClass.class); - assertTypes(node4); + assertTypes(node4, ValueClass.class); + + assertCacheStarted(CACHE_NAME, node1, node2, node3); + + assertCacheNotStarted(CACHE_NAME, node4); node4.cache(CACHE_NAME); - assertTypes(node4, ValueClass.class); + + assertCacheStarted(CACHE_NAME, node4); } /** @@ -345,40 +365,31 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { IgniteEx node7 = startClient(7, KeyClass.class, ValueClass.class, KeyClass2.class, ValueClass2.class); IgniteEx node8 = startClientNoCache(8); - assertTypes(node1, ValueClass.class); - assertTypes(node2, ValueClass.class); - assertTypes(node3, ValueClass.class); - assertTypes(node4, ValueClass.class); - assertTypes(node5, ValueClass.class); - assertTypes(node6, ValueClass.class); - assertTypes(node7, ValueClass.class); + assertCacheStarted(CACHE_NAME, node1, node2, node3, node4, node5, node6, node7); + assertCacheNotStarted(CACHE_NAME, node8); + assertTypes(node8, ValueClass.class); - assertTypes(node8); node8.cache(CACHE_NAME); - assertTypes(node8, ValueClass.class); + + assertCacheStarted(CACHE_NAME, node8); destroySqlCache(node2); node2.getOrCreateCache( cacheConfiguration(KeyClass.class, ValueClass.class, KeyClass2.class, ValueClass2.class)); - assertTypes(node1, ValueClass.class, ValueClass2.class); - assertTypes(node2, ValueClass.class, ValueClass2.class); - assertTypes(node3, ValueClass.class, ValueClass2.class); - assertTypes(node4, ValueClass.class, ValueClass2.class); - assertTypes(node5, ValueClass.class, ValueClass2.class); + assertCacheStarted(CACHE_NAME, node1, node2, node3, node4, node5); + assertCacheNotStarted(CACHE_NAME, node6, node7, node8); - assertTypes(node6); - assertTypes(node7); - assertTypes(node8); + assertTypes(node6, ValueClass.class, ValueClass2.class); + assertTypes(node7, ValueClass.class, ValueClass2.class); + assertTypes(node8, ValueClass.class, ValueClass2.class); node6.cache(CACHE_NAME); node7.cache(CACHE_NAME); node8.cache(CACHE_NAME); - assertTypes(node6, ValueClass.class, ValueClass2.class); - assertTypes(node7, ValueClass.class, ValueClass2.class); - assertTypes(node8, ValueClass.class, ValueClass2.class); + assertCacheStarted(CACHE_NAME, node6, node7, node8); } /** @@ -399,11 +410,14 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { IgniteEx node3 = startNoCache(3); assertTypes(node1, ValueClass.class); assertTypes(node2, ValueClass.class); + assertTypes(node3, ValueClass.class); - assertTypes(node3); + assertCacheStarted(CACHE_NAME, node1, node2); + + assertCacheNotStarted(CACHE_NAME, node3); node3.cache(CACHE_NAME); - assertTypes(node3, ValueClass.class); + assertCacheStarted(CACHE_NAME, node1, node3); } /** @@ -416,7 +430,12 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { assertTypes(node1, ValueClass.class); IgniteEx node2 = startClientNoCache(2); - assertTypes(node2); + + GridCacheContext<Object, Object> context0 = node2.context().cache().context().cacheContext(CU.cacheId(CACHE_NAME)); + node2.cache(CACHE_NAME); + GridCacheContext<Object, Object> context = node2.context().cache().context().cacheContext(CU.cacheId(CACHE_NAME)); + GridCacheAdapter<Object, Object> entries = node2.context().cache().internalCache(CACHE_NAME); + assertTrue(entries.active()); node2.cache(CACHE_NAME); assertTypes(node2, ValueClass.class); @@ -431,7 +450,7 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { IgniteFuture reconnFut = null; - try { + try { node2.cache(CACHE_NAME); fail(); @@ -442,13 +461,17 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { node1 = start(1, KeyClass.class, ValueClass.class, KeyClass2.class, ValueClass2.class); assertTypes(node1, ValueClass.class, ValueClass2.class); + assertTypes(node2, ValueClass.class); + + assertCacheStarted(CACHE_NAME, node1); reconnFut.get(); - assertTypes(node2); + assertTypes(node2, ValueClass.class, ValueClass2.class); + assertCacheNotStarted(CACHE_NAME, node2); node2.cache(CACHE_NAME); - assertTypes(node2, ValueClass.class, ValueClass2.class); + assertCacheStarted(CACHE_NAME, node2); } /** @@ -462,10 +485,11 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { assertTypes(node1, ValueClass.class); final IgniteEx node2 = startClientNoCache(2); - assertTypes(node2); + assertTypes(node2, ValueClass.class); + assertCacheNotStarted(CACHE_NAME, node2); node2.cache(CACHE_NAME); - assertTypes(node2, ValueClass.class); + assertCacheStarted(CACHE_NAME, node2); reconnectClientNode(log, node2, node1, new Runnable() { @Override public void run() { @@ -489,6 +513,45 @@ public class SchemaExchangeSelfTest extends AbstractSchemaSelfTest { } /** + * Check is cache started on the given node or not. + * + * @param cacheName Cache name. + * @param node Node to check cache. + * @return {@code true} in case cache is started. + */ + private boolean isCacheStarted(String cacheName, IgniteEx node) { + GridCacheContext cacheCtx = node.context().cache().context().cacheContext(CU.cacheId(cacheName)); + + return cacheCtx != null; + } + + /** + * Check is cache started on the given nodes. + * + * @param nodes Node to check cache. + * @param cacheName Cache name. + * @throws AssertionFailedError If failed. + */ + private void assertCacheStarted(String cacheName, IgniteEx... nodes) throws AssertionFailedError { + for (IgniteEx node : nodes) { + assertTrue(isCacheStarted(cacheName, node)); + } + } + + /** + * Check is cache not started on the given nodes. + * + * @param nodes Node to check cache. + * @param cacheName Cache name. + * @throws AssertionFailedError If failed. + */ + private void assertCacheNotStarted(String cacheName, IgniteEx... nodes) throws AssertionFailedError { + for (IgniteEx node : nodes) { + assertFalse(isCacheStarted(cacheName, node)); + } + } + + /** * Ensure that only provided types exists for the given cache. * * @param node Node. http://git-wip-us.apache.org/repos/asf/ignite/blob/d19123d4/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java ---------------------------------------------------------------------- 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 25cb473..d96b445 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 @@ -43,6 +43,8 @@ import org.apache.ignite.internal.processors.cache.CacheReplicatedQueryMetricsLo import org.apache.ignite.internal.processors.cache.CacheSqlQueryValueCopySelfTest; import org.apache.ignite.internal.processors.cache.DdlTransactionSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheCrossCacheQuerySelfTest; +import org.apache.ignite.internal.processors.cache.GridCacheDynamicLoadOnClientPersistentTest; +import org.apache.ignite.internal.processors.cache.GridCacheDynamicLoadOnClientTest; import org.apache.ignite.internal.processors.cache.GridCacheFullTextQuerySelfTest; import org.apache.ignite.internal.processors.cache.GridCacheLazyQueryPartitionsReleaseTest; import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexDisabledSelfTest; @@ -533,6 +535,9 @@ public class IgniteBinaryCacheQueryTestSuite extends TestSuite { // Partition pruning. suite.addTestSuite(InOperationExtractPartitionSelfTest.class); + suite.addTestSuite(GridCacheDynamicLoadOnClientTest.class); + suite.addTestSuite(GridCacheDynamicLoadOnClientPersistentTest.class); + return suite; } }
