You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by zs...@apache.org on 2022/04/07 09:01:58 UTC
[ignite-3] branch ignite-14925-sorted-indexes updated: IGNITE-16266 Add unique id for indexes
This is an automated email from the ASF dual-hosted git repository.
zstan pushed a commit to branch ignite-14925-sorted-indexes
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/ignite-14925-sorted-indexes by this push:
new 81e27785b IGNITE-16266 Add unique id for indexes
81e27785b is described below
commit 81e27785b6c7a1ad32b3cb3ddc988d7f716e030d
Author: zstan <st...@gmail.com>
AuthorDate: Thu Apr 7 12:01:46 2022 +0300
IGNITE-16266 Add unique id for indexes
---
.../table/TableIndexConfigurationSchema.java | 6 +
.../apache/ignite/lang/IndexNotFoundException.java | 12 ++
.../ignite/internal/manager/AbstractProducer.java | 2 +-
.../apache/ignite/internal/idx/IndexManager.java | 9 ++
.../ignite/internal/idx/InternalSortedIndex.java | 7 +
.../internal/idx/event/IndexEventParameters.java | 23 +++-
.../ignite/internal/idx/IndexManagerImpl.java | 141 ++++++++++++++-------
.../internal/idx/InternalSortedIndexImpl.java | 10 +-
.../internal/runner/app/IgniteCliRunnerTest.java | 39 ++++--
.../internal/sql/engine/util/QueryChecker.java | 7 +-
.../ignite/internal/schema/ByteBufferRow.java | 11 +-
.../internal/sql/engine/SqlQueryProcessor.java | 2 +-
.../sql/engine/exec/LogicalRelImplementor.java | 2 +-
.../sql/engine/externalize/RelInputEx.java | 13 +-
.../sql/engine/externalize/RelJsonReader.java | 21 ++-
.../internal/sql/engine/prepare/PlannerHelper.java | 2 +-
.../internal/sql/engine/rel/AbstractIndexScan.java | 22 ++--
.../internal/sql/engine/rel/IgniteIndexScan.java | 23 ++--
.../engine/rel/ProjectableFilterableTableScan.java | 2 +-
.../engine/rel/logical/IgniteLogicalIndexScan.java | 13 +-
.../sql/engine/rule/LogicalScanConverterRule.java | 4 +-
.../sql/engine/rule/logical/ExposeIndexRule.java | 4 +-
.../engine/rule/logical/FilterScanMergeRule.java | 2 +-
.../engine/rule/logical/ProjectScanMergeRule.java | 2 +-
.../internal/sql/engine/schema/IgniteIndex.java | 33 ++---
.../sql/engine/schema/IgniteTableImpl.java | 10 +-
.../sql/engine/schema/InternalIgniteTable.java | 10 +-
.../sql/engine/schema/SqlSchemaManager.java | 10 ++
.../sql/engine/schema/SqlSchemaManagerImpl.java | 65 ++++++++--
.../internal/sql/engine/util/BaseQueryContext.java | 1 +
.../sql/engine/exec/MockedStructuresTest.java | 3 +-
.../sql/engine/externalize/RelJsonReaderTest.java | 49 ++++++-
.../sql/engine/planner/AbstractPlannerTest.java | 51 +++++---
.../engine/planner/JoinColocationPlannerTest.java | 13 +-
.../internal/sql/engine/planner/PlannerTest.java | 6 +-
.../sql/engine/planner/TableDmlPlannerTest.java | 7 +-
36 files changed, 448 insertions(+), 189 deletions(-)
diff --git a/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/TableIndexConfigurationSchema.java b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/TableIndexConfigurationSchema.java
index 819795c8a..86fd7950c 100644
--- a/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/TableIndexConfigurationSchema.java
+++ b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/TableIndexConfigurationSchema.java
@@ -17,6 +17,8 @@
package org.apache.ignite.configuration.schemas.table;
+import java.util.UUID;
+import org.apache.ignite.configuration.annotation.InternalId;
import org.apache.ignite.configuration.annotation.PolymorphicConfig;
import org.apache.ignite.configuration.annotation.PolymorphicId;
import org.apache.ignite.configuration.annotation.Value;
@@ -40,6 +42,10 @@ public class TableIndexConfigurationSchema {
@PolymorphicId
public String type;
+ /** Index id. **/
+ @InternalId
+ public UUID id;
+
/** Index name. */
@Value
@Immutable
diff --git a/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java b/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java
index 1e89aee02..471132e35 100644
--- a/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java
+++ b/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java
@@ -17,6 +17,8 @@
package org.apache.ignite.lang;
+import java.util.UUID;
+
/**
* Exception is thrown when appropriate index is not found.
*/
@@ -29,4 +31,14 @@ public class IndexNotFoundException extends IgniteException {
public IndexNotFoundException(String indexName) {
super(IgniteStringFormatter.format("Index '{}' does not exist.", indexName));
}
+
+ /**
+ * Create a new exception with given index name.
+ *
+ * @param indexName Index canonical name.
+ * @param id Index id.
+ */
+ public IndexNotFoundException(String indexName, UUID id) {
+ super(IgniteStringFormatter.format("Index '{}' was concurrently modified or deleted, id='{}'.", indexName, id));
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/manager/AbstractProducer.java b/modules/core/src/main/java/org/apache/ignite/internal/manager/AbstractProducer.java
index 8a86a302e..704081b40 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/manager/AbstractProducer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/manager/AbstractProducer.java
@@ -57,7 +57,7 @@ public abstract class AbstractProducer<T extends Event, P extends EventParameter
* @param params Event parameters.
* @param err Exception when it was happened, or {@code null} otherwise.
*/
- protected void fireEvent(T evt, P params, Throwable err) {
+ protected void fireEvent(T evt, P params, @Nullable Throwable err) {
ConcurrentLinkedQueue<EventListener<P>> queue = listeners.get(evt);
if (queue == null) {
diff --git a/modules/index-api/src/main/java/org/apache/ignite/internal/idx/IndexManager.java b/modules/index-api/src/main/java/org/apache/ignite/internal/idx/IndexManager.java
index f1a195019..fcaed349e 100644
--- a/modules/index-api/src/main/java/org/apache/ignite/internal/idx/IndexManager.java
+++ b/modules/index-api/src/main/java/org/apache/ignite/internal/idx/IndexManager.java
@@ -28,6 +28,7 @@ import org.apache.ignite.internal.manager.Producer;
import org.apache.ignite.lang.IndexAlreadyExistsException;
import org.apache.ignite.lang.IndexNotFoundException;
import org.apache.ignite.lang.NodeStoppingException;
+import org.jetbrains.annotations.Nullable;
/**
* Internal index manager facade provides low-level methods for indexes operations.
@@ -102,4 +103,12 @@ public interface IndexManager extends Producer<IndexEvent, IndexEventParameters>
* @throws NodeStoppingException If an implementation stopped before the method was invoked.
*/
CompletableFuture<InternalSortedIndex> indexAsync(String idxCanonicalName);
+
+ /**
+ * Returns index by specified id.
+ *
+ * @param id Index id.
+ * @return Index or {@code null} if can`t be found.
+ */
+ @Nullable InternalSortedIndex getIndexById(UUID id);
}
diff --git a/modules/index-api/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndex.java b/modules/index-api/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndex.java
index ba9b54cfd..422d2d2d7 100644
--- a/modules/index-api/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndex.java
+++ b/modules/index-api/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndex.java
@@ -45,6 +45,13 @@ public interface InternalSortedIndex {
*/
String name();
+ /**
+ * Return index id.
+ *
+ * @return Index id.
+ */
+ UUID id();
+
/**
* Return indexed table.
*
diff --git a/modules/index-api/src/main/java/org/apache/ignite/internal/idx/event/IndexEventParameters.java b/modules/index-api/src/main/java/org/apache/ignite/internal/idx/event/IndexEventParameters.java
index 3b286a5df..f3b6dd947 100644
--- a/modules/index-api/src/main/java/org/apache/ignite/internal/idx/event/IndexEventParameters.java
+++ b/modules/index-api/src/main/java/org/apache/ignite/internal/idx/event/IndexEventParameters.java
@@ -17,14 +17,18 @@
package org.apache.ignite.internal.idx.event;
+import java.util.UUID;
import org.apache.ignite.internal.idx.InternalSortedIndex;
import org.apache.ignite.internal.manager.EventParameters;
import org.jetbrains.annotations.Nullable;
/**
- * Table event parameters. There are properties which associate with a concrete table.
+ * Index event parameters. There are properties which are associates with a concrete index.
*/
public class IndexEventParameters implements EventParameters {
+ /** Index id. */
+ private final UUID idxId;
+
/** Index name. */
private final String idxName;
@@ -41,32 +45,39 @@ public class IndexEventParameters implements EventParameters {
* @param idx Index instance.
*/
public IndexEventParameters(String tblName, InternalSortedIndex idx) {
- this(idx.name(), tblName, idx);
+ this(idx.id(), idx.name(), tblName, idx);
}
/**
* Constructor.
*
+ * @param idxId Index id.
* @param idxName Index name.
* @param tblName Table name.
*/
- public IndexEventParameters(String idxName, String tblName) {
- this(idxName, tblName, null);
+ public IndexEventParameters(UUID idxId, String idxName, String tblName) {
+ this(idxId, idxName, tblName, null);
}
/**
* Constructor.
*
+ * @param idxId Index id.
* @param idxName Index name.
* @param tblName Table name.
- * @param idx Index.
+ * @param idx Index.
*/
- private IndexEventParameters(String idxName, String tblName, @Nullable InternalSortedIndex idx) {
+ private IndexEventParameters(UUID idxId, String idxName, String tblName, @Nullable InternalSortedIndex idx) {
+ this.idxId = idxId;
this.idxName = idxName;
this.tblName = tblName;
this.idx = idx;
}
+ public UUID indexId() {
+ return idxId;
+ }
+
public String indexName() {
return idxName;
}
diff --git a/modules/index/src/main/java/org/apache/ignite/internal/idx/IndexManagerImpl.java b/modules/index/src/main/java/org/apache/ignite/internal/idx/IndexManagerImpl.java
index ebada673f..f6ee3fa6a 100644
--- a/modules/index/src/main/java/org/apache/ignite/internal/idx/IndexManagerImpl.java
+++ b/modules/index/src/main/java/org/apache/ignite/internal/idx/IndexManagerImpl.java
@@ -18,10 +18,12 @@
package org.apache.ignite.internal.idx;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.directProxy;
+import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.getByInternalId;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -51,6 +53,7 @@ import org.apache.ignite.internal.schema.Column;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.table.TableImpl;
import org.apache.ignite.internal.table.distributed.TableManager;
+import org.apache.ignite.internal.util.IgniteObjectName;
import org.apache.ignite.internal.util.IgniteSpinBusyLock;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.lang.IgniteLogger;
@@ -58,7 +61,6 @@ import org.apache.ignite.lang.IndexAlreadyExistsException;
import org.apache.ignite.lang.IndexNotFoundException;
import org.apache.ignite.lang.NodeStoppingException;
import org.apache.ignite.lang.TableNotFoundException;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -74,6 +76,9 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
/** Indexes by canonical name. */
private final Map<String, InternalSortedIndex> idxsByName = new ConcurrentHashMap<>();
+ /** Indexes by id. */
+ private final Map<UUID, InternalSortedIndex> idxsById = new ConcurrentHashMap<>();
+
/** Busy lock to stop synchronously. */
private final IgniteSpinBusyLock busyLock = new IgniteSpinBusyLock();
@@ -83,7 +88,7 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
/**
* Constructor.
*
- * @param tablesCfg Tables configuration.
+ * @param tablesCfg Tables configuration.
*/
public IndexManagerImpl(
TableManager tblMgr,
@@ -98,16 +103,15 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
tablesCfg.tables().any().indices().listenElements(
new ConfigurationNamedListListener<>() {
@Override
- public @NotNull CompletableFuture<?> onCreate(@NotNull ConfigurationNotificationEvent<TableIndexView> ctx) {
+ public CompletableFuture<?> onCreate(ConfigurationNotificationEvent<TableIndexView> ctx) {
TableConfiguration tbl = ctx.config(TableConfiguration.class);
String tblName = tbl.name().value();
+ UUID idxId = ctx.newValue().id();
String idxName = ctx.newValue().name();
if (!busyLock.enterBusy()) {
fireEvent(IndexEvent.CREATE,
- new IndexEventParameters(
- idxName,
- tblName),
+ new IndexEventParameters(idxId, idxName, tblName),
new NodeStoppingException());
return CompletableFuture.completedFuture(new NodeStoppingException());
@@ -115,7 +119,7 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
try {
onIndexCreate(ctx);
} catch (Exception e) {
- fireEvent(IndexEvent.CREATE, new IndexEventParameters(idxName, tblName), e);
+ fireEvent(IndexEvent.CREATE, new IndexEventParameters(idxId, idxName, tblName), e);
LOG.error("Internal error, index creation failed [name={}, table={}]", e, idxName, tblName);
@@ -128,24 +132,22 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
}
@Override
- public @NotNull CompletableFuture<?> onRename(@NotNull String oldName, @NotNull String newName,
- @NotNull ConfigurationNotificationEvent<TableIndexView> ctx) {
+ public CompletableFuture<?> onRename(String oldName, String newName,
+ ConfigurationNotificationEvent<TableIndexView> ctx) {
// TODO: IGNITE-16196 Supports index rename
return ConfigurationNamedListListener.super.onRename(oldName, newName, ctx);
}
@Override
- public @NotNull CompletableFuture<?> onDelete(@NotNull ConfigurationNotificationEvent<TableIndexView> ctx) {
+ public CompletableFuture<?> onDelete(ConfigurationNotificationEvent<TableIndexView> ctx) {
TableConfiguration tbl = ctx.config(TableConfiguration.class);
String tblName = tbl.name().value();
String idxName = ctx.oldValue().name();
+ UUID idxId = ctx.oldValue().id();
if (!busyLock.enterBusy()) {
fireEvent(IndexEvent.DROP,
- new IndexEventParameters(
- idxName,
- tblName
- ),
+ new IndexEventParameters(idxId, idxName, tblName),
new NodeStoppingException());
return CompletableFuture.completedFuture(new NodeStoppingException());
@@ -160,7 +162,7 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
}
@Override
- public @NotNull CompletableFuture<?> onUpdate(@NotNull ConfigurationNotificationEvent<TableIndexView> ctx) {
+ public CompletableFuture<?> onUpdate(ConfigurationNotificationEvent<TableIndexView> ctx) {
assert false : "Index cannot be updated [ctx=" + ctx + ']';
return CompletableFuture.completedFuture(null);
@@ -172,11 +174,19 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
TableConfiguration tbl = ctx.config(TableConfiguration.class);
String tblName = tbl.name().value();
- InternalSortedIndex idx = idxsByName.remove(ctx.oldValue().name());
+ String idxName = ctx.oldValue().name();
+ UUID idxId = ctx.oldValue().id();
+
+ InternalSortedIndex idx = idxsByName.remove(idxName);
+
+ assert idx != null : "Index wasn't found: indexName=" + idxName;
+
+ idxsById.remove(idxId);
idx.drop();
fireEvent(IndexEvent.DROP, new IndexEventParameters(
+ idxId,
idx.name(),
tblName
), null);
@@ -234,7 +244,7 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
try {
CompletableFuture<Void> idxFut = new CompletableFuture<>();
- indexAsyncInternal(idxCanonicalName).thenAccept((idx) -> {
+ indexAsync(idxCanonicalName).thenAccept((idx) -> {
if (idx == null) {
idxFut.completeExceptionally(new IndexNotFoundException(idxCanonicalName));
return;
@@ -283,6 +293,9 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
if (!busyLock.enterBusy()) {
throw new IgniteException(new NodeStoppingException());
}
+
+ String idxName = IgniteObjectName.parseCanonicalName(idxCanonicalName);
+
try {
CompletableFuture<InternalSortedIndex> idxFut = new CompletableFuture<>();
@@ -291,17 +304,17 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
idxFut.completeExceptionally(new TableNotFoundException(tblCanonicalName));
}
- indexAsyncInternal(idxCanonicalName).thenAccept((idx) -> {
+ indexAsync(idxName).thenAccept((idx) -> {
if (idx != null) {
idxFut.completeExceptionally(new IndexAlreadyExistsException(idxCanonicalName));
}
tblMgr.alterTableAsync(tblCanonicalName, chng -> chng.changeIndices(idxes -> {
- if (idxes.get(idxCanonicalName) != null) {
+ if (idxes.get(idxName) != null) {
idxFut.completeExceptionally(new IndexAlreadyExistsException(idxCanonicalName));
}
- idxes.create(idxCanonicalName, idxChange::accept);
+ idxes.create(idxName, idxChange::accept);
}
)).whenComplete((res, t) -> {
if (t != null) {
@@ -313,7 +326,7 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
idxFut.completeExceptionally(ex);
} else {
- idxFut.complete(idxsByName.get(idxCanonicalName));
+ idxFut.complete(idxsByName.get(idxName));
}
});
});
@@ -338,14 +351,22 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
throw new IgniteException(new NodeStoppingException());
}
try {
- return indexAsyncInternal(idxCanonicalName);
+ String idxName = IgniteObjectName.parseCanonicalName(idxCanonicalName);
+
+ UUID idxId = directIndexId(idxName);
+
+ if (idxId == null) { // If not configured.
+ return CompletableFuture.completedFuture(null);
+ }
+
+ return indexAsyncInternal(idxId);
} finally {
busyLock.leaveBusy();
}
}
- private CompletableFuture<InternalSortedIndex> indexAsyncInternal(String idxCanonicalName) {
- var idx = idxsByName.get(idxCanonicalName);
+ private CompletableFuture<InternalSortedIndex> indexAsyncInternal(UUID idxId) {
+ InternalSortedIndex idx = idxsById.get(idxId);
if (idx != null) {
return CompletableFuture.completedFuture(idx);
@@ -355,8 +376,8 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
EventListener<IndexEventParameters> clo = new EventListener<>() {
@Override
- public boolean notify(@NotNull IndexEventParameters parameters, @Nullable Throwable e) {
- if (!idxCanonicalName.equals(parameters.indexName())) {
+ public boolean notify(IndexEventParameters parameters, @Nullable Throwable e) {
+ if (!idxId.equals(parameters.indexId())) {
return false;
}
@@ -370,16 +391,16 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
}
@Override
- public void remove(@NotNull Throwable e) {
+ public void remove(Throwable e) {
getIdxFut.completeExceptionally(e);
}
};
listen(IndexEvent.CREATE, clo);
- idx = idxsByName.get(idxCanonicalName);
+ idx = idxsById.get(idxId);
- if (idx != null && getIdxFut.complete(idx) || !isIndexConfigured(idxCanonicalName) && getIdxFut.complete(null)) {
+ if (idx != null && getIdxFut.complete(idx) || !isIndexConfigured(idxId) && getIdxFut.complete(null)) {
removeListener(IndexEvent.CREATE, clo, null);
} else {
getIdxFut.thenRun(() -> removeListener(IndexEvent.CREATE, clo, null));
@@ -391,10 +412,34 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
/**
* Checks that the index is configured with specific name.
*
- * @param idxName Index name.
+ * @param idxId Index id.
* @return True when the table is configured into cluster, false otherwise.
*/
- private boolean isIndexConfigured(String idxName) {
+ private boolean isIndexConfigured(UUID idxId) {
+ try {
+ NamedListView<TableView> directTablesCfg = directProxy(tablesCfg.tables()).value();
+
+ // TODO: IGNITE-15721 Need to review this approach after the ticket would be fixed.
+ // Probably, it won't be required getting configuration of all tables from Metastore.
+ for (String name : directTablesCfg.namedListKeys()) {
+ TableView tableView = directTablesCfg.get(name);
+
+ getByInternalId(tableView.indices(), idxId);
+ }
+
+ return true;
+ } catch (NoSuchElementException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets direct id of index with {@code idxName}.
+ *
+ * @param idxName Index name.
+ * @return TableIndexView.
+ */
+ private @Nullable UUID directIndexId(String idxName) {
NamedListView<TableView> directTablesCfg = directProxy(tablesCfg.tables()).value();
// TODO: IGNITE-15721 Need to review this approach after the ticket would be fixed.
@@ -403,16 +448,16 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
TableView tableView = directTablesCfg.get(name);
if (tableView != null) {
- if (tableView.indices().get(idxName) != null) {
- return true;
+ TableIndexView tableIndexView = tableView.indices().get(idxName);
+
+ if (tableIndexView != null) {
+ return tableIndexView.id();
}
}
}
-
- return false;
+ return null;
}
-
/**
* Waits for future result and return, or unwraps {@link CompletionException} to {@link IgniteException} if failed.
*
@@ -454,7 +499,7 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
* @return A root exception which will be acceptable to throw for public API.
*/
//TODO: IGNITE-16051 Implement exception converter for public API.
- private @NotNull IgniteException getRootCause(Throwable t) {
+ private IgniteException getRootCause(Throwable t) {
Throwable ex;
if (t instanceof CompletionException) {
@@ -479,10 +524,10 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
// ).collect(Collectors.toMap(Column::name, Function.identity()));
List<SortedIndexColumnDescriptor> idxCols = Stream.concat(
- idxView.columns().namedListKeys().stream(),
- Arrays.stream(tblSchema.keyColumns().columns())
- .map(Column::name)
- )
+ idxView.columns().namedListKeys().stream(),
+ Arrays.stream(tblSchema.keyColumns().columns())
+ .map(Column::name)
+ )
.distinct()
.map(colName -> {
IndexColumnView idxCol = idxView.columns().get(colName);
@@ -493,12 +538,13 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
.collect(Collectors.toList());
SortedIndexDescriptor idxDesc = new SortedIndexDescriptor(
- idxView.name(),
+ idxView.id().toString(),
idxCols,
tblSchema.keyColumns().columns()
);
InternalSortedIndexImpl idx = new InternalSortedIndexImpl(
+ idxView.id(),
idxView.name(),
tbl.internalTable().storage().createSortedIndex(idxDesc),
tbl
@@ -506,8 +552,17 @@ public class IndexManagerImpl extends AbstractProducer<IndexEvent, IndexEventPar
tbl.addRowListener(idx);
- idxsByName.put(idx.name(), idx);
+ idxsById.put(idxView.id(), idx);
+ idxsByName.put(idxView.name(), idx);
fireEvent(IndexEvent.CREATE, new IndexEventParameters(tbl.name(), idx), null);
}
+
+ /** {@inheritDoc} */
+ @Override
+ public InternalSortedIndex getIndexById(UUID id) {
+ InternalSortedIndex res = join(indexAsyncInternal(id));
+
+ return res;
+ }
}
diff --git a/modules/index/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndexImpl.java b/modules/index/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndexImpl.java
index b7c598c05..320e0a0fd 100644
--- a/modules/index/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndexImpl.java
+++ b/modules/index/src/main/java/org/apache/ignite/internal/idx/InternalSortedIndexImpl.java
@@ -46,6 +46,8 @@ import org.jetbrains.annotations.Nullable;
* Internal index manager facade provides low-level methods for indexes operations.
*/
public class InternalSortedIndexImpl implements InternalSortedIndex, StorageRowListener {
+ private final UUID id;
+
private final String name;
private final TableImpl tbl;
@@ -57,7 +59,8 @@ public class InternalSortedIndexImpl implements InternalSortedIndex, StorageRowL
/**
* Create sorted index.
*/
- public InternalSortedIndexImpl(String name, SortedIndexStorage store, TableImpl tbl) {
+ public InternalSortedIndexImpl(UUID id, String name, SortedIndexStorage store, TableImpl tbl) {
+ this.id = id;
this.name = name;
this.store = store;
this.tbl = tbl;
@@ -71,6 +74,11 @@ public class InternalSortedIndexImpl implements InternalSortedIndex, StorageRowL
return name;
}
+ /** {@inheritDoc} */
+ @Override public UUID id() {
+ return id;
+ }
+
/** {@inheritDoc} */
@Override
public UUID tableId() {
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgniteCliRunnerTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgniteCliRunnerTest.java
index a600ab0fd..d28040201 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgniteCliRunnerTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgniteCliRunnerTest.java
@@ -20,9 +20,13 @@ package org.apache.ignite.internal.runner.app;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.nio.file.Path;
+import java.util.Objects;
+import java.util.stream.Stream;
+import org.apache.ignite.Ignite;
import org.apache.ignite.app.IgniteCliRunner;
import org.apache.ignite.internal.testframework.WorkDirectory;
import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
+import org.apache.ignite.internal.util.IgniteUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -36,19 +40,28 @@ public class IgniteCliRunnerTest {
public void runnerArgsSmokeTest(@WorkDirectory Path workDir) throws Exception {
Path configPath = Path.of(IgniteCliRunnerTest.class.getResource("/ignite-config.json").toURI());
- assertNotNull(IgniteCliRunner.start(
- new String[]{
- "--config", configPath.toAbsolutePath().toString(),
- "--work-dir", workDir.resolve("node1").toAbsolutePath().toString(),
- "node1"
- }
- ));
+ Ignite node1 = null;
+ Ignite node2 = null;
+ try {
+ node1 = IgniteCliRunner.start(
+ new String[]{
+ "--config", configPath.toAbsolutePath().toString(),
+ "--work-dir", workDir.resolve("node1").toAbsolutePath().toString(),
+ "node1"
+ }
+ );
+ assertNotNull(node1);
- assertNotNull(IgniteCliRunner.start(
- new String[]{
- "--work-dir", workDir.resolve("node2").toAbsolutePath().toString(),
- "node2"
- }
- ));
+ node2 = IgniteCliRunner.start(
+ new String[]{
+ "--work-dir", workDir.resolve("node2").toAbsolutePath().toString(),
+ "node2"
+ }
+ );
+
+ assertNotNull(node2);
+ } finally {
+ IgniteUtils.closeAll(Stream.of(node1, node2).filter(Objects::nonNull));
+ }
}
}
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
index 31b55d2f0..b37f21c9b 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
@@ -71,7 +71,8 @@ public abstract class QueryChecker {
* @return Matcher.
*/
public static Matcher<String> containsIndexScan(String schema, String tblName) {
- return containsSubPlan("IgniteIndexScan(table=[[" + schema + ", " + tblName + "]]");
+ return matchesOnce(".*IgniteIndexScan\\(table=\\[\\[" + schema + ", " + tblName + "\\]\\],"
+ + " tableId=\\[.*\\].*\\)");
}
/**
@@ -83,8 +84,8 @@ public abstract class QueryChecker {
* @return Matcher.
*/
public static Matcher<String> containsIndexScan(String schema, String tblName, String idxName) {
- return matchesOnce(".*IgniteIndexScan\\(tableId=\\[.*\\], index=\\[" + idxName
- + "\\].*requiredColumns=\\[\\{(\\d|\\W|,)+\\}\\].*");
+ return matchesOnce(".*IgniteIndexScan\\(table=\\[\\[" + schema + ", " + tblName + "\\]\\],"
+ + " tableId=\\[.*\\], index=\\[" + idxName + "\\].*\\)");
}
/**
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/ByteBufferRow.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/ByteBufferRow.java
index 410195c4e..f5d925113 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/ByteBufferRow.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/ByteBufferRow.java
@@ -24,6 +24,7 @@ import java.nio.ByteOrder;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
/**
* Heap byte buffer-based row.
@@ -196,13 +197,9 @@ public class ByteBufferRow implements BinaryRow {
}
/** {@inheritDoc} */
- @Override public byte[] bytes() {
+ @Override
+ public byte[] bytes() {
// TODO IGNITE-15934 avoid copy.
- byte[] tmp = new byte[buf.limit()];
-
- buf.get(tmp);
- buf.rewind();
-
- return tmp;
+ return Arrays.copyOf(buf.array(), buf.limit());
}
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
index 06e2039d9..cf63cade1 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
@@ -168,7 +168,7 @@ public class SqlQueryProcessor implements QueryProcessor {
extensions = extensionList.stream().collect(Collectors.toMap(SqlExtension::name, Function.identity()));
- SqlSchemaManagerImpl schemaManager = new SqlSchemaManagerImpl(tblManager, planCache::clear);
+ SqlSchemaManagerImpl schemaManager = new SqlSchemaManagerImpl(tblManager, idxManager, planCache::clear);
executionSrvc = registerService(new ExecutionServiceImpl<>(
clusterSrvc.topologyService(),
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java
index 88076e0c4..64ca49c83 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java
@@ -302,7 +302,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
Supplier<RowT> upper = upperCond == null ? null : expressionFactory.rowSource(upperCond);
Function<RowT, RowT> prj = projects == null ? null : expressionFactory.project(projects, rowType);
- IgniteIndex idx = tbl.getIndex(rel.indexName());
+ IgniteIndex idx = rel.getIndex();
ColocationGroup group = ctx.group(rel.sourceId());
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelInputEx.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelInputEx.java
index b1c3ab016..bb56d52f7 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelInputEx.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelInputEx.java
@@ -20,6 +20,8 @@ package org.apache.ignite.internal.sql.engine.externalize;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelInput;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
+import org.apache.ignite.lang.IndexNotFoundException;
/**
* Extension to the {@link RelInput} interface.
@@ -38,8 +40,17 @@ public interface RelInputEx extends RelInput {
/**
* Returns table by its id.
*
- * @param tag Tag under which id is serialised.
+ * @param tag Tag under which id is serialized.
* @return A table with given id.
*/
RelOptTable getTableById(String tag);
+
+ /**
+ * Returns an index by its id.
+ *
+ * @param tag Tag represents id serialization.
+ * @param idxName Index name.
+ * @throws IndexNotFoundException If not found.
+ */
+ IgniteIndex getIndexById(String tag, String idxName);
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReader.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReader.java
index f91f9c3d1..cec776b81 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReader.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReader.java
@@ -28,6 +28,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
import org.apache.calcite.plan.RelOptCluster;
@@ -47,6 +48,7 @@ import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.schema.SqlSchemaManager;
import org.apache.ignite.internal.sql.engine.util.Commons;
@@ -155,12 +157,29 @@ public class RelJsonReader {
@Override
public RelOptTable getTableById(String tag) {
String tableId = getString(tag);
+
+ Objects.requireNonNull(tableId);
+
IgniteTable table = schemaManager.tableById(UUID.fromString(tableId));
- return RelOptTableImpl.create(null, table.getRowType(Commons.typeFactory()), List.of(tableId),
+ List<String> tableName = getStringList("table");
+
+ return RelOptTableImpl.create(null, table.getRowType(Commons.typeFactory()), tableName,
table, null);
}
+ /** {@inheritDoc} */
+ @Override
+ public IgniteIndex getIndexById(String tag, String idxName) {
+ String idxId = getString(tag);
+
+ Objects.requireNonNull(idxId);
+
+ UUID id = UUID.fromString(idxId);
+
+ return schemaManager.indexById(id);
+ }
+
/** {@inheritDoc} */
@Override
public RelNode getInput() {
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
index c3b98fad0..4a9012c35 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
@@ -235,7 +235,7 @@ public class PlannerHelper {
}
IntSet indexedCols = CollectionUtils.setOf(
- tbl.getIndex(((AbstractIndexScan) scan).indexName()).collation().getKeys());
+ ((AbstractIndexScan) scan).getIndex().collation().getKeys());
spoolNeeded = modifyNode.getUpdateColumnList().stream()
.map(tbl.descriptor()::columnDescriptor)
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java
index 4a67b625b..80e61df4e 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.sql.engine.rel;
+import static org.apache.calcite.sql.SqlExplainLevel.EXPPLAN_ATTRIBUTES;
+
import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCost;
@@ -31,7 +33,9 @@ import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.sql.engine.externalize.RelInputEx;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.util.IndexConditions;
import org.jetbrains.annotations.Nullable;
@@ -39,7 +43,7 @@ import org.jetbrains.annotations.Nullable;
* Class with index conditions info.
*/
public abstract class AbstractIndexScan extends ProjectableFilterableTableScan {
- protected final String idxName;
+ protected final IgniteIndex index;
protected final IndexConditions idxCond;
@@ -50,7 +54,8 @@ public abstract class AbstractIndexScan extends ProjectableFilterableTableScan {
*/
protected AbstractIndexScan(RelInput input) {
super(input);
- idxName = input.getString("index");
+ String idxName = input.getString("indexName");
+ index = ((RelInputEx) input).getIndexById("indexId", idxName);
idxCond = new IndexConditions(input);
}
@@ -63,7 +68,7 @@ public abstract class AbstractIndexScan extends ProjectableFilterableTableScan {
RelTraitSet traitSet,
List<RelHint> hints,
RelOptTable table,
- String idxName,
+ IgniteIndex idx,
@Nullable List<RexNode> proj,
@Nullable RexNode cond,
@Nullable IndexConditions idxCond,
@@ -71,25 +76,26 @@ public abstract class AbstractIndexScan extends ProjectableFilterableTableScan {
) {
super(cluster, traitSet, hints, table, proj, cond, reqColumns);
- this.idxName = idxName;
+ this.index = idx;
this.idxCond = idxCond;
}
/** {@inheritDoc} */
@Override
protected RelWriter explainTerms0(RelWriter pw) {
- pw = pw.item("index", idxName);
+ pw = pw.item("indexName", index.name());
+ pw = pw.itemIf("indexId", index.id().toString(), pw.getDetailLevel() != EXPPLAN_ATTRIBUTES);
pw = super.explainTerms0(pw);
return idxCond.explainTerms(pw);
}
/**
- * Get index name.
+ * Get index instance.
* TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
*/
- public String indexName() {
- return idxName;
+ public IgniteIndex getIndex() {
+ return index;
}
/**
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java
index 26c41cf48..26cbd3874 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.RelInput;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.util.IndexConditions;
import org.jetbrains.annotations.Nullable;
@@ -58,14 +59,14 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
* @param cluster Cluster that this relational expression belongs to
* @param traits Traits of this relational expression
* @param tbl Table definition.
- * @param idxName Index name.
+ * @param idx Index impl.
*/
public IgniteIndexScan(
RelOptCluster cluster,
RelTraitSet traits,
RelOptTable tbl,
- String idxName) {
- this(cluster, traits, tbl, idxName, null, null, null, null);
+ IgniteIndex idx) {
+ this(cluster, traits, tbl, idx, null, null, null, null);
}
/**
@@ -74,7 +75,7 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
* @param cluster Cluster that this relational expression belongs to
* @param traits Traits of this relational expression
* @param tbl Table definition.
- * @param idxName Index name.
+ * @param idx Index impl.
* @param proj Projects.
* @param cond Filters.
* @param requiredCols Participating columns.
@@ -83,13 +84,13 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
RelOptCluster cluster,
RelTraitSet traits,
RelOptTable tbl,
- String idxName,
+ IgniteIndex idx,
@Nullable List<RexNode> proj,
@Nullable RexNode cond,
@Nullable IndexConditions idxCond,
@Nullable ImmutableBitSet requiredCols
) {
- this(-1L, cluster, traits, tbl, idxName, proj, cond, idxCond, requiredCols);
+ this(-1L, cluster, traits, tbl, idx, proj, cond, idxCond, requiredCols);
}
/**
@@ -98,7 +99,7 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
* @param cluster Cluster that this relational expression belongs to
* @param traits Traits of this relational expression
* @param tbl Table definition.
- * @param idxName Index name.
+ * @param idx Index impl.
* @param proj Projects.
* @param cond Filters.
* @param requiredCols Participating columns.
@@ -108,13 +109,13 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
RelOptCluster cluster,
RelTraitSet traits,
RelOptTable tbl,
- String idxName,
+ IgniteIndex idx,
@Nullable List<RexNode> proj,
@Nullable RexNode cond,
@Nullable IndexConditions idxCond,
@Nullable ImmutableBitSet requiredCols
) {
- super(cluster, traits, List.of(), tbl, idxName, proj, cond, idxCond, requiredCols);
+ super(cluster, traits, List.of(), tbl, idx, proj, cond, idxCond, requiredCols);
this.sourceId = sourceId;
}
@@ -142,13 +143,13 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
@Override
public IgniteRel clone(long sourceId) {
return new IgniteIndexScan(sourceId, getCluster(), getTraitSet(), getTable(),
- idxName, projects, condition, idxCond, requiredColumns);
+ index, projects, condition, idxCond, requiredColumns);
}
/** {@inheritDoc} */
@Override
public IgniteRel clone(RelOptCluster cluster, List<IgniteRel> inputs) {
return new IgniteIndexScan(sourceId, cluster, getTraitSet(), getTable(),
- idxName, projects, condition, idxCond, requiredColumns);
+ index, projects, condition, idxCond, requiredColumns);
}
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java
index bbd60c720..b7b304617 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java
@@ -133,7 +133,7 @@ public abstract class ProjectableFilterableTableScan extends TableScan {
@Override
public RelWriter explainTerms(RelWriter pw) {
return explainTerms0(pw
- .itemIf("table", table.getQualifiedName(), pw.getDetailLevel() == EXPPLAN_ATTRIBUTES)
+ .item("table", table.getQualifiedName())
.itemIf("tableId", table.unwrap(IgniteTable.class).id().toString(),
pw.getDetailLevel() != EXPPLAN_ATTRIBUTES)
);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/logical/IgniteLogicalIndexScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/logical/IgniteLogicalIndexScan.java
index f64cce5e9..7b1a2c951 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/logical/IgniteLogicalIndexScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/logical/IgniteLogicalIndexScan.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.mapping.Mappings;
import org.apache.ignite.internal.sql.engine.rel.AbstractIndexScan;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.InternalIgniteTable;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
@@ -45,7 +46,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan {
RelOptCluster cluster,
RelTraitSet traits,
RelOptTable table,
- String idxName,
+ IgniteIndex idx,
@Nullable List<RexNode> proj,
@Nullable RexNode cond,
@Nullable ImmutableBitSet requiredColumns
@@ -53,7 +54,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan {
InternalIgniteTable tbl = table.unwrap(InternalIgniteTable.class);
IgniteTypeFactory typeFactory = Commons.typeFactory(cluster);
RelDataType rowType = tbl.getRowType(typeFactory, requiredColumns);
- RelCollation collation = tbl.getIndex(idxName).collation();
+ RelCollation collation = idx.collation();
if (requiredColumns != null) {
Mappings.TargetMapping targetMapping = Commons.mapping(requiredColumns,
@@ -79,7 +80,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan {
cluster,
traits,
table,
- idxName,
+ idx,
proj,
cond,
idxCond,
@@ -92,7 +93,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan {
* @param cluster Cluster that this relational expression belongs to
* @param traits Traits of this relational expression
* @param tbl Table definition.
- * @param idxName Index name.
+ * @param idx Index impl.
* @param proj Projects.
* @param cond Filters.
* @param idxCond Index conditions.
@@ -102,12 +103,12 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan {
RelOptCluster cluster,
RelTraitSet traits,
RelOptTable tbl,
- String idxName,
+ IgniteIndex idx,
@Nullable List<RexNode> proj,
@Nullable RexNode cond,
@Nullable IndexConditions idxCond,
@Nullable ImmutableBitSet requiredCols
) {
- super(cluster, traits, List.of(), tbl, idxName, proj, cond, idxCond, requiredCols);
+ super(cluster, traits, List.of(), tbl, idx, proj, cond, idxCond, requiredCols);
}
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/LogicalScanConverterRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/LogicalScanConverterRule.java
index e8f9b963b..204733ba4 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/LogicalScanConverterRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/LogicalScanConverterRule.java
@@ -64,7 +64,7 @@ public abstract class LogicalScanConverterRule<T extends ProjectableFilterableTa
) {
RelOptCluster cluster = rel.getCluster();
InternalIgniteTable table = rel.getTable().unwrap(InternalIgniteTable.class);
- IgniteIndex index = table.getIndex(rel.indexName());
+ IgniteIndex index = rel.getIndex();
RelDistribution distribution = table.distribution();
RelCollation collation = index.collation();
@@ -95,7 +95,7 @@ public abstract class LogicalScanConverterRule<T extends ProjectableFilterableTa
cluster,
traits,
rel.getTable(),
- rel.indexName(),
+ rel.getIndex(),
rel.projects(),
rel.condition(),
rel.indexConditions(),
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ExposeIndexRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ExposeIndexRule.java
index b25cefeae..a56be0a4f 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ExposeIndexRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ExposeIndexRule.java
@@ -63,8 +63,8 @@ public class ExposeIndexRule extends RelRule<ExposeIndexRule.Config> {
RexNode condition = scan.condition();
ImmutableBitSet requiredCols = scan.requiredColumns();
- List<IgniteLogicalIndexScan> indexes = igniteTable.indexes().keySet().stream()
- .map(idxName -> igniteTable.toRel(cluster, optTable, idxName, proj, condition, requiredCols))
+ List<IgniteLogicalIndexScan> indexes = igniteTable.indexes().values().stream()
+ .map(idx -> igniteTable.toRel(cluster, optTable, idx, proj, condition, requiredCols))
.collect(Collectors.toList());
if (indexes.isEmpty()) {
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/FilterScanMergeRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/FilterScanMergeRule.java
index b100aa49e..531e80ff8 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/FilterScanMergeRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/FilterScanMergeRule.java
@@ -158,7 +158,7 @@ public abstract class FilterScanMergeRule<T extends ProjectableFilterableTableSc
RelTraitSet traits,
RexNode cond
) {
- return IgniteLogicalIndexScan.create(cluster, traits, scan.getTable(), scan.indexName(),
+ return IgniteLogicalIndexScan.create(cluster, traits, scan.getTable(), scan.getIndex(),
scan.projects(), cond, scan.requiredColumns());
}
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ProjectScanMergeRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ProjectScanMergeRule.java
index a32d7a52a..325e4240e 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ProjectScanMergeRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/ProjectScanMergeRule.java
@@ -200,7 +200,7 @@ public abstract class ProjectScanMergeRule<T extends ProjectableFilterableTableS
cluster,
traits,
scan.getTable(),
- scan.indexName(),
+ scan.getIndex(),
projections,
cond, requiredColumns
);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteIndex.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteIndex.java
index e30041372..00eaaa182 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteIndex.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteIndex.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.sql.engine.schema;
+import java.util.Objects;
+import java.util.UUID;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -33,37 +35,18 @@ import org.apache.ignite.internal.sql.engine.metadata.ColocationGroup;
public class IgniteIndex {
private final RelCollation collation;
- private final String idxName;
-
private final InternalSortedIndex idx;
private final InternalIgniteTable tbl;
- /**
- * Constructor.
- * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
- */
- public IgniteIndex(RelCollation collation, String name, InternalIgniteTable tbl) {
- this(collation, name, null, tbl);
- }
-
/**
* Constructor.
* TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
*/
public IgniteIndex(RelCollation collation, InternalSortedIndex idx, InternalIgniteTable tbl) {
- this(collation, idx.name(), idx, tbl);
- }
-
- /**
- * Constructor.
- * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
- */
- private IgniteIndex(RelCollation collation, String name, InternalSortedIndex idx, InternalIgniteTable tbl) {
- this.collation = collation;
- idxName = name;
- this.idx = idx;
- this.tbl = tbl;
+ this.collation = Objects.requireNonNull(collation);
+ this.idx = Objects.requireNonNull(idx);
+ this.tbl = Objects.requireNonNull(tbl);
}
public RelCollation collation() {
@@ -71,7 +54,7 @@ public class IgniteIndex {
}
public String name() {
- return idxName;
+ return idx.name();
}
public InternalIgniteTable table() {
@@ -82,6 +65,10 @@ public class IgniteIndex {
return idx;
}
+ public UUID id() {
+ return idx.id();
+ }
+
/**
* Scan index.
*/
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java
index a893918a8..2725fb4dd 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java
@@ -158,7 +158,7 @@ public class IgniteTableImpl extends AbstractTable implements InternalIgniteTabl
public IgniteLogicalIndexScan toRel(
RelOptCluster cluster,
RelOptTable relOptTable,
- String idxName,
+ IgniteIndex idx,
List<RexNode> proj,
RexNode condition,
ImmutableBitSet requiredCols
@@ -166,9 +166,9 @@ public class IgniteTableImpl extends AbstractTable implements InternalIgniteTabl
RelTraitSet traitSet = cluster.traitSetOf(Convention.Impl.NONE)
.replace(distribution())
.replace(RewindabilityTrait.REWINDABLE)
- .replace(getIndex(idxName).collation());
+ .replace(idx.collation());
- return IgniteLogicalIndexScan.create(cluster, traitSet, relOptTable, idxName, proj, condition, requiredCols);
+ return IgniteLogicalIndexScan.create(cluster, traitSet, relOptTable, idx, proj, condition, requiredCols);
}
/** {@inheritDoc} */
@@ -212,8 +212,8 @@ public class IgniteTableImpl extends AbstractTable implements InternalIgniteTabl
/** {@inheritDoc} */
@Override
- public void removeIndex(String idxName) {
- indexes.remove(idxName);
+ public IgniteIndex removeIndex(String idxName) {
+ return indexes.remove(idxName);
}
/** {@inheritDoc} */
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/InternalIgniteTable.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/InternalIgniteTable.java
index 99b95a118..4ea6b97cc 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/InternalIgniteTable.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/InternalIgniteTable.java
@@ -49,11 +49,11 @@ public interface InternalIgniteTable extends IgniteTable {
*
* @param cluster Custer.
* @param relOptTbl Table.
- * @param idxName Index name.
+ * @param idx Index impl.
* @return Table relational expression.
*/
- default IgniteLogicalIndexScan toRel(RelOptCluster cluster, RelOptTable relOptTbl, String idxName) {
- return toRel(cluster, relOptTbl, idxName, null, null, null);
+ default IgniteLogicalIndexScan toRel(RelOptCluster cluster, RelOptTable relOptTbl, IgniteIndex idx) {
+ return toRel(cluster, relOptTbl, idx, null, null, null);
}
/**
@@ -73,7 +73,7 @@ public interface InternalIgniteTable extends IgniteTable {
IgniteLogicalIndexScan toRel(
RelOptCluster cluster,
RelOptTable relOptTbl,
- String idxName,
+ IgniteIndex idx,
List<RexNode> proj,
RexNode condition,
ImmutableBitSet requiredCols
@@ -148,5 +148,5 @@ public interface InternalIgniteTable extends IgniteTable {
*
* @param idxName Index name.
*/
- void removeIndex(String idxName);
+ IgniteIndex removeIndex(String idxName);
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManager.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManager.java
index 7c1aeb690..d83dc5efa 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManager.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManager.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.sql.engine.schema;
import java.util.UUID;
import org.apache.calcite.schema.SchemaPlus;
+import org.apache.ignite.lang.IgniteInternalException;
import org.jetbrains.annotations.Nullable;
/**
@@ -38,4 +39,13 @@ public interface SqlSchemaManager {
* @return The table.
*/
IgniteTable tableById(UUID id);
+
+ /**
+ * Returns the index by id.
+ *
+ * @param id An id of required index.
+ * @return Appropriate index instance.
+ * @throws IgniteInternalException if not found.
+ */
+ IgniteIndex indexById(UUID id);
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java
index e5bd3a9ea..62b98155b 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java
@@ -33,6 +33,7 @@ import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.tools.Frameworks;
+import org.apache.ignite.internal.idx.IndexManager;
import org.apache.ignite.internal.idx.InternalSortedIndex;
import org.apache.ignite.internal.schema.Column;
import org.apache.ignite.internal.schema.SchemaDescriptor;
@@ -41,6 +42,7 @@ import org.apache.ignite.internal.sql.engine.extension.SqlExtension.ExternalSche
import org.apache.ignite.internal.table.TableImpl;
import org.apache.ignite.internal.table.distributed.TableManager;
import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.IgniteLogger;
import org.apache.ignite.lang.IgniteStringFormatter;
import org.apache.ignite.lang.NodeStoppingException;
import org.jetbrains.annotations.NotNull;
@@ -50,25 +52,33 @@ import org.jetbrains.annotations.Nullable;
* Holds actual schema and mutates it on schema change, requested by Ignite.
*/
public class SqlSchemaManagerImpl implements SqlSchemaManager {
+ /** Logger. */
+ private static final IgniteLogger LOG = IgniteLogger.forClass(SqlSchemaManagerImpl.class);
+
private final Map<String, IgniteSchema> igniteSchemas = new HashMap<>();
private final Map<UUID, IgniteTable> tablesById = new ConcurrentHashMap<>();
+ private final Map<UUID, IgniteIndex> indexById = new ConcurrentHashMap<>();
+
private final Map<String, Schema> externalCatalogs = new HashMap<>();
private final Runnable onSchemaUpdatedCallback;
private final TableManager tableManager;
+ private final IndexManager indexManager;
+
private volatile SchemaPlus calciteSchema;
/**
* Constructor.
* TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
*/
- public SqlSchemaManagerImpl(TableManager tableManager, Runnable onSchemaUpdatedCallback) {
+ public SqlSchemaManagerImpl(TableManager tblManager, IndexManager idxManager, Runnable onSchemaUpdatedCallback) {
+ tableManager = tblManager;
+ indexManager = idxManager;
this.onSchemaUpdatedCallback = onSchemaUpdatedCallback;
- this.tableManager = tableManager;
SchemaPlus newCalciteSchema = Frameworks.createRootSchema(false);
newCalciteSchema.add("PUBLIC", new IgniteSchema("PUBLIC"));
@@ -106,6 +116,25 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
return table;
}
+ /** {@inheritDoc} */
+ @Override
+ public IgniteIndex indexById(UUID id) throws IgniteInternalException {
+ IgniteIndex idx = indexById.get(id);
+
+ if (idx == null) {
+ indexManager.getIndexById(id);
+
+ idx = indexById.get(id);
+ }
+
+ if (idx == null) {
+ throw new IgniteInternalException(
+ IgniteStringFormatter.format("Index not found [idxId={}]", id));
+ }
+
+ return idx;
+ }
+
private void ensureTableStructuresCreated(UUID id) {
try {
tableManager.table(id);
@@ -163,7 +192,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
IgniteSchema schema = igniteSchemas.computeIfAbsent(schemaName, IgniteSchema::new);
- schema.addTable(removeSchema(schemaName, table.name()), igniteTable);
+ schema.addTable(normalizeSchema(schemaName, table.name()), igniteTable);
tablesById.put(igniteTable.id(), igniteTable);
rebuild();
@@ -204,7 +233,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
IgniteSchema schema = igniteSchemas.computeIfAbsent(schemaName, IgniteSchema::new);
- String tblName = removeSchema(schemaName, table.name());
+ String tblName = normalizeSchema(schemaName, table.name());
// Rebuild indexes collation.
igniteTable.addIndexes(schema.internalTable(tblName).indexes().values().stream()
@@ -230,6 +259,8 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
InternalIgniteTable table = (InternalIgniteTable) schema.getTable(tableName);
if (table != null) {
+ table.indexes().values().forEach(indexById::remove);
+
tablesById.remove(table.id());
schema.removeTable(tableName);
}
@@ -241,7 +272,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
* Build new SQL schema when new index is created.
*/
public void onIndexCreated(String schema, String tblName, InternalSortedIndex idx) {
- InternalIgniteTable tbl = igniteSchemas.get(schema).internalTable(removeSchema(schema, tblName));
+ InternalIgniteTable tbl = igniteSchemas.get(schema).internalTable(normalizeSchema(schema, tblName));
tbl.addIndex(createIndex(idx, tbl));
@@ -262,20 +293,28 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
)
).collect(Collectors.toList());
- return new IgniteIndex(
- RelCollations.of(idxFieldsCollation),
- idx,
- tbl
- );
+ IgniteIndex idx0 = new IgniteIndex(RelCollations.of(idxFieldsCollation), idx, tbl);
+
+ indexById.put(idx0.id(), idx0);
+
+ return idx0;
}
/**
* Build new SQL schema when existed index is dropped.
*/
public void onIndexDropped(String schema, String tblName, String idxName) {
- InternalIgniteTable tbl = igniteSchemas.get(schema).internalTable(removeSchema(schema, tblName));
+ InternalIgniteTable tbl = igniteSchemas.get(schema).internalTable(normalizeSchema(schema, tblName));
+
+ IgniteIndex idx0 = tbl.removeIndex(idxName);
- tbl.removeIndex(idxName);
+ if (idx0 != null) {
+ IgniteIndex old = indexById.remove(idx0.id());
+
+ if (old == null) {
+ LOG.trace(IgniteStringFormatter.format("Index [name={}] not found in inner store.", idxName));
+ }
+ }
rebuild();
}
@@ -293,7 +332,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager {
onSchemaUpdatedCallback.run();
}
- private static String removeSchema(String schemaName, String canonicalName) {
+ private static String normalizeSchema(String schemaName, String canonicalName) {
return canonicalName.substring(schemaName.length() + 1);
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/BaseQueryContext.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/BaseQueryContext.java
index 0085362b6..006d78cba 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/BaseQueryContext.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/BaseQueryContext.java
@@ -98,6 +98,7 @@ public final class BaseQueryContext extends AbstractQueryContext {
RelOptCluster cluster = RelOptCluster.create(DUMMY_PLANNER, DFLT_REX_BUILDER);
cluster.setMetadataProvider(IgniteMetadata.METADATA_PROVIDER);
+ cluster.setMetadataQuerySupplier(RelMetadataQueryEx::create);
CLUSTER = cluster;
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/MockedStructuresTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/MockedStructuresTest.java
index b6c44b42d..8bb9cd480 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/MockedStructuresTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/MockedStructuresTest.java
@@ -172,8 +172,9 @@ public class MockedStructuresTest extends IgniteAbstractTest {
@Test
void checkAppropriateTableFound() throws Exception {
TableManager tableManager = mock(TableManager.class);
+ IndexManager indexManager = mock(IndexManager.class);
- SqlSchemaManagerImpl schemaManager = new SqlSchemaManagerImpl(tableManager, () -> {});
+ SqlSchemaManagerImpl schemaManager = new SqlSchemaManagerImpl(tableManager, indexManager, () -> {});
UUID tblId = UUID.randomUUID();
assertTrue(assertThrows(IgniteInternalException.class, () -> schemaManager.tableById(tblId))
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReaderTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReaderTest.java
index 63e84a604..0a98de3e8 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReaderTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/externalize/RelJsonReaderTest.java
@@ -29,7 +29,10 @@ import java.util.UUID;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.schema.Statistic;
+import org.apache.ignite.internal.sql.engine.rel.AbstractIndexScan;
+import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteTableScan;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.schema.SqlSchemaManager;
import org.junit.jupiter.api.Test;
@@ -39,12 +42,11 @@ import org.mockito.Mockito;
* Tests to verify {@link RelJsonReader} behaviour.
*/
public class RelJsonReaderTest {
-
/**
* Test verifies that during deserialization table being resolved by its ID.
*/
@Test
- void fromJson() {
+ void fromJsonTblScan() {
UUID tableId = UUID.randomUUID();
IgniteTable igniteTableMock = mock(IgniteTable.class);
@@ -59,6 +61,7 @@ public class RelJsonReaderTest {
+ " \"rels\" : [ {\n"
+ " \"id\" : \"0\",\n"
+ " \"relOp\" : \"IgniteTableScan\",\n"
+ + " \"table\" : [\"PUBLIC\", \"TEST\"],\n"
+ " \"tableId\" : \"" + tableId + "\",\n"
+ " \"inputs\" : [ ]\n"
+ " } ]\n"
@@ -71,4 +74,46 @@ public class RelJsonReaderTest {
assertThat(node.getTable().unwrap(IgniteTable.class), is(igniteTableMock));
Mockito.verify(schemaMock).tableById(tableId);
}
+
+ @Test
+ void fromJsonIdxScan() {
+ UUID indexId = UUID.randomUUID();
+ UUID tableId = UUID.randomUUID();
+
+ IgniteTable igniteTableMock = mock(IgniteTable.class);
+ IgniteIndex igniteIdxMock = mock(IgniteIndex.class);
+ when(igniteTableMock.getStatistic()).thenReturn(new Statistic() {});
+ when(igniteTableMock.getRowType(any())).thenReturn(mock(RelDataType.class));
+
+ SqlSchemaManager schemaMock = mock(SqlSchemaManager.class);
+
+ when(schemaMock.tableById(tableId)).thenReturn(igniteTableMock);
+ when(schemaMock.indexById(indexId)).thenReturn(igniteIdxMock);
+
+ String json = ""
+ + "{\n"
+ + " \"rels\" : [ {\n"
+ + " \"id\" : \"0\",\n"
+ + " \"relOp\" : \"IgniteIndexScan\",\n"
+ + " \"index\" : \"idx0\",\n"
+ + " \"table\" : [\"PUBLIC\", \"TEST\"],\n"
+ + " \"indexId\" : \"" + indexId + "\",\n"
+ + " \"tableId\" : \"" + tableId + "\",\n"
+ + " \"inputs\" : [ ]\n"
+ + " } ]\n"
+ + "}";
+
+ RelNode node = RelJsonReader.fromJson(schemaMock, json);
+
+ assertThat(node, isA(IgniteIndexScan.class));
+ assertThat(node.getTable(), notNullValue());
+ assertThat(node.getTable().unwrap(IgniteTable.class), is(igniteTableMock));
+
+ AbstractIndexScan scan = (AbstractIndexScan) node;
+ assertThat(scan.getIndex(), notNullValue());
+ assertThat(scan.getIndex(), is(igniteIdxMock));
+
+ Mockito.verify(schemaMock).tableById(tableId);
+ Mockito.verify(schemaMock).indexById(indexId);
+ }
}
\ No newline at end of file
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
index 7a22652fb..c80be021f 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
@@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.mock;
import java.util.ArrayList;
import java.util.Arrays;
@@ -71,6 +72,7 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql2rel.InitializerContext;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Util;
+import org.apache.ignite.internal.idx.InternalSortedIndexImpl;
import org.apache.ignite.internal.schema.BinaryRow;
import org.apache.ignite.internal.schema.NativeType;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
@@ -100,7 +102,9 @@ import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
import org.apache.ignite.internal.sql.engine.util.BaseQueryContext;
+import org.apache.ignite.internal.storage.index.SortedIndexStorage;
import org.apache.ignite.internal.table.InternalTable;
+import org.apache.ignite.internal.table.TableImpl;
import org.apache.ignite.internal.testframework.IgniteAbstractTest;
import org.apache.ignite.internal.testframework.IgniteTestUtils;
import org.apache.ignite.internal.util.ArrayUtils;
@@ -312,16 +316,11 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
}
protected static void createTable(IgniteSchema schema, String name, RelDataType type, IgniteDistribution distr) {
- TestTable table = new TestTable(type) {
+ TestTable table = new TestTable(type, name) {
@Override
public IgniteDistribution distribution() {
return distr;
}
-
- @Override
- public String name() {
- return name;
- }
};
schema.addTable(name, table);
@@ -520,13 +519,16 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
List<RelNode> deserializedNodes = new ArrayList<>();
- Map<UUID, IgniteTable> tableMap = publicSchema.getTableNames().stream()
+ Map<UUID, InternalIgniteTable> tableMap = publicSchema.getTableNames().stream()
.map(publicSchema::getTable)
- .map(IgniteTable.class::cast)
+ .map(InternalIgniteTable.class::cast)
.collect(Collectors.toMap(IgniteTable::id, Function.identity()));
+ Map<UUID, IgniteIndex> idxMap = tableMap.values().stream().map(InternalIgniteTable::indexes).flatMap(i -> i.values().stream())
+ .collect(Collectors.toMap(IgniteIndex::id, Function.identity()));
+
for (String s : serialized) {
- RelJsonReader reader = new RelJsonReader(new SqlSchemaManagerImpl(tableMap));
+ RelJsonReader reader = new RelJsonReader(new SqlSchemaManagerImpl(tableMap, idxMap));
deserializedNodes.add(reader.read(s));
}
@@ -576,6 +578,10 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
this(type, 100.0);
}
+ TestTable(RelDataType type, String name) {
+ this(name, type, 100.0);
+ }
+
TestTable(RelDataType type, double rowCnt) {
this(UUID.randomUUID().toString(), type, rowCnt);
}
@@ -611,12 +617,12 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
public IgniteLogicalIndexScan toRel(
RelOptCluster cluster,
RelOptTable relOptTbl,
- String idxName,
+ IgniteIndex idx,
@Nullable List<RexNode> proj,
@Nullable RexNode cond,
@Nullable ImmutableBitSet requiredColumns
) {
- return IgniteLogicalIndexScan.create(cluster, cluster.traitSet(), relOptTbl, idxName, proj, cond, requiredColumns);
+ return IgniteLogicalIndexScan.create(cluster, cluster.traitSet(), relOptTbl, idx, proj, cond, requiredColumns);
}
/** {@inheritDoc} */
@@ -735,7 +741,7 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
* TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
*/
public TestTable addIndex(RelCollation collation, String name) {
- indexes.put(name, new IgniteIndex(collation, name, this));
+ indexes.put(name, new TestIgniteIndex(collation, name, this));
return this;
}
@@ -748,7 +754,7 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
/** {@inheritDoc} */
@Override
- public void removeIndex(String idxName) {
+ public IgniteIndex removeIndex(String idxName) {
throw new AssertionError();
}
@@ -928,10 +934,13 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
}
static class SqlSchemaManagerImpl implements SqlSchemaManager {
- private final Map<UUID, IgniteTable> tablesById;
+ private final Map<UUID, InternalIgniteTable> tablesById;
+
+ private final Map<UUID, IgniteIndex> idxMap;
- public SqlSchemaManagerImpl(Map<UUID, IgniteTable> tablesById) {
+ public SqlSchemaManagerImpl(Map<UUID, InternalIgniteTable> tablesById, Map<UUID, IgniteIndex> idxMap) {
this.tablesById = tablesById;
+ this.idxMap = idxMap;
}
@Override
@@ -943,5 +952,17 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
public IgniteTable tableById(UUID id) {
return tablesById.get(id);
}
+
+ @Override
+ public IgniteIndex indexById(UUID id) {
+ return idxMap.get(id);
+ }
+ }
+
+ static class TestIgniteIndex extends IgniteIndex {
+ public TestIgniteIndex(RelCollation collation, String idxName, InternalIgniteTable tbl) {
+ super(collation, new InternalSortedIndexImpl(UUID.randomUUID(), idxName, mock(SortedIndexStorage.class),
+ mock(TableImpl.class)), tbl);
+ }
}
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinColocationPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinColocationPlannerTest.java
index 2dcf2c7b1..6ea122581 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinColocationPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinColocationPlannerTest.java
@@ -35,7 +35,6 @@ import org.apache.ignite.internal.sql.engine.rel.IgniteExchange;
import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteMergeJoin;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
-import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.junit.jupiter.api.Test;
@@ -56,7 +55,7 @@ public class JoinColocationPlannerTest extends AbstractPlannerTest {
"VAL", String.class
);
- tbl.addIndex(new IgniteIndex(RelCollations.of(0), "PK", tbl));
+ tbl.addIndex(new TestIgniteIndex(RelCollations.of(0), "PK", tbl));
IgniteSchema schema = createSchema(tbl);
@@ -89,7 +88,7 @@ public class JoinColocationPlannerTest extends AbstractPlannerTest {
"VAL", String.class
);
- tbl.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", tbl));
+ tbl.addIndex(new TestIgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", tbl));
IgniteSchema schema = createSchema(tbl);
@@ -123,7 +122,7 @@ public class JoinColocationPlannerTest extends AbstractPlannerTest {
"VAL", String.class
);
- complexTbl.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTbl));
+ complexTbl.addIndex(new TestIgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTbl));
TestTable simpleTbl = createTable(
"SIMPLE_TBL",
@@ -133,7 +132,7 @@ public class JoinColocationPlannerTest extends AbstractPlannerTest {
"VAL", String.class
);
- simpleTbl.addIndex(new IgniteIndex(RelCollations.of(0), "PK", simpleTbl));
+ simpleTbl.addIndex(new TestIgniteIndex(RelCollations.of(0), "PK", simpleTbl));
IgniteSchema schema = createSchema(complexTbl, simpleTbl);
@@ -172,7 +171,7 @@ public class JoinColocationPlannerTest extends AbstractPlannerTest {
"VAL", String.class
);
- complexTblDirect.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTblDirect));
+ complexTblDirect.addIndex(new TestIgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTblDirect));
TestTable complexTblIndirect = createTable(
"COMPLEX_TBL_INDIRECT",
@@ -182,7 +181,7 @@ public class JoinColocationPlannerTest extends AbstractPlannerTest {
"VAL", String.class
);
- complexTblIndirect.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTblIndirect));
+ complexTblIndirect.addIndex(new TestIgniteIndex(RelCollations.of(ImmutableIntList.of(0, 1)), "PK", complexTblIndirect));
IgniteSchema schema = createSchema(complexTblDirect, complexTblIndirect);
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTest.java
index ebd9a981c..d518aee7f 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTest.java
@@ -98,7 +98,7 @@ public class PlannerTest extends AbstractPlannerTest {
.build()) {
@Override
public IgniteIndex getIndex(String idxName) {
- return new IgniteIndex(null, (String) null, null);
+ return new TestIgniteIndex(null, (String) null, null);
}
@Override
@@ -756,7 +756,7 @@ public class PlannerTest extends AbstractPlannerTest {
}
};
- emp.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(1, 2)), "emp_idx", emp));
+ emp.addIndex(new TestIgniteIndex(RelCollations.of(ImmutableIntList.of(1, 2)), "emp_idx", emp));
TestTable dept = new TestTable(
new RelDataTypeFactory.Builder(f)
@@ -770,7 +770,7 @@ public class PlannerTest extends AbstractPlannerTest {
}
};
- dept.addIndex(new IgniteIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "dep_idx", dept));
+ dept.addIndex(new TestIgniteIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "dep_idx", dept));
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TableDmlPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TableDmlPlannerTest.java
index 2a85167e3..c1214d2b1 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TableDmlPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TableDmlPlannerTest.java
@@ -31,7 +31,6 @@ import org.apache.calcite.rel.core.Spool;
import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteTableModify;
import org.apache.ignite.internal.sql.engine.rel.IgniteTableScan;
-import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.junit.jupiter.api.Test;
@@ -81,7 +80,7 @@ public class TableDmlPlannerTest extends AbstractPlannerTest {
public void insertCachesIndexScan() throws Exception {
TestTable tbl = createTable("TEST", IgniteDistributions.random(), "VAL", Integer.class);
- tbl.addIndex(new IgniteIndex(RelCollations.of(0), "IDX", tbl));
+ tbl.addIndex(new TestIgniteIndex(RelCollations.of(0), "IDX", tbl));
IgniteSchema schema = createSchema(tbl);
@@ -138,7 +137,7 @@ public class TableDmlPlannerTest extends AbstractPlannerTest {
public void updateNotCachesNonDependentIndexScan() throws Exception {
TestTable tbl = createTable("TEST", IgniteDistributions.random(), "VAL", Integer.class, "IDX_VAL", Integer.class);
- tbl.addIndex(new IgniteIndex(RelCollations.of(1), "IDX", tbl));
+ tbl.addIndex(new TestIgniteIndex(RelCollations.of(1), "IDX", tbl));
IgniteSchema schema = createSchema(tbl);
@@ -164,7 +163,7 @@ public class TableDmlPlannerTest extends AbstractPlannerTest {
public void updateCachesDependentIndexScan() throws Exception {
TestTable tbl = createTable("TEST", IgniteDistributions.random(), "VAL", Integer.class);
- tbl.addIndex(new IgniteIndex(RelCollations.of(0), "IDX", tbl));
+ tbl.addIndex(new TestIgniteIndex(RelCollations.of(0), "IDX", tbl));
IgniteSchema schema = createSchema(tbl);