You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ko...@apache.org on 2025/11/21 11:46:17 UTC
(ignite-3) branch main updated: IGNITE-26705 Sql. Replace sql.engine.exec.row.RowSchema with StructNativeType (#6968)
This is an automated email from the ASF dual-hosted git repository.
korlov 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 38489d84f29 IGNITE-26705 Sql. Replace sql.engine.exec.row.RowSchema with StructNativeType (#6968)
38489d84f29 is described below
commit 38489d84f294501f60fc30eadea96e375c528d6d
Author: korlov42 <ko...@apache.org>
AuthorDate: Fri Nov 21 13:46:11 2025 +0200
IGNITE-26705 Sql. Replace sql.engine.exec.row.RowSchema with StructNativeType (#6968)
---
.../java/org/apache/ignite/sql/ColumnType.java | 5 +-
.../ignite/table/AbstractImmutableTupleTest.java | 2 +-
.../ignite/internal/compute/PojoConverter.java | 1 +
.../internal/compute/SharedComputeUtils.java | 1 +
.../org/apache/ignite/client/ClientTupleTest.java | 2 +-
.../apache/ignite/internal/type/NativeType.java | 52 ++---
.../apache/ignite/internal/type/NativeTypes.java | 80 +++++++-
.../ignite/internal/type/StructNativeType.java | 126 ++++++++++++
.../internal/table/ItPublicApiColocationTest.java | 6 +-
.../CatalogToSchemaDescriptorConverterTest.java | 2 +-
.../sql/engine/ItDynamicParameterTest.java | 2 +-
.../sql/engine/exec/LogicalRelImplementor.java | 44 ++---
.../internal/sql/engine/exec/RowHandler.java | 6 +-
.../internal/sql/engine/exec/SqlRowHandler.java | 62 +++---
.../sql/engine/exec/UpdatableTableImpl.java | 22 +--
.../sql/engine/exec/exp/ExpressionFactory.java | 4 +-
.../sql/engine/exec/exp/ExpressionFactoryImpl.java | 4 +-
.../engine/exec/exp/JoinProjectionImplementor.java | 23 +--
.../sql/engine/exec/exp/ProjectionImplementor.java | 37 ++--
.../engine/exec/exp/RowProviderImplementor.java | 26 +--
.../sql/engine/exec/exp/ValuesImplementor.java | 6 +-
.../exec/exp/func/SystemRangeTableFunction.java | 6 +-
.../internal/sql/engine/exec/rel/HashJoinNode.java | 13 +-
.../sql/engine/exec/rel/MergeJoinNode.java | 13 +-
.../internal/sql/engine/exec/rel/ModifyNode.java | 19 +-
.../sql/engine/exec/rel/NestedLoopJoinNode.java | 13 +-
.../internal/sql/engine/exec/row/BaseTypeSpec.java | 78 --------
.../internal/sql/engine/exec/row/NullTypeSpec.java | 47 -----
.../internal/sql/engine/exec/row/RowSchema.java | 136 -------------
.../sql/engine/exec/row/RowSchemaTypes.java | 106 ----------
.../internal/sql/engine/exec/row/RowType.java | 72 -------
.../internal/sql/engine/exec/row/TypeSpec.java | 57 ------
.../sql/engine/prepare/KeyValueGetPlan.java | 9 +-
.../sql/engine/prepare/SelectCountPlan.java | 11 +-
.../sql/engine/type/IgniteTypeFactory.java | 28 ++-
.../ignite/internal/sql/engine/util/TypeUtils.java | 132 +++++++------
.../exec/IdentityDistributionFunctionSelfTest.java | 8 +-
.../sql/engine/exec/PartitionsResolutionTest.java | 12 +-
.../exec/ProjectedTableRowConverterSelfTest.java | 8 +-
.../sql/engine/exec/TableRowConverterSelfTest.java | 24 +--
.../engine/exec/exp/ExpressionFactoryImplTest.java | 3 +-
.../sql/engine/exec/rel/AsyncRootNodeTest.java | 6 +-
.../sql/engine/exec/rel/BaseAggregateTest.java | 16 +-
.../rel/CorrelatedNestedLoopJoinExecutionTest.java | 12 +-
.../exec/rel/DataSourceScanNodeExecutionTest.java | 35 ++--
.../sql/engine/exec/rel/ExchangeExecutionTest.java | 8 +-
.../exec/rel/HashAggregateExecutionTest.java | 10 +-
.../rel/HashAggregateSingleGroupExecutionTest.java | 5 +-
.../exec/rel/IndexScanNodeExecutionTest.java | 12 +-
.../engine/exec/rel/IntersectExecutionTest.java | 22 +--
.../sql/engine/exec/rel/MinusExecutionTest.java | 20 +-
.../engine/exec/rel/ModifyNodeExecutionTest.java | 84 ++++----
.../engine/exec/rel/ScannableTableSelfTest.java | 11 +-
.../exec/rel/SortAggregateExecutionTest.java | 10 +-
.../exec/rel/TableScanNodeExecutionTest.java | 10 +-
.../sql/engine/exec/row/RowSchemaTest.java | 130 ------------
.../sql/engine/exec/row/RowSchemaTypesTest.java | 217 ---------------------
.../sql/engine/exec/row/SqlRowHandlerTest.java | 100 ++++------
.../sql/engine/framework/ArrayRowHandler.java | 15 +-
.../internal/sql/engine/util/TypeUtilsTest.java | 124 +++++-------
.../internal/sql/engine/util/SqlTestUtils.java | 1 +
.../internal/systemview/SystemViewManagerTest.java | 2 +-
.../ignite/internal/table/ItColocationTest.java | 8 +-
63 files changed, 739 insertions(+), 1427 deletions(-)
diff --git a/modules/api/src/main/java/org/apache/ignite/sql/ColumnType.java b/modules/api/src/main/java/org/apache/ignite/sql/ColumnType.java
index 22ecb67785b..b22f5b3b2ef 100644
--- a/modules/api/src/main/java/org/apache/ignite/sql/ColumnType.java
+++ b/modules/api/src/main/java/org/apache/ignite/sql/ColumnType.java
@@ -91,7 +91,10 @@ public enum ColumnType {
PERIOD(17, Period.class, true, false, false),
/** Time interval. SQL type: none. */
- DURATION(18, Duration.class, true, false, false);
+ DURATION(18, Duration.class, true, false, false),
+
+ /** Structured type having named fields. SQL type: none. */
+ STRUCT(19, Object.class, false, false, false);
private final Class<?> javaClass;
private final boolean precisionAllowed;
diff --git a/modules/api/src/testFixtures/java/org/apache/ignite/table/AbstractImmutableTupleTest.java b/modules/api/src/testFixtures/java/org/apache/ignite/table/AbstractImmutableTupleTest.java
index c321eec566d..b4933892c7f 100644
--- a/modules/api/src/testFixtures/java/org/apache/ignite/table/AbstractImmutableTupleTest.java
+++ b/modules/api/src/testFixtures/java/org/apache/ignite/table/AbstractImmutableTupleTest.java
@@ -101,7 +101,7 @@ public abstract class AbstractImmutableTupleTest {
protected abstract Tuple createTupleOfSingleColumn(ColumnType type, String columnName, Object value);
- @EnumSource(value = ColumnType.class, mode = Mode.EXCLUDE, names = {"PERIOD", "DURATION", "NULL"})
+ @EnumSource(value = ColumnType.class, mode = Mode.EXCLUDE, names = {"PERIOD", "DURATION", "NULL", "STRUCT"})
@ParameterizedTest
public void testTupleColumnsEquality(ColumnType type) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
diff --git a/modules/client-common/src/main/java/org/apache/ignite/internal/compute/PojoConverter.java b/modules/client-common/src/main/java/org/apache/ignite/internal/compute/PojoConverter.java
index 9333a1a1039..a3484a94ceb 100644
--- a/modules/client-common/src/main/java/org/apache/ignite/internal/compute/PojoConverter.java
+++ b/modules/client-common/src/main/java/org/apache/ignite/internal/compute/PojoConverter.java
@@ -33,6 +33,7 @@ import org.apache.ignite.table.mapper.PojoMapper;
/** Converts POJO to Tuple and back. */
public class PojoConverter {
private static final Set<Class<?>> NATIVE_TYPES = Arrays.stream(ColumnType.values())
+ .filter(type -> type != ColumnType.STRUCT)
.map(ColumnType::javaClass)
.collect(Collectors.toUnmodifiableSet());
diff --git a/modules/client-common/src/main/java/org/apache/ignite/internal/compute/SharedComputeUtils.java b/modules/client-common/src/main/java/org/apache/ignite/internal/compute/SharedComputeUtils.java
index a750cee0af3..8fde6c25bc0 100644
--- a/modules/client-common/src/main/java/org/apache/ignite/internal/compute/SharedComputeUtils.java
+++ b/modules/client-common/src/main/java/org/apache/ignite/internal/compute/SharedComputeUtils.java
@@ -53,6 +53,7 @@ import org.jetbrains.annotations.Nullable;
*/
public class SharedComputeUtils {
private static final Set<Class<?>> NATIVE_TYPES = Arrays.stream(ColumnType.values())
+ .filter(type -> type != ColumnType.STRUCT)
.map(ColumnType::javaClass)
.collect(Collectors.toUnmodifiableSet());
diff --git a/modules/client/src/test/java/org/apache/ignite/client/ClientTupleTest.java b/modules/client/src/test/java/org/apache/ignite/client/ClientTupleTest.java
index 633bdba46e1..e0f7696b589 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/ClientTupleTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientTupleTest.java
@@ -234,7 +234,7 @@ public class ClientTupleTest extends AbstractMutableTupleTest {
.collect(Collectors.toSet());
for (ColumnType columnType : ColumnType.values()) {
- if (columnType == ColumnType.NULL) {
+ if (columnType == ColumnType.NULL || columnType == ColumnType.STRUCT) {
continue;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java
index 6abbbae3744..b956e1905fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.type;
-import java.util.Arrays;
+import java.util.EnumSet;
import org.apache.ignite.internal.tostring.S;
import org.apache.ignite.sql.ColumnType;
import org.jetbrains.annotations.TestOnly;
@@ -41,18 +41,11 @@ public class NativeType implements Comparable<NativeType> {
* @param size Type size in bytes.
*/
protected NativeType(ColumnType typeSpec, int size) {
- this.fixedSize = !((typeSpec.precisionAllowed() && typeSpec.scaleAllowed()) || typeSpec.lengthAllowed());
-
- if (!this.fixedSize) {
- throw new IllegalArgumentException("Size must be provided only for fixed-length types: " + typeSpec);
- }
-
- if (size <= 0) {
- throw new IllegalArgumentException("Size must be positive [typeSpec=" + typeSpec + ", size=" + size + ']');
- }
-
- this.typeSpec = typeSpec;
- this.size = size;
+ this(
+ typeSpec,
+ isFixedSize(typeSpec),
+ size
+ );
}
/**
@@ -61,15 +54,29 @@ public class NativeType implements Comparable<NativeType> {
* @param typeSpec Type spec.
*/
protected NativeType(ColumnType typeSpec) {
- this.fixedSize = !((typeSpec.precisionAllowed() && typeSpec.scaleAllowed()) || typeSpec.lengthAllowed());
+ this(
+ typeSpec,
+ isFixedSize(typeSpec),
+ 0
+ );
+ }
- if (this.fixedSize) {
- throw new IllegalArgumentException("Fixed-length types must be created by the "
- + "length-aware constructor: " + typeSpec);
+ private static boolean isFixedSize(ColumnType typeSpec) {
+ return !((typeSpec.precisionAllowed() && typeSpec.scaleAllowed()) || typeSpec.lengthAllowed());
+ }
+
+ protected NativeType(ColumnType typeSpec, boolean fixedSize, int size) {
+ if (fixedSize && size <= 0) {
+ throw new IllegalArgumentException("Size must be positive [typeSpec=" + typeSpec + ", size=" + size + ']');
+ }
+
+ if (!fixedSize && size > 0) {
+ throw new IllegalArgumentException("Size must be provided only for fixed-length types: " + typeSpec);
}
+ this.fixedSize = fixedSize;
this.typeSpec = typeSpec;
- this.size = 0;
+ this.size = size;
}
/**
@@ -170,11 +177,12 @@ public class NativeType implements Comparable<NativeType> {
"fixed", fixedLength());
}
-
- // TODO https://issues.apache.org/jira/browse/IGNITE-17373 Remove filter after this issue is resolved
+ /** Returns an array of fully supported types. */
@TestOnly
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17373 Remove filter after this issue is resolved
public static ColumnType[] nativeTypes() {
- return Arrays.stream(ColumnType.values()).filter(v -> v != ColumnType.NULL && v != ColumnType.DURATION
- && v != ColumnType.PERIOD).toArray(ColumnType[]::new);
+ return EnumSet.complementOf(EnumSet.of(
+ ColumnType.NULL, ColumnType.DURATION, ColumnType.PERIOD, ColumnType.STRUCT
+ )).toArray(ColumnType[]::new);
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypes.java b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypes.java
index de044a6904c..6b1acfe025f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypes.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypes.java
@@ -22,6 +22,10 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.internal.type.StructNativeType.Field;
+import org.apache.ignite.internal.util.StringUtils;
import org.apache.ignite.sql.ColumnType;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
@@ -37,6 +41,9 @@ public class NativeTypes {
*/
public static final int MAX_TIME_PRECISION = 9;
+ /** NULL type. */
+ public static final NativeType NULL = new NativeType(ColumnType.NULL, 1);
+
/**
* BOOLEAN type.
*/
@@ -128,7 +135,7 @@ public class NativeTypes {
* Creates a DECIMAL type with maximal precision and scale.
*
* @param precision Precision.
- * @param scale Scale.
+ * @param scale Scale.
* @return Native type.
*/
public static NativeType decimalOf(int precision, int scale) {
@@ -165,6 +172,11 @@ public class NativeTypes {
return TemporalNativeType.timestamp(precision);
}
+ /** Returns builder to create structured type. */
+ public static RowTypeBuilder rowBuilder() {
+ return new RowTypeBuilder();
+ }
+
/**
* Return the native type for specified object.
*
@@ -258,4 +270,70 @@ public class NativeTypes {
return MAX_TIME_PRECISION - trailingZeroes;
}
+
+ /** A builder for constructing {@link StructNativeType} instances. */
+ public static class RowTypeBuilder {
+ private RowTypeBuilder() {
+ }
+
+ private final List<Field> fields = new ArrayList<>();
+
+ /**
+ * Adds a field to this struct type builder.
+ *
+ * <p>Fields are added in the order this method is called, and this order is preserved in the resulting {@link StructNativeType}.
+ *
+ * @param name The name of the field; Must not be null or blank.
+ * @param type The native type of the field; Must not be null.
+ * @param nullable Whether the field can contain null values.
+ * @return This builder instance for method chaining.
+ * @throws IllegalArgumentException If any argument violates provided constraints.
+ */
+ public RowTypeBuilder addField(String name, NativeType type, boolean nullable) {
+ if (StringUtils.nullOrBlank(name)) {
+ throw new IllegalArgumentException("Name must not be null or blank: "
+ + (name == null ? "<null>" : "\"" + name + "\"") + ".");
+ }
+
+ if (type == null) {
+ throw new IllegalArgumentException("Type must not be null.");
+ }
+
+ fields.add(new Field(name, type, nullable));
+
+ return this;
+ }
+
+ /**
+ * Adds a field to this struct type builder.
+ *
+ * <p>Fields are added in the order this method is called, and this order is preserved in the resulting {@link StructNativeType}.
+ *
+ * @param field The field to add; Must not be null.
+ * @return This builder instance for method chaining.
+ * @throws IllegalArgumentException If any argument violates provided constraints.
+ */
+ public RowTypeBuilder addField(Field field) {
+ if (field == null) {
+ throw new IllegalArgumentException("Field must not be null.");
+ }
+
+ fields.add(field);
+
+ return this;
+ }
+
+ /**
+ * Builds and returns a new {@link StructNativeType} with the fields that have been added.
+ *
+ * <p>The returned struct contains an immutable copy of the fields in the order they were added. This method can be called multiple
+ * times to create multiple struct instances, though subsequent modifications to the builder will not affect previously built
+ * instances.
+ *
+ * @return A new {@code StructNativeType} instance containing the configured fields.
+ */
+ public StructNativeType build() {
+ return new StructNativeType(List.copyOf(fields));
+ }
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/type/StructNativeType.java b/modules/core/src/main/java/org/apache/ignite/internal/type/StructNativeType.java
new file mode 100644
index 00000000000..27b157f77fc
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/type/StructNativeType.java
@@ -0,0 +1,126 @@
+/*
+ * 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.type;
+
+import java.util.List;
+import java.util.Objects;
+import org.apache.ignite.internal.tostring.S;
+import org.apache.ignite.sql.ColumnType;
+
+/**
+ * Represents a structured native type that contains multiple named fields.
+ *
+ * <p>A struct type is a composite data type that groups together zero or more fields, each with its own name, type, and nullability
+ * constraint.
+ *
+ * @see NativeType
+ * @see Field
+ */
+public class StructNativeType extends NativeType {
+ private final List<Field> fields;
+
+ StructNativeType(List<Field> fields) {
+ super(ColumnType.STRUCT, false, 0);
+
+ this.fields = fields;
+ }
+
+ /** Returns the list of fields in this struct. */
+ public List<Field> fields() {
+ return fields;
+ }
+
+ /** Returns the number of fields in this struct. */
+ public int fieldsCount() {
+ return fields.size();
+ }
+
+ /**
+ * Represents a single field within a struct type.
+ *
+ * <p>Each field has a name, a native type, and a nullability flag. Fields are immutable once created and can be compared for equality
+ * based on all three properties.
+ */
+ public static class Field {
+ private final String name;
+ private final NativeType type;
+ private final boolean nullable;
+
+ Field(String name, NativeType type, boolean nullable) {
+ this.name = name;
+ this.type = type;
+ this.nullable = nullable;
+ }
+
+ /** Returns the name of this field. */
+ public String name() {
+ return name;
+ }
+
+ /** Returns the type of this field. */
+ public NativeType type() {
+ return type;
+ }
+
+ /** Returns whether this field can contain null values. */
+ public boolean nullable() {
+ return nullable;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Field field = (Field) o;
+ return nullable == field.nullable && Objects.equals(name, field.name) && Objects.equals(type, field.type);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, type, nullable);
+ }
+
+ @Override
+ public String toString() {
+ return S.toString(this);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ StructNativeType that = (StructNativeType) o;
+ return Objects.equals(fields, that.fields);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), fields);
+ }
+
+ @Override
+ public String toString() {
+ return S.toString(this);
+ }
+}
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItPublicApiColocationTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItPublicApiColocationTest.java
index 3c7fedc3ffa..21e19fd7337 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItPublicApiColocationTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItPublicApiColocationTest.java
@@ -69,7 +69,7 @@ public class ItPublicApiColocationTest extends ClusterPerClassIntegrationTest {
* Check colocation by one column PK and explicit colocation key for all types.
*/
@ParameterizedTest(name = "type=" + ARGUMENTS_PLACEHOLDER)
- @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION"}, mode = Mode.EXCLUDE)
+ @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Mode.EXCLUDE)
public void colocationOneColumn(ColumnType type) {
String sqlType = SqlTestUtils.toSqlType(type);
String createTableScript = String.join(";",
@@ -121,8 +121,8 @@ public class ItPublicApiColocationTest extends ClusterPerClassIntegrationTest {
*/
@CartesianTest
public void colocationTwoColumns(
- @Enum(names = {"NULL", "PERIOD", "DURATION"}, mode = Enum.Mode.EXCLUDE) ColumnType t0,
- @Enum(names = {"NULL", "PERIOD", "DURATION"}, mode = Enum.Mode.EXCLUDE) ColumnType t1
+ @Enum(names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Enum.Mode.EXCLUDE) ColumnType t0,
+ @Enum(names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Enum.Mode.EXCLUDE) ColumnType t1
) {
String sqlType0 = SqlTestUtils.toSqlType(t0);
String sqlType1 = SqlTestUtils.toSqlType(t1);
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/catalog/CatalogToSchemaDescriptorConverterTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/catalog/CatalogToSchemaDescriptorConverterTest.java
index d21fe73152a..4ce85e19223 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/catalog/CatalogToSchemaDescriptorConverterTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/catalog/CatalogToSchemaDescriptorConverterTest.java
@@ -58,7 +58,7 @@ public class CatalogToSchemaDescriptorConverterTest extends AbstractSchemaConver
private static final int TEST_SCALE = 5;
@ParameterizedTest
- @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION"}, mode = Mode.EXCLUDE)
+ @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Mode.EXCLUDE)
public void convertColumnType(ColumnType typeSpec) {
CatalogTableColumnDescriptor columnDescriptor = TestColumnDescriptors.forSpec(typeSpec);
diff --git a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java
index e702d00eb44..c99a5966f10 100644
--- a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java
+++ b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java
@@ -256,7 +256,7 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
@ParameterizedTest
@EnumSource(value = ColumnType.class,
// TODO: https://issues.apache.org/jira/browse/IGNITE-17373
- names = {"DURATION", "PERIOD"},
+ names = {"DURATION", "PERIOD", "STRUCT"},
mode = Mode.EXCLUDE
)
void testMetadataTypesForDynamicParameters(ColumnType type) {
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 26dee4328d9..1ab2f74f6d2 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
@@ -20,7 +20,7 @@ package org.apache.ignite.internal.sql.engine.exec;
import static org.apache.calcite.rel.RelDistribution.Type.HASH_DISTRIBUTED;
import static org.apache.ignite.internal.sql.engine.rule.LogicalScanConverterRule.createMapping;
import static org.apache.ignite.internal.sql.engine.util.TypeUtils.combinedRowType;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import static org.apache.ignite.internal.util.ArrayUtils.asList;
import static org.apache.ignite.internal.util.CollectionUtils.first;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
@@ -97,7 +97,6 @@ import org.apache.ignite.internal.sql.engine.exec.rel.SortNode;
import org.apache.ignite.internal.sql.engine.exec.rel.TableScanNode;
import org.apache.ignite.internal.sql.engine.exec.rel.TableSpoolNode;
import org.apache.ignite.internal.sql.engine.exec.rel.UnionAllNode;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.prepare.bounds.SearchBounds;
import org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin;
import org.apache.ignite.internal.sql.engine.rel.IgniteExchange;
@@ -356,7 +355,6 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
RelDataType outType = rel.getRowType();
RelDataType leftType = rel.getLeft().getRowType();
RelDataType rightType = rel.getRight().getRowType();
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightType));
assert rel.getJoinType() == JoinRelType.INNER || rel.getJoinType() == JoinRelType.LEFT
: CNLJ_NOT_SUPPORTED_JOIN_ASSERTION_MSG;
@@ -368,7 +366,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
SqlJoinPredicate<RowT> joinPredicate = expressionFactory.joinPredicate(rel.getCondition(), outType, leftType.getFieldCount());
BiPredicate<RowT, RowT> cond = (left, right) -> joinPredicate.test(ctx, left, right);
- RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
+ RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(convertStructuredType(rightType));
Node<RowT> node = new CorrelatedNestedLoopJoinNode<>(ctx, cond, rel.getVariablesSet(),
rel.getJoinType(), rightRowFactory, joinProjection);
@@ -515,8 +513,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
return new ScanNode<>(ctx, Collections.emptyList());
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
PartitionProvider<RowT> partitionProvider = ctx.getPartitionProvider(rel.sourceId(), group, tbl);
return new IndexScanNode<>(
@@ -570,8 +567,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
}
// TODO: IGNITE-22822 fix required columns.
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
PartitionProvider<RowT> partitionProvider = ctx.getPartitionProvider(rel.sourceId(), group, tbl);
@@ -614,8 +610,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
prj = row -> sqlProjection.project(ctx, row);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
return new DataSourceScanNode<>(
ctx,
rowFactory,
@@ -756,8 +751,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
public Node<RowT> visit(IgniteSetOp rel) {
RelDataType rowType = rel.getRowType();
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
List<Node<RowT>> inputs = Commons.transform(rel.getInputs(), this::visit);
int columnNum;
@@ -811,11 +805,9 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
IgniteTable table = rel.getTable().unwrapOrThrow(IgniteTable.class);
UpdatableTable updatableTable = resolvedDependencies.updatableTable(table.id());
RelDataType rowType = rel.getInput().getRowType();
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
ModifyNode<RowT> node = new ModifyNode<>(
- ctx, updatableTable, rel.sourceId(), rel.getOperation(), rel.getUpdateColumnList(), rowFactory
+ ctx, updatableTable, rel.sourceId(), rel.getOperation(), rel.getUpdateColumnList(), convertStructuredType(rowType)
);
Node<RowT> input = visit(rel.getInput());
@@ -830,9 +822,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
public Node<RowT> visit(IgniteReceiver rel) {
RelDataType rowType = rel.getRowType();
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
-
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
RelCollation collation = rel.collation();
Comparator<RowT> comp = null;
@@ -868,8 +858,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
).get(ctx);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
HashAggregateNode<RowT> node = new HashAggregateNode<>(ctx, type, rel.getGroupSets(), accumulators, rowFactory);
@@ -897,8 +886,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
).get(ctx);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
HashAggregateNode<RowT> node = new HashAggregateNode<>(ctx, type, rel.getGroupSets(), accumulators, rowFactory);
@@ -925,8 +913,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
).get(ctx);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
HashAggregateNode<RowT> node = new HashAggregateNode<>(ctx, type, rel.getGroupSets(), accumulators, rowFactory);
@@ -954,8 +941,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
).get(ctx);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
RelCollation collation = rel.collation();
Comparator<RowT> comp = null;
@@ -1002,8 +988,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
).get(ctx);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
RelCollation collation = rel.collation();
Comparator<RowT> comp = null;
@@ -1049,8 +1034,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
).get(ctx);
}
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<RowT> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
RelCollation collation = rel.collation();
Comparator<RowT> comp = null;
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/RowHandler.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/RowHandler.java
index e0dee713cc6..2cf92d15e0e 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/RowHandler.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/RowHandler.java
@@ -20,7 +20,7 @@ package org.apache.ignite.internal.sql.engine.exec;
import java.nio.ByteBuffer;
import org.apache.ignite.internal.lang.InternalTuple;
import org.apache.ignite.internal.schema.BinaryTuple;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/**
@@ -63,7 +63,7 @@ public interface RowHandler<RowT> {
String toString(RowT row);
/** Creates a factory that produces rows with fields defined by the given schema. */
- RowFactory<RowT> factory(RowSchema rowSchema);
+ RowFactory<RowT> factory(StructNativeType rowSchema);
/**
* Provide methods for inner row assembly.
@@ -100,7 +100,7 @@ public interface RowHandler<RowT> {
*
* @return RowSchema.
*/
- RowSchema rowSchema();
+ StructNativeType rowSchema();
/**
* The result row will satisfy the current factory's schema.
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/SqlRowHandler.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/SqlRowHandler.java
index c37540e83d5..3e5ccb61e2e 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/SqlRowHandler.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/SqlRowHandler.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.sql.engine.exec;
import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
import static org.apache.ignite.internal.sql.engine.util.Commons.readValue;
+import static org.apache.ignite.sql.ColumnType.NULL;
import java.math.BigDecimal;
import java.time.Duration;
@@ -34,12 +35,11 @@ import org.apache.ignite.internal.lang.IgniteStringBuilder;
import org.apache.ignite.internal.lang.InternalTuple;
import org.apache.ignite.internal.schema.BinaryTuple;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchemaTypes;
-import org.apache.ignite.internal.sql.engine.exec.row.TypeSpec;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.type.DecimalNativeType;
import org.apache.ignite.internal.type.NativeType;
+import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/**
@@ -55,12 +55,12 @@ import org.jetbrains.annotations.Nullable;
*
* <p>Factory method {@link RowFactory#create(InternalTuple)} allows to
* create rows without any additional conversions. But the fields in
- * binary tuple must match the factory {@link RowSchema row schema}.
+ * binary tuple must match the factory {@link StructNativeType row schema}.
*/
public class SqlRowHandler implements RowHandler<RowWrapper> {
public static final RowHandler<RowWrapper> INSTANCE = new SqlRowHandler();
- private static final ObjectsArrayRowWrapper EMPTY_ROW = new ObjectsArrayRowWrapper(RowSchema.builder().build(), new Object[0]);
+ private static final ObjectsArrayRowWrapper EMPTY_ROW = new ObjectsArrayRowWrapper(NativeTypes.rowBuilder().build(), new Object[0]);
private SqlRowHandler() {
}
@@ -104,7 +104,7 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
}
@Override
- public RowFactory<RowWrapper> factory(RowSchema rowSchema) {
+ public RowFactory<RowWrapper> factory(StructNativeType rowSchema) {
int schemaLen = rowSchema.fields().size();
return new RowFactory<>() {
@@ -143,7 +143,7 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
/** {@inheritDoc} */
@Override
- public RowSchema rowSchema() {
+ public StructNativeType rowSchema() {
return rowSchema;
}
@@ -178,12 +178,12 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
* Wrapper over an array of objects.
*/
private static class ObjectsArrayRowWrapper extends RowWrapper {
- private final RowSchema rowSchema;
+ private final StructNativeType rowType;
private final Object[] row;
- ObjectsArrayRowWrapper(RowSchema rowSchema, Object[] row) {
- assert row.length == rowSchema.fields().size();
- this.rowSchema = rowSchema;
+ ObjectsArrayRowWrapper(StructNativeType rowType, Object[] row) {
+ assert row.length == rowType.fields().size();
+ this.rowType = rowType;
this.row = row;
}
@@ -208,9 +208,9 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
int estimatedSize = 0;
boolean exactEstimate = true;
for (int i = 0; i < row.length; i++) {
- NativeType nativeType = RowSchemaTypes.toNativeType(rowSchema.fields().get(i));
+ NativeType nativeType = rowType.fields().get(i).type();
- if (nativeType == null) {
+ if (nativeType.spec() == NULL) {
assert row[i] == null;
continue;
@@ -247,26 +247,24 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
for (int i = 0; i < row.length; i++) {
Object value = row[i];
- appendValue(tupleBuilder, rowSchema.fields().get(i), value);
+ appendValue(tupleBuilder, rowType.fields().get(i).type(), value);
}
return new BinaryTuple(row.length, tupleBuilder.build());
}
- private static void appendValue(BinaryTupleBuilder builder, TypeSpec schemaType, @Nullable Object value) {
+ private static void appendValue(BinaryTupleBuilder builder, NativeType type, @Nullable Object value) {
if (value == null) {
builder.appendNull();
return;
}
- NativeType nativeType = RowSchemaTypes.toNativeType(schemaType);
+ value = TypeUtils.fromInternal(value, type.spec());
- value = TypeUtils.fromInternal(value, nativeType.spec());
+ assert value != null : type;
- assert value != null : nativeType;
-
- switch (nativeType.spec()) {
+ switch (type.spec()) {
case BOOLEAN:
builder.appendBoolean((boolean) value);
break;
@@ -296,7 +294,7 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
break;
case DECIMAL:
- builder.appendDecimalNotNull((BigDecimal) value, ((DecimalNativeType) nativeType).scale());
+ builder.appendDecimalNotNull((BigDecimal) value, ((DecimalNativeType) type).scale());
break;
case UUID:
@@ -336,7 +334,7 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
break;
default:
- throw new UnsupportedOperationException("Unknown type " + nativeType);
+ throw new UnsupportedOperationException("Unknown type " + type);
}
}
}
@@ -345,11 +343,11 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
* Wrapper over an {@link BinaryTuple}.
*/
private static class BinaryTupleRowWrapper extends RowWrapper {
- private final RowSchema rowSchema;
+ private final StructNativeType rowType;
private final InternalTuple tuple;
- BinaryTupleRowWrapper(RowSchema rowSchema, InternalTuple tuple) {
- this.rowSchema = rowSchema;
+ BinaryTupleRowWrapper(StructNativeType rowType, InternalTuple tuple) {
+ this.rowType = rowType;
this.tuple = tuple;
}
@@ -361,9 +359,9 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
@Override
@Nullable
Object get(int field) {
- NativeType nativeType = RowSchemaTypes.toNativeType(rowSchema.fields().get(field));
+ NativeType nativeType = rowType.fields().get(field).type();
- if (nativeType == null) {
+ if (nativeType.spec() == NULL) {
return null;
}
@@ -395,15 +393,15 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
private final int schemaLen;
- private final RowSchema rowSchema;
+ private final StructNativeType rowType;
Object[] data;
int fieldIdx;
- RowBuilderImpl(RowSchema rowSchema) {
- this.rowSchema = rowSchema;
- this.schemaLen = rowSchema.fields().size();
+ RowBuilderImpl(StructNativeType rowType) {
+ this.rowType = rowType;
+ this.schemaLen = rowType.fields().size();
fieldIdx = 0;
}
@@ -425,7 +423,7 @@ public class SqlRowHandler implements RowHandler<RowWrapper> {
public RowWrapper build() {
checkState();
- return rowSchema.fields().isEmpty() ? EMPTY_ROW : new ObjectsArrayRowWrapper(rowSchema, data);
+ return rowType.fields().isEmpty() ? EMPTY_ROW : new ObjectsArrayRowWrapper(rowType, data);
}
/** {@inheritDoc} */
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/UpdatableTableImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/UpdatableTableImpl.java
index b6e6f63b4b6..dee3c66b9dd 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/UpdatableTableImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/UpdatableTableImpl.java
@@ -22,7 +22,7 @@ import static org.apache.ignite.internal.partition.replicator.network.replicatio
import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_UPSERT_ALL;
import static org.apache.ignite.internal.replicator.message.ReplicaMessageUtils.toReplicationGroupIdMessage;
import static org.apache.ignite.internal.sql.engine.util.RowTypeUtils.rowType;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import static org.apache.ignite.internal.table.distributed.storage.InternalTableImpl.collectRejectedRowsResponses;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
import static org.apache.ignite.lang.ErrorGroups.Sql.CONSTRAINT_VIOLATION_ERR;
@@ -35,7 +35,6 @@ import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.util.Static;
import org.apache.ignite.internal.components.NodeProperties;
@@ -54,7 +53,6 @@ import org.apache.ignite.internal.replicator.message.ReplicationGroupIdMessage;
import org.apache.ignite.internal.schema.BinaryRow;
import org.apache.ignite.internal.schema.BinaryRowEx;
import org.apache.ignite.internal.sql.engine.exec.mapping.ColocationGroup;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.prepare.IgniteSqlValidatorErrorMessages;
import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptor;
import org.apache.ignite.internal.sql.engine.schema.TableDescriptor;
@@ -63,6 +61,7 @@ import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.table.InternalTable;
import org.apache.ignite.internal.table.distributed.storage.RowBatch;
import org.apache.ignite.internal.tx.InternalTransaction;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.sql.SqlException;
import org.jetbrains.annotations.Nullable;
@@ -97,7 +96,7 @@ public final class UpdatableTableImpl implements UpdatableTable {
private final TableRowConverter rowConverter;
- private RowSchema rowSchema;
+ private StructNativeType rowSchema;
/** Constructor. */
UpdatableTableImpl(
@@ -137,7 +136,7 @@ public final class UpdatableTableImpl implements UpdatableTable {
validateNotNullConstraint(ectx.rowHandler(), rows);
RelDataType rowType = rowType(descriptor(), ectx.getTypeFactory());
- Supplier<RowSchema> schemaSupplier = makeSchemaSupplier(ectx);
+ Supplier<StructNativeType> schemaSupplier = makeSchemaSupplier(ectx);
rows = validateCharactersOverflowAndTrimIfPossible(rowType, ectx.rowHandler(), rows, schemaSupplier);
@@ -228,7 +227,7 @@ public final class UpdatableTableImpl implements UpdatableTable {
validateNotNullConstraint(ectx.rowHandler(), row);
RelDataType rowType = rowType(descriptor(), ectx.getTypeFactory());
- Supplier<RowSchema> schemaSupplier = makeSchemaSupplier(ectx);
+ Supplier<StructNativeType> schemaSupplier = makeSchemaSupplier(ectx);
RowT validatedRow = TypeUtils.validateStringTypesOverflowAndTrimIfPossible(rowType, ectx.rowHandler(), row, schemaSupplier);
@@ -259,7 +258,7 @@ public final class UpdatableTableImpl implements UpdatableTable {
validateNotNullConstraint(ectx.rowHandler(), rows);
RelDataType rowType = rowType(descriptor(), ectx.getTypeFactory());
- Supplier<RowSchema> schemaSupplier = makeSchemaSupplier(ectx);
+ Supplier<StructNativeType> schemaSupplier = makeSchemaSupplier(ectx);
rows = validateCharactersOverflowAndTrimIfPossible(rowType, ectx.rowHandler(), rows, schemaSupplier);
@@ -387,8 +386,7 @@ public final class UpdatableTableImpl implements UpdatableTable {
RowHandler<RowT> handler = ectx.rowHandler();
IgniteTypeFactory typeFactory = ectx.getTypeFactory();
- RowSchema rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType(desc, typeFactory)));
- RowHandler.RowFactory<RowT> rowFactory = handler.factory(rowSchema);
+ RowHandler.RowFactory<RowT> rowFactory = handler.factory(convertStructuredType(rowType(desc, typeFactory)));
ArrayList<String> conflictRows = new ArrayList<>(response.size());
@@ -419,7 +417,7 @@ public final class UpdatableTableImpl implements UpdatableTable {
RelDataType rowType,
RowHandler<RowT> rowHandler,
List<RowT> rows,
- Supplier<RowSchema> schemaSupplier
+ Supplier<StructNativeType> schemaSupplier
) {
List<RowT> out = new ArrayList<>(rows.size());
@@ -451,14 +449,14 @@ public final class UpdatableTableImpl implements UpdatableTable {
}
}
- private <RowT> Supplier<RowSchema> makeSchemaSupplier(ExecutionContext<RowT> ectx) {
+ private <RowT> Supplier<StructNativeType> makeSchemaSupplier(ExecutionContext<RowT> ectx) {
return () -> {
if (rowSchema != null) {
return rowSchema;
}
RelDataType rowType = rowType(descriptor(), ectx.getTypeFactory());
- rowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
+ rowSchema = convertStructuredType(rowType);
return rowSchema;
};
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactory.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactory.java
index 9dd8789d586..302a73b73d5 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactory.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactory.java
@@ -83,10 +83,10 @@ public interface ExpressionFactory<RowT> {
* Creates a Project function. Resulting function returns a row with different fields, fields order, fields types, etc.
*
* @param projects Projection expressions.
- * @param rowType Input row type.
+ * @param inputRowType Input row type.
* @return Project function.
*/
- SqlProjection<RowT> project(List<RexNode> projects, RelDataType rowType);
+ SqlProjection<RowT> project(List<RexNode> projects, RelDataType inputRowType);
/**
* Creates a Project function. Resulting function returns a row with different fields, fields order, fields types, etc.
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImpl.java
index aee61662f05..373ff6e6086 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImpl.java
@@ -138,8 +138,8 @@ public class ExpressionFactoryImpl<RowT> implements ExpressionFactory<RowT> {
/** {@inheritDoc} */
@Override
- public SqlProjection<RowT> project(List<RexNode> projects, RelDataType rowType) {
- return projectionImplementor.implement(projects, rowType);
+ public SqlProjection<RowT> project(List<RexNode> projects, RelDataType inputRowType) {
+ return projectionImplementor.implement(projects, inputRowType);
}
/** {@inheritDoc} */
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/JoinProjectionImplementor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/JoinProjectionImplementor.java
index 920f65865a9..d4e9c12e719 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/JoinProjectionImplementor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/JoinProjectionImplementor.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.sql.engine.exec.exp;
import static org.apache.ignite.internal.sql.engine.exec.exp.ExpressionFactoryImpl.digest;
import static org.apache.ignite.internal.sql.engine.util.Commons.cast;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.structuredTypeFromRelTypeList;
import java.lang.reflect.Modifier;
import java.util.List;
@@ -40,11 +41,10 @@ import org.apache.calcite.sql.validate.SqlConformance;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowBuilder;
import org.apache.ignite.internal.sql.engine.exec.exp.RexToLixTranslator.InputGetter;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.IgniteMethod;
-import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.sql.engine.util.cache.Cache;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.lang.ErrorGroups.Sql;
import org.apache.ignite.sql.SqlException;
@@ -82,10 +82,9 @@ class JoinProjectionImplementor {
Cache<String, SqlJoinProjection<RowT>> cache = cast(this.cache);
return cache.get(digest, key -> {
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(RexUtil.types(projections));
SqlJoinProjectionExt<RowT> projectionExt = implementInternal(projections, type, firstRowSize);
- return new SqlJoinProjectionImpl<>(projectionExt, rowSchema);
+ return new SqlJoinProjectionImpl<>(projectionExt, structuredTypeFromRelTypeList(RexUtil.types(projections)));
});
}
@@ -152,21 +151,15 @@ class JoinProjectionImplementor {
private static class SqlJoinProjectionImpl<RowT> implements SqlJoinProjection<RowT> {
private final SqlJoinProjectionExt<RowT> projection;
- private final RowSchema rowSchema;
-
- /**
- * Constructor.
- *
- * @param projection Scalar.
- * @param rowSchema Row factory.
- */
- private SqlJoinProjectionImpl(SqlJoinProjectionExt<RowT> projection, RowSchema rowSchema) {
+ private final StructNativeType rowType;
+
+ private SqlJoinProjectionImpl(SqlJoinProjectionExt<RowT> projection, StructNativeType rowType) {
this.projection = projection;
- this.rowSchema = rowSchema;
+ this.rowType = rowType;
}
private RowBuilder<RowT> builder(ExecutionContext<RowT> context) {
- return context.rowHandler().factory(rowSchema).rowBuilder();
+ return context.rowHandler().factory(rowType).rowBuilder();
}
@Override
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ProjectionImplementor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ProjectionImplementor.java
index 87e18b5d420..c6c07d3ded0 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ProjectionImplementor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ProjectionImplementor.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.sql.engine.exec.exp;
import static org.apache.ignite.internal.sql.engine.exec.exp.ExpressionFactoryImpl.digest;
import static org.apache.ignite.internal.sql.engine.util.Commons.cast;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.structuredTypeFromRelTypeList;
import java.lang.reflect.Modifier;
import java.util.List;
@@ -40,11 +41,10 @@ import org.apache.calcite.sql.validate.SqlConformance;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowBuilder;
import org.apache.ignite.internal.sql.engine.exec.exp.RexToLixTranslator.InputGetter;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.IgniteMethod;
-import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.sql.engine.util.cache.Cache;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.lang.ErrorGroups.Sql;
import org.apache.ignite.sql.SqlException;
@@ -71,25 +71,24 @@ class ProjectionImplementor {
* Implements given list of projections as {@link SqlProjection}.
*
* @param projections The list of projections, i.e. expressions used to compute a new row.
- * @param type The type of the input row.
+ * @param inputRowType The type of the input row.
* @param <RowT> The type of the execution row.
* @return An implementation of projection.
* @see SqlProjection
*/
- public <RowT> SqlProjection<RowT> implement(List<RexNode> projections, RelDataType type) {
- String digest = digest(SqlProjection.class, projections, type);
+ public <RowT> SqlProjection<RowT> implement(List<RexNode> projections, RelDataType inputRowType) {
+ String digest = digest(SqlProjection.class, projections, inputRowType);
Cache<String, SqlProjection<RowT>> cache = cast(this.cache);
return cache.get(digest, key -> {
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(RexUtil.types(projections));
- SqlProjectionExt<RowT> projectionExt = implementInternal(projections, type);
+ SqlProjectionExt<RowT> projectionExt = implementInternal(projections, inputRowType);
- return new SqlProjectionImpl<>(projectionExt, rowSchema);
+ return new SqlProjectionImpl<>(projectionExt, structuredTypeFromRelTypeList(RexUtil.types(projections)));
});
}
- private <RowT> SqlProjectionExt<RowT> implementInternal(List<RexNode> projections, RelDataType type) {
- RexProgramBuilder programBuilder = new RexProgramBuilder(type, rexBuilder);
+ private <RowT> SqlProjectionExt<RowT> implementInternal(List<RexNode> projections, RelDataType inputRowType) {
+ RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder);
for (RexNode node : projections) {
assert node != null : "unexpected nullable node";
@@ -111,7 +110,7 @@ class ProjectionImplementor {
Expression rowHandler = builder.append("hnd", Expressions.call(ctx, IgniteMethod.CONTEXT_ROW_HANDLER.method()));
- InputGetter inputGetter = new FieldGetter(rowHandler, row, type);
+ InputGetter inputGetter = new FieldGetter(rowHandler, row, inputRowType);
Function1<String, InputGetter> correlates = new CorrelatesBuilder(builder, ctx, rowHandler).build(projections);
@@ -150,21 +149,15 @@ class ProjectionImplementor {
private static class SqlProjectionImpl<RowT> implements SqlProjection<RowT> {
private final SqlProjectionExt<RowT> projection;
- private final RowSchema rowSchema;
-
- /**
- * Constructor.
- *
- * @param projection Scalar.
- * @param rowSchema Row factory.
- */
- private SqlProjectionImpl(SqlProjectionExt<RowT> projection, RowSchema rowSchema) {
+ private final StructNativeType rowType;
+
+ private SqlProjectionImpl(SqlProjectionExt<RowT> projection, StructNativeType rowType) {
this.projection = projection;
- this.rowSchema = rowSchema;
+ this.rowType = rowType;
}
private RowBuilder<RowT> builder(ExecutionContext<RowT> context) {
- return context.rowHandler().factory(rowSchema).rowBuilder();
+ return context.rowHandler().factory(rowType).rowBuilder();
}
@Override
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RowProviderImplementor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RowProviderImplementor.java
index 78c0a2362c3..f500e85c6aa 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RowProviderImplementor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RowProviderImplementor.java
@@ -43,13 +43,13 @@ import org.apache.calcite.sql.validate.SqlConformance;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowBuilder;
import org.apache.ignite.internal.sql.engine.exec.exp.RexToLixTranslator.InputGetter;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.IgniteMethod;
import org.apache.ignite.internal.sql.engine.util.Primitives;
import org.apache.ignite.internal.sql.engine.util.RexUtils;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.sql.engine.util.cache.Cache;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.lang.ErrorGroups.Sql;
import org.apache.ignite.sql.SqlException;
@@ -98,9 +98,9 @@ class RowProviderImplementor {
Cache<String, SqlRowProvider<RowT>> cache = cast(this.cache);
return cache.get(digest, key -> {
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(typeList);
+ StructNativeType rowType = TypeUtils.structuredTypeFromRelTypeList(typeList);
- return new SqlRowProviderImpl<>(implementInternal(values), rowSchema);
+ return new SqlRowProviderImpl<>(implementInternal(values), rowType);
});
}
@@ -110,8 +110,8 @@ class RowProviderImplementor {
literalValues.add((RexLiteral) values.get(i));
}
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(typeList);
- return new ConstantRow<>(literalValues, types, rowSchema);
+ StructNativeType rowType = TypeUtils.structuredTypeFromRelTypeList(typeList);
+ return new ConstantRow<>(literalValues, types, rowType);
}
private <RowT> SqlRowProviderExt<RowT> implementInternal(List<RexNode> values) {
@@ -174,8 +174,8 @@ class RowProviderImplementor {
private static class SqlRowProviderImpl<RowT> extends AbstractRowProvider<RowT> {
private final SqlRowProviderExt<RowT> rowProvider;
- private SqlRowProviderImpl(SqlRowProviderExt<RowT> rowProvider, RowSchema rowSchema) {
- super(rowSchema);
+ private SqlRowProviderImpl(SqlRowProviderExt<RowT> rowProvider, StructNativeType rowType) {
+ super(rowType);
this.rowProvider = rowProvider;
}
@@ -190,8 +190,8 @@ class RowProviderImplementor {
private final List<RexLiteral> values;
private final List<Class<?>> types;
- private ConstantRow(List<RexLiteral> values, List<Class<?>> types, RowSchema rowSchema) {
- super(rowSchema);
+ private ConstantRow(List<RexLiteral> values, List<Class<?>> types, StructNativeType rowType) {
+ super(rowType);
this.values = values;
this.types = types;
@@ -211,14 +211,14 @@ class RowProviderImplementor {
}
private abstract static class AbstractRowProvider<RowT> implements SqlRowProvider<RowT> {
- private final RowSchema rowSchema;
+ private final StructNativeType rowType;
- private AbstractRowProvider(RowSchema rowSchema) {
- this.rowSchema = rowSchema;
+ private AbstractRowProvider(StructNativeType rowType) {
+ this.rowType = rowType;
}
private RowBuilder<RowT> builder(ExecutionContext<RowT> context) {
- return context.rowHandler().factory(rowSchema).rowBuilder();
+ return context.rowHandler().factory(rowType).rowBuilder();
}
abstract void buildRow(ExecutionContext<RowT> context, RowBuilder<RowT> rowBuilder);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ValuesImplementor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ValuesImplementor.java
index 8c1bb0c881d..178d7dd1454 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ValuesImplementor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ValuesImplementor.java
@@ -26,10 +26,10 @@ import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexLiteral;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowBuilder;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.Primitives;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
+import org.apache.ignite.internal.type.StructNativeType;
/** Implementor which implements {@link SqlScalar} returning list of rows. */
class ValuesImplementor {
@@ -51,12 +51,12 @@ class ValuesImplementor {
<RowT> SqlScalar<RowT, List<RowT>> implement(List<List<RexLiteral>> values, RelDataType rowType) {
List<RelDataType> typeList = RelOptUtil.getFieldTypeList(rowType);
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(typeList);
+ StructNativeType structNativeType = TypeUtils.structuredTypeFromRelTypeList(typeList);
List<Class<?>> types = Commons.transform(typeList, type -> Primitives.wrap((Class<?>) typeFactory.getJavaClass(type)));
return context -> {
List<RowT> results = new ArrayList<>(values.size());
- RowBuilder<RowT> rowBuilder = context.rowHandler().factory(rowSchema).rowBuilder();
+ RowBuilder<RowT> rowBuilder = context.rowHandler().factory(structNativeType).rowBuilder();
for (List<RexLiteral> row : values) {
for (int i = 0; i < types.size(); i++) {
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/func/SystemRangeTableFunction.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/func/SystemRangeTableFunction.java
index 908ab5cab9f..f2d84fcf873 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/func/SystemRangeTableFunction.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/func/SystemRangeTableFunction.java
@@ -22,16 +22,16 @@ import java.util.Objects;
import java.util.function.Supplier;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/** Implementation of {@link IgniteSqlOperatorTable#SYSTEM_RANGE system range function}. */
public final class SystemRangeTableFunction<RowT> implements TableFunction<RowT> {
- private final RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.INT64)
+ private final StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("X", NativeTypes.INT64, false)
.build();
private final Supplier<Long> startExpr;
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/HashJoinNode.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/HashJoinNode.java
index 2cf74b79a4b..9013a1752cc 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/HashJoinNode.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/HashJoinNode.java
@@ -18,7 +18,7 @@
package org.apache.ignite.internal.sql.engine.exec.rel;
import static org.apache.ignite.internal.sql.engine.util.Commons.cast;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.ArrayList;
@@ -29,7 +29,6 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.BiPredicate;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.core.JoinInfo;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.type.RelDataType;
@@ -37,7 +36,7 @@ import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlJoinProjection;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/** HashJoin implementor. */
@@ -104,7 +103,7 @@ public abstract class HashJoinNode<RowT> extends AbstractRightMaterializedJoinNo
case LEFT: {
assert projection != null;
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightRowType));
+ StructNativeType rightRowSchema = convertStructuredType(rightRowType);
RowHandler.RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
return new LeftHashJoin<>(ctx, joinInfo, projection, rightRowFactory, nonEquiCondition);
@@ -112,7 +111,7 @@ public abstract class HashJoinNode<RowT> extends AbstractRightMaterializedJoinNo
case RIGHT: {
assert projection != null;
- RowSchema leftRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(leftRowType));
+ StructNativeType leftRowSchema = convertStructuredType(leftRowType);
RowHandler.RowFactory<RowT> leftRowFactory = ctx.rowHandler().factory(leftRowSchema);
return new RightHashJoin<>(ctx, joinInfo, projection, leftRowFactory, nonEquiCondition);
@@ -120,8 +119,8 @@ public abstract class HashJoinNode<RowT> extends AbstractRightMaterializedJoinNo
case FULL: {
assert projection != null;
- RowSchema leftRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(leftRowType));
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightRowType));
+ StructNativeType leftRowSchema = convertStructuredType(leftRowType);
+ StructNativeType rightRowSchema = convertStructuredType(rightRowType);
RowHandler.RowFactory<RowT> leftRowFactory = ctx.rowHandler().factory(leftRowSchema);
RowHandler.RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/MergeJoinNode.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/MergeJoinNode.java
index c7cbb2a0367..d381ef47d13 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/MergeJoinNode.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/MergeJoinNode.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.sql.engine.exec.rel;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
import java.util.ArrayDeque;
@@ -25,7 +25,6 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.Deque;
import java.util.List;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.ignite.internal.lang.IgniteStringBuilder;
@@ -33,7 +32,7 @@ import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlJoinProjection;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/**
@@ -227,7 +226,7 @@ public abstract class MergeJoinNode<RowT> extends AbstractNode<RowT> {
case LEFT: {
assert outputProjection != null;
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightRowType));
+ StructNativeType rightRowSchema = convertStructuredType(rightRowType);
RowHandler.RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
return new LeftJoin<>(ctx, comp, outputProjection, rightRowFactory);
@@ -236,7 +235,7 @@ public abstract class MergeJoinNode<RowT> extends AbstractNode<RowT> {
case RIGHT: {
assert outputProjection != null;
- RowSchema leftRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(leftRowType));
+ StructNativeType leftRowSchema = convertStructuredType(leftRowType);
RowHandler.RowFactory<RowT> leftRowFactory = ctx.rowHandler().factory(leftRowSchema);
return new RightJoin<>(ctx, comp, outputProjection, leftRowFactory);
@@ -245,8 +244,8 @@ public abstract class MergeJoinNode<RowT> extends AbstractNode<RowT> {
case FULL: {
assert outputProjection != null;
- RowSchema leftRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(leftRowType));
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightRowType));
+ StructNativeType leftRowSchema = convertStructuredType(leftRowType);
+ StructNativeType rightRowSchema = convertStructuredType(rightRowType);
RowHandler.RowFactory<RowT> leftRowFactory = ctx.rowHandler().factory(leftRowSchema);
RowHandler.RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNode.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNode.java
index 4506cfc9d9a..98f92d35258 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNode.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNode.java
@@ -34,12 +34,13 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.UpdatableTable;
import org.apache.ignite.internal.sql.engine.exec.mapping.ColocationGroup;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptor;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.schema.TableDescriptor;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
+import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.internal.util.Pair;
import org.jetbrains.annotations.Nullable;
@@ -76,8 +77,8 @@ import org.jetbrains.annotations.Nullable;
*/
public class ModifyNode<RowT> extends AbstractNode<RowT> implements SingleNode<RowT>, Downstream<RowT> {
- private static final RowSchema MODIFY_RESULT = RowSchema.builder()
- .addField(NativeTypes.INT64)
+ private static final StructNativeType MODIFY_RESULT = NativeTypes.rowBuilder()
+ .addField("UPDATE_COUNT", NativeTypes.INT64, false)
.build();
private final TableModify.Operation modifyOp;
@@ -114,7 +115,7 @@ public class ModifyNode<RowT> extends AbstractNode<RowT> implements SingleNode<R
* @param sourceId Source id.
* @param op A type of the update operation.
* @param updateColumns Enumeration of columns to update if applicable.
- * @param inputRowFactory Row factory for input row.
+ * @param inputRowType Input row type.
*/
public ModifyNode(
ExecutionContext<RowT> ctx,
@@ -122,7 +123,7 @@ public class ModifyNode<RowT> extends AbstractNode<RowT> implements SingleNode<R
long sourceId,
TableModify.Operation op,
@Nullable List<String> updateColumns,
- RowFactory<RowT> inputRowFactory
+ StructNativeType inputRowType
) {
super(ctx);
@@ -131,9 +132,7 @@ public class ModifyNode<RowT> extends AbstractNode<RowT> implements SingleNode<R
this.modifyOp = op;
this.updateColumns = updateColumns;
- RowSchema rowSchema = inputRowFactory.rowSchema();
- int fullRowSize = rowSchema.fields().size();
- this.mapping = mapping(table.descriptor(), updateColumns, fullRowSize);
+ this.mapping = mapping(table.descriptor(), updateColumns, inputRowType.fieldsCount());
// insert mapping actually can be required only for INSERT and MERGE operations
if (op == Operation.INSERT || op == Operation.MERGE) {
@@ -145,8 +144,8 @@ public class ModifyNode<RowT> extends AbstractNode<RowT> implements SingleNode<R
this.insertRowMapping = null;
}
- RowSchema mappedRowSchema = mapping != null ? RowSchema.map(rowSchema, mapping) : rowSchema;
- RowSchema mappedInsertRowSchema = insertRowMapping != null ? RowSchema.map(rowSchema, insertRowMapping) : rowSchema;
+ StructNativeType mappedRowSchema = mapping != null ? TypeUtils.map(inputRowType, mapping) : inputRowType;
+ StructNativeType mappedInsertRowSchema = insertRowMapping != null ? TypeUtils.map(inputRowType, insertRowMapping) : inputRowType;
this.mappedRowFactory = ctx.rowHandler().factory(mappedRowSchema);
this.mappedInsertRowFactory = ctx.rowHandler().factory(mappedInsertRowSchema);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/NestedLoopJoinNode.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/NestedLoopJoinNode.java
index 8792861c3be..3d86ee417f1 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/NestedLoopJoinNode.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/rel/NestedLoopJoinNode.java
@@ -17,20 +17,19 @@
package org.apache.ignite.internal.sql.engine.exec.rel;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.PrimitiveIterator;
import java.util.function.BiPredicate;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlJoinProjection;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/**
@@ -105,7 +104,7 @@ public abstract class NestedLoopJoinNode<RowT> extends AbstractRightMaterialized
case LEFT: {
assert joinProjection != null;
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightRowType));
+ StructNativeType rightRowSchema = convertStructuredType(rightRowType);
RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
return new LeftJoin<>(ctx, cond, joinProjection, rightRowFactory);
@@ -114,7 +113,7 @@ public abstract class NestedLoopJoinNode<RowT> extends AbstractRightMaterialized
case RIGHT: {
assert joinProjection != null;
- RowSchema leftRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(leftRowType));
+ StructNativeType leftRowSchema = convertStructuredType(leftRowType);
RowFactory<RowT> leftRowFactory = ctx.rowHandler().factory(leftRowSchema);
return new RightJoin<>(ctx, cond, joinProjection, leftRowFactory);
@@ -123,8 +122,8 @@ public abstract class NestedLoopJoinNode<RowT> extends AbstractRightMaterialized
case FULL: {
assert joinProjection != null;
- RowSchema leftRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(leftRowType));
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightRowType));
+ StructNativeType leftRowSchema = convertStructuredType(leftRowType);
+ StructNativeType rightRowSchema = convertStructuredType(rightRowType);
RowFactory<RowT> leftRowFactory = ctx.rowHandler().factory(leftRowSchema);
RowFactory<RowT> rightRowFactory = ctx.rowHandler().factory(rightRowSchema);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/BaseTypeSpec.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/BaseTypeSpec.java
deleted file mode 100644
index 55c5453d67f..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/BaseTypeSpec.java
+++ /dev/null
@@ -1,78 +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.sql.engine.exec.row;
-
-import java.util.Objects;
-import org.apache.ignite.internal.tostring.S;
-import org.apache.ignite.internal.type.NativeType;
-
-/**
- * Base type represents a {@link NativeType}.
- */
-public class BaseTypeSpec extends TypeSpec {
-
- private final NativeType nativeType;
-
- /** Creates a basic type with default nullability (non-nullable). */
- BaseTypeSpec(NativeType nativeType) {
- super(false);
- this.nativeType = nativeType;
- }
-
- /** Creates a basic type with the given nullability. */
- public BaseTypeSpec(NativeType nativeType, boolean nullable) {
- super(nullable);
- // TODO Uncomment his check after https://issues.apache.org/jira/browse/IGNITE-20163 is fixed
- // this.nativeType = Objects.requireNonNull(nativeType, "native type has not been specified.");
- this.nativeType = nativeType;
- }
-
- /** Returns a native type that this base type represents. */
- public NativeType nativeType() {
- return nativeType;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- if (!super.equals(o)) {
- return false;
- }
- BaseTypeSpec that = (BaseTypeSpec) o;
- return Objects.equals(nativeType, that.nativeType);
- }
-
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return Objects.hash(super.hashCode(), nativeType);
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return S.toString(BaseTypeSpec.class, this, "nullable", isNullable());
- }
-
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/NullTypeSpec.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/NullTypeSpec.java
deleted file mode 100644
index eb6fb8227d7..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/NullTypeSpec.java
+++ /dev/null
@@ -1,47 +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.sql.engine.exec.row;
-
-import org.apache.ignite.internal.tostring.S;
-
-/** A type for untyped null. This type is used to represent untyped null produced the optimizer. */
-public final class NullTypeSpec extends TypeSpec {
-
- /** Constructor. */
- NullTypeSpec() {
- super(true);
- }
-
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean equals(Object obj) {
- return super.equals(obj);
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return S.toString(NullTypeSpec.class, this);
- }
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchema.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchema.java
deleted file mode 100644
index 1d3cbb693eb..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchema.java
+++ /dev/null
@@ -1,136 +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.sql.engine.exec.row;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import org.apache.ignite.internal.tostring.S;
-import org.apache.ignite.internal.type.NativeType;
-
-/**
- * Row schema used by execution engine.
- */
-public final class RowSchema {
- private final List<TypeSpec> fields;
-
- private RowSchema(List<TypeSpec> types) {
- this.fields = types;
- }
-
- /** A list of schema fields. */
- public List<TypeSpec> fields() {
- return fields;
- }
-
-
- /** {@inheritDoc}. */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- RowSchema rowSchema = (RowSchema) o;
- return Objects.equals(fields, rowSchema.fields);
- }
-
- /** {@inheritDoc}. */
- @Override
- public int hashCode() {
- return Objects.hash(fields);
- }
-
- /** {@inheritDoc}. */
- @Override
- public String toString() {
- return S.toString(RowSchema.class, this, "fields", this.fields);
- }
-
- /** Creates a builder that creates instances of row schemas. */
- public static Builder builder() {
- return new Builder();
- }
-
- /** Row schema builder. */
- public static class Builder {
-
- private final List<TypeSpec> types = new ArrayList<>();
-
- private Builder() {
-
- }
-
- /** Adds a field of the given type. */
- public Builder addField(TypeSpec typeSpec) {
- types.add(typeSpec);
- return this;
- }
-
- /** Adds a field of the given non-nullable native type. */
- public Builder addField(NativeType nativeType) {
- return addField(nativeType, false);
- }
-
- /** Adds a field of the given native type with the specified nullability. */
- public Builder addField(NativeType nativeType, boolean nullable) {
- types.add(new BaseTypeSpec(nativeType, nullable));
- return this;
- }
-
- /** Creates an instance of row schema. */
- public RowSchema build() {
- return new RowSchema(types);
- }
- }
-
- /**
- * Creates a new schema based on original schema and provided mapping.
- */
- public static RowSchema map(RowSchema schema, int[] mapping) {
- assert mapping != null && mapping.length > 0;
-
- List<TypeSpec> fields = schema.fields();
- Builder builder = builder();
-
- for (int i : mapping) {
- TypeSpec typeSpec = fields.get(i);
- builder.addField(typeSpec);
- }
-
- return builder.build();
- }
-
- /**
- * Creates a new schema as a concatenation of the given schemas.
- */
- public static RowSchema concat(RowSchema left, RowSchema right) {
- Builder builder = builder();
-
- for (TypeSpec typeSpec : left.fields()) {
- builder.addField(typeSpec);
- }
- for (TypeSpec typeSpec : right.fields()) {
- builder.addField(typeSpec);
- }
-
- return builder.build();
- }
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTypes.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTypes.java
deleted file mode 100644
index 97835612d85..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTypes.java
+++ /dev/null
@@ -1,106 +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.sql.engine.exec.row;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
-import org.apache.ignite.internal.type.NativeType;
-import org.apache.ignite.internal.type.NativeTypes;
-import org.apache.ignite.internal.util.Pair;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Defines methods to provide instances of {@link TypeSpec}s.
- */
-public final class RowSchemaTypes {
-
- /** NULL type. */
- public static final NullTypeSpec NULL = new NullTypeSpec();
-
- /** Map of {@code <not nullable, nullable>} {@link BaseTypeSpec}s.*/
- static final Map<NativeType, Pair<BaseTypeSpec, BaseTypeSpec>> INTERNED_TYPES;
-
- static {
- List<NativeType> nativeTypeList = Arrays.asList(
- NativeTypes.BOOLEAN,
- NativeTypes.INT8,
- NativeTypes.INT16,
- NativeTypes.INT32,
- NativeTypes.INT64,
- NativeTypes.FLOAT,
- NativeTypes.DOUBLE,
- NativeTypes.STRING,
- NativeTypes.BYTES,
- NativeTypes.DATE,
- NativeTypes.UUID
- );
-
- INTERNED_TYPES = nativeTypeList.stream().map(t -> {
- BaseTypeSpec notNull = new BaseTypeSpec(t, false);
- BaseTypeSpec nullable = new BaseTypeSpec(t, true);
-
- return Map.entry(t, new Pair<>(notNull, nullable));
- }).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
- }
-
- private RowSchemaTypes() {
-
- }
-
- /** Returns a non-nullable {@link BaseTypeSpec} that corresponds to the given native type without nullability. */
- public static BaseTypeSpec nativeType(NativeType nativeType) {
- return nativeTypeWithNullability(nativeType, false);
- }
-
- /** Returns a {@link BaseTypeSpec} that corresponds to the given native type with the specified nullability. */
- public static BaseTypeSpec nativeTypeWithNullability(NativeType nativeType, boolean nullable) {
- Pair<BaseTypeSpec, BaseTypeSpec> typePair = INTERNED_TYPES.get(nativeType);
-
- if (typePair != null) {
- return nullable ? typePair.getSecond() : typePair.getFirst();
- } else {
- return new BaseTypeSpec(nativeType, nullable);
- }
- }
-
- /**
- * Convert specified schema {@link TypeSpec type} to {@link NativeType native type}.
- *
- * @param type Row schema type.
- * @return Native type or {@code null} if type is a {@link NullTypeSpec}.
- * @throws IllegalArgumentException If provided type cannot be converted to a native type.
- */
- public static @Nullable NativeType toNativeType(TypeSpec type) {
- if (type instanceof NullTypeSpec) {
- return null;
- }
-
- if (!(type instanceof BaseTypeSpec)) {
- throw new IllegalArgumentException("Unexpected type; " + type);
- }
-
- NativeType nativeType = ((BaseTypeSpec) type).nativeType();
-
- assert nativeType != null : type;
-
- return nativeType;
- }
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowType.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowType.java
deleted file mode 100644
index f0615b4c0f7..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/RowType.java
+++ /dev/null
@@ -1,72 +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.sql.engine.exec.row;
-
-import java.util.List;
-import java.util.Objects;
-import org.apache.ignite.internal.tostring.S;
-
-/**
- * Row type is a type that consists of a list of other {@link TypeSpec}s.
- */
-public class RowType extends TypeSpec {
-
- private final List<TypeSpec> fields;
-
- /** Creates a row type with the given nullability. */
- public RowType(List<TypeSpec> fields, boolean nullable) {
- super(nullable);
- if (fields.isEmpty()) {
- throw new IllegalArgumentException("Field list can not be empty");
- }
- this.fields = fields;
- }
-
- /** A list of types this row consists of. */
- public List<TypeSpec> fields() {
- return fields;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- if (!super.equals(o)) {
- return false;
- }
- RowType that = (RowType) o;
- return Objects.equals(fields, that.fields);
- }
-
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return Objects.hash(super.hashCode(), fields);
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return S.toString(RowType.class, this, "nullable", isNullable());
- }
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/TypeSpec.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/TypeSpec.java
deleted file mode 100644
index 07a8e86d143..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/row/TypeSpec.java
+++ /dev/null
@@ -1,57 +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.sql.engine.exec.row;
-
-import java.util.Objects;
-
-/**
- * Base class for types of fields of {@link RowSchema}.
- */
-public abstract class TypeSpec {
-
- private final boolean nullable;
-
- /** Constructor. */
- public TypeSpec(boolean nullable) {
- this.nullable = nullable;
- }
-
- /** Returns {@code true} if values of this type can be {@code null}. */
- public boolean isNullable() {
- return nullable;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- TypeSpec typeSpec = (TypeSpec) o;
- return nullable == typeSpec.nullable;
- }
-
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return Objects.hash(nullable);
- }
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
index 683a63757fb..97678c141a7 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
@@ -18,13 +18,13 @@
package org.apache.ignite.internal.sql.engine.prepare;
import static org.apache.ignite.internal.sql.engine.util.Commons.cast;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableIntList;
@@ -45,7 +45,6 @@ import org.apache.ignite.internal.sql.engine.exec.ScannableTable;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlPredicate;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlProjection;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlRowProvider;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.prepare.partitionawareness.PartitionAwarenessMetadata;
import org.apache.ignite.internal.sql.engine.prepare.pruning.PartitionPruningMetadata;
import org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueGet;
@@ -57,6 +56,7 @@ import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.IteratorToDataCursorAdapter;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.tx.InternalTransaction;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.sql.ResultSetMetadata;
import org.jetbrains.annotations.Nullable;
@@ -175,8 +175,9 @@ public class KeyValueGetPlan implements ExplainablePlan, ExecutablePlan {
SqlProjection<RowT> projection = projectionExpr == null ? null : ctx.expressionFactory().project(projectionExpr, rowType);
RowHandler<RowT> rowHandler = ctx.rowHandler();
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
- RowFactory<RowT> rowFactory = rowHandler.factory(rowSchema);
+ StructNativeType nativeType = convertStructuredType(rowType);
+
+ RowFactory<RowT> rowFactory = rowHandler.factory(nativeType);
List<RexNode> keyExpressions = lookupNode.keyExpressions();
SqlRowProvider<RowT> keySupplier = ctx.expressionFactory().rowSource(keyExpressions);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java
index 6bff7395ade..e851b600357 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java
@@ -40,7 +40,6 @@ import org.apache.ignite.internal.sql.engine.exec.ExecutableTableRegistry;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlProjection;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.prepare.partitionawareness.PartitionAwarenessMetadata;
import org.apache.ignite.internal.sql.engine.prepare.pruning.PartitionPruningMetadata;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
@@ -53,6 +52,7 @@ import org.apache.ignite.internal.sql.engine.util.IteratorToDataCursorAdapter;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.tx.InternalTransaction;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.sql.ResultSetMetadata;
import org.jetbrains.annotations.Nullable;
@@ -171,13 +171,12 @@ public class SelectCountPlan implements ExplainablePlan, ExecutablePlan {
RowHandler<RowT> rowHandler = ctx.rowHandler();
SchemaAwareConverter<Object, Object> internalTypeConverter = TypeUtils.resultTypeConverter(resultType);
+ StructNativeType rowType = NativeTypes.rowBuilder()
+ .addField("COUNT", NativeTypes.INT64, false)
+ .build();
return rowCount -> {
- RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.INT64)
- .build();
-
- RowT rowCountRow = ctx.rowHandler().factory(rowSchema)
+ RowT rowCountRow = ctx.rowHandler().factory(rowType)
.rowBuilder()
.addField(rowCount)
.build();
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
index 570fc8e947b..cda666dc12d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
@@ -43,7 +43,9 @@ import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rel.type.RelDataTypeSystem;
+import org.apache.calcite.rel.type.RelRecordType;
import org.apache.calcite.sql.SqlIntervalQualifier;
import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.parser.SqlParserPos;
@@ -55,6 +57,7 @@ import org.apache.ignite.internal.sql.engine.util.IgniteCustomAssignmentsRules;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
import org.jetbrains.annotations.Nullable;
/**
@@ -235,16 +238,21 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
}
/**
- * Gets ColumnType type for RelDataType.
+ * Converts given {@link RelDataType relation type} to {@link NativeType native type}.
*
* @param relType Rel type.
- * @return ColumnType type or null.
+ * @return Native type. Never null.
+ * @throws IllegalArgumentException If conversion is not supported for given relation type.
*/
- public static NativeType relDataTypeToNative(RelDataType relType) {
+ public static NativeType relDataTypeToNative(RelDataType relType) throws IllegalArgumentException {
assert relType instanceof BasicSqlType
- || relType instanceof IntervalSqlType : "Not supported:" + relType;
+ || relType instanceof IntervalSqlType
+ || relType instanceof RelRecordType
+ : "Not supported: " + relType;
switch (relType.getSqlTypeName()) {
+ case NULL:
+ return NativeTypes.NULL;
case BOOLEAN:
return NativeTypes.BOOLEAN;
case TINYINT:
@@ -277,7 +285,7 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
// TODO: https://issues.apache.org/jira/browse/IGNITE-17373
- throw new IllegalArgumentException("Type is not supported yet: " + relType);
+ return NativeTypes.PERIOD;
case INTERVAL_DAY:
case INTERVAL_DAY_HOUR:
case INTERVAL_DAY_MINUTE:
@@ -289,7 +297,7 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
case INTERVAL_MINUTE_SECOND:
case INTERVAL_SECOND:
// TODO: https://issues.apache.org/jira/browse/IGNITE-17373
- throw new IllegalArgumentException("Type is not supported yet:" + relType);
+ return NativeTypes.DURATION;
case VARCHAR:
case CHAR:
return relType.getPrecision() == PRECISION_NOT_SPECIFIED
@@ -302,6 +310,14 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
: NativeTypes.blobOf(relType.getPrecision());
case UUID:
return NativeTypes.UUID;
+ case ROW:
+ RowTypeBuilder builder = NativeTypes.rowBuilder();
+
+ for (RelDataTypeField field : relType.getFieldList()) {
+ builder.addField(field.getName(), relDataTypeToNative(field.getType()), field.getType().isNullable());
+ }
+
+ return builder.build();
case ANY:
default:
throw new IllegalArgumentException("Type is not supported: " + relType);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
index 527afe7231e..eddc3196661 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
@@ -32,7 +32,6 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneOffset;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
@@ -49,8 +48,6 @@ import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
-import org.apache.calcite.sql.type.BasicSqlType;
-import org.apache.calcite.sql.type.IntervalSqlType;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeName.Limit;
import org.apache.calcite.sql.type.SqlTypeUtil;
@@ -58,16 +55,13 @@ import org.apache.ignite.internal.sql.engine.SchemaAwareConverter;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowBuilder;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
-import org.apache.ignite.internal.sql.engine.exec.row.BaseTypeSpec;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchemaTypes;
-import org.apache.ignite.internal.sql.engine.exec.row.RowType;
-import org.apache.ignite.internal.sql.engine.exec.row.TypeSpec;
import org.apache.ignite.internal.sql.engine.prepare.ParameterType;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.type.DecimalNativeType;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.internal.type.TemporalNativeType;
import org.apache.ignite.internal.type.VarlenNativeType;
import org.apache.ignite.sql.ColumnMetadata;
@@ -165,7 +159,9 @@ public class TypeUtils {
private static class SupportedParamClassesHolder {
// TODO: https://issues.apache.org/jira/browse/IGNITE-17373
- static final Set<ColumnType> UNSUPPORTED_COLUMN_TYPES_AS_PARAMETERS = Set.of(ColumnType.PERIOD, ColumnType.DURATION);
+ static final Set<ColumnType> UNSUPPORTED_COLUMN_TYPES_AS_PARAMETERS = Set.of(
+ ColumnType.PERIOD, ColumnType.DURATION, ColumnType.STRUCT
+ );
static final Set<Class<?>> SUPPORTED_PARAM_CLASSES;
static {
@@ -557,6 +553,8 @@ public class TypeUtils {
/** Converts {@link ColumnType} to corresponding {@link NativeType}. */
public static NativeType columnType2NativeType(ColumnType columnType, int precision, int scale, int length) {
switch (columnType) {
+ case NULL:
+ return NativeTypes.NULL;
case BOOLEAN:
return NativeTypes.BOOLEAN;
case INT8:
@@ -590,7 +588,6 @@ public class TypeUtils {
// fallthrough
case PERIOD:
case DURATION:
- case NULL:
default:
throw new IllegalArgumentException("No NativeType for type: " + columnType);
}
@@ -710,58 +707,81 @@ public class TypeUtils {
return true;
}
- /** Creates an instance of {@link RowSchema} from a list of the given {@link RelDataType}s. */
- public static RowSchema rowSchemaFromRelTypes(List<RelDataType> types) {
- RowSchema.Builder fieldTypes = RowSchema.builder();
+ /**
+ * Converts a relational record type to a {@link StructNativeType}.
+ *
+ * <p>This method takes a {@link RelDataType} and converts it to its native struct representation using the {@link IgniteTypeFactory}.
+ * The method validates that the resulting native type is indeed a struct type.
+ *
+ * @param recordType The relational data type to convert; must represent a record/struct type.
+ * @return The corresponding {@code StructNativeType}.
+ * @throws IllegalArgumentException If the provided type cannot be converted to a struct type or does not represent a record
+ * type.
+ * @see IgniteTypeFactory#relDataTypeToNative(RelDataType)
+ */
+ public static StructNativeType convertStructuredType(RelDataType recordType) {
+ NativeType result = IgniteTypeFactory.relDataTypeToNative(recordType);
- for (RelDataType relType : types) {
- TypeSpec typeSpec = convertToTypeSpec(relType);
- fieldTypes.addField(typeSpec);
+ if (result instanceof StructNativeType) {
+ return (StructNativeType) result;
}
- return fieldTypes.build();
+ throw new IllegalArgumentException("Provided type is not record type: " + recordType);
}
- private static TypeSpec convertToTypeSpec(RelDataType type) {
- boolean simpleType = type instanceof BasicSqlType;
- boolean nullable = type.isNullable();
-
- if (SqlTypeName.ANY == type.getSqlTypeName()) {
- // TODO Some JSON functions that return ANY as well : https://issues.apache.org/jira/browse/IGNITE-20163
- return new BaseTypeSpec(null, nullable);
- } else if (SqlTypeUtil.isNull(type)) {
- return RowSchemaTypes.NULL;
- } else if (simpleType) {
- NativeType nativeType = IgniteTypeFactory.relDataTypeToNative(type);
- return RowSchemaTypes.nativeTypeWithNullability(nativeType, nullable);
- } else if (type instanceof IntervalSqlType) {
- IntervalSqlType intervalType = (IntervalSqlType) type;
- boolean yearMonth = intervalType.getIntervalQualifier().isYearMonth();
-
- if (yearMonth) {
- // YEAR MONTH interval is stored as number of days in ints.
- return RowSchemaTypes.nativeTypeWithNullability(NativeTypes.PERIOD, nullable);
- } else {
- // DAY interval is stored as time as long.
- return RowSchemaTypes.nativeTypeWithNullability(NativeTypes.DURATION, nullable);
- }
- } else if (SqlTypeUtil.isRow(type)) {
- List<TypeSpec> fields = new ArrayList<>();
+ /**
+ * Creates a {@link StructNativeType} from a list of relational data types.
+ *
+ * <p>This method constructs a struct where each field is automatically named using the pattern "F0", "F1", "F2", etc., corresponding to
+ * the position of the type in the input list. Each field's type is converted to its native equivalent, and nullability is preserved
+ * from the original relational type.
+ *
+ * <p>Example: Given types [INT, STRING, BOOLEAN], this creates a struct with fields:
+ * <ul>
+ * <li>F0: INT (nullable as per input type)</li>
+ * <li>F1: STRING (nullable as per input type)</li>
+ * <li>F2: BOOLEAN (nullable as per input type)</li>
+ * </ul>
+ *
+ * @param types The list of relational data types to convert; must not be null.
+ * @return A new {@code StructNativeType} with auto-generated field names.
+ * @see IgniteTypeFactory#relDataTypeToNative(RelDataType)
+ */
+ public static StructNativeType structuredTypeFromRelTypeList(List<RelDataType> types) {
+ RowTypeBuilder builder = NativeTypes.rowBuilder();
- for (RelDataTypeField field : type.getFieldList()) {
- TypeSpec fieldTypeSpec = convertToTypeSpec(field.getType());
- fields.add(fieldTypeSpec);
- }
+ int idx = 0;
+ for (RelDataType type : types) {
+ builder.addField("F" + idx++, IgniteTypeFactory.relDataTypeToNative(type), type.isNullable());
+ }
- return new RowType(fields, type.isNullable());
+ return builder.build();
+ }
- } else if (SqlTypeUtil.isMap(type) || SqlTypeUtil.isMultiset(type) || SqlTypeUtil.isArray(type)) {
- // TODO https://issues.apache.org/jira/browse/IGNITE-20162
- // Add collection types support
- throw new IllegalArgumentException("Collection types is not supported: " + type);
- } else {
- throw new IllegalArgumentException("Unexpected type: " + type);
+ /**
+ * Creates a new {@link StructNativeType} by selecting and reordering fields from an existing schema.
+ *
+ * <p>This method produces a struct containing only the fields specified by the mapping array, in the order they appear in the mapping.
+ * Fields are referenced by their index in the original schema. The same field can be included multiple times if its index appears
+ * multiple times in the mapping.
+ *
+ * <p>Example: Given a schema with fields [A, B, C, D] and mapping [2, 0, 2], the result will contain fields [C, A, C].
+ *
+ * @param schema The source struct schema to map from; must not be null.
+ * @param mapping The array of field indices specifying which fields to include and their order; must not be null or empty, and
+ * all indices must be valid for the schema.
+ * @return A new {@code StructNativeType} containing the mapped fields.
+ */
+ public static StructNativeType map(StructNativeType schema, int[] mapping) {
+ assert mapping != null && mapping.length > 0;
+
+ RowTypeBuilder builder = NativeTypes.rowBuilder();
+
+ for (int i : mapping) {
+ builder.addField(schema.fields().get(i));
}
+
+ return builder.build();
}
/** Check limitation for character and binary types and throws exception if row does not fit into type defined.
@@ -789,7 +809,7 @@ public class TypeUtils {
RelDataType rowType,
RowHandler<RowT> rowHandler,
RowT row,
- Supplier<RowSchema> schema
+ Supplier<StructNativeType> schema
) {
boolean containValidatedType =
rowType.getFieldList().stream().anyMatch(t -> STRING_TYPES.contains(t.getType().getSqlTypeName()));
@@ -871,7 +891,9 @@ public class TypeUtils {
}
}
- private static <RowT> RowBuilder<RowT> buildPartialRow(RowHandler<RowT> rowHandler, Supplier<RowSchema> schema, int endPos, RowT row) {
+ private static <RowT> RowBuilder<RowT> buildPartialRow(
+ RowHandler<RowT> rowHandler, Supplier<StructNativeType> schema, int endPos, RowT row
+ ) {
RowFactory<RowT> factory = rowHandler.factory(schema.get());
RowBuilder<RowT> bldr = factory.rowBuilder();
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java
index 18643885bce..de6d431a28d 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java
@@ -28,13 +28,13 @@ import java.util.Collection;
import java.util.List;
import org.apache.calcite.rel.RelDistribution.Type;
import org.apache.ignite.internal.sql.engine.exec.mapping.ColocationGroup;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.trait.Destination;
import org.apache.ignite.internal.sql.engine.trait.DistributionFunction.IdentityDistribution;
import org.apache.ignite.internal.sql.engine.trait.Identity;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -50,9 +50,9 @@ public class IdentityDistributionFunctionSelfTest {
private final RowHandler<Object[]> rowHandler = ArrayRowHandler.INSTANCE;
- private final RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.STRING)
+ private final StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, true)
+ .addField("C2", NativeTypes.STRING, true)
.build();
private final ColocationGroup colocationGroup = new ColocationGroup(LongList.of(1L), List.of(NODE_1, NODE_2, NODE_3),
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/PartitionsResolutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/PartitionsResolutionTest.java
index 0240546e205..eb650ced3be 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/PartitionsResolutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/PartitionsResolutionTest.java
@@ -26,7 +26,6 @@ import org.apache.calcite.rel.type.RelDataTypeFactory.Builder;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.planner.AbstractPlannerTest.TestTableDescriptor;
import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptor;
import org.apache.ignite.internal.sql.engine.schema.PartitionCalculator;
@@ -35,6 +34,7 @@ import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.junit.jupiter.api.Test;
/** Assignments resolution test. */
@@ -93,11 +93,11 @@ public class PartitionsResolutionTest {
return extractor.partition(row);
}
- private final RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
+ private final StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, true)
+ .addField("C2", NativeTypes.INT32, true)
+ .addField("C3", NativeTypes.INT32, true)
+ .addField("C4", NativeTypes.INT32, true)
.build();
private static TableDescriptor createTableDescriptor(List<Integer> distrKeys) {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ProjectedTableRowConverterSelfTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ProjectedTableRowConverterSelfTest.java
index 36e18de50ec..4a04de15aba 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ProjectedTableRowConverterSelfTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ProjectedTableRowConverterSelfTest.java
@@ -33,10 +33,10 @@ import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.SchemaRegistry;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -69,9 +69,9 @@ public class ProjectedTableRowConverterSelfTest extends BaseIgniteAbstractTest {
null
);
- RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C2", NativeTypes.INT32, false)
.build();
RowHandler<RowWrapper> rowHandler = SqlRowHandler.INSTANCE;
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/TableRowConverterSelfTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/TableRowConverterSelfTest.java
index 019867afb6d..2ca3abfe59e 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/TableRowConverterSelfTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/TableRowConverterSelfTest.java
@@ -37,11 +37,11 @@ import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.SchemaRegistry;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.schema.TableDescriptor;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.internal.util.ColocationUtils;
import org.apache.ignite.internal.util.HashCalculator;
import org.jetbrains.annotations.Nullable;
@@ -77,9 +77,9 @@ public class TableRowConverterSelfTest extends BaseIgniteAbstractTest {
null
);
- RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C2", NativeTypes.INT32, false)
.build();
RowHandler<RowWrapper> rowHandler = SqlRowHandler.INSTANCE;
@@ -116,11 +116,11 @@ public class TableRowConverterSelfTest extends BaseIgniteAbstractTest {
null
);
- RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.BOOLEAN)
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C2", NativeTypes.BOOLEAN, false)
+ .addField("C3", NativeTypes.INT32, false)
+ .addField("C4", NativeTypes.INT32, false)
.build();
RowHandler<RowWrapper> rowHandler = SqlRowHandler.INSTANCE;
@@ -166,9 +166,9 @@ public class TableRowConverterSelfTest extends BaseIgniteAbstractTest {
List.of(keyColumnNames[colocationColumn])
);
- RowSchema rowSchema = RowSchema.builder()
- .addField(schema.keyColumns().get(0).type())
- .addField(schema.keyColumns().get(1).type())
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", schema.keyColumns().get(0).type(), false)
+ .addField("C2", schema.keyColumns().get(1).type(), false)
.build();
RowHandler<RowWrapper> rowHandler = SqlRowHandler.INSTANCE;
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImplTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImplTest.java
index 534f70e31de..4477f49fcac 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImplTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/exp/ExpressionFactoryImplTest.java
@@ -882,7 +882,8 @@ public class ExpressionFactoryImplTest extends BaseIgniteAbstractTest {
EnumSet<ColumnType> ignoredTypes = EnumSet.of(
// TODO https://issues.apache.org/jira/browse/IGNITE-17373
ColumnType.DURATION,
- ColumnType.PERIOD
+ ColumnType.PERIOD,
+ ColumnType.STRUCT
);
List<Arguments> arguments = new ArrayList<>();
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AsyncRootNodeTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AsyncRootNodeTest.java
index a018e32a73d..6c5173fbe12 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AsyncRootNodeTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AsyncRootNodeTest.java
@@ -46,8 +46,8 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.ScannableDataSource;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.internal.util.AsyncCursor.BatchedResult;
import org.junit.jupiter.api.Test;
@@ -56,8 +56,8 @@ import org.junit.jupiter.api.Test;
*/
@SuppressWarnings("NumericCastThatLosesPrecision")
class AsyncRootNodeTest extends AbstractExecutionTest<RowWrapper> {
- private static final RowSchema SINGLE_INT_ROW_SCHEMA = RowSchema.builder()
- .addField(NativeTypes.INT32)
+ private static final StructNativeType SINGLE_INT_ROW_SCHEMA = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.INT32, true)
.build();
private static final BinaryTupleSchema SINGLE_INT_SCHEMA = BinaryTupleSchema.create(
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java
index 34dc7e642b8..ab1c4873189 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java
@@ -36,11 +36,9 @@ import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
@@ -51,12 +49,13 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.AccumulatorWrapper;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.Accumulators;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.AggregateType;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.lang.ErrorGroups.Sql;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
@@ -765,25 +764,26 @@ public abstract class BaseAggregateTest extends AbstractExecutionTest<Object[]>
return ctx.expressionFactory().accumulatorsFactory(type, asList(call), inRowType).get(ctx);
}
- protected static RowSchema createOutputSchema(
+ protected static StructNativeType createOutputSchema(
ExecutionContext<Object[]> ctx,
AggregateCall call,
RelDataType inRowType,
ImmutableBitSet grpSet
) {
- RelDataTypeFactory.Builder outputType = new RelDataTypeFactory.Builder(ctx.getTypeFactory());
+ RowTypeBuilder builder = NativeTypes.rowBuilder();
// Add keys
for (int i = 0; i < grpSet.length(); i++) {
if (grpSet.get(i)) {
- outputType.add("F" + i, inRowType.getFieldList().get(i).getType());
+ RelDataType type = inRowType.getFieldList().get(i).getType();
+ builder.addField("F" + i, IgniteTypeFactory.relDataTypeToNative(type), type.isNullable());
}
}
// Add aggregation result
- outputType.add("R0", call.getType());
+ builder.addField("R0", IgniteTypeFactory.relDataTypeToNative(call.getType()), false);
- return TypeUtils.rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(outputType.build()));
+ return builder.build();
}
enum TestAggregateType {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/CorrelatedNestedLoopJoinExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/CorrelatedNestedLoopJoinExecutionTest.java
index 36f2d3a00fc..0477ca78ca7 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/CorrelatedNestedLoopJoinExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/CorrelatedNestedLoopJoinExecutionTest.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.sql.engine.exec.rel;
import static org.apache.calcite.rel.core.JoinRelType.INNER;
import static org.apache.calcite.rel.core.JoinRelType.LEFT;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -32,14 +32,12 @@ import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.exp.func.IterableTableFunction;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.sql.engine.util.Commons;
@@ -77,14 +75,12 @@ public class CorrelatedNestedLoopJoinExecutionTest extends AbstractExecutionTest
IgniteTypeFactory tf = ctx.getTypeFactory();
RelDataType rightType = TypeUtils.createRowType(tf, TypeUtils.native2relationalTypes(tf, NativeTypes.INT32, NativeTypes.STRING));
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightType));
-
CorrelatedNestedLoopJoinNode<Object[]> join = new CorrelatedNestedLoopJoinNode<>(
ctx,
(r1, r2) -> Objects.equals(hnd.get(2, r1), hnd.get(0, r2)),
Set.of(new CorrelationId(0)),
joinType,
- hnd.factory(rightRowSchema),
+ hnd.factory(convertStructuredType(rightType)),
identityProjection()
);
@@ -233,8 +229,6 @@ public class CorrelatedNestedLoopJoinExecutionTest extends AbstractExecutionTest
IgniteTypeFactory tf = ctx.getTypeFactory();
RelDataType rightType = TypeUtils.createRowType(tf, TypeUtils.native2relationalTypes(tf, NativeTypes.INT32, NativeTypes.STRING));
- RowSchema rightRowSchema = rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rightType));
-
RowHandler<Object[]> hnd = ctx.rowHandler();
return new CorrelatedNestedLoopJoinNode<>(
@@ -242,7 +236,7 @@ public class CorrelatedNestedLoopJoinExecutionTest extends AbstractExecutionTest
(r1, r2) -> Objects.equals(hnd.get(2, r1), hnd.get(0, r2)),
Set.of(new CorrelationId(0)),
joinType,
- hnd.factory(rightRowSchema),
+ hnd.factory(convertStructuredType(rightType)),
identityProjection()
);
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/DataSourceScanNodeExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/DataSourceScanNodeExecutionTest.java
index 362b69a7747..1028a991096 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/DataSourceScanNodeExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/DataSourceScanNodeExecutionTest.java
@@ -48,23 +48,23 @@ import org.apache.ignite.internal.sql.engine.exec.ScannableDataSource;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
import org.apache.ignite.internal.sql.engine.exec.TestDownstream;
-import org.apache.ignite.internal.sql.engine.exec.row.BaseTypeSpec;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
-import org.apache.ignite.internal.sql.engine.exec.row.TypeSpec;
import org.apache.ignite.internal.sql.engine.framework.DataProvider;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
+import org.apache.ignite.internal.type.StructNativeType;
+import org.apache.ignite.internal.type.StructNativeType.Field;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test;
/** Tests to verify {@link DataSourceScanNode}. */
@SuppressWarnings("resource")
public class DataSourceScanNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
- private static final RowSchema ROW_SCHEMA = RowSchema.builder()
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT64)
- .addField(NativeTypes.INT8)
- .addField(NativeTypes.stringOf(64))
- .addField(NativeTypes.UUID)
+ private static final StructNativeType ROW_SCHEMA = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.INT32, true)
+ .addField("C2", NativeTypes.INT64, true)
+ .addField("C3", NativeTypes.INT8, true)
+ .addField("C4", NativeTypes.stringOf(64), true)
+ .addField("C5", NativeTypes.UUID, true)
.build();
private static final BinaryTupleSchema TUPLE_SCHEMA = fromRowSchema(ROW_SCHEMA);
@@ -242,7 +242,7 @@ public class DataSourceScanNodeExecutionTest extends AbstractExecutionTest<RowWr
private void checkDataSourceScan(int bufferSize, int sourceSize) {
ExecutionContext<RowWrapper> ctx = executionContext(bufferSize);
- RowSchema schema = RowSchema.builder().addField(NativeTypes.INT32).build();
+ StructNativeType schema = NativeTypes.rowBuilder().addField("C1", NativeTypes.INT32, true).build();
RowFactory<RowWrapper> rowFactory = ctx.rowHandler().factory(schema);
BinaryTupleSchema tupleSchema = fromRowSchema(schema);
TupleFactory tupleFactory = tupleFactoryFromSchema(tupleSchema);
@@ -340,23 +340,22 @@ public class DataSourceScanNodeExecutionTest extends AbstractExecutionTest<RowWr
return SqlRowHandler.INSTANCE;
}
- private static BinaryTupleSchema fromRowSchema(RowSchema schema) {
+ private static BinaryTupleSchema fromRowSchema(StructNativeType schema) {
Element[] elements = new Element[schema.fields().size()];
int idx = 0;
- for (TypeSpec spec : schema.fields()) {
- assert spec instanceof BaseTypeSpec : spec;
-
- elements[idx++] = new Element(((BaseTypeSpec) spec).nativeType(), spec.isNullable());
+ for (Field field : schema.fields()) {
+ elements[idx++] = new Element(field.type(), field.nullable());
}
return BinaryTupleSchema.create(elements);
}
- private static RowSchema project(RowSchema schema, int[] projection) {
- RowSchema.Builder builder = RowSchema.builder();
+ private static StructNativeType project(StructNativeType schema, int[] projection) {
+ RowTypeBuilder builder = NativeTypes.rowBuilder();
for (int i : projection) {
- builder.addField(schema.fields().get(i));
+ Field field = schema.fields().get(i);
+ builder.addField(field.name(), field.type(), field.nullable());
}
return builder.build();
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ExchangeExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ExchangeExecutionTest.java
index 0bace4eaf6a..6ed8c850ee9 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ExchangeExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ExchangeExecutionTest.java
@@ -61,7 +61,6 @@ import org.apache.ignite.internal.sql.engine.exec.QueryTaskExecutor;
import org.apache.ignite.internal.sql.engine.exec.QueryTaskExecutorImpl;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.mapping.FragmentDescription;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.framework.ClusterServiceFactory;
import org.apache.ignite.internal.sql.engine.framework.DataProvider;
@@ -76,6 +75,7 @@ import org.apache.ignite.internal.testframework.IgniteTestUtils.PredicateMatcher
import org.apache.ignite.internal.testframework.matchers.CompletableFutureExceptionMatcher;
import org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.internal.util.AsyncCursor.BatchedResult;
import org.apache.ignite.internal.util.IgniteSpinBusyLock;
import org.apache.ignite.network.NetworkAddress;
@@ -112,9 +112,9 @@ public class ExchangeExecutionTest extends AbstractExecutionTest<Object[]> {
* Schema of the rows used in the tests. All data providers created within this test class must
* conform to this row schema.
*/
- private static final RowSchema ROW_SCHEMA = RowSchema.builder()
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
+ private static final StructNativeType ROW_SCHEMA = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.INT32, true)
+ .addField("C2", NativeTypes.INT32, true)
.build();
private final Map<String, MailboxRegistry> mailboxes = new HashMap<>();
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java
index 3444b8f24e9..d79b14d08be 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java
@@ -25,7 +25,6 @@ import static org.apache.ignite.internal.util.CollectionUtils.first;
import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.core.AggregateCall;
@@ -36,12 +35,12 @@ import org.apache.calcite.util.mapping.Mapping;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlComparator;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.rel.agg.MapReduceAggregates;
import org.apache.ignite.internal.sql.engine.rel.agg.MapReduceAggregates.MapReduceAgg;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.PlanUtils;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
+import org.apache.ignite.internal.type.StructNativeType;
/**
* HashAggregateExecutionTest.
@@ -61,7 +60,7 @@ public class HashAggregateExecutionTest extends BaseAggregateTest {
assert grpSets.size() == 1 : "Test checks only simple GROUP BY";
ImmutableBitSet grpSet = grpSets.get(0);
- RowSchema outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
+ StructNativeType outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
RowFactory<Object[]> outputRowFactory = ctx.rowHandler().factory(outputRowSchema);
HashAggregateNode<Object[]> agg = new HashAggregateNode<>(
@@ -122,8 +121,7 @@ public class HashAggregateExecutionTest extends BaseAggregateTest {
// Map node
RelDataType reduceRowType = PlanUtils.createHashAggRowType(grpSets, ctx.getTypeFactory(), inRowType, List.of(call));
- RowSchema reduceRowSchema = TypeUtils.rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(reduceRowType));
- RowFactory<Object[]> mapRowFactory = ctx.rowHandler().factory(reduceRowSchema);
+ RowFactory<Object[]> mapRowFactory = ctx.rowHandler().factory(TypeUtils.convertStructuredType(reduceRowType));
HashAggregateNode<Object[]> aggMap = new HashAggregateNode<>(
ctx,
@@ -147,7 +145,7 @@ public class HashAggregateExecutionTest extends BaseAggregateTest {
true
);
- RowSchema outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
+ StructNativeType outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
RowFactory<Object[]> outputRowFactory = ctx.rowHandler().factory(outputRowSchema);
HashAggregateNode<Object[]> aggRdc = new HashAggregateNode<>(
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateSingleGroupExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateSingleGroupExecutionTest.java
index 094567aad66..8bb26622346 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateSingleGroupExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateSingleGroupExecutionTest.java
@@ -26,7 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.List;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.type.RelDataType;
@@ -40,7 +39,6 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.AccumulatorWrapper;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.AggregateType;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.rel.agg.MapReduceAggregates;
import org.apache.ignite.internal.sql.engine.rel.agg.MapReduceAggregates.MapReduceAgg;
@@ -378,8 +376,7 @@ public class HashAggregateSingleGroupExecutionTest extends AbstractExecutionTest
List<AccumulatorWrapper<Object[]>> accumulators =
ctx.expressionFactory().accumulatorsFactory(aggregateType, List.of(call), inputType).get(ctx);
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(outputType));
- RowFactory<Object[]> rowFactory = rowHandler().factory(rowSchema);
+ RowFactory<Object[]> rowFactory = rowHandler().factory(TypeUtils.convertStructuredType(outputType));
return new HashAggregateNode<>(ctx, aggregateType, grpSets, accumulators, rowFactory);
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IndexScanNodeExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IndexScanNodeExecutionTest.java
index 028594bb23c..8e83a21362f 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IndexScanNodeExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IndexScanNodeExecutionTest.java
@@ -49,7 +49,6 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.ScannableTable;
import org.apache.ignite.internal.sql.engine.exec.exp.RangeCondition;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.framework.DataProvider;
import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
@@ -64,6 +63,8 @@ import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.tx.InternalTransaction;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -162,7 +163,7 @@ public class IndexScanNodeExecutionTest extends AbstractExecutionTest<Object[]>
SingleRangeIterable<Object[]> conditions = new SingleRangeIterable<>(new Object[]{}, null, false, false);
- RowSchema schema = RowSchema.builder().addField(NativeTypes.INT32).build();
+ StructNativeType schema = NativeTypes.rowBuilder().addField("C1", NativeTypes.INT32, false).build();
RowFactory<Object[]> rowFactory = ctx.rowHandler().factory(schema);
TableDescriptor tableDescriptor = createTableDescriptor(columns);
@@ -271,13 +272,14 @@ public class IndexScanNodeExecutionTest extends AbstractExecutionTest<Object[]>
private static IndexScanNode<Object[]> createIndexNode(ExecutionContext<Object[]> ctx, IgniteIndex indexDescriptor,
TableDescriptor tableDescriptor, TestScannableTable<?> scannableTable, @Nullable Comparator<Object[]> comparator) {
- RowSchema.Builder rowSchemaBuilder = RowSchema.builder();
+ RowTypeBuilder rowSchemaBuilder = NativeTypes.rowBuilder();
+ int idx = 0;
for (RelFieldCollation ignored : indexDescriptor.collation().getFieldCollations()) {
- rowSchemaBuilder = rowSchemaBuilder.addField(NativeTypes.INT32);
+ rowSchemaBuilder = rowSchemaBuilder.addField("C" + idx++, NativeTypes.INT32, true);
}
- RowSchema rowSchema = rowSchemaBuilder.build();
+ StructNativeType rowSchema = rowSchemaBuilder.build();
RowFactory<Object[]> rowFactory = ctx.rowHandler().factory(rowSchema);
SingleRangeIterable<Object[]> conditions = new SingleRangeIterable<>(new Object[]{}, null, false, false);
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IntersectExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IntersectExecutionTest.java
index 170528d3cee..3998934d2d2 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IntersectExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/IntersectExecutionTest.java
@@ -22,8 +22,8 @@ import java.util.List;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.AggregateType;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
/**
* Test execution of INTERSECT operator.
@@ -34,25 +34,25 @@ public class IntersectExecutionTest extends AbstractSetOpExecutionTest {
protected AbstractSetOpNode<Object[]> setOpNodeFactory(ExecutionContext<Object[]> ctx,
AggregateType type, int columnCount, boolean all, int inputsCnt) {
- RowSchema rowSchema;
+ StructNativeType rowSchema;
switch (type) {
case MAP:
- rowSchema = RowSchema.builder()
+ rowSchema = NativeTypes.rowBuilder()
// input columns
- .addField(NativeTypes.STRING)
+ .addField("C1", NativeTypes.STRING, false)
// counters
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
+ .addField("C2", NativeTypes.INT32, false)
+ .addField("C3", NativeTypes.INT32, false)
+ .addField("C4", NativeTypes.INT32, false)
+ .addField("C5", NativeTypes.INT32, false)
.build();
break;
case REDUCE:
case SINGLE:
- rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
+ rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C2", NativeTypes.INT32, false)
.build();
break;
default:
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/MinusExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/MinusExecutionTest.java
index 388d1e073fe..d290f74878c 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/MinusExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/MinusExecutionTest.java
@@ -21,8 +21,8 @@ import java.util.Arrays;
import java.util.List;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.exp.agg.AggregateType;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
/**
* Test execution of MINUS (EXCEPT) operator.
@@ -33,24 +33,24 @@ public class MinusExecutionTest extends AbstractSetOpExecutionTest {
protected AbstractSetOpNode<Object[]> setOpNodeFactory(ExecutionContext<Object[]> ctx,
AggregateType type, int columnCount, boolean all, int inputsCnt) {
- RowSchema rowSchema;
+ StructNativeType rowSchema;
switch (type) {
case MAP:
- rowSchema = RowSchema.builder()
+ rowSchema = NativeTypes.rowBuilder()
// input columns
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C1", NativeTypes.INT32, false)
// counters
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT32)
+ .addField("C1", NativeTypes.INT32, false)
+ .addField("C1", NativeTypes.INT32, false)
.build();
break;
case REDUCE:
case SINGLE:
- rowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
+ rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C1", NativeTypes.INT32, false)
.build();
break;
default:
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNodeExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNodeExecutionTest.java
index 4f0791b2392..c227f6ddb66 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNodeExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ModifyNodeExecutionTest.java
@@ -52,9 +52,6 @@ import org.apache.ignite.internal.sql.engine.exec.TestDownstream;
import org.apache.ignite.internal.sql.engine.exec.UpdatableTable;
import org.apache.ignite.internal.sql.engine.exec.mapping.ColocationGroup;
import org.apache.ignite.internal.sql.engine.exec.mapping.FragmentDescription;
-import org.apache.ignite.internal.sql.engine.exec.row.BaseTypeSpec;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema.Builder;
import org.apache.ignite.internal.sql.engine.framework.DataProvider;
import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptor;
import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptorImpl;
@@ -63,6 +60,9 @@ import org.apache.ignite.internal.sql.engine.schema.TableDescriptor;
import org.apache.ignite.internal.sql.engine.schema.TableDescriptorImpl;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
+import org.apache.ignite.internal.type.StructNativeType;
+import org.apache.ignite.internal.type.StructNativeType.Field;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
@@ -83,23 +83,22 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
private static final long SOURCE_ID = 42;
- private static final RowSchema INT_LONG_SCHEMA = RowSchema.builder()
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT64)
+ private static final StructNativeType INT_LONG_SCHEMA = NativeTypes.rowBuilder()
+ .addField("C0", NativeTypes.INT32, true)
+ .addField("C1", NativeTypes.INT64, true)
.build();
@SuppressWarnings("OverridableMethodCallDuringObjectConstruction")
private final RowHandler<RowWrapper> handler = rowHandler();
- private final RowHandler.RowFactory<RowWrapper> rowFactory = handler.factory(INT_LONG_SCHEMA);
@Mock
private UpdatableTable updatableTable;
@BeforeEach
void setUpMock() {
- RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.INT64)
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.INT32, false)
+ .addField("C2", NativeTypes.INT64, false)
.build();
TableDescriptor tableDescriptor = createTableDescriptor(rowSchema);
@@ -114,7 +113,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
Node<RowWrapper> sourceNode = createSource(sourceSize, context);
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.INSERT, null, rowFactory
+ context, updatableTable, SOURCE_ID, Operation.INSERT, null, INT_LONG_SCHEMA
);
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
@@ -147,7 +146,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
Node<RowWrapper> sourceNode = createSource(sourceSize, context);
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.UPDATE, null, rowFactory
+ context, updatableTable, SOURCE_ID, Operation.UPDATE, null, INT_LONG_SCHEMA
);
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
@@ -180,7 +179,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
Node<RowWrapper> sourceNode = createSource(sourceSize, context);
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.DELETE, null, rowFactory
+ context, updatableTable, SOURCE_ID, Operation.DELETE, null, INT_LONG_SCHEMA
);
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
@@ -213,7 +212,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
Node<RowWrapper> sourceNode = createSource(sourceSize, context);
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.INSERT, null, rowFactory
+ context, updatableTable, SOURCE_ID, Operation.INSERT, null, INT_LONG_SCHEMA
);
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
@@ -241,7 +240,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
Node<RowWrapper> sourceNode = createSource(sourceSize, context);
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.UPDATE, null, rowFactory
+ context, updatableTable, SOURCE_ID, Operation.UPDATE, null, INT_LONG_SCHEMA
);
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
@@ -269,7 +268,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
Node<RowWrapper> sourceNode = createSource(sourceSize, context);
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.DELETE, null, rowFactory
+ context, updatableTable, SOURCE_ID, Operation.DELETE, null, INT_LONG_SCHEMA
);
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
@@ -326,27 +325,27 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
ExecutionContext<RowWrapper> context = executionContext();
RowHandler<RowWrapper> rowHandler = context.rowHandler();
- RowSchema.Builder dstRowSchemaBuilder = RowSchema.builder();
+ RowTypeBuilder dstRowSchemaBuilder = NativeTypes.rowBuilder();
for (int i = 0; i < colCount; i++) {
- dstRowSchemaBuilder.addField(NativeTypes.INT32, true);
+ dstRowSchemaBuilder.addField("C" + i, NativeTypes.INT32, true);
}
- RowSchema dstRowSchema = dstRowSchemaBuilder.build();
+ StructNativeType dstRowSchema = dstRowSchemaBuilder.build();
- RowSchema.Builder srcRowSchemaBuilder = RowSchema.builder();
+ RowTypeBuilder srcRowSchemaBuilder = NativeTypes.rowBuilder();
for (int i = 0; i < colCount; i++) {
- srcRowSchemaBuilder.addField(NativeTypes.INT32, true);
+ srcRowSchemaBuilder.addField("C" + i, NativeTypes.INT32, true);
}
- RowSchema srcRowSchema = srcRowSchemaBuilder.build();
+ StructNativeType srcRowSchema = srcRowSchemaBuilder.build();
- RowSchema updateSchema = RowSchema.builder()
- .addField(NativeTypes.INT32, true)
+ StructNativeType updateSchema = NativeTypes.rowBuilder()
+ .addField("C0", NativeTypes.INT32, true)
.build();
- RowSchema mergeRowSchema = RowSchema.concat(RowSchema.concat(srcRowSchema, dstRowSchema), updateSchema);
+ StructNativeType mergeRowSchema = concat(srcRowSchema, dstRowSchema, updateSchema);
Mockito.reset(updatableTable);
@@ -393,13 +392,6 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
RowWrapper mergeRow1 = concatRow(mergeRowFactory, srcRow1, dstRow1, noUpdate);
RowWrapper mergeRow2 = concatRow(mergeRowFactory, srcRow2, dstRow2, update);
- Builder inputRowBuilder = RowSchema.builder();
- srcFactory.rowSchema().fields().forEach(inputRowBuilder::addField);
- dstFactory.rowSchema().fields().forEach(inputRowBuilder::addField);
- inputRowBuilder.addField(NativeTypes.INT32, true); // updated field value
-
- RowFactory<RowWrapper> inputRowFactory = rowHandler.factory(inputRowBuilder.build());
-
Node<RowWrapper> sourceNode = new ScanNode<>(
context, DataProvider.fromCollection(List.of(mergeRow1, mergeRow2))
);
@@ -407,7 +399,7 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
TestDownstream<RowWrapper> downstream = new TestDownstream<>();
ModifyNode<RowWrapper> modifyNode = new ModifyNode<>(
- context, updatableTable, SOURCE_ID, Operation.MERGE, List.of("C1"), inputRowFactory
+ context, updatableTable, SOURCE_ID, Operation.MERGE, List.of("C1"), mergeRowSchema
);
modifyNode.register(List.of(sourceNode));
modifyNode.onRegister(downstream);
@@ -454,19 +446,19 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
return builder.build();
}
- private static TableDescriptor createTableDescriptor(RowSchema rowSchema) {
+ private static TableDescriptor createTableDescriptor(StructNativeType rowSchema) {
List<ColumnDescriptor> columns = new ArrayList<>();
for (int i = 0; i < rowSchema.fields().size(); i++) {
- BaseTypeSpec typeSpec = (BaseTypeSpec) rowSchema.fields().get(i);
+ Field field = rowSchema.fields().get(i);
ColumnDescriptorImpl col = new ColumnDescriptorImpl(
- "C" + i,
+ field.name(),
false,
false,
false,
- typeSpec.isNullable(),
+ field.nullable(),
i,
- typeSpec.nativeType(),
+ field.type(),
DefaultValueStrategy.DEFAULT_NULL,
null
);
@@ -495,9 +487,9 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
return rowCount / MODIFY_BATCH_SIZE + (rowCount % MODIFY_BATCH_SIZE == 0 ? 0 : 1);
}
- private Node<RowWrapper> createSource(int rowCount, ExecutionContext<RowWrapper> context) {
+ private static Node<RowWrapper> createSource(int rowCount, ExecutionContext<RowWrapper> context) {
return new ScanNode<>(
- context, DataProvider.fromRow(rowFactory.create(1, 1L), rowCount)
+ context, DataProvider.fromRow(context.rowHandler().factory(INT_LONG_SCHEMA).create(1, 1L), rowCount)
);
}
@@ -511,4 +503,16 @@ public class ModifyNodeExecutionTest extends AbstractExecutionTest<RowWrapper> {
ColocationGroup colocationGroup = new ColocationGroup(LongList.of(), List.of(), Int2ObjectMaps.emptyMap());
return new FragmentDescription(0, true, Long2ObjectMaps.singleton(SOURCE_ID, colocationGroup), null, null, null);
}
+
+ private static StructNativeType concat(StructNativeType... types) {
+ RowTypeBuilder builder = NativeTypes.rowBuilder();
+
+ for (StructNativeType type : types) {
+ for (Field field : type.fields()) {
+ builder.addField(field.name(), field.type(), field.nullable());
+ }
+ }
+
+ return builder.build();
+ }
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ScannableTableSelfTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ScannableTableSelfTest.java
index 0b60d17f050..03ae832cef8 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ScannableTableSelfTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/ScannableTableSelfTest.java
@@ -70,17 +70,17 @@ import org.apache.ignite.internal.sql.engine.exec.ScannableTableImpl;
import org.apache.ignite.internal.sql.engine.exec.TableRowConverter;
import org.apache.ignite.internal.sql.engine.exec.TxAttributes;
import org.apache.ignite.internal.sql.engine.exec.exp.RangeCondition;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.framework.NoOpTransaction;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.sql.engine.util.Commons;
+import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.table.IndexScanCriteria;
import org.apache.ignite.internal.table.InternalTable;
import org.apache.ignite.internal.table.OperationContext;
import org.apache.ignite.internal.table.TxContext;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
-import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.hamcrest.Matchers;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Named;
@@ -613,7 +613,7 @@ public class ScannableTableSelfTest extends BaseIgniteAbstractTest {
final RelDataType rowType;
- final RowSchema rowSchema;
+ final StructNativeType rowSchema;
final BitSet indexColumns = new BitSet();
@@ -623,17 +623,14 @@ public class ScannableTableSelfTest extends BaseIgniteAbstractTest {
TestInput(int columnCount) {
Builder builder = new Builder(TYPE_FACTORY);
- RowSchema.Builder rowSchema = RowSchema.builder();
-
for (int i = 1; i <= columnCount; i++) {
builder.add("C" + i, SqlTypeName.INTEGER);
- rowSchema.addField(NativeTypes.INT32);
}
indexColumns.set(0);
rowType = builder.build();
- this.rowSchema = rowSchema.build();
+ this.rowSchema = TypeUtils.convertStructuredType(rowType);
}
void addRow(BinaryRow row) {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/SortAggregateExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/SortAggregateExecutionTest.java
index 823de37eb8b..bd177444c40 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/SortAggregateExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/SortAggregateExecutionTest.java
@@ -27,7 +27,6 @@ import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
-import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.core.AggregateCall;
@@ -38,11 +37,11 @@ import org.apache.calcite.util.mapping.Mapping;
import org.apache.ignite.internal.sql.engine.exec.ExecutionContext;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlComparator;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.rel.agg.MapReduceAggregates;
import org.apache.ignite.internal.sql.engine.rel.agg.MapReduceAggregates.MapReduceAgg;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
+import org.apache.ignite.internal.type.StructNativeType;
/**
* SortAggregateExecutionTest.
@@ -74,7 +73,7 @@ public class SortAggregateExecutionTest extends BaseAggregateTest {
cmp = (r1, r2) -> comparator.compare(ctx, r1, r2);
}
- RowSchema outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
+ StructNativeType outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
RowFactory<Object[]> outputRowFactory = ctx.rowHandler().factory(outputRowSchema);
SortAggregateNode<Object[]> agg = new SortAggregateNode<>(
@@ -125,8 +124,7 @@ public class SortAggregateExecutionTest extends BaseAggregateTest {
}
// Map node
- RowSchema reduceRowSchema = TypeUtils.rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(inRowType));
- RowFactory<Object[]> mapRowFactory = ctx.rowHandler().factory(reduceRowSchema);
+ RowFactory<Object[]> mapRowFactory = ctx.rowHandler().factory(TypeUtils.convertStructuredType(inRowType));
SortAggregateNode<Object[]> aggMap = new SortAggregateNode<>(
ctx,
@@ -175,7 +173,7 @@ public class SortAggregateExecutionTest extends BaseAggregateTest {
true
);
- RowSchema outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
+ StructNativeType outputRowSchema = createOutputSchema(ctx, call, inRowType, grpSet);
RowFactory<Object[]> outputRowFactory = ctx.rowHandler().factory(outputRowSchema);
SortAggregateNode<Object[]> aggRdc = new SortAggregateNode<>(
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/TableScanNodeExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/TableScanNodeExecutionTest.java
index 6f1bdda4e2b..e2f06383bd9 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/TableScanNodeExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/TableScanNodeExecutionTest.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.sql.engine.exec.rel;
import static org.apache.ignite.internal.replicator.ReplicatorConstants.DEFAULT_IDLE_SAFE_TIME_PROPAGATION_PERIOD_MILLISECONDS;
import static org.apache.ignite.internal.sql.engine.util.Commons.IN_BUFFER_SIZE;
-import static org.apache.ignite.internal.sql.engine.util.TypeUtils.rowSchemaFromRelTypes;
+import static org.apache.ignite.internal.sql.engine.util.TypeUtils.convertStructuredType;
import static org.apache.ignite.internal.testframework.IgniteTestUtils.deriveUuidFrom;
import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.apache.ignite.internal.util.IgniteUtils.closeAll;
@@ -75,7 +75,6 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.ScannableTable;
import org.apache.ignite.internal.sql.engine.exec.ScannableTableImpl;
import org.apache.ignite.internal.sql.engine.exec.TableRowConverter;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.framework.DataProvider;
import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
@@ -98,6 +97,7 @@ import org.apache.ignite.internal.tx.impl.TxManagerImpl;
import org.apache.ignite.internal.tx.storage.state.TxStateStorage;
import org.apache.ignite.internal.tx.test.TestLocalRwTxCounter;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.network.NetworkAddress;
import org.apache.ignite.table.QualifiedName;
import org.apache.ignite.table.QualifiedNameHelper;
@@ -131,8 +131,6 @@ public class TableScanNodeExecutionTest extends AbstractExecutionTest<Object[]>
RelDataType rowType = TypeUtils.createRowType(tf, TypeUtils.native2relationalTypes(tf,
NativeTypes.INT32, NativeTypes.STRING, NativeTypes.INT32));
- RowSchema rowSchema = rowSchemaFromRelTypes(List.of(rowType));
-
int inBufSize = IN_BUFFER_SIZE;
List<PartitionWithConsistencyToken> partsWithConsistencyTokens = IntStream.range(0, TestInternalTableImpl.PART_CNT)
@@ -147,7 +145,7 @@ public class TableScanNodeExecutionTest extends AbstractExecutionTest<Object[]>
sizes[i] = inBufSize * (i + 1) + ThreadLocalRandom.current().nextInt(100);
}
- RowFactory<Object[]> rowFactory = ctx.rowHandler().factory(rowSchema);
+ RowFactory<Object[]> rowFactory = ctx.rowHandler().factory(convertStructuredType(rowType));
int i = 0;
@@ -276,7 +274,7 @@ public class TableScanNodeExecutionTest extends AbstractExecutionTest<Object[]>
.mapToObj(i -> new PartitionWithConsistencyToken(1, 42L))
.collect(Collectors.toList());
- RowSchema schema = RowSchema.builder().addField(NativeTypes.INT32).build();
+ StructNativeType schema = NativeTypes.rowBuilder().addField("C1", NativeTypes.INT32, false).build();
RowFactory<Object[]> rowFactory = ctx.rowHandler().factory(schema);
ScannableTable scannableTable = TestBuilders.tableScan(DataProvider.fromRow(new Object[]{42}, partDataSize));
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTest.java
deleted file mode 100644
index 31355bb1d33..00000000000
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTest.java
+++ /dev/null
@@ -1,130 +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.sql.engine.exec.row;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-
-import java.util.List;
-import org.apache.ignite.internal.type.NativeTypes;
-import org.junit.jupiter.api.Test;
-
-/** Tests for {@link RowSchema}. */
-public class RowSchemaTest {
-
- /** Schema equality. */
- @Test
- public void testSchemaEquality() {
- RowSchema s1 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
- assertEquals(s1, s1);
-
- List<BaseTypeSpec> fields = List.of(new BaseTypeSpec(NativeTypes.INT32));
- assertEquals(fields, s1.fields());
-
- RowSchema s2 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- assertEquals(s1, s2);
- }
-
- /** Schema inequality. */
- @Test
- public void testSchemaInequality() {
- {
- RowSchema s1 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- RowSchema s2 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .build();
-
- assertNotEquals(s1, s2);
- }
-
- {
- RowSchema s1 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- RowSchema s2 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- assertNotEquals(s1, s2);
- }
-
- {
- RowSchema s1 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .build();
-
- RowSchema s2 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- assertNotEquals(s1, s2);
- }
- }
-
- /** Schema concatenation. */
- @Test
- public void testSchemaConcat() {
- RowSchema s1 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .build();
-
- RowSchema s2 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- RowSchema expected = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- RowSchema concatenated = RowSchema.concat(s1, s2);
-
- assertEquals(expected, concatenated);
- }
-
- /** Schema projection. */
- @Test
- public void testSchemaProjection() {
- RowSchema s1 = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .addField(new BaseTypeSpec(NativeTypes.INT64))
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .build();
-
- RowSchema expected = RowSchema.builder()
- .addField(new BaseTypeSpec(NativeTypes.STRING))
- .addField(new BaseTypeSpec(NativeTypes.INT32))
- .build();
-
- RowSchema projected = RowSchema.map(s1, new int[]{2, 0});
-
- assertEquals(expected, projected);
- }
-}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTypesTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTypesTest.java
deleted file mode 100644
index d0624d7586b..00000000000
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/RowSchemaTypesTest.java
+++ /dev/null
@@ -1,217 +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.sql.engine.exec.row;
-
-import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import com.google.common.collect.Streams;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.ignite.internal.type.NativeType;
-import org.apache.ignite.internal.type.NativeTypes;
-import org.apache.ignite.internal.util.Pair;
-import org.apache.ignite.sql.ColumnType;
-import org.junit.jupiter.api.DynamicTest;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestFactory;
-
-/** Tests for {@link RowSchemaTypes}. */
-public class RowSchemaTypesTest {
-
- /** NULL type. */
- @Test
- public void testNullType() {
- assertEquals(new NullTypeSpec(), RowSchemaTypes.NULL);
- assertTrue(RowSchemaTypes.NULL.isNullable(), "NULL should be nullable");
- }
-
- /** {@link RowType} equality. */
- @Test
- public void testRowType() {
- RowType rowType1 = new RowType(List.of(RowSchemaTypes.nativeType(NativeTypes.INT32)), false);
- RowType rowType2 = new RowType(List.of(RowSchemaTypes.nativeType(NativeTypes.INT32)), false);
-
- RowType rowType3 = new RowType(List.of(
- RowSchemaTypes.nativeType(NativeTypes.INT32),
- RowSchemaTypes.nativeType(NativeTypes.INT32)),
- false);
-
- assertEquals(rowType1, rowType2);
- assertNotEquals(rowType1, rowType3);
- }
-
- /** Creating {@link RowType} with no fields should not be possible. */
- @Test
- public void testEmptyRowTypeIsIllegal() {
- assertThrows(IllegalArgumentException.class, () -> new RowType(List.of(), false));
- }
-
- /** Conversion from {@link NativeType} to {@link BaseTypeSpec}. */
- @TestFactory
- public Stream<DynamicTest> testFromNativeType() {
- List<NativeTypeToBaseTestCase> testCaseList = new ArrayList<>();
-
- for (ConversionTest testCase : ConversionTest.values()) {
- NativeType nativeType = testCase.nativeType;
- Supplier<BaseTypeSpec> fromNotNull = () -> RowSchemaTypes.nativeType(nativeType);
-
- if (testCase.interned) {
- Pair<BaseTypeSpec, BaseTypeSpec> typePair = RowSchemaTypes.INTERNED_TYPES.get(nativeType);
- testCaseList.add(new NativeTypeToBaseTestCase(nativeType, true, typePair.getFirst(), false, fromNotNull));
-
- } else {
- BaseTypeSpec notNull = new BaseTypeSpec(nativeType, false);
- testCaseList.add(new NativeTypeToBaseTestCase(nativeType, false, notNull, false, fromNotNull));
- }
- }
-
- return testCaseList.stream().map(NativeTypeToBaseTestCase::toTest);
- }
-
- /** Conversion from {@link NativeType} to {@link BaseTypeSpec}. */
- @TestFactory
- public Stream<DynamicTest> testFromNativeTypeWithNullability() {
- List<NativeTypeToBaseTestCase> testCaseList = new ArrayList<>();
-
- for (ConversionTest testCase : ConversionTest.values()) {
- NativeType nativeType = testCase.nativeType;
- Supplier<BaseTypeSpec> fromNotNull = () -> RowSchemaTypes.nativeTypeWithNullability(nativeType, false);
- Supplier<BaseTypeSpec> fromNullable = () -> RowSchemaTypes.nativeTypeWithNullability(nativeType, true);
-
- if (testCase.interned) {
- Pair<BaseTypeSpec, BaseTypeSpec> typePair = RowSchemaTypes.INTERNED_TYPES.get(nativeType);
-
- testCaseList.add(new NativeTypeToBaseTestCase(nativeType, true, typePair.getFirst(), false, fromNotNull));
- testCaseList.add(new NativeTypeToBaseTestCase(nativeType, true, typePair.getSecond(), true, fromNullable));
- } else {
- BaseTypeSpec notNull = new BaseTypeSpec(nativeType, false);
- BaseTypeSpec nullable = new BaseTypeSpec(nativeType, true);
-
- testCaseList.add(new NativeTypeToBaseTestCase(nativeType, false, notNull, false, fromNotNull));
- testCaseList.add(new NativeTypeToBaseTestCase(nativeType, false, nullable, true, fromNullable));
- }
- }
-
- // Check for missed types add fail if such types present.
-
- Set<Entry<ColumnType, Boolean>> typeSpecs = new CopyOnWriteArraySet<>();
-
- for (ColumnType spec : NativeType.nativeTypes()) {
- typeSpecs.add(Map.entry(spec, true));
- typeSpecs.add(Map.entry(spec, false));
- }
-
- DynamicTest dynamicTest = DynamicTest.dynamicTest("Ensure all native types were checked", () -> {
- for (NativeTypeToBaseTestCase test : testCaseList) {
- typeSpecs.remove(Map.entry(test.nativeType.spec(), test.nullable));
- }
- List<String> typePairs = typeSpecs.stream()
- .map(p -> format("<{}, nullable={}>", p.getKey().name(), p.getValue()))
- .collect(Collectors.toList());
-
- assertTrue(typeSpecs.isEmpty(), typePairs.toString());
- });
-
- return Streams.concat(testCaseList.stream().map(NativeTypeToBaseTestCase::toTest), Stream.of(dynamicTest));
- }
-
- enum ConversionTest {
- // type, interned or not.
- BOOLEAN(NativeTypes.BOOLEAN, true),
-
- INT8(NativeTypes.INT8, true),
- INT16(NativeTypes.INT16, true),
- INT32(NativeTypes.INT32, true),
- INT64(NativeTypes.INT64, true),
- FLOAT(NativeTypes.FLOAT, true),
- DOUBLE(NativeTypes.DOUBLE, true),
- DECIMAL_10_0(NativeTypes.decimalOf(10, 0), false),
- DECIMAL_10_4(NativeTypes.decimalOf(10, 4), false),
-
- STRING(NativeTypes.INT16, true),
- STRING_8(NativeTypes.stringOf(8), false),
- BYTES(NativeTypes.BYTES, true),
- BYTES_8(NativeTypes.blobOf(8), false),
-
- UUID(NativeTypes.UUID, true),
-
- DATE(NativeTypes.DATE, true),
- TIME_2(NativeTypes.time(2), false),
- DATETIME_2(NativeTypes.datetime(2), false),
- TIMESTAMP_2(NativeTypes.timestamp(2), false),
- ;
-
- final NativeType nativeType;
- final boolean interned;
-
- ConversionTest(NativeType nativeType, boolean interned) {
- this.nativeType = nativeType;
- this.interned = interned;
- }
- }
-
- private static final class NativeTypeToBaseTestCase {
-
- final NativeType nativeType;
-
- final boolean internedType;
-
- final BaseTypeSpec expected;
-
- final boolean nullable;
-
- final Supplier<BaseTypeSpec> result;
-
- NativeTypeToBaseTestCase(NativeType nativeType, boolean sameType,
- BaseTypeSpec expected, boolean nullable, Supplier<BaseTypeSpec> result) {
- this.internedType = sameType;
- this.nativeType = nativeType;
- this.nullable = nullable;
- this.expected = expected;
- this.result = result;
- }
-
- DynamicTest toTest() {
- String name = format("{} {} {}", (nullable ? "NULLABLE " : ""), nativeType, (internedType ? "SAME" : "EQUAL"));
-
- return DynamicTest.dynamicTest(name, () -> {
- BaseTypeSpec actual = result.get();
-
- if (internedType) {
- assertSame(expected, actual, "descriptors should point to the same object");
- } else {
- assertEquals(expected, actual, "descriptors does not match");
- }
-
- assertEquals(nullable, actual.isNullable(), "Nullability does not match: " + actual);
- });
- }
- }
-}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/SqlRowHandlerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/SqlRowHandlerTest.java
index 9cf3e24be1b..66289f751b3 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/SqlRowHandlerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/row/SqlRowHandlerTest.java
@@ -41,12 +41,13 @@ import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowBuilder;
import org.apache.ignite.internal.sql.engine.exec.RowHandler.RowFactory;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler;
import org.apache.ignite.internal.sql.engine.exec.SqlRowHandler.RowWrapper;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema.Builder;
import org.apache.ignite.internal.sql.engine.util.SqlTestUtils;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.testframework.IgniteAbstractTest;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.NativeTypes.RowTypeBuilder;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.sql.ColumnType;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
@@ -76,7 +77,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
public void testBytebufferSerialization() {
List<ColumnType> columnTypes = shuffledColumnTypes();
Object[] sourceData = values(columnTypes);
- RowSchema schema = rowSchema(columnTypes, sourceData);
+ StructNativeType schema = rowSchema(columnTypes, sourceData);
int elementsCount = schema.fields().size();
@@ -89,8 +90,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
for (int i = 0; i < elementsCount; i++) {
String msg = schema.fields().get(i).toString();
- TypeSpec typeSpec = schema.fields().get(i);
- Object expected = convertToInternal(typeSpec, sourceData[i]);
+ Object expected = convertToInternal(schema.fields().get(i).type(), sourceData[i]);
assertThat(msg, handler.get(i, src), equalTo(expected));
assertThat(msg, handler.get(i, dest), equalTo(expected));
@@ -111,7 +111,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
int[] mapping = {3, 5};
Object[] sourceData = values(columnTypes);
- RowSchema schema = rowSchema(columnTypes, sourceData);
+ StructNativeType schema = rowSchema(columnTypes, sourceData);
RowFactory<RowWrapper> factory = handler.factory(schema);
@@ -119,7 +119,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
RowWrapper srcBinRow = factory.create(handler.toBinaryTuple(srcRow));
- RowSchema mappedSchema = rowSchema(columnTypes.subList(0, mapping.length), Arrays.copyOf(sourceData, mapping.length));
+ StructNativeType mappedSchema = rowSchema(columnTypes.subList(0, mapping.length), Arrays.copyOf(sourceData, mapping.length));
RowFactory<RowWrapper> mappedFactory = handler.factory(mappedSchema);
RowWrapper mappedRow = mappedFactory.map(srcRow, mapping);
@@ -143,18 +143,18 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
public void testUpdateRowSchemaOnMapping() {
RowHandler<RowWrapper> handler = SqlRowHandler.INSTANCE;
- RowSchema rowSchema = RowSchema.builder()
- .addField(NativeTypes.INT32)
- .addField(NativeTypes.STRING)
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.INT32, false)
+ .addField("C2", NativeTypes.STRING, false)
.build();
RowWrapper row1 = handler.factory(rowSchema).rowBuilder()
.addField(1).addField("2")
.build();
- RowSchema reverseRowSchema = RowSchema.builder()
- .addField(NativeTypes.STRING)
- .addField(NativeTypes.INT32)
+ StructNativeType reverseRowSchema = NativeTypes.rowBuilder()
+ .addField("C1", NativeTypes.STRING, false)
+ .addField("C2", NativeTypes.INT32, false)
.build();
RowFactory<RowWrapper> factory = handler.factory(reverseRowSchema);
@@ -180,7 +180,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
public void testRowBuilder(ColumnType type) {
Object value1 = SqlTestUtils.generateValueByTypeWithMaxScalePrecisionForSql(type);
- RowSchema rowSchema = rowSchema(List.of(type), new Object[]{value1});
+ StructNativeType rowSchema = rowSchema(List.of(type), new Object[]{value1});
RowFactory<RowWrapper> rowFactory = handler.factory(rowSchema);
RowBuilder<RowWrapper> builder = rowFactory.rowBuilder();
@@ -199,7 +199,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
@Test
public void testRowBuilderRejectInvalidField() {
- RowSchema rowSchema = rowSchema(List.of(ColumnType.INT32), new Object[]{1});
+ StructNativeType rowSchema = rowSchema(List.of(ColumnType.INT32), new Object[]{1});
RowFactory<RowWrapper> rowFactory = handler.factory(rowSchema);
RowBuilder<RowWrapper> builder = rowFactory.rowBuilder();
@@ -211,7 +211,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
@Test
public void testRowBuilderBuildReset() {
- RowSchema rowSchema = rowSchema(List.of(ColumnType.INT32), new Object[]{1});
+ StructNativeType rowSchema = rowSchema(List.of(ColumnType.INT32), new Object[]{1});
RowFactory<RowWrapper> rowFactory = handler.factory(rowSchema);
RowBuilder<RowWrapper> builder = rowFactory.rowBuilder();
@@ -237,7 +237,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
@Test
public void testRowBuilderBuildingIncompleteRowIsNotAllowed() {
- RowSchema rowSchema = rowSchema(List.of(ColumnType.INT32, ColumnType.INT32), new Object[]{1, 2});
+ StructNativeType rowSchema = rowSchema(List.of(ColumnType.INT32, ColumnType.INT32), new Object[]{1, 2});
RowFactory<RowWrapper> rowFactory = handler.factory(rowSchema);
RowBuilder<RowWrapper> rowBuilder = rowFactory.rowBuilder();
@@ -249,19 +249,19 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
@Test
public void testRowBuilderEmptyRow() {
- RowFactory<RowWrapper> rowFactory = handler.factory(RowSchema.builder().build());
+ RowFactory<RowWrapper> rowFactory = handler.factory(NativeTypes.rowBuilder().build());
RowBuilder<RowWrapper> rowBuilder = rowFactory.rowBuilder();
assertNotNull(rowBuilder.build());
}
@ParameterizedTest
// TODO: https://issues.apache.org/jira/browse/IGNITE-17373 Interval type support.
- @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION"}, mode = EnumSource.Mode.EXCLUDE)
+ @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = EnumSource.Mode.EXCLUDE)
public void testIsNull(ColumnType columnType) {
NativeType nativeType = TypeUtils.columnType2NativeType(columnType, 3, 3, 0);
- RowSchema rowSchema = RowSchema.builder()
- .addField(nativeType, true)
+ StructNativeType rowSchema = NativeTypes.rowBuilder()
+ .addField("C1", nativeType, true)
.build();
RowFactory<RowWrapper> rowFactory = handler.factory(rowSchema);
@@ -279,23 +279,20 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
}
}
- private RowSchema rowSchema(List<ColumnType> columnTypes, Object[] values) {
- Builder schemaBuilder = RowSchema.builder();
+ private StructNativeType rowSchema(List<ColumnType> columnTypes, Object[] values) {
+ RowTypeBuilder schemaBuilder = NativeTypes.rowBuilder();
for (int i = 0; i < values.length; i++) {
ColumnType type = columnTypes.get(i);
- if (type == ColumnType.NULL) {
- schemaBuilder.addField(new NullTypeSpec());
-
- continue;
- }
-
NativeType nativeType = values[i] == null
? TypeUtils.columnType2NativeType(type, 9, 3, 20)
: NativeTypes.fromObject(values[i]);
- schemaBuilder.addField(nativeType, values[i] == null || rnd.nextBoolean());
+ assertNotNull(nativeType, "Unable to create nativeType for columnType="
+ + type + " and value={" + values[i] + "}");
+
+ schemaBuilder.addField("F$" + i, nativeType, values[i] == null || rnd.nextBoolean());
}
return schemaBuilder.build();
@@ -313,12 +310,11 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
return values;
}
- private static Object[] wrap(Object[] values, RowSchema rowSchema) {
+ private static Object[] wrap(Object[] values, StructNativeType rowSchema) {
Object[] newValues = new Object[values.length];
for (int i = 0; i < values.length; i++) {
- TypeSpec typeSpec = rowSchema.fields().get(i);
- newValues[i] = convertToInternal(typeSpec, values[i]);
+ newValues[i] = convertToInternal(rowSchema.fields().get(i).type(), values[i]);
}
return newValues;
@@ -326,7 +322,7 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
private static Set<ColumnType> columnTypes() {
// TODO Include ignored types to test after https://issues.apache.org/jira/browse/IGNITE-17373
- return EnumSet.complementOf(EnumSet.of(ColumnType.PERIOD, ColumnType.DURATION));
+ return EnumSet.complementOf(EnumSet.of(ColumnType.PERIOD, ColumnType.DURATION, ColumnType.STRUCT));
}
private List<ColumnType> shuffledColumnTypes() {
@@ -337,41 +333,11 @@ public class SqlRowHandlerTest extends IgniteAbstractTest {
return columnTypes;
}
- private final class ConcatTestParameters {
- final RowSchema leftSchema;
- final RowSchema rightSchema;
- final Object[] leftData;
- final Object[] rightData;
- final RowWrapper left;
- final RowWrapper right;
-
- ConcatTestParameters(boolean leftTupleRequired, boolean rightTupleRequired) {
- List<ColumnType> columnTypes1 = shuffledColumnTypes();
- List<ColumnType> columnTypes2 = shuffledColumnTypes();
-
- leftData = values(columnTypes1);
- rightData = values(columnTypes2);
- leftSchema = rowSchema(columnTypes1, leftData);
- rightSchema = rowSchema(columnTypes2, rightData);
-
- RowFactory<RowWrapper> factory1 = handler.factory(leftSchema);
- RowFactory<RowWrapper> factory2 = handler.factory(rightSchema);
-
- RowWrapper left = factory1.create(wrap(leftData, leftSchema));
- RowWrapper right = factory2.create(wrap(rightData, rightSchema));
-
- this.left = leftTupleRequired ? factory1.create(handler.toBinaryTuple(left)) : left;
- this.right = rightTupleRequired ? factory2.create(handler.toBinaryTuple(right)) : right;
- }
- }
-
- private static @Nullable Object convertToInternal(TypeSpec typeSpec, Object value) {
- if (typeSpec instanceof NullTypeSpec) {
+ private static @Nullable Object convertToInternal(NativeType type, Object value) {
+ if (type.spec() == ColumnType.NULL) {
return null;
- } else {
- BaseTypeSpec baseTypeSpec = (BaseTypeSpec) typeSpec;
- NativeType nativeType = baseTypeSpec.nativeType();
- return TypeUtils.toInternal(value, nativeType.spec());
}
+
+ return TypeUtils.toInternal(value, type.spec());
}
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/ArrayRowHandler.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/ArrayRowHandler.java
index 0fea828a45f..a919c963acd 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/ArrayRowHandler.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/ArrayRowHandler.java
@@ -31,12 +31,11 @@ import org.apache.ignite.internal.lang.InternalTuple;
import org.apache.ignite.internal.schema.BinaryTuple;
import org.apache.ignite.internal.schema.InvalidTypeException;
import org.apache.ignite.internal.sql.engine.exec.RowHandler;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchemaTypes;
import org.apache.ignite.internal.sql.engine.util.TypeUtils;
import org.apache.ignite.internal.type.DecimalNativeType;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.jetbrains.annotations.Nullable;
/**
@@ -84,8 +83,8 @@ public class ArrayRowHandler implements RowHandler<Object[]> {
/** {@inheritDoc} */
@Override
- public RowFactory<Object[]> factory(RowSchema rowSchema) {
- int schemaLen = rowSchema.fields().size();
+ public RowFactory<Object[]> factory(StructNativeType rowType) {
+ int schemaLen = rowType.fields().size();
return new RowFactory<>() {
/** {@inheritDoc} */
@@ -119,7 +118,7 @@ public class ArrayRowHandler implements RowHandler<Object[]> {
Object[] row = new Object[tuple.elementCount()];
for (int i = 0; i < row.length; i++) {
- NativeType nativeType = RowSchemaTypes.toNativeType(rowSchema.fields().get(i));
+ NativeType nativeType = rowType.fields().get(i).type();
if (nativeType == null) {
row[i] = null;
@@ -135,13 +134,13 @@ public class ArrayRowHandler implements RowHandler<Object[]> {
/** {@inheritDoc} */
@Override
- public RowSchema rowSchema() {
- return rowSchema;
+ public StructNativeType rowSchema() {
+ return rowType;
}
@Override
public Object[] map(Object[] row, int[] mapping) {
- assert mapping.length == rowSchema.fields().size();
+ assert mapping.length == rowType.fields().size();
Object[] newRow = new Object[mapping.length];
for (int i = 0; i < mapping.length; i++) {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
index 6cead4f4e85..dd40eb1e555 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
@@ -21,6 +21,17 @@ import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
import static org.apache.ignite.internal.sql.engine.util.SqlTestUtils.assertThrowsSqlException;
import static org.apache.ignite.internal.sql.engine.util.TypeUtils.lowerBoundFor;
import static org.apache.ignite.internal.sql.engine.util.TypeUtils.upperBoundFor;
+import static org.apache.ignite.internal.type.NativeTypes.BOOLEAN;
+import static org.apache.ignite.internal.type.NativeTypes.BYTES;
+import static org.apache.ignite.internal.type.NativeTypes.DOUBLE;
+import static org.apache.ignite.internal.type.NativeTypes.FLOAT;
+import static org.apache.ignite.internal.type.NativeTypes.INT16;
+import static org.apache.ignite.internal.type.NativeTypes.INT32;
+import static org.apache.ignite.internal.type.NativeTypes.INT64;
+import static org.apache.ignite.internal.type.NativeTypes.INT8;
+import static org.apache.ignite.internal.type.NativeTypes.NULL;
+import static org.apache.ignite.internal.type.NativeTypes.STRING;
+import static org.apache.ignite.internal.type.NativeTypes.UUID;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@@ -40,25 +51,20 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeFactory.Builder;
-import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.sql.SqlIntervalQualifier;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.ignite.internal.sql.engine.exec.row.BaseTypeSpec;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
-import org.apache.ignite.internal.sql.engine.exec.row.RowSchemaTypes;
-import org.apache.ignite.internal.sql.engine.exec.row.RowType;
-import org.apache.ignite.internal.sql.engine.exec.row.TypeSpec;
import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.StructNativeType;
import org.apache.ignite.lang.ErrorGroups.Sql;
import org.apache.ignite.sql.ColumnType;
import org.junit.jupiter.api.DynamicTest;
@@ -78,17 +84,6 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
private static final IgniteTypeFactory TYPE_FACTORY = Commons.typeFactory();
- private static final BaseTypeSpec BOOLEAN = RowSchemaTypes.nativeType(NativeTypes.BOOLEAN);
- private static final BaseTypeSpec INT8 = RowSchemaTypes.nativeType(NativeTypes.INT8);
- private static final BaseTypeSpec INT16 = RowSchemaTypes.nativeType(NativeTypes.INT16);
- private static final BaseTypeSpec INT32 = RowSchemaTypes.nativeType(NativeTypes.INT32);
- private static final BaseTypeSpec INT64 = RowSchemaTypes.nativeType(NativeTypes.INT64);
- private static final BaseTypeSpec FLOAT = RowSchemaTypes.nativeType(NativeTypes.FLOAT);
- private static final BaseTypeSpec DOUBLE = RowSchemaTypes.nativeType(NativeTypes.DOUBLE);
- private static final BaseTypeSpec STRING = RowSchemaTypes.nativeType(NativeTypes.stringOf(65536));
- private static final BaseTypeSpec BYTES = RowSchemaTypes.nativeType(NativeTypes.blobOf(65536));
- private static final BaseTypeSpec UUID = RowSchemaTypes.nativeType(NativeTypes.UUID);
-
@Test
public void testValidateCharactersOverflowAndTrimIfPossible() {
IgniteTypeFactory typeFactory = Commons.typeFactory();
@@ -244,8 +239,7 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
}
private static Object[] buildTrimmedRow(RelDataType rowType, Object[] input) {
- List<RelDataType> columnTypes = rowType.getFieldList().stream().map(RelDataTypeField::getType).collect(Collectors.toList());
- RowSchema rowSchema = TypeUtils.rowSchemaFromRelTypes(columnTypes);
+ StructNativeType rowSchema = TypeUtils.convertStructuredType(rowType);
Object[] newRow = TypeUtils.validateStringTypesOverflowAndTrimIfPossible(rowType,
ArrayRowHandler.INSTANCE,
@@ -387,11 +381,12 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
});
}
- /** Conversion to base types + their NULLABLE variants from rel types. */
+ /** Conversion to base types. */
@TestFactory
public Stream<DynamicTest> testSimpleTypesConversion() {
List<RelToExecTestCase> testCaseList = new ArrayList<>();
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.NULL, NULL));
testCaseList.add(new RelToExecTestCase(SqlTypeName.BOOLEAN, BOOLEAN));
testCaseList.add(new RelToExecTestCase(SqlTypeName.TINYINT, INT8));
@@ -402,68 +397,48 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
testCaseList.add(new RelToExecTestCase(SqlTypeName.REAL, FLOAT));
testCaseList.add(new RelToExecTestCase(SqlTypeName.DOUBLE, DOUBLE));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.DECIMAL, RowSchemaTypes.nativeType(NativeTypes.decimalOf(32767, 0))));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.DECIMAL, 10, RowSchemaTypes.nativeType(NativeTypes.decimalOf(10, 0))));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.DECIMAL, 10, 4, RowSchemaTypes.nativeType(NativeTypes.decimalOf(10, 4))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.DECIMAL, NativeTypes.decimalOf(32767, 0)));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.DECIMAL, 10, NativeTypes.decimalOf(10, 0)));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.DECIMAL, 10, 4, NativeTypes.decimalOf(10, 4)));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.CHAR, RowSchemaTypes.nativeType(NativeTypes.stringOf(1))));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.CHAR, 8, RowSchemaTypes.nativeType(NativeTypes.stringOf(8))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.CHAR, NativeTypes.stringOf(1)));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.CHAR, 8, NativeTypes.stringOf(8)));
testCaseList.add(new RelToExecTestCase(SqlTypeName.VARCHAR, STRING));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.VARCHAR, 8, RowSchemaTypes.nativeType(NativeTypes.stringOf(8))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.VARCHAR, 8, NativeTypes.stringOf(8)));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.BINARY, RowSchemaTypes.nativeType(NativeTypes.blobOf(1))));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.BINARY, 8, RowSchemaTypes.nativeType(NativeTypes.blobOf(8))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.BINARY, NativeTypes.blobOf(1)));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.BINARY, 8, NativeTypes.blobOf(8)));
testCaseList.add(new RelToExecTestCase(SqlTypeName.VARBINARY, BYTES));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.VARBINARY, 8, RowSchemaTypes.nativeType(NativeTypes.blobOf(8))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.VARBINARY, 8, NativeTypes.blobOf(8)));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.DATE, RowSchemaTypes.nativeType(NativeTypes.DATE)));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.DATE, NativeTypes.DATE));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.TIME, 4, RowSchemaTypes.nativeType(NativeTypes.time(4))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.TIME, 4, NativeTypes.time(4)));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE, 4, RowSchemaTypes.nativeType(NativeTypes.time(4))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE, 4, NativeTypes.time(4)));
- testCaseList.add(new RelToExecTestCase(SqlTypeName.TIMESTAMP, 4, RowSchemaTypes.nativeType(NativeTypes.datetime(4))));
+ testCaseList.add(new RelToExecTestCase(SqlTypeName.TIMESTAMP, 4, NativeTypes.datetime(4)));
testCaseList.add(new RelToExecTestCase(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE, 4,
- RowSchemaTypes.nativeType(NativeTypes.timestamp(4))));
+ NativeTypes.timestamp(4)));
for (SqlTypeName interval : SqlTypeName.YEAR_INTERVAL_TYPES) {
SqlIntervalQualifier yearMonth = new SqlIntervalQualifier(interval.getStartUnit(), interval.getEndUnit(), SqlParserPos.ZERO);
testCaseList.add(new RelToExecTestCase(TYPE_FACTORY.createSqlIntervalType(yearMonth),
- RowSchemaTypes.nativeType(NativeTypes.PERIOD)));
+ NativeTypes.PERIOD));
}
for (SqlTypeName interval : SqlTypeName.DAY_INTERVAL_TYPES) {
SqlIntervalQualifier dayTime = new SqlIntervalQualifier(interval.getStartUnit(), interval.getEndUnit(), SqlParserPos.ZERO);
testCaseList.add(new RelToExecTestCase(TYPE_FACTORY.createSqlIntervalType(dayTime),
- RowSchemaTypes.nativeType(NativeTypes.DURATION)));
+ NativeTypes.DURATION));
}
testCaseList.add(new RelToExecTestCase(SqlTypeName.UUID, UUID));
- // Add test cases for nullable variants
- for (RelToExecTestCase testCase : new ArrayList<>(testCaseList)) {
- RelDataType nullableRelType = TYPE_FACTORY.createTypeWithNullability(testCase.input, true);
- BaseTypeSpec typeSpec = (BaseTypeSpec) testCase.expected;
-
- testCaseList.add(new RelToExecTestCase(nullableRelType, new BaseTypeSpec(typeSpec.nativeType(), true)));
- }
-
return testCaseList.stream().map(RelToExecTestCase::toTest);
}
- /** NULL type conversion. */
- @TestFactory
- public Stream<DynamicTest> testNullTypeConversion() {
- RelDataType nullType = TYPE_FACTORY.createSqlType(SqlTypeName.NULL);
-
- return Stream.of(
- new RelToExecTestCase(nullType, RowSchemaTypes.NULL),
- new RelToExecTestCase(TYPE_FACTORY.createTypeWithNullability(nullType, true), RowSchemaTypes.NULL)
- )
- .map(RelToExecTestCase::toTest);
- }
-
/** Conversion to row types from struct rel types. */
@TestFactory
public Stream<DynamicTest> testRowTypesConversion() {
@@ -476,7 +451,10 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
.add("f2", TYPE_FACTORY.createTypeWithNullability(TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER), true))
.build();
- RowType expected1 = new RowType(List.of(BOOLEAN, new BaseTypeSpec(INT32.nativeType(), true)), false);
+ StructNativeType expected1 = NativeTypes.rowBuilder()
+ .addField("f1", BOOLEAN, false)
+ .addField("f2", INT32, true)
+ .build();
RelToExecTestCase simpleRow = new RelToExecTestCase(relType1, expected1);
testCaseList.add(simpleRow);
@@ -494,11 +472,18 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
)
.build();
- RowType expected2 = new RowType(List.of(
- BOOLEAN,
- new BaseTypeSpec(INT32.nativeType(), true),
- new RowType(List.of(new BaseTypeSpec(INT64.nativeType(), true), STRING), false)),
- false);
+ StructNativeType expected2 = NativeTypes.rowBuilder()
+ .addField("f1", BOOLEAN, false)
+ .addField("f2", INT32, true)
+ .addField(
+ "f3",
+ NativeTypes.rowBuilder()
+ .addField("f3_f1", INT64, true)
+ .addField("f3_f2", STRING, false)
+ .build(),
+ false
+ )
+ .build();
testCaseList.add(new RelToExecTestCase(relType2, expected2));
@@ -581,33 +566,32 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
final RelDataType input;
- final TypeSpec expected;
+ final NativeType expected;
- RelToExecTestCase(SqlTypeName input, TypeSpec expected) {
+ RelToExecTestCase(SqlTypeName input, NativeType expected) {
this.input = TYPE_FACTORY.createSqlType(input);
this.expected = expected;
}
- RelToExecTestCase(SqlTypeName input, int precision, TypeSpec expected) {
+ RelToExecTestCase(SqlTypeName input, int precision, NativeType expected) {
this.input = TYPE_FACTORY.createSqlType(input, precision);
this.expected = expected;
}
- RelToExecTestCase(SqlTypeName input, int precision, int scale, TypeSpec expected) {
+ RelToExecTestCase(SqlTypeName input, int precision, int scale, NativeType expected) {
this.input = TYPE_FACTORY.createSqlType(input, precision, scale);
this.expected = expected;
}
- RelToExecTestCase(RelDataType input, TypeSpec expected) {
+ RelToExecTestCase(RelDataType input, NativeType expected) {
this.input = input;
this.expected = expected;
}
DynamicTest toTest() {
return DynamicTest.dynamicTest((input.isNullable() ? "NULLABLE " : "") + input, () -> {
- RowSchema schema = TypeUtils.rowSchemaFromRelTypes(List.of(input));
+ NativeType actualType = IgniteTypeFactory.relDataTypeToNative(input);
- TypeSpec actualType = schema.fields().get(0);
assertEquals(expected, actualType, input.getFullTypeString());
});
}
diff --git a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/SqlTestUtils.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/SqlTestUtils.java
index a560000f3f3..2082ff7f36a 100644
--- a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/SqlTestUtils.java
+++ b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/SqlTestUtils.java
@@ -127,6 +127,7 @@ public class SqlTestUtils {
COLUMN_TYPE_TO_SQL_TYPE_NAME_MAP.put(ColumnType.UUID, SqlTypeName.UUID);
COLUMN_TYPE_TO_SQL_TYPE_NAME_MAP.put(ColumnType.PERIOD, null);
COLUMN_TYPE_TO_SQL_TYPE_NAME_MAP.put(ColumnType.DURATION, null);
+ COLUMN_TYPE_TO_SQL_TYPE_NAME_MAP.put(ColumnType.STRUCT, null);
for (ColumnType value : ColumnType.values()) {
assert COLUMN_TYPE_TO_SQL_TYPE_NAME_MAP.containsKey(value) : "absent type is " + value;
diff --git a/modules/system-view/src/test/java/org/apache/ignite/internal/systemview/SystemViewManagerTest.java b/modules/system-view/src/test/java/org/apache/ignite/internal/systemview/SystemViewManagerTest.java
index 7b55b50654a..b4f122b78d3 100644
--- a/modules/system-view/src/test/java/org/apache/ignite/internal/systemview/SystemViewManagerTest.java
+++ b/modules/system-view/src/test/java/org/apache/ignite/internal/systemview/SystemViewManagerTest.java
@@ -151,7 +151,7 @@ public class SystemViewManagerTest extends BaseIgniteAbstractTest {
}
@ParameterizedTest
- @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION"}, mode = Mode.EXCLUDE)
+ @EnumSource(value = ColumnType.class, names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Mode.EXCLUDE)
public void registerAllColumnTypes(ColumnType typeSpec) {
NativeType type = SchemaTestUtils.specToType(typeSpec);
diff --git a/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItColocationTest.java b/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItColocationTest.java
index 5c7e6d2d3a8..3f20527a039 100644
--- a/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItColocationTest.java
+++ b/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItColocationTest.java
@@ -402,8 +402,8 @@ public class ItColocationTest extends BaseIgniteAbstractTest {
*/
@CartesianTest
public void colocationTwoColumnsInsert(
- @Enum(names = {"NULL", "PERIOD", "DURATION"}, mode = Enum.Mode.EXCLUDE) ColumnType t0,
- @Enum(names = {"NULL", "PERIOD", "DURATION"}, mode = Enum.Mode.EXCLUDE) ColumnType t1
+ @Enum(names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Enum.Mode.EXCLUDE) ColumnType t0,
+ @Enum(names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Enum.Mode.EXCLUDE) ColumnType t1
) {
init(t0, t1);
@@ -427,8 +427,8 @@ public class ItColocationTest extends BaseIgniteAbstractTest {
*/
@CartesianTest
public void colocationTwoColumnsInsertAll(
- @Enum(names = {"NULL", "PERIOD", "DURATION"}, mode = Enum.Mode.EXCLUDE) ColumnType t0,
- @Enum(names = {"NULL", "PERIOD", "DURATION"}, mode = Enum.Mode.EXCLUDE) ColumnType t1
+ @Enum(names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Enum.Mode.EXCLUDE) ColumnType t0,
+ @Enum(names = {"NULL", "PERIOD", "DURATION", "STRUCT"}, mode = Enum.Mode.EXCLUDE) ColumnType t1
) {
int keysCount = t0 == ColumnType.BOOLEAN && t0 == t1 ? 2 : KEYS;