This is an automated email from the ASF dual-hosted git repository.
mpochatkin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 69e5cf4b66 IGNITE-23185 Add methods to access table and zone
definitions (#4452)
69e5cf4b66 is described below
commit 69e5cf4b662d9aaa8486637126820ab5df605e64
Author: Mikhail <[email protected]>
AuthorDate: Wed Oct 2 17:07:54 2024 +0300
IGNITE-23185 Add methods to access table and zone definitions (#4452)
---
.../org/apache/ignite/catalog/IgniteCatalog.java | 32 ++++
.../catalog/definitions/ColumnDefinition.java | 19 ++
.../catalog/definitions/IndexDefinition.java | 20 ++
.../catalog/definitions/TableDefinition.java | 40 ++++
.../ignite/catalog/definitions/ZoneDefinition.java | 16 ++
.../ignite/internal/catalog/ItCatalogDslTest.java | 84 ++++++++-
.../internal/matcher/ColumnDefinitionsMatcher.java | 62 +++++++
.../internal/matcher/TableDefinitionMatcher.java | 203 +++++++++++++++++++++
.../internal/matcher/ZoneDefinitionMatcher.java | 186 +++++++++++++++++++
.../catalog/sql/CreateFromDefinitionImpl.java | 8 +-
.../internal/catalog/sql/CreateTableImpl.java | 4 +-
.../internal/catalog/sql/CreateZoneImpl.java | 18 +-
.../internal/catalog/sql/IgniteCatalogSqlImpl.java | 85 ++++++++-
.../apache/ignite/internal/catalog/sql/Option.java | 100 ++++++++++
.../ignite/internal/catalog/sql/QueryContext.java | 7 +
.../ignite/internal/catalog/sql/QueryUtils.java | 8 +
.../internal/catalog/sql/SelectFromView.java | 91 +++++++++
.../catalog/sql/TableDefinitionCollector.java | 171 +++++++++++++++++
.../ignite/internal/catalog/sql/WithOption.java | 80 --------
.../ignite/internal/catalog/sql/QueryPartTest.java | 6 +-
.../catalog/CatalogSystemViewRegistry.java | 4 +-
.../systemviews/TablesSystemViewProvider.java | 146 +++++++++++++++
.../systemviews/ZonesSystemViewProvider.java | 51 +++++-
.../ignite/internal/client/TcpIgniteClient.java | 2 +-
.../threading/PublicApiThreadingIgniteCatalog.java | 21 +++
25 files changed, 1348 insertions(+), 116 deletions(-)
diff --git
a/modules/api/src/main/java/org/apache/ignite/catalog/IgniteCatalog.java
b/modules/api/src/main/java/org/apache/ignite/catalog/IgniteCatalog.java
index c4d37d9219..fc46666280 100644
--- a/modules/api/src/main/java/org/apache/ignite/catalog/IgniteCatalog.java
+++ b/modules/api/src/main/java/org/apache/ignite/catalog/IgniteCatalog.java
@@ -191,6 +191,22 @@ public interface IgniteCatalog {
*/
Table createTable(TableDefinition definition);
+ /**
+ * Returns definition of the table with provided name or {@code null} if
table doesn't exist.
+ *
+ * @param tableName Table name.
+ * @return Future with table definition with provided name or {@code null}
if table doesn't exist.
+ */
+ CompletableFuture<TableDefinition> tableDefinitionAsync(String tableName);
+
+ /**
+ * Returns definition of the table with provided name or {@code null} if
table doesn't exist.
+ *
+ * @param tableName Table name.
+ * @return Table definition with provided name.
+ */
+ TableDefinition tableDefinition(String tableName);
+
/**
* Creates a query object from the zone definition.
*
@@ -205,6 +221,22 @@ public interface IgniteCatalog {
*/
void createZone(ZoneDefinition definition);
+ /**
+ * Returns definition of the zone with provided name or {@code null} if
zone doesn't exist.
+ *
+ * @param zoneName Zone name.
+ * @return Future with zone definition with provided name or {@code null}
if zone doesn't exist.
+ */
+ CompletableFuture<ZoneDefinition> zoneDefinitionAsync(String zoneName);
+
+ /**
+ * Returns definition of the zone with provided name or {@code null} if
zone doesn't exist.
+ *
+ * @param zoneName Zone name.
+ * @return Zone definition with provided name.
+ */
+ ZoneDefinition zoneDefinition(String zoneName);
+
/**
* Creates a {@code DROP TABLE} query object from the table definition.
*
diff --git
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ColumnDefinition.java
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ColumnDefinition.java
index af32f8dd92..f42bbf3960 100644
---
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ColumnDefinition.java
+++
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ColumnDefinition.java
@@ -100,4 +100,23 @@ public class ColumnDefinition {
public @Nullable String definition() {
return definition;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ColumnDefinition that = (ColumnDefinition) o;
+ return Objects.equals(name, that.name)
+ && Objects.equals(type, that.type)
+ && Objects.equals(definition, that.definition);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, type, definition);
+ }
}
diff --git
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/IndexDefinition.java
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/IndexDefinition.java
index bc8f6d9fc5..6b0647fa33 100644
---
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/IndexDefinition.java
+++
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/IndexDefinition.java
@@ -18,6 +18,7 @@
package org.apache.ignite.catalog.definitions;
import java.util.List;
+import java.util.Objects;
import org.apache.ignite.catalog.ColumnSorted;
import org.apache.ignite.catalog.IndexType;
import org.jetbrains.annotations.Nullable;
@@ -65,4 +66,23 @@ public class IndexDefinition {
public List<ColumnSorted> columns() {
return columns;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ IndexDefinition that = (IndexDefinition) o;
+ return Objects.equals(name, that.name)
+ && type == that.type
+ && Objects.equals(columns, that.columns);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, type, columns);
+ }
}
diff --git
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/TableDefinition.java
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/TableDefinition.java
index fdbccc4726..e6c0fabf50 100644
---
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/TableDefinition.java
+++
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/TableDefinition.java
@@ -206,6 +206,46 @@ public class TableDefinition {
return new Builder(this);
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ TableDefinition that = (TableDefinition) o;
+ return ifNotExists == that.ifNotExists
+ && Objects.equals(tableName, that.tableName)
+ && Objects.equals(schemaName, that.schemaName)
+ && Objects.equals(columns, that.columns)
+ && pkType == that.pkType
+ && Objects.equals(pkColumns, that.pkColumns)
+ && Objects.equals(colocationColumns, that.colocationColumns)
+ && Objects.equals(zoneName, that.zoneName)
+ && Objects.equals(keyClass, that.keyClass)
+ && Objects.equals(valueClass, that.valueClass)
+ && Objects.equals(indexes, that.indexes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ tableName,
+ schemaName,
+ ifNotExists,
+ columns,
+ pkType,
+ pkColumns,
+ colocationColumns,
+ zoneName,
+ keyClass,
+ valueClass,
+ indexes
+ );
+ }
+
/**
* Builder for the table definition.
*/
diff --git
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ZoneDefinition.java
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ZoneDefinition.java
index ded14aea11..605f4c2918 100644
---
a/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ZoneDefinition.java
+++
b/modules/api/src/main/java/org/apache/ignite/catalog/definitions/ZoneDefinition.java
@@ -176,6 +176,22 @@ public class ZoneDefinition {
return new Builder(this);
}
+ @Override
+ public String toString() {
+ return "ZoneDefinition{"
+ + "zoneName='" + zoneName + '\''
+ + ", ifNotExists=" + ifNotExists
+ + ", partitions=" + partitions
+ + ", replicas=" + replicas
+ + ", distributionAlgorithm='" + distributionAlgorithm + '\''
+ + ", dataNodesAutoAdjust=" + dataNodesAutoAdjust
+ + ", dataNodesAutoAdjustScaleUp=" + dataNodesAutoAdjustScaleUp
+ + ", dataNodesAutoAdjustScaleDown=" +
dataNodesAutoAdjustScaleDown
+ + ", filter='" + filter + '\''
+ + ", storageProfiles='" + storageProfiles + '\''
+ + '}';
+ }
+
/**
* Builder for the zone definition.
*/
diff --git
a/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/catalog/ItCatalogDslTest.java
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/catalog/ItCatalogDslTest.java
index d786d9d680..7d4ecd89e3 100644
---
a/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/catalog/ItCatalogDslTest.java
+++
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/catalog/ItCatalogDslTest.java
@@ -31,25 +31,31 @@ import static org.hamcrest.Matchers.nullValue;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.catalog.ColumnSorted;
import org.apache.ignite.catalog.ColumnType;
import org.apache.ignite.catalog.IgniteCatalog;
+import org.apache.ignite.catalog.IndexType;
+import org.apache.ignite.catalog.definitions.ColumnDefinition;
import org.apache.ignite.catalog.definitions.TableDefinition;
import org.apache.ignite.catalog.definitions.ZoneDefinition;
import org.apache.ignite.internal.ClusterPerClassIntegrationTest;
+import org.apache.ignite.internal.matcher.TableDefinitionMatcher;
+import org.apache.ignite.internal.matcher.ZoneDefinitionMatcher;
import org.apache.ignite.sql.SqlException;
import org.apache.ignite.table.KeyValueView;
import org.apache.ignite.table.RecordView;
+import org.apache.ignite.table.Table;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@SuppressWarnings("ThrowableNotThrown")
class ItCatalogDslTest extends ClusterPerClassIntegrationTest {
- static final String POJO_KV_TABLE_NAME = "pojo_kv_test";
+ static final String POJO_KV_TABLE_NAME = "POJO_KV_TEST";
static final String POJO_RECORD_TABLE_NAME = "pojo_record_test";
- static final String ZONE_NAME = "zone_test";
+ static final String ZONE_NAME = "ZONE_TEST";
private static final int KEY = 1;
@@ -190,7 +196,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
@Test
void primitiveKeyKvViewFromAnnotation() throws Exception {
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(Integer.class, PojoValue.class);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(Integer.class, PojoValue.class);
assertThat(tableFuture, will(not(nullValue())));
KeyValueView<Integer, PojoValue> keyValueView = tableFuture.get()
@@ -202,7 +208,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
@Test
void pojoKeyKvViewFromAnnotation() throws Exception {
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(PojoKey.class, PojoValue.class);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(PojoKey.class, PojoValue.class);
assertThat(tableFuture, will(not(nullValue())));
KeyValueView<PojoKey, PojoValue> keyValueView = tableFuture.get()
@@ -219,7 +225,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
.value(PojoValue.class)
.build();
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(definition);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(definition);
assertThat(tableFuture, will(not(nullValue())));
KeyValueView<Integer, PojoValue> keyValueView =
tableFuture.get().keyValueView(Integer.class, PojoValue.class);
@@ -235,7 +241,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
.value(PojoValue.class)
.build();
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(definition);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(definition);
assertThat(tableFuture, will(not(nullValue())));
KeyValueView<PojoKey, PojoValue> keyValueView =
tableFuture.get().keyValueView(PojoKey.class, PojoValue.class);
@@ -246,7 +252,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
@Test
void pojoRecordViewFromAnnotation() throws Exception {
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(Pojo.class);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(Pojo.class);
assertThat(tableFuture, will(not(nullValue())));
RecordView<Pojo> recordView = tableFuture.get().recordView(Pojo.class);
@@ -259,7 +265,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
void pojoRecordViewFromDefinition() throws Exception {
TableDefinition definition =
TableDefinition.builder(POJO_RECORD_TABLE_NAME).record(Pojo.class).build();
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(definition);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(definition);
assertThat(tableFuture, will(not(nullValue())));
RecordView<Pojo> recordView = tableFuture.get().recordView(Pojo.class);
@@ -270,7 +276,7 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
@Test
void createFromAnnotationAndInsertBySql() throws Exception {
- CompletableFuture<org.apache.ignite.table.Table> tableFuture =
catalog().createTableAsync(Pojo.class);
+ CompletableFuture<Table> tableFuture =
catalog().createTableAsync(Pojo.class);
assertThat(tableFuture, will(not(nullValue())));
sql("insert into " + POJO_RECORD_TABLE_NAME + " (id, id_str, f_name,
l_name, str) values (1, '1', 'f', 'l', 's')");
@@ -282,6 +288,66 @@ class ItCatalogDslTest extends
ClusterPerClassIntegrationTest {
assertThat(tableFuture.get().recordView(Pojo.class).get(null, pojo),
is(pojo));
}
+ @Test
+ public void createAndGetDefinitionTest() {
+ ZoneDefinition zoneDefinition = ZoneDefinition
+ .builder(ZONE_NAME)
+ .storageProfiles(DEFAULT_AIPERSIST_PROFILE_NAME)
+ .partitions(3)
+ .replicas(3)
+ .dataNodesAutoAdjustScaleDown(0)
+ .dataNodesAutoAdjustScaleUp(1)
+ .filter("$..*")
+ .distributionAlgorithm("distributionAlgorithm")
+ .build();
+
+ assertThat(catalog().createZoneAsync(zoneDefinition),
willCompleteSuccessfully());
+
+ ZoneDefinition actual = catalog().zoneDefinition(ZONE_NAME);
+ assertThat(
+ actual,
+ ZoneDefinitionMatcher.isZoneDefinition()
+ .withZoneName(zoneDefinition.zoneName())
+ .withPartitions(zoneDefinition.partitions())
+ .withReplicas(zoneDefinition.replicas())
+
.withDataNodesAutoAdjustScaleDown(zoneDefinition.dataNodesAutoAdjustScaleDown())
+
.withDataNodesAutoAdjustScaleUp(zoneDefinition.dataNodesAutoAdjustScaleUp())
+ .withFilter(zoneDefinition.filter())
+ // TODO: https://issues.apache.org/jira/browse/IGNITE-22162
+ // .withDistributionAlgorithm(zoneDefinition.distributionAlgorithm())
+ );
+
+ ColumnDefinition column1 = column("COL1", ColumnType.INT32);
+ ColumnDefinition column2 = column("COL2", ColumnType.INT64);
+ ColumnDefinition column3 = column("COL3", ColumnType.BOOLEAN);
+ ColumnDefinition column4 = column("COL4", ColumnType.VARCHAR);
+ ColumnDefinition column5 = column("COL5", ColumnType.DECIMAL);
+
+
+ TableDefinition definition =
TableDefinition.builder(POJO_KV_TABLE_NAME)
+ .zone(ZONE_NAME)
+ .columns(List.of(column1, column2, column3, column4, column5))
+ .primaryKey(IndexType.HASH,
ColumnSorted.column(column1.name()), ColumnSorted.column(column3.name()))
+ .index("INDEX_1", IndexType.HASH,
ColumnSorted.column(column2.name()), ColumnSorted.column(column5.name()))
+ .colocateBy(column3.name())
+ .build();
+
+ assertThat(catalog().createTableAsync(definition),
willCompleteSuccessfully());
+
+ TableDefinition actual1 =
catalog().tableDefinition(POJO_KV_TABLE_NAME);
+ assertThat(
+ actual1,
+ TableDefinitionMatcher.isTableDefinition()
+ .withTableName(definition.tableName())
+ .withZoneName(definition.zoneName())
+ .withColumns(definition.columns())
+ .withPkType(definition.primaryKeyType())
+ .withPkColumns(definition.primaryKeyColumns())
+ .withIndexes(definition.indexes())
+ .withColocationColumns(definition.colocationColumns())
+ );
+ }
+
private static IgniteCatalog catalog() {
return CLUSTER.node(0).catalog();
}
diff --git
a/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/ColumnDefinitionsMatcher.java
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/ColumnDefinitionsMatcher.java
new file mode 100644
index 0000000000..3819ef80e1
--- /dev/null
+++
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/ColumnDefinitionsMatcher.java
@@ -0,0 +1,62 @@
+/*
+ * 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.matcher;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.apache.ignite.catalog.ColumnType;
+import org.apache.ignite.catalog.definitions.ColumnDefinition;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matcher implementation of {@link ColumnDefinition}.
+ */
+public class ColumnDefinitionsMatcher extends
TypeSafeMatcher<List<ColumnDefinition>> {
+
+ private final Map<String, ColumnDefinition> columns;
+
+ public ColumnDefinitionsMatcher(List<ColumnDefinition> columns) {
+ this.columns =
columns.stream().collect(Collectors.toMap(ColumnDefinition::name,
Function.identity()));
+ }
+
+ @Override
+ protected boolean matchesSafely(List<ColumnDefinition> item) {
+ for (ColumnDefinition actualCol : item) {
+ ColumnDefinition expectedCol = columns.get(actualCol.name());
+ if (expectedCol == null) {
+ return false;
+ }
+
+ ColumnType<?> actualType = actualCol.type();
+ ColumnType<?> expectedType = expectedCol.type();
+ if (expectedType != null && actualType != null &&
expectedType.type() != actualType.type()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+
+ }
+}
diff --git
a/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/TableDefinitionMatcher.java
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/TableDefinitionMatcher.java
new file mode 100644
index 0000000000..a55d290a6b
--- /dev/null
+++
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/TableDefinitionMatcher.java
@@ -0,0 +1,203 @@
+/*
+ * 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.matcher;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.equalToIgnoringCase;
+
+import java.util.List;
+import org.apache.ignite.catalog.ColumnSorted;
+import org.apache.ignite.catalog.IndexType;
+import org.apache.ignite.catalog.definitions.ColumnDefinition;
+import org.apache.ignite.catalog.definitions.IndexDefinition;
+import org.apache.ignite.catalog.definitions.TableDefinition;
+import org.apache.ignite.internal.testframework.matchers.AnythingMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matcher implementation for {@link TableDefinition}.
+ */
+public class TableDefinitionMatcher extends TypeSafeMatcher<TableDefinition> {
+ private Matcher<String> tableNameMatcher = AnythingMatcher.anything();
+
+ private Matcher<String> schemaNameMatcher = AnythingMatcher.anything();
+
+ private Matcher<Boolean> ifNotExistsMatcher = AnythingMatcher.anything();
+
+ private Matcher<List<ColumnDefinition>> columnsMatcher =
AnythingMatcher.anything();
+
+ private Matcher<IndexType> pkTypeMatcher = AnythingMatcher.anything();
+
+ private Matcher<List<ColumnSorted>> pkColumnsMatcher =
AnythingMatcher.anything();
+
+ private Matcher<List<String>> colocationColumnsMatcher =
AnythingMatcher.anything();
+
+ private Matcher<String> zoneNameMatcher = AnythingMatcher.anything();
+
+ private Matcher<Class<?>> keyClassMatcher = AnythingMatcher.anything();
+
+ private Matcher<Class<?>> valueClassMatcher = AnythingMatcher.anything();
+
+ private Matcher<List<IndexDefinition>> indexesMatcher =
AnythingMatcher.anything();
+
+ public TableDefinitionMatcher withTableNameMatcher(Matcher<String>
tableNameMatcher) {
+ this.tableNameMatcher = tableNameMatcher;
+ return this;
+ }
+
+ public TableDefinitionMatcher withTableName(String tableName) {
+ return withTableNameMatcher(equalToIgnoringCase(tableName));
+ }
+
+ public TableDefinitionMatcher withSchemaNameMatcher(Matcher<String>
schemaNameMatcher) {
+ this.schemaNameMatcher = schemaNameMatcher;
+ return this;
+ }
+
+ public TableDefinitionMatcher withSchemaName(String schemaName) {
+ return withSchemaNameMatcher(equalToIgnoringCase(schemaName));
+ }
+
+ public TableDefinitionMatcher withIfNotExistsMatcher(Matcher<Boolean>
ifNotExists) {
+ this.ifNotExistsMatcher = ifNotExists;
+ return this;
+ }
+
+ public TableDefinitionMatcher withIfNotExists(boolean ifNotExists) {
+ return withIfNotExistsMatcher(equalTo(ifNotExists));
+ }
+
+ public TableDefinitionMatcher
withColumnsMatcher(Matcher<List<ColumnDefinition>> columns) {
+ this.columnsMatcher = columns;
+ return this;
+ }
+
+ public TableDefinitionMatcher withColumns(List<ColumnDefinition> columns) {
+ return withColumnsMatcher(new ColumnDefinitionsMatcher(columns));
+ }
+
+ public TableDefinitionMatcher withPkTypeMatcher(Matcher<IndexType> pkType)
{
+ this.pkTypeMatcher = pkType;
+ return this;
+ }
+
+ public TableDefinitionMatcher withPkType(IndexType pkType) {
+ return withPkTypeMatcher(equalTo(pkType));
+ }
+
+ public TableDefinitionMatcher
withPkColumnsMatcher(Matcher<List<ColumnSorted>> pkColumns) {
+ this.pkColumnsMatcher = pkColumns;
+ return this;
+ }
+
+ public TableDefinitionMatcher withPkColumns(List<ColumnSorted> pkColumns) {
+ return withPkColumnsMatcher(equalTo(pkColumns));
+ }
+
+ public TableDefinitionMatcher
withColocationColumnsMatcher(Matcher<List<String>> colocationColumns) {
+ this.colocationColumnsMatcher = colocationColumns;
+ return this;
+ }
+
+ public TableDefinitionMatcher withColocationColumns(List<String>
colocationColumns) {
+ return withColocationColumnsMatcher(equalTo(colocationColumns));
+ }
+
+ public TableDefinitionMatcher withZoneNameMatcher(Matcher<String>
zoneName) {
+ this.zoneNameMatcher = zoneName;
+ return this;
+ }
+
+ public TableDefinitionMatcher withZoneName(String zoneName) {
+ return withZoneNameMatcher(equalTo(zoneName));
+ }
+
+ public TableDefinitionMatcher withKeyClassMatcher(Matcher<Class<?>>
keyClass) {
+ this.keyClassMatcher = keyClass;
+ return this;
+ }
+
+ public TableDefinitionMatcher withKeyClass(Class<?> keyClass) {
+ return withKeyClassMatcher(equalTo(keyClass));
+ }
+
+ public TableDefinitionMatcher withValueClassMatcher(Matcher<Class<?>>
valueClass) {
+ this.valueClassMatcher = valueClass;
+ return this;
+ }
+
+ public TableDefinitionMatcher withValueClass(Class<?> valueClass) {
+ return withValueClassMatcher(equalTo(valueClass));
+ }
+
+ public TableDefinitionMatcher
withIndexesMatcher(Matcher<List<IndexDefinition>> indexes) {
+ this.indexesMatcher = indexes;
+ return this;
+ }
+
+ public TableDefinitionMatcher withIndexes(List<IndexDefinition> indexes) {
+ return withIndexesMatcher(equalTo(indexes));
+ }
+
+ public static TableDefinitionMatcher isTableDefinition() {
+ return new TableDefinitionMatcher();
+ }
+
+ @Override
+ protected boolean matchesSafely(TableDefinition tableDefinition) {
+ return tableNameMatcher.matches(tableDefinition.tableName())
+ && schemaNameMatcher.matches(tableDefinition.schemaName())
+ && ifNotExistsMatcher.matches(tableDefinition.ifNotExists())
+ && columnsMatcher.matches(tableDefinition.columns())
+ && pkTypeMatcher.matches(tableDefinition.primaryKeyType())
+ &&
pkColumnsMatcher.matches(tableDefinition.primaryKeyColumns())
+ &&
colocationColumnsMatcher.matches(tableDefinition.colocationColumns())
+ && zoneNameMatcher.matches(tableDefinition.zoneName())
+ && keyClassMatcher.matches(tableDefinition.keyClass())
+ && valueClassMatcher.matches(tableDefinition.valueClass())
+ && indexesMatcher.matches(tableDefinition.indexes());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Table definition with ")
+ .appendText("table name
").appendDescriptionOf(tableNameMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("schema name
").appendDescriptionOf(schemaNameMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("if not exists
").appendDescriptionOf(ifNotExistsMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("columns ").appendDescriptionOf(columnsMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("pk type ").appendDescriptionOf(pkTypeMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("pk columns
").appendDescriptionOf(pkColumnsMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("colocation columns
").appendDescriptionOf(columnsMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("zone name ").appendDescriptionOf(zoneNameMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("key class ").appendDescriptionOf(keyClassMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("value class
").appendDescriptionOf(valueClassMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("indexes ").appendDescriptionOf(indexesMatcher);
+ }
+}
diff --git
a/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/ZoneDefinitionMatcher.java
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/ZoneDefinitionMatcher.java
new file mode 100644
index 0000000000..d8003438a6
--- /dev/null
+++
b/modules/catalog-dsl/src/integrationTest/java/org/apache/ignite/internal/matcher/ZoneDefinitionMatcher.java
@@ -0,0 +1,186 @@
+/*
+ * 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.matcher;
+
+import static org.hamcrest.Matchers.equalTo;
+
+import org.apache.ignite.catalog.definitions.ZoneDefinition;
+import org.apache.ignite.internal.testframework.matchers.AnythingMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matcher implementation for {@link ZoneDefinition}.
+ */
+public class ZoneDefinitionMatcher extends TypeSafeMatcher<ZoneDefinition> {
+ private Matcher<String> zoneNameMatcher = AnythingMatcher.anything();
+
+ private Matcher<Boolean> ifNotExistsMatcher = AnythingMatcher.anything();
+
+ private Matcher<Integer> partitionsMatcher = AnythingMatcher.anything();
+
+ private Matcher<Integer> replicasMatcher = AnythingMatcher.anything();
+
+ private Matcher<String> distributionAlgorithmMatcher =
AnythingMatcher.anything();
+
+ private Matcher<Integer> dataNodesAutoAdjustMatcher =
AnythingMatcher.anything();
+
+ private Matcher<Integer> dataNodesAutoAdjustScaleUpMatcher =
AnythingMatcher.anything();
+
+ private Matcher<Integer> dataNodesAutoAdjustScaleDownMatcher =
AnythingMatcher.anything();
+
+ private Matcher<String> filterMatcher = AnythingMatcher.anything();
+
+ private Matcher<String> storageProfiles = AnythingMatcher.anything();
+
+ public ZoneDefinitionMatcher withZoneNameMatcher(Matcher<String>
zoneNameMatcher) {
+ this.zoneNameMatcher = zoneNameMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withZoneName(String zoneName) {
+ return withZoneNameMatcher(equalTo(zoneName));
+ }
+
+ public ZoneDefinitionMatcher withIfNotExistsMatcher(Matcher<Boolean>
ifNotExistsMatcher) {
+ this.ifNotExistsMatcher = ifNotExistsMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withIfNotExists(boolean ifNotExists) {
+ return withIfNotExistsMatcher(equalTo(ifNotExists));
+ }
+
+ public ZoneDefinitionMatcher withPartitionsMatcher(Matcher<Integer>
partitionsMatcher) {
+ this.partitionsMatcher = partitionsMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withPartitions(int partitions) {
+ return withPartitionsMatcher(equalTo(partitions));
+ }
+
+ public ZoneDefinitionMatcher withReplicasMatcher(Matcher<Integer>
replicasMatcher) {
+ this.replicasMatcher = replicasMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withReplicas(int replicas) {
+ return withReplicasMatcher(equalTo(replicas));
+ }
+
+ public ZoneDefinitionMatcher
withDistributionAlgorithmMatcher(Matcher<String>
withDistributionAlgorithmMatcher) {
+ this.distributionAlgorithmMatcher = withDistributionAlgorithmMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withDistributionAlgorithm(String
distributionAlgorithm) {
+ return
withDistributionAlgorithmMatcher(equalTo(distributionAlgorithm));
+ }
+
+ public ZoneDefinitionMatcher
withDataNodesAutoAdjustMatcher(Matcher<Integer> dataNodesAutoAdjustMatcher) {
+ this.dataNodesAutoAdjustMatcher = dataNodesAutoAdjustMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withDataNodesAutoAdjust(int
dataNodesAutoAdjust) {
+ return withDataNodesAutoAdjustMatcher(equalTo(dataNodesAutoAdjust));
+ }
+
+ public ZoneDefinitionMatcher withDataNodesAutoAdjustScaleUpMatcher(
+ Matcher<Integer> dataNodesAutoAdjustScaleUpMatcher) {
+ this.dataNodesAutoAdjustScaleUpMatcher =
dataNodesAutoAdjustScaleUpMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withDataNodesAutoAdjustScaleUp(int
dataNodesAutoAdjustScaleUp) {
+ return
withDataNodesAutoAdjustScaleUpMatcher(equalTo(dataNodesAutoAdjustScaleUp));
+ }
+
+ public ZoneDefinitionMatcher withDataNodesAutoAdjustScaleDownMatcher(
+ Matcher<Integer> dataNodesAutoAdjustScaleDownMatcher) {
+ this.dataNodesAutoAdjustScaleDownMatcher =
dataNodesAutoAdjustScaleDownMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withDataNodesAutoAdjustScaleDown(int
dataNodesAutoAdjustScaleDown) {
+ return
withDataNodesAutoAdjustScaleDownMatcher(equalTo(dataNodesAutoAdjustScaleDown));
+ }
+
+ public ZoneDefinitionMatcher withFilterMatcher(Matcher<String>
filterMatcher) {
+ this.filterMatcher = filterMatcher;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withFilter(String filter) {
+ return withFilterMatcher(equalTo(filter));
+ }
+
+ public ZoneDefinitionMatcher withStorageProfilesMatcher(Matcher<String>
storageProfiles) {
+ this.storageProfiles = storageProfiles;
+ return this;
+ }
+
+ public ZoneDefinitionMatcher withStorageProfiles(String storageProfiles) {
+ return withStorageProfilesMatcher(equalTo(storageProfiles));
+ }
+
+ public static ZoneDefinitionMatcher isZoneDefinition() {
+ return new ZoneDefinitionMatcher();
+ }
+
+ @Override
+ protected boolean matchesSafely(ZoneDefinition zoneDefinition) {
+ return zoneNameMatcher.matches(zoneDefinition.zoneName())
+ && ifNotExistsMatcher.matches(zoneDefinition.ifNotExists())
+ && partitionsMatcher.matches(zoneDefinition.partitions())
+ && replicasMatcher.matches(zoneDefinition.replicas())
+ &&
distributionAlgorithmMatcher.matches(zoneDefinition.distributionAlgorithm())
+ &&
dataNodesAutoAdjustMatcher.matches(zoneDefinition.dataNodesAutoAdjust())
+ && zoneNameMatcher.matches(zoneDefinition.zoneName())
+ &&
dataNodesAutoAdjustScaleUpMatcher.matches(zoneDefinition.dataNodesAutoAdjustScaleUp())
+ &&
dataNodesAutoAdjustScaleDownMatcher.matches(zoneDefinition.dataNodesAutoAdjustScaleDown())
+ && filterMatcher.matches(zoneDefinition.filter())
+ && storageProfiles.matches(zoneDefinition.storageProfiles());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Zone definition with ")
+ .appendText("zone name ").appendDescriptionOf(zoneNameMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("if not exists
").appendDescriptionOf(ifNotExistsMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("partitions
").appendDescriptionOf(partitionsMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("replicas ").appendDescriptionOf(replicasMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("affinity
").appendDescriptionOf(distributionAlgorithmMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("data nodes auto adjust
").appendDescriptionOf(dataNodesAutoAdjustMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("data nodes auto adjust scale up
").appendDescriptionOf(dataNodesAutoAdjustScaleUpMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("data nodes auto adjust scale down
").appendDescriptionOf(dataNodesAutoAdjustScaleDownMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("filter ").appendDescriptionOf(filterMatcher)
+ .appendText(System.lineSeparator())
+ .appendText("storage profiles
").appendDescriptionOf(storageProfiles);
+ }
+}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateFromDefinitionImpl.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateFromDefinitionImpl.java
index c5dc84dc6a..7fb190cbdb 100644
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateFromDefinitionImpl.java
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateFromDefinitionImpl.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.catalog.sql;
import static
org.apache.ignite.internal.catalog.sql.CreateFromAnnotationsImpl.processColumns;
+import static
org.apache.ignite.internal.catalog.sql.QueryUtils.isGreaterThanOrEqualToZero;
import static
org.apache.ignite.internal.catalog.sql.QueryUtils.isGreaterThanZero;
import java.util.ArrayList;
@@ -70,20 +71,19 @@ class CreateFromDefinitionImpl extends
AbstractCatalogQuery<TableZoneId> {
createZone.distributionAlgorithm(def.distributionAlgorithm());
}
- if (isGreaterThanZero(def.dataNodesAutoAdjust())) {
+ if (isGreaterThanOrEqualToZero(def.dataNodesAutoAdjust())) {
createZone.dataNodesAutoAdjust(def.dataNodesAutoAdjust());
}
- if (isGreaterThanZero(def.dataNodesAutoAdjustScaleUp())) {
+ if (isGreaterThanOrEqualToZero(def.dataNodesAutoAdjustScaleUp())) {
createZone.dataNodesAutoAdjustScaleUp(def.dataNodesAutoAdjustScaleUp());
}
- if (isGreaterThanZero(def.dataNodesAutoAdjustScaleDown())) {
+ if (isGreaterThanOrEqualToZero(def.dataNodesAutoAdjustScaleDown())) {
createZone.dataNodesAutoAdjustScaleDown(def.dataNodesAutoAdjustScaleDown());
}
if (!StringUtils.nullOrBlank(def.filter())) {
createZone.filter(def.filter());
}
-
return this;
}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateTableImpl.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateTableImpl.java
index db92258fc1..d29159e8b6 100644
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateTableImpl.java
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateTableImpl.java
@@ -38,7 +38,7 @@ class CreateTableImpl extends AbstractCatalogQuery<Name> {
private final List<Constraint> constraints = new ArrayList<>();
- private final List<WithOption> withOptions = new ArrayList<>();
+ private final List<Option> withOptions = new ArrayList<>();
private Colocate colocate;
@@ -119,7 +119,7 @@ class CreateTableImpl extends AbstractCatalogQuery<Name> {
CreateTableImpl zone(String zone) {
Objects.requireNonNull(zone, "Zone name must not be null.");
- withOptions.add(WithOption.primaryZone(zone));
+ withOptions.add(Option.primaryZone(zone));
return this;
}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateZoneImpl.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateZoneImpl.java
index dc426c4942..1a35774b4b 100644
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateZoneImpl.java
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/CreateZoneImpl.java
@@ -29,7 +29,7 @@ class CreateZoneImpl extends AbstractCatalogQuery<Name> {
private boolean ifNotExists;
- private final List<WithOption> withOptions = new ArrayList<>();
+ private final List<Option> withOptions = new ArrayList<>();
/**
* Constructor for internal usage.
@@ -60,21 +60,21 @@ class CreateZoneImpl extends AbstractCatalogQuery<Name> {
CreateZoneImpl replicas(Integer n) {
Objects.requireNonNull(n, "Replicas count must not be null.");
- withOptions.add(WithOption.replicas(n));
+ withOptions.add(Option.replicas(n));
return this;
}
CreateZoneImpl partitions(Integer n) {
Objects.requireNonNull(n, "Partitions must not be null.");
- withOptions.add(WithOption.partitions(n));
+ withOptions.add(Option.partitions(n));
return this;
}
CreateZoneImpl distributionAlgorithm(String distributionAlgorithm) {
Objects.requireNonNull(distributionAlgorithm, "Partition distribution
algorithm must not be null.");
-
withOptions.add(WithOption.distributionAlgorithm(distributionAlgorithm));
+ withOptions.add(Option.distributionAlgorithm(distributionAlgorithm));
return this;
}
@@ -84,35 +84,35 @@ class CreateZoneImpl extends AbstractCatalogQuery<Name> {
"Timeout between node added or node left topology event itself
and data nodes switch must not be null."
);
- withOptions.add(WithOption.dataNodesAutoAdjust(adjust));
+ withOptions.add(Option.dataNodesAutoAdjust(adjust));
return this;
}
CreateZoneImpl dataNodesAutoAdjustScaleUp(Integer adjust) {
Objects.requireNonNull(adjust, "Timeout between node added topology
event itself and data nodes switch must not be null.");
- withOptions.add(WithOption.dataNodesAutoAdjustScaleUp(adjust));
+ withOptions.add(Option.dataNodesAutoAdjustScaleUp(adjust));
return this;
}
CreateZoneImpl dataNodesAutoAdjustScaleDown(Integer adjust) {
Objects.requireNonNull(adjust, "Timeout between node left topology
event itself and data nodes switch must not be null.");
- withOptions.add(WithOption.dataNodesAutoAdjustScaleDown(adjust));
+ withOptions.add(Option.dataNodesAutoAdjustScaleDown(adjust));
return this;
}
CreateZoneImpl filter(String filter) {
Objects.requireNonNull(filter, "Filter must not be null.");
- withOptions.add(WithOption.filter(filter));
+ withOptions.add(Option.filter(filter));
return this;
}
CreateZoneImpl storageProfiles(String storageProfiles) {
Objects.requireNonNull(storageProfiles, "Storage profiles must not be
null");
- withOptions.add(WithOption.storageProfiles(storageProfiles));
+ withOptions.add(Option.storageProfiles(storageProfiles));
return this;
}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/IgniteCatalogSqlImpl.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/IgniteCatalogSqlImpl.java
index 1ee2c4a170..c749203cbc 100644
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/IgniteCatalogSqlImpl.java
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/IgniteCatalogSqlImpl.java
@@ -17,16 +17,20 @@
package org.apache.ignite.internal.catalog.sql;
+import static org.apache.ignite.internal.catalog.sql.Option.name;
import static
org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.mapToPublicException;
import static org.apache.ignite.internal.util.ExceptionUtils.unwrapCause;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import org.apache.ignite.catalog.IgniteCatalog;
import org.apache.ignite.catalog.definitions.TableDefinition;
import org.apache.ignite.catalog.definitions.ZoneDefinition;
+import org.apache.ignite.internal.util.CompletableFutures;
import org.apache.ignite.internal.util.ExceptionUtils;
import org.apache.ignite.sql.IgniteSql;
+import org.apache.ignite.sql.SqlRow;
import org.apache.ignite.table.IgniteTables;
import org.apache.ignite.table.Table;
@@ -82,12 +86,29 @@ public class IgniteCatalogSqlImpl implements IgniteCatalog {
return join(createTableAsync(definition));
}
+ @Override
+ public CompletableFuture<TableDefinition> tableDefinitionAsync(String
tableName) {
+ TableDefinitionCollector collector = new
TableDefinitionCollector(tableName, sql);
+
+ return collector.collectDefinition().thenApply(builder -> {
+ if (builder != null) {
+ return builder.build();
+ }
+ return null;
+ });
+ }
+
+ @Override
+ public TableDefinition tableDefinition(String tableName) {
+ return join(tableDefinitionAsync(tableName));
+ }
+
@Override
public CompletableFuture<Void> createZoneAsync(ZoneDefinition definition) {
return new CreateFromDefinitionImpl(sql)
.from(definition)
.executeAsync()
- .thenRun(() -> {});
+ .thenApply(unused -> null);
}
@Override
@@ -95,13 +116,52 @@ public class IgniteCatalogSqlImpl implements IgniteCatalog
{
join(createZoneAsync(definition));
}
+ @Override
+ public CompletableFuture<ZoneDefinition> zoneDefinitionAsync(String
zoneName) {
+ List<String> zoneViewColumns = List.of(
+ "PARTITIONS",
+ "REPLICAS",
+ "DATA_NODES_AUTO_ADJUST_SCALE_UP",
+ "DATA_NODES_AUTO_ADJUST_SCALE_DOWN",
+ "DATA_NODES_FILTER"
+ );
+ return new SelectFromView<>(sql, zoneViewColumns, "ZONES",
name(zoneName), row -> toZoneDefinitionBuilder(zoneName, row))
+ .executeAsync()
+ .thenApply(zoneDefinitions -> {
+ if (zoneDefinitions.isEmpty()) {
+ return null;
+ }
+ assert zoneDefinitions.size() == 1;
+
+ return zoneDefinitions.get(0);
+ })
+ .thenCompose(
+ zoneDefinition -> {
+ if (zoneDefinition == null) {
+ return
CompletableFutures.nullCompletedFuture();
+ }
+ return new SelectFromView<>(sql,
+ List.of("STORAGE_PROFILE"),
+ "ZONE_STORAGE_PROFILES",
+ Option.zoneName(zoneName),
+ row -> row.stringValue("STORAGE_PROFILE")
+ ).executeAsync()
+ .thenApply(profiles ->
zoneDefinition.storageProfiles(String.join(", ", profiles)).build());
+ });
+ }
+
+ @Override
+ public ZoneDefinition zoneDefinition(String zoneName) {
+ return join(zoneDefinitionAsync(zoneName));
+ }
+
@Override
public CompletableFuture<Void> dropTableAsync(TableDefinition definition) {
return new DropTableImpl(sql)
.name(definition.schemaName(), definition.tableName())
.ifExists()
.executeAsync()
- .thenRun(() -> {});
+ .thenApply(unused -> null);
}
@Override
@@ -110,7 +170,7 @@ public class IgniteCatalogSqlImpl implements IgniteCatalog {
.name(name)
.ifExists()
.executeAsync()
- .thenRun(() -> {});
+ .thenApply(unused -> null);
}
@Override
@@ -129,7 +189,7 @@ public class IgniteCatalogSqlImpl implements IgniteCatalog {
.name(definition.zoneName())
.ifExists()
.executeAsync()
- .thenRun(() -> {});
+ .thenApply(unused -> null);
}
@Override
@@ -138,7 +198,7 @@ public class IgniteCatalogSqlImpl implements IgniteCatalog {
.name(name)
.ifExists()
.executeAsync()
- .thenRun(() -> {});
+ .thenApply(unused -> null);
}
@Override
@@ -151,6 +211,21 @@ public class IgniteCatalogSqlImpl implements IgniteCatalog
{
join(dropZoneAsync(name));
}
+ private static ZoneDefinition.Builder toZoneDefinitionBuilder(String
zoneName, SqlRow row) {
+ int partitions = row.intValue("PARTITIONS");
+ int replicas = row.intValue("REPLICAS");
+ int dataNodesAutoAdjustScaleUp =
row.intValue("DATA_NODES_AUTO_ADJUST_SCALE_UP");
+ int dataNodesAutoAdjustScaleDown =
row.intValue("DATA_NODES_AUTO_ADJUST_SCALE_DOWN");
+ String filter = row.stringValue("DATA_NODES_FILTER");
+
+ return ZoneDefinition.builder(zoneName)
+ .partitions(partitions)
+ .replicas(replicas)
+ .dataNodesAutoAdjustScaleUp(dataNodesAutoAdjustScaleUp)
+ .dataNodesAutoAdjustScaleDown(dataNodesAutoAdjustScaleDown)
+ .filter(filter);
+ }
+
private static <R> R join(CompletableFuture<R> future) {
try {
return future.join();
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/Option.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/Option.java
new file mode 100644
index 0000000000..56bdb665f5
--- /dev/null
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/Option.java
@@ -0,0 +1,100 @@
+/*
+ * 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.catalog.sql;
+
+class Option extends QueryPart {
+ private final String name;
+
+ private final Object value;
+
+ private Option(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public static Option primaryZone(String zone) {
+ return new Option("PRIMARY_ZONE", zone.toUpperCase());
+ }
+
+ public static Option partitions(Integer partitions) {
+ return new Option("PARTITIONS", partitions);
+ }
+
+ public static Option replicas(Integer replicas) {
+ return new Option("REPLICAS", replicas);
+ }
+
+ public static Option dataNodesAutoAdjust(Integer adjust) {
+ return new Option("DATA_NODES_AUTO_ADJUST", adjust);
+ }
+
+ public static Option dataNodesAutoAdjustScaleUp(Integer adjust) {
+ return new Option("DATA_NODES_AUTO_ADJUST_SCALE_UP", adjust);
+ }
+
+ public static Option dataNodesAutoAdjustScaleDown(Integer adjust) {
+ return new Option("DATA_NODES_AUTO_ADJUST_SCALE_DOWN", adjust);
+ }
+
+ public static Option distributionAlgorithm(String distributionAlgorithm) {
+ return new Option("DISTRIBUTION_ALGORITHM", distributionAlgorithm);
+ }
+
+ public static Option dataRegion(String dataRegion) {
+ return new Option("DATAREGION", dataRegion);
+ }
+
+ public static Option storageProfiles(String storageProfiles) {
+ return new Option("STORAGE_PROFILES", storageProfiles);
+ }
+
+ public static Option name(String name) {
+ return new Option("NAME", name);
+ }
+
+ public static Option tableName(String tableName) {
+ return new Option("TABLE_NAME", tableName);
+ }
+
+ public static Option zoneName(String zoneName) {
+ return new Option("ZONE_NAME", zoneName);
+ }
+
+ public static Option indexId(int indexId) {
+ return new Option("INDEX_ID", indexId);
+ }
+
+ public static Option filter(String filter) {
+ return new Option("DATA_NODES_FILTER", filter);
+ }
+
+ @Override
+ protected void accept(QueryContext ctx) {
+ ctx.sql(name).sql("=");
+ boolean isStringValue = value instanceof String;
+ if (isStringValue) {
+ String strValue = value.toString();
+ char quoteChar = '\'';
+ if (!QueryUtils.isQuoted(strValue, quoteChar)) {
+ ctx.sql(quoteChar).sql(strValue).sql(quoteChar);
+ }
+ } else {
+ ctx.sql(value.toString());
+ }
+ }
+}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryContext.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryContext.java
index d2d23f5699..6cd438e408 100644
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryContext.java
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryContext.java
@@ -47,6 +47,13 @@ class QueryContext {
return sql.toString();
}
+ QueryContext sql(char c) {
+ applyNewLine();
+ sql.append(c);
+ resetSeparatorFlags();
+ return this;
+ }
+
QueryContext sql(String s) {
applyNewLine();
sql.append(s);
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryUtils.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryUtils.java
index f6d7de9deb..9d98da51f2 100644
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryUtils.java
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/QueryUtils.java
@@ -53,6 +53,10 @@ class QueryUtils {
return n != null && n > 0;
}
+ static boolean isGreaterThanOrEqualToZero(Integer n) {
+ return n != null && n >= 0;
+ }
+
/**
* Converts comma-separated string to a list of strings, leading and
trailing spaces are trimmed.
*
@@ -65,4 +69,8 @@ class QueryUtils {
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
}
+
+ static boolean isQuoted(String string, char quoteChar) {
+ return string.charAt(0) == quoteChar && string.charAt(string.length()
- 1) == quoteChar;
+ }
}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/SelectFromView.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/SelectFromView.java
new file mode 100644
index 0000000000..f880d40a1c
--- /dev/null
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/SelectFromView.java
@@ -0,0 +1,91 @@
+/*
+ * 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.catalog.sql;
+
+import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import org.apache.ignite.sql.IgniteSql;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.sql.async.AsyncResultSet;
+
+class SelectFromView<T> extends AbstractCatalogQuery<List<T>> {
+ private final String viewName;
+
+ private final List<String> columns;
+
+ private final List<Option> whereOptions = new ArrayList<>();
+
+ private final Function<SqlRow, T> mapper;
+
+ SelectFromView(IgniteSql sql, List<String> columns, String viewName,
Option whereOption, Function<SqlRow, T> mapper) {
+ this(sql, columns, viewName, List.of(whereOption), mapper);
+ }
+
+ SelectFromView(IgniteSql sql, List<String> columns, String viewName,
List<Option> whereOptions, Function<SqlRow, T> mapper) {
+ super(sql);
+ this.viewName = viewName;
+ this.columns = columns;
+ this.whereOptions.addAll(whereOptions);
+ this.mapper = mapper;
+ }
+
+ @Override
+ public CompletableFuture<List<T>> executeAsync() {
+ return sql.executeAsync(null, toString()).thenCompose(resultSet -> {
+ List<T> result = new ArrayList<>();
+ return iterate(resultSet, result).thenApply(unused -> result);
+ });
+ }
+
+ private CompletableFuture<Void> iterate(AsyncResultSet<SqlRow> resultSet,
List<T> result) {
+ for (SqlRow row : resultSet.currentPage()) {
+ result.add(mapper.apply(row));
+ }
+ if (resultSet.hasMorePages()) {
+ return resultSet.fetchNextPage().thenCompose(nextPage ->
iterate(nextPage, result));
+ } else {
+ return nullCompletedFuture();
+ }
+ }
+
+ @Override
+ // Noop
+ protected List<T> result() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ protected void accept(QueryContext ctx) {
+ ctx.sql("SELECT " + String.join(", ", columns) + " FROM SYSTEM." +
viewName + " ");
+
+ if (!whereOptions.isEmpty()) {
+ ctx.sql("WHERE ");
+ for (Option option : whereOptions) {
+ option.accept(ctx);
+ }
+ }
+
+ System.out.println("SELECT");
+ System.out.println(ctx.getSql());
+ }
+}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/TableDefinitionCollector.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/TableDefinitionCollector.java
new file mode 100644
index 0000000000..5102cf5e3d
--- /dev/null
+++
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/TableDefinitionCollector.java
@@ -0,0 +1,171 @@
+/*
+ * 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.catalog.sql;
+
+import static org.apache.ignite.internal.catalog.sql.Option.name;
+import static org.apache.ignite.internal.catalog.sql.Option.tableName;
+import static org.apache.ignite.internal.catalog.sql.QueryUtils.splitByComma;
+import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import org.apache.ignite.catalog.ColumnSorted;
+import org.apache.ignite.catalog.ColumnType;
+import org.apache.ignite.catalog.IndexType;
+import org.apache.ignite.catalog.definitions.ColumnDefinition;
+import org.apache.ignite.catalog.definitions.TableDefinition;
+import org.apache.ignite.catalog.definitions.TableDefinition.Builder;
+import org.apache.ignite.sql.IgniteSql;
+
+/**
+ * Table definition information collector from system views.
+ */
+public class TableDefinitionCollector {
+ private static final List<String> TABLE_VIEW_COLUMNS = List.of("SCHEMA",
"PK_INDEX_ID", "ZONE", "COLOCATION_KEY_INDEX");
+
+ private static final List<String> INDEX_VIEW_COLUMNS = List.of("INDEX_ID",
"INDEX_NAME", "COLUMNS", "TYPE");
+
+ private static final List<String> TABLE_COLUMNS_VIEW_COLUMNS =
List.of("COLUMN_NAME", "TYPE", "LENGTH", "PREC", "SCALE",
+ "NULLABLE");
+
+ private final String tableName;
+
+ private final IgniteSql sql;
+
+ public TableDefinitionCollector(String tableName, IgniteSql sql) {
+ this.tableName = tableName;
+ this.sql = sql;
+ }
+
+ /**
+ * Collect all table info from corresponding system views.
+ *
+ * @return Future with table definition build or {@code null} if table
doesn't exist.
+ */
+ public CompletableFuture<TableDefinition.Builder> collectDefinition() {
+ return collectTableInfo()
+ .thenCompose(builder -> {
+ if (builder == null) {
+ return nullCompletedFuture();
+ } else {
+ return
collectIndexes(builder).thenCompose(this::collectColumns);
+ }
+ });
+ }
+
+ private CompletableFuture<TableDefinitionBuilderWithIndexId>
collectTableInfo() {
+ return new SelectFromView<>(sql, TABLE_VIEW_COLUMNS, "TABLES",
name(tableName), row -> {
+ String schema = row.stringValue("SCHEMA");
+ int indexId = row.intValue("PK_INDEX_ID");
+ String zone = row.stringValue("ZONE");
+ String colocationColumns = row.stringValue("COLOCATION_KEY_INDEX");
+ Builder builder = TableDefinition.builder(tableName).schema(schema)
+ .zone(zone)
+ .colocateBy(splitByComma(colocationColumns));
+ return new TableDefinitionBuilderWithIndexId(builder, indexId);
+ }).executeAsync().thenApply(definitions -> {
+ if (definitions.isEmpty()) {
+ return null;
+ }
+
+ assert definitions.size() == 1;
+
+ return definitions.get(0);
+ });
+ }
+
+ private CompletableFuture<Builder>
collectIndexes(TableDefinitionBuilderWithIndexId tableDefinitionWithPkIndexId) {
+ return new SelectFromView<>(sql, INDEX_VIEW_COLUMNS, "INDEXES",
tableName(tableName), row -> {
+ int pkIndexId = tableDefinitionWithPkIndexId.indexId;
+
+ int indexId = row.intValue("INDEX_ID");
+ String indexName = row.stringValue("INDEX_NAME");
+ String columns = row.stringValue("COLUMNS");
+ String type = row.stringValue("TYPE");
+
+ return Index.create(indexName, type, columns, indexId ==
pkIndexId);
+ }).executeAsync().thenApply(indexes -> {
+ Builder builder = tableDefinitionWithPkIndexId.builder;
+ for (Index index : indexes) {
+ if (index.isPkIndex) {
+ builder.primaryKey(index.type, index.columns);
+ } else {
+ builder.index(index.name, index.type, index.columns);
+ }
+ }
+ return builder;
+ });
+ }
+
+ private CompletableFuture<TableDefinition.Builder>
collectColumns(TableDefinition.Builder builder) {
+ return new SelectFromView<>(sql, TABLE_COLUMNS_VIEW_COLUMNS,
"TABLE_COLUMNS", tableName(tableName),
+ row -> {
+ String columnName = row.stringValue("COLUMN_NAME");
+ String type = row.stringValue("TYPE");
+ int length = row.intValue("LENGTH");
+ int precision = row.intValue("PREC");
+ int scale = row.intValue("SCALE");
+ boolean nullable = row.booleanValue("NULLABLE");
+
+ Class<?> typeClass =
org.apache.ignite.sql.ColumnType.valueOf(type).javaClass();
+ return ColumnDefinition.column(columnName,
ColumnType.of(typeClass, length, precision, scale, nullable));
+ }).executeAsync().thenApply(builder::columns);
+ }
+
+ private static class Index {
+ private final String name;
+
+ private final IndexType type;
+
+ private final List<ColumnSorted> columns;
+
+ private final boolean isPkIndex;
+
+ private Index(String name, IndexType type, List<ColumnSorted> columns,
boolean isPkIndex) {
+ this.name = name;
+ this.type = type;
+ this.columns = columns;
+ this.isPkIndex = isPkIndex;
+ }
+
+ private static Index create(String name, String type, String columns,
boolean isPkIndex) {
+ return new Index(name, IndexType.valueOf(type), fromRaw(columns),
isPkIndex);
+ }
+ }
+
+ private static List<ColumnSorted> fromRaw(String columns) {
+ return Arrays.stream(columns.split(","))
+ .map(String::trim)
+ .filter(s -> !s.isEmpty())
+ .map(ColumnSorted::column)
+ .collect(Collectors.toList());
+ }
+
+ private static class TableDefinitionBuilderWithIndexId {
+ private final TableDefinition.Builder builder;
+
+ private final int indexId;
+
+ private TableDefinitionBuilderWithIndexId(TableDefinition.Builder
builder, int indexId) {
+ this.builder = builder;
+ this.indexId = indexId;
+ }
+ }
+}
diff --git
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/WithOption.java
b/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/WithOption.java
deleted file mode 100644
index 80397c6994..0000000000
---
a/modules/catalog-dsl/src/main/java/org/apache/ignite/internal/catalog/sql/WithOption.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.catalog.sql;
-
-class WithOption extends QueryPart {
- private final String name;
-
- private final Object value;
-
- private WithOption(String name, Object value) {
- this.name = name;
- this.value = value;
- }
-
- public static WithOption primaryZone(String zone) {
- return new WithOption("PRIMARY_ZONE", zone.toUpperCase());
- }
-
- public static WithOption partitions(Integer partitions) {
- return new WithOption("PARTITIONS", partitions);
- }
-
- public static WithOption replicas(Integer replicas) {
- return new WithOption("REPLICAS", replicas);
- }
-
- public static WithOption distributionAlgorithm(String
distributionAlgorithm) {
- return new WithOption("DISTRIBUTION_ALGORITHM", distributionAlgorithm);
- }
-
- public static WithOption dataNodesAutoAdjust(Integer adjust) {
- return new WithOption("DATA_NODES_AUTO_ADJUST", adjust);
- }
-
- public static WithOption dataNodesAutoAdjustScaleUp(Integer adjust) {
- return new WithOption("DATA_NODES_AUTO_ADJUST_SCALE_UP", adjust);
- }
-
- public static WithOption dataNodesAutoAdjustScaleDown(Integer adjust) {
- return new WithOption("DATA_NODES_AUTO_ADJUST_SCALE_DOWN", adjust);
- }
-
- public static WithOption filter(String filter) {
- return new WithOption("DATA_NODES_FILTER", filter);
- }
-
- public static WithOption dataRegion(String dataRegion) {
- return new WithOption("DATAREGION", dataRegion);
- }
-
- public static WithOption storageProfiles(String storageProfiles) {
- return new WithOption("STORAGE_PROFILES", storageProfiles);
- }
-
- @Override
- protected void accept(QueryContext ctx) {
- ctx.sql(name).sql("=");
- boolean isNeedsQuotes = value instanceof String;
- if (isNeedsQuotes) {
- ctx.sql("'").sql(value.toString()).sql("'");
- } else {
- ctx.sql(value.toString());
- }
- }
-}
diff --git
a/modules/catalog-dsl/src/test/java/org/apache/ignite/internal/catalog/sql/QueryPartTest.java
b/modules/catalog-dsl/src/test/java/org/apache/ignite/internal/catalog/sql/QueryPartTest.java
index 46e772ad6a..5b0f906108 100644
---
a/modules/catalog-dsl/src/test/java/org/apache/ignite/internal/catalog/sql/QueryPartTest.java
+++
b/modules/catalog-dsl/src/test/java/org/apache/ignite/internal/catalog/sql/QueryPartTest.java
@@ -138,13 +138,13 @@ class QueryPartTest {
@Test
void withOptionPart() {
- WithOption withOption = WithOption.primaryZone("z");
+ Option withOption = Option.primaryZone("z");
assertThat(sql(withOption), is("PRIMARY_ZONE='Z'"));
- withOption = WithOption.partitions(1);
+ withOption = Option.partitions(1);
assertThat(sql(withOption), is("PARTITIONS=1"));
- withOption = WithOption.replicas(1);
+ withOption = Option.replicas(1);
assertThat(sql(withOption), is("REPLICAS=1"));
}
diff --git
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogSystemViewRegistry.java
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogSystemViewRegistry.java
index a9b27f1ff4..fb6b8b2e6d 100644
---
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogSystemViewRegistry.java
+++
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogSystemViewRegistry.java
@@ -22,6 +22,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.ignite.internal.catalog.systemviews.IndexSystemViewProvider;
import org.apache.ignite.internal.catalog.systemviews.SystemViewViewProvider;
+import org.apache.ignite.internal.catalog.systemviews.TablesSystemViewProvider;
import org.apache.ignite.internal.catalog.systemviews.ZonesSystemViewProvider;
import org.apache.ignite.internal.systemview.api.SystemView;
import org.apache.ignite.internal.systemview.api.SystemViewProvider;
@@ -40,7 +41,8 @@ public class CatalogSystemViewRegistry implements
SystemViewProvider {
providers = List.of(
new SystemViewViewProvider(),
new IndexSystemViewProvider(),
- new ZonesSystemViewProvider()
+ new ZonesSystemViewProvider(),
+ new TablesSystemViewProvider()
);
}
diff --git
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/TablesSystemViewProvider.java
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/TablesSystemViewProvider.java
new file mode 100644
index 0000000000..8913425a45
--- /dev/null
+++
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/TablesSystemViewProvider.java
@@ -0,0 +1,146 @@
+/*
+ * 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.catalog.systemviews;
+
+import static org.apache.ignite.internal.type.NativeTypes.BOOLEAN;
+import static org.apache.ignite.internal.type.NativeTypes.INT32;
+import static org.apache.ignite.internal.type.NativeTypes.STRING;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Flow.Publisher;
+import java.util.function.Supplier;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.CatalogSystemViewProvider;
+import
org.apache.ignite.internal.catalog.descriptors.CatalogTableColumnDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
+import org.apache.ignite.internal.systemview.api.SystemView;
+import org.apache.ignite.internal.systemview.api.SystemViews;
+import org.apache.ignite.internal.util.SubscriptionUtils;
+
+/**
+ * Exposes information on tables.
+ *
+ * <ul>
+ * <li>TABLES - available tables</li>
+ * <li>TABLE_COLUMNS - columns of available tables.</li>
+ * </ul>
+ */
+public class TablesSystemViewProvider implements CatalogSystemViewProvider {
+ @Override
+ public List<SystemView<?>> getView(Supplier<Catalog> catalogSupplier) {
+ return List.of(
+ getTablesSystemView(catalogSupplier),
+ getTableColumnsSystemView(catalogSupplier)
+ );
+ }
+
+ private static SystemView<?> getTablesSystemView(Supplier<Catalog>
catalogSupplier) {
+ Iterable<TableWithSchemaAndZoneName> tablesData = () -> {
+ Catalog catalog = catalogSupplier.get();
+
+ return catalog.tables().stream().map(table -> {
+ String schemaName =
Objects.requireNonNull(catalog.schema(table.schemaId()), "Schema must be not
null.").name();
+ String zoneName =
Objects.requireNonNull(catalog.zone(table.zoneId()), "Zone must be not
null.").name();
+
+ return new TableWithSchemaAndZoneName(table, schemaName,
zoneName);
+ }).iterator();
+ };
+
+ Publisher<TableWithSchemaAndZoneName> viewDataPublisher =
SubscriptionUtils.fromIterable(tablesData);
+
+ return SystemViews.<TableWithSchemaAndZoneName>clusterViewBuilder()
+ .name("TABLES")
+ .addColumn("SCHEMA", STRING, entry -> entry.schemaName)
+ .addColumn("NAME", STRING, entry -> entry.table.name())
+ .addColumn("ID", INT32, entry -> entry.table.id())
+ .addColumn("PK_INDEX_ID", INT32, entry ->
entry.table.primaryKeyIndexId())
+ .addColumn("ZONE", STRING, entry -> entry.zoneName)
+ .addColumn("STORAGE_PROFILE", STRING, entry ->
entry.table.storageProfile())
+ .addColumn("COLOCATION_KEY_INDEX", STRING, entry ->
concatColumns(entry.table.colocationColumns()))
+ .dataProvider(viewDataPublisher)
+ .build();
+ }
+
+ private static String concatColumns(List<String> columns) {
+ if (columns == null || columns.isEmpty()) {
+ return "NULL";
+ }
+ return String.join(", ", columns);
+ }
+
+ private static SystemView<?> getTableColumnsSystemView(Supplier<Catalog>
catalogSupplier) {
+ Iterable<ColumnWithTableId> viewData = () -> {
+ Catalog catalog = catalogSupplier.get();
+
+ return catalog.tables().stream()
+ .flatMap(table -> table.columns().stream()
+ .map(columnDescriptor -> new ColumnWithTableId(
+ catalog.schema(table.schemaId()).name(),
+ table.name(),
+ table.id(),
+ columnDescriptor
+ )
+ )
+ )
+ .iterator();
+ };
+
+ Publisher<ColumnWithTableId> viewDataPublisher =
SubscriptionUtils.fromIterable(viewData);
+
+ return SystemViews.<ColumnWithTableId>clusterViewBuilder()
+ .name("TABLE_COLUMNS")
+ .addColumn("SCHEMA", STRING, entry -> entry.schema)
+ .addColumn("TABLE_NAME", STRING, entry -> entry.tableName)
+ .addColumn("TABLE_ID", INT32, entry -> entry.tableId)
+ .addColumn("COLUMN_NAME", STRING, entry ->
entry.descriptor.name())
+ .addColumn("TYPE", STRING, entry ->
entry.descriptor.type().name())
+ .addColumn("NULLABLE", BOOLEAN, entry ->
entry.descriptor.nullable())
+ .addColumn("PREC", INT32, entry ->
entry.descriptor.precision())
+ .addColumn("SCALE", INT32, entry -> entry.descriptor.scale())
+ .addColumn("LENGTH", INT32, entry -> entry.descriptor.length())
+ .dataProvider(viewDataPublisher)
+ .build();
+ }
+
+ private static class ColumnWithTableId {
+ private final CatalogTableColumnDescriptor descriptor;
+ private final String tableName;
+ private final String schema;
+ private final int tableId;
+
+ private ColumnWithTableId(String schema, String tableName, int
tableId, CatalogTableColumnDescriptor descriptor) {
+ this.schema = schema;
+ this.tableName = tableName;
+ this.descriptor = descriptor;
+ this.tableId = tableId;
+ }
+ }
+
+ private static class TableWithSchemaAndZoneName {
+ private final CatalogTableDescriptor table;
+ private final String schemaName;
+ private final String zoneName;
+
+ private TableWithSchemaAndZoneName(CatalogTableDescriptor table,
String schemaName, String zoneName) {
+ this.table = table;
+ this.schemaName = schemaName;
+ this.zoneName = zoneName;
+ }
+ }
+}
diff --git
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/ZonesSystemViewProvider.java
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/ZonesSystemViewProvider.java
index 13be1e872e..c5579f2f47 100644
---
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/ZonesSystemViewProvider.java
+++
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/systemviews/ZonesSystemViewProvider.java
@@ -22,9 +22,11 @@ import static
org.apache.ignite.internal.type.NativeTypes.INT32;
import static org.apache.ignite.internal.type.NativeTypes.STRING;
import java.util.List;
+import java.util.Objects;
import java.util.function.Supplier;
import org.apache.ignite.internal.catalog.Catalog;
import org.apache.ignite.internal.catalog.CatalogSystemViewProvider;
+import
org.apache.ignite.internal.catalog.descriptors.CatalogStorageProfileDescriptor;
import org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor;
import org.apache.ignite.internal.systemview.api.SystemView;
import org.apache.ignite.internal.systemview.api.SystemViews;
@@ -43,7 +45,11 @@ public final class ZonesSystemViewProvider implements
CatalogSystemViewProvider
/** {@inheritDoc} */
@Override
public List<SystemView<?>> getView(Supplier<Catalog> catalogSupplier) {
- SystemView<?> zoneSystemView =
SystemViews.<ZoneWithDefaultMarker>clusterViewBuilder()
+ return List.of(getZoneView(catalogSupplier),
getStorageProfilesView(catalogSupplier));
+ }
+
+ private static SystemView<?> getZoneView(Supplier<Catalog>
catalogSupplier) {
+ return SystemViews.<ZoneWithDefaultMarker>clusterViewBuilder()
.name("ZONES")
.addColumn("NAME", STRING, wrapper -> wrapper.zone.name())
.addColumn("PARTITIONS", INT32, wrapper ->
wrapper.zone.partitions())
@@ -60,8 +66,34 @@ public final class ZonesSystemViewProvider implements
CatalogSystemViewProvider
}
))
.build();
+ }
+
+ private static SystemView<?> getStorageProfilesView(Supplier<Catalog>
catalogSupplier) {
+ Iterable<ZoneWithProfile> viewData = () -> {
+ Catalog catalog = catalogSupplier.get();
+
+ return catalog.zones().stream()
+ .flatMap(zone -> {
+ List<CatalogStorageProfileDescriptor> profiles =
zone.storageProfiles().profiles();
+ CatalogStorageProfileDescriptor defaultProfile =
zone.storageProfiles().defaultProfile();
+
+ return profiles.stream().map(profile ->
+ new ZoneWithProfile(
+ zone.name(),
+ profile.storageProfile(),
+
Objects.equals(profile.storageProfile(), defaultProfile.storageProfile())
+ )
+ );
+ }).iterator();
+ };
- return List.of(zoneSystemView);
+ return SystemViews.<ZoneWithProfile>clusterViewBuilder()
+ .name("ZONE_STORAGE_PROFILES")
+ .addColumn("ZONE_NAME", STRING, zone -> zone.zoneName)
+ .addColumn("STORAGE_PROFILE", STRING, zone -> zone.profileName)
+ .addColumn("IS_DEFAULT_PROFILE", BOOLEAN, zone ->
zone.isDefaultProfile)
+ .dataProvider(SubscriptionUtils.fromIterable(viewData))
+ .build();
}
/** Wraps a CatalogZoneDescriptor and a flag indicating whether this zone
is the default zone. */
@@ -74,4 +106,19 @@ public final class ZonesSystemViewProvider implements
CatalogSystemViewProvider
this.isDefault = isDefault;
}
}
+
+ /**
+ * Wraps a zone and a one of storage profile of the zone.
+ */
+ private static class ZoneWithProfile {
+ private final String zoneName;
+ private final String profileName;
+ private final boolean isDefaultProfile;
+
+ private ZoneWithProfile(String zoneName, String profileName, boolean
defaultProfile) {
+ this.zoneName = zoneName;
+ this.profileName = profileName;
+ this.isDefaultProfile = defaultProfile;
+ }
+ }
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
index 58d991a54b..08568c6d4f 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
@@ -209,7 +209,7 @@ public class TcpIgniteClient implements IgniteClient {
@Override
public IgniteCatalog catalog() {
- return new IgniteCatalogSqlImpl(sql(), tables);
+ return new IgniteCatalogSqlImpl(sql, tables);
}
/** {@inheritDoc} */
diff --git
a/modules/runner/src/main/java/org/apache/ignite/internal/threading/PublicApiThreadingIgniteCatalog.java
b/modules/runner/src/main/java/org/apache/ignite/internal/threading/PublicApiThreadingIgniteCatalog.java
index 0316465336..db1c0e8de6 100644
---
a/modules/runner/src/main/java/org/apache/ignite/internal/threading/PublicApiThreadingIgniteCatalog.java
+++
b/modules/runner/src/main/java/org/apache/ignite/internal/threading/PublicApiThreadingIgniteCatalog.java
@@ -78,6 +78,16 @@ public class PublicApiThreadingIgniteCatalog implements
IgniteCatalog, Wrapper {
return wrapTableForPublicUse(table);
}
+ @Override
+ public CompletableFuture<TableDefinition> tableDefinitionAsync(String
tableName) {
+ return doAsyncOperation(() -> catalog.tableDefinitionAsync(tableName));
+ }
+
+ @Override
+ public TableDefinition tableDefinition(String tableName) {
+ return execUserSyncOperation(() -> catalog.tableDefinition(tableName));
+ }
+
@Override
public CompletableFuture<Void> createZoneAsync(ZoneDefinition definition) {
return doAsyncOperation(() -> catalog.createZoneAsync(definition));
@@ -88,6 +98,17 @@ public class PublicApiThreadingIgniteCatalog implements
IgniteCatalog, Wrapper {
execUserSyncOperation(() -> catalog.createZone(definition));
}
+
+ @Override
+ public CompletableFuture<ZoneDefinition> zoneDefinitionAsync(String
zoneName) {
+ return execUserSyncOperation(() ->
catalog.zoneDefinitionAsync(zoneName));
+ }
+
+ @Override
+ public ZoneDefinition zoneDefinition(String zoneName) {
+ return execUserSyncOperation(() -> catalog.zoneDefinition(zoneName));
+ }
+
@Override
public CompletableFuture<Void> dropTableAsync(TableDefinition definition) {
return doAsyncOperation(() -> catalog.dropTableAsync(definition));