IGNITE-5533: Proper index cleanup in H2 database during DROP TALBE. This closes #2167.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/333e32b5 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/333e32b5 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/333e32b5 Branch: refs/heads/master Commit: 333e32b58fd6e7341fcc14b862140f244b575315 Parents: 3f6c174 Author: Alexander Paschenko <[email protected]> Authored: Thu Jul 6 13:00:33 2017 +0300 Committer: devozerov <[email protected]> Committed: Thu Jul 6 13:00:33 2017 +0300 ---------------------------------------------------------------------- .../processors/query/h2/opt/GridH2Table.java | 49 +++++++++++++++++- .../cache/index/H2DynamicTableSelfTest.java | 53 ++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/333e32b5/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 d656cc3..76d0258 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 @@ -40,7 +40,9 @@ import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteBiTuple; import org.h2.command.ddl.CreateTableData; +import org.h2.engine.DbObject; import org.h2.engine.Session; +import org.h2.engine.SysProperties; import org.h2.index.Index; import org.h2.index.IndexType; import org.h2.index.SpatialIndex; @@ -48,6 +50,7 @@ import org.h2.message.DbException; import org.h2.result.Row; import org.h2.result.SearchRow; import org.h2.result.SortOrder; +import org.h2.schema.SchemaObject; import org.h2.table.IndexColumn; import org.h2.table.TableBase; import org.h2.table.TableType; @@ -76,6 +79,9 @@ public class GridH2Table extends TableBase { /** */ private final int pkIndexPos; + /** Total number of system indexes. */ + private final int sysIdxsCnt; + /** */ private final Map<String, GridH2IndexBase> tmpIdxs = new HashMap<>(); @@ -184,6 +190,8 @@ public class GridH2Table extends TableBase { pkIndexPos = hasHashIndex ? 2 : 1; + sysIdxsCnt = idxs.size(); + final int segments = desc != null ? desc.context().config().getQueryParallelism() : // Get index segments count from PK index. Null desc can be passed from tests. index(pkIndexPos).segmentsCount(); @@ -449,6 +457,45 @@ public class GridH2Table extends TableBase { // No-op. } + /** {@inheritDoc} */ + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") + @Override public void removeChildrenAndResources(Session ses) { + lock(true); + + try { + super.removeChildrenAndResources(ses); + + // Clear all user indexes registered in schema. + while (idxs.size() > sysIdxsCnt) { + Index idx = idxs.get(sysIdxsCnt); + + if (idx.getName() != null && idx.getSchema().findIndex(ses, idx.getName()) == idx) { + // This call implicitly removes both idx and its proxy, if any, from idxs. + database.removeSchemaObject(ses, idx); + + // We have to call destroy here if we are who has removed this index from the table. + if (idx instanceof GridH2IndexBase) + ((GridH2IndexBase)idx).destroy(); + } + } + + if (SysProperties.CHECK) { + for (SchemaObject obj : database.getAllSchemaObjects(DbObject.INDEX)) { + Index idx = (Index) obj; + if (idx.getTable() == this) + DbException.throwInternalError("index not dropped: " + idx.getName()); + } + } + + database.removeMeta(ses, getId()); + invalidate(); + + } + finally { + unlock(true); + } + } + /** * Destroy the table. */ @@ -791,7 +838,7 @@ public class GridH2Table extends TableBase { Index cloneIdx = createDuplicateIndexIfNeeded(idx); ArrayList<Index> newIdxs = new ArrayList<>( - idxs.size() + ((cloneIdx == null) ? 1 : 2)); + idxs.size() + ((cloneIdx == null) ? 1 : 2)); newIdxs.addAll(idxs); http://git-wip-us.apache.org/repos/asf/ignite/blob/333e32b5/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 5975b4e..b0e69f1 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 @@ -694,6 +694,59 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest { } /** + * Tests behavior on sequential create and drop of a table and its index. + */ + public void testTableAndIndexRecreate() { + execute("drop table if exists \"PUBLIC\".t"); + + // First let's check behavior without index name set + execute("create table \"PUBLIC\".t (a int primary key, b varchar(30))"); + + fillRecreatedTable(); + + execute("create index on \"PUBLIC\".t (b desc)"); + execute("drop table \"PUBLIC\".t"); + + assertNull(client().cache("t")); + + execute("create table \"PUBLIC\".t (a int primary key, b varchar(30))"); + + fillRecreatedTable(); + + execute("create index on \"PUBLIC\".t (b desc)"); + execute("drop table \"PUBLIC\".t"); + + assertNull(client().cache("t")); + + // And now let's do the same for the named index + execute("create table \"PUBLIC\".t (a int primary key, b varchar(30))"); + + fillRecreatedTable(); + + execute("create index namedIdx on \"PUBLIC\".t (b desc)"); + execute("drop table \"PUBLIC\".t"); + + assertNull(client().cache("t")); + + execute("create table \"PUBLIC\".t (a int primary key, b varchar(30))"); + + fillRecreatedTable(); + + execute("create index namedIdx on \"PUBLIC\".t (b desc)"); + execute("drop table \"PUBLIC\".t"); + } + + /** + * Fill re-created table with data. + */ + private void fillRecreatedTable() { + for (int j = 1; j < 10; j++) { + String s = Integer.toString(j); + execute("insert into \"PUBLIC\".t (a,b) values (" + s + ", '" + s + "')"); + } + } + + /** * Check that dynamic cache created with {@code CREATE TABLE} is correctly configured affinity wise. * @param cacheName Cache name to check. * @param affKeyFieldName Expected affinity key field name.
