This is an automated email from the ASF dual-hosted git repository. amashenkov pushed a commit to branch igntie-22156 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit aa4d058d92d0433e74a85b18f82c2fd806a30d37 Author: amashenkov <[email protected]> AuthorDate: Tue Apr 30 20:10:56 2024 +0300 Replace inheritance with delegation for UpgradingRowAdapter. --- .../requests/table/ClientHandlerTupleTests.java | 6 +- .../schema/registry/UpgradingRowAdapter.java | 123 ++++++++++-------- .../org/apache/ignite/internal/schema/row/Row.java | 144 +++------------------ .../internal/schema/row/{Row.java => RowImpl.java} | 60 +++------ .../schema/registry/UpgradingRowAdapterTest.java | 135 ++++++++++--------- .../internal/table/MutableRowTupleAdapter.java | 4 +- .../ignite/internal/table/RecordViewImpl.java | 6 +- 7 files changed, 185 insertions(+), 293 deletions(-) diff --git a/modules/client-handler/src/test/java/org/apache/ignite/client/handler/requests/table/ClientHandlerTupleTests.java b/modules/client-handler/src/test/java/org/apache/ignite/client/handler/requests/table/ClientHandlerTupleTests.java index 93c94e5c52..a2e653afe7 100644 --- a/modules/client-handler/src/test/java/org/apache/ignite/client/handler/requests/table/ClientHandlerTupleTests.java +++ b/modules/client-handler/src/test/java/org/apache/ignite/client/handler/requests/table/ClientHandlerTupleTests.java @@ -40,7 +40,7 @@ import java.time.LocalTime; import java.time.Month; import java.util.Random; import java.util.UUID; -import org.apache.ignite.internal.schema.BinaryTuple; +import org.apache.ignite.internal.binarytuple.BinaryTupleReader; import org.apache.ignite.internal.schema.Column; import org.apache.ignite.internal.schema.SchemaDescriptor; import org.apache.ignite.internal.schema.marshaller.TupleMarshallerException; @@ -91,7 +91,7 @@ public class ClientHandlerTupleTests { public void testTupleEquality() throws TupleMarshallerException { Tuple tuple = createTuple(); - BinaryTuple binaryTuple = new TupleMarshallerImpl(fullSchema).marshal(tuple).binaryTuple(); + BinaryTupleReader binaryTuple = new TupleMarshallerImpl(fullSchema).marshal(tuple).binaryTuple(); Tuple clientHandlerTuple = new ClientHandlerTuple(fullSchema, null, binaryTuple, false); assertEquals(tuple, clientHandlerTuple); @@ -101,7 +101,7 @@ public class ClientHandlerTupleTests { public void testTupleEqualityKeyOnly() throws TupleMarshallerException { Tuple tuple = createKeyTuple(); - BinaryTuple binaryTuple = new TupleMarshallerImpl(fullSchema).marshalKey(tuple).binaryTuple(); + BinaryTupleReader binaryTuple = new TupleMarshallerImpl(fullSchema).marshalKey(tuple).binaryTuple(); Tuple clientHandlerTuple = new ClientHandlerTuple(fullSchema, null, binaryTuple, true); assertEquals(tuple, clientHandlerTuple); diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapter.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapter.java index b3753a14cb..1684b39db0 100644 --- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapter.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapter.java @@ -47,7 +47,7 @@ import org.jetbrains.annotations.Nullable; /** * Adapter for row of older schema. */ -public class UpgradingRowAdapter extends Row { +public class UpgradingRowAdapter implements Row { /** Column mapper. */ private final ColumnMapper mapper; @@ -56,8 +56,13 @@ public class UpgradingRowAdapter extends Row { private final BinaryTupleSchema newBinaryTupleSchema; + /** Row of previous version. */ + private final Row row; + private UpgradingRowAdapter(SchemaDescriptor newSchema, BinaryTupleSchema newBinaryTupleSchema, Row row, ColumnMapper mapper) { - super(false, row.schema(), row.binaryTupleSchema(), row); + assert !row.keyOnly() : "Can't upgrade special purpose row representing a key."; + + this.row = row; this.newSchema = newSchema; this.mapper = mapper; @@ -100,6 +105,12 @@ public class UpgradingRowAdapter extends Row { return newSchema.version(); } + /** {@inheritDoc} */ + @Override + public boolean keyOnly() { + return false; + } + /** * Map column. * @@ -125,13 +136,13 @@ public class UpgradingRowAdapter extends Row { public boolean booleanValue(int colIdx) { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.BOOLEAN != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (boolean) column.defaultValue() : super.booleanValue(mappedId); + return mappedId < 0 ? (boolean) column.defaultValue() : row.booleanValue(mappedId); } /** {@inheritDoc} */ @@ -139,13 +150,13 @@ public class UpgradingRowAdapter extends Row { public Boolean booleanValueBoxed(int colIdx) { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.BOOLEAN != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (Boolean) column.defaultValue() : super.booleanValueBoxed(mappedId); + return mappedId < 0 ? (Boolean) column.defaultValue() : row.booleanValueBoxed(mappedId); } /** {@inheritDoc} */ @@ -153,11 +164,11 @@ public class UpgradingRowAdapter extends Row { public byte byteValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT8); - return mappedId < 0 ? (byte) column.defaultValue() : super.byteValue(mappedId); + return mappedId < 0 ? (byte) column.defaultValue() : row.byteValue(mappedId); } /** {@inheritDoc} */ @@ -165,11 +176,11 @@ public class UpgradingRowAdapter extends Row { public Byte byteValueBoxed(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT8); - return mappedId < 0 ? (Byte) column.defaultValue() : super.byteValueBoxed(mappedId); + return mappedId < 0 ? (Byte) column.defaultValue() : row.byteValueBoxed(mappedId); } /** {@inheritDoc} */ @@ -177,11 +188,11 @@ public class UpgradingRowAdapter extends Row { public short shortValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT16); - return mappedId < 0 ? (short) column.defaultValue() : super.shortValue(mappedId); + return mappedId < 0 ? (short) column.defaultValue() : row.shortValue(mappedId); } /** {@inheritDoc} */ @@ -189,11 +200,11 @@ public class UpgradingRowAdapter extends Row { public Short shortValueBoxed(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT16); - return mappedId < 0 ? (Short) column.defaultValue() : super.shortValueBoxed(mappedId); + return mappedId < 0 ? (Short) column.defaultValue() : row.shortValueBoxed(mappedId); } /** {@inheritDoc} */ @@ -201,11 +212,11 @@ public class UpgradingRowAdapter extends Row { public int intValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT32); - return mappedId < 0 ? (int) column.defaultValue() : super.intValue(mappedId); + return mappedId < 0 ? (int) column.defaultValue() : row.intValue(mappedId); } /** {@inheritDoc} */ @@ -213,11 +224,11 @@ public class UpgradingRowAdapter extends Row { public Integer intValueBoxed(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT32); - return mappedId < 0 ? (Integer) column.defaultValue() : super.intValueBoxed(mappedId); + return mappedId < 0 ? (Integer) column.defaultValue() : row.intValueBoxed(mappedId); } /** {@inheritDoc} */ @@ -225,11 +236,11 @@ public class UpgradingRowAdapter extends Row { public long longValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT64); - return mappedId < 0 ? (long) column.defaultValue() : super.longValue(mappedId); + return mappedId < 0 ? (long) column.defaultValue() : row.longValue(mappedId); } /** {@inheritDoc} */ @@ -237,11 +248,11 @@ public class UpgradingRowAdapter extends Row { public Long longValueBoxed(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.INT64); - return mappedId < 0 ? (Long) column.defaultValue() : super.longValueBoxed(mappedId); + return mappedId < 0 ? (Long) column.defaultValue() : row.longValueBoxed(mappedId); } /** {@inheritDoc} */ @@ -249,11 +260,11 @@ public class UpgradingRowAdapter extends Row { public float floatValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.FLOAT); - return mappedId < 0 ? (float) column.defaultValue() : super.floatValue(mappedId); + return mappedId < 0 ? (float) column.defaultValue() : row.floatValue(mappedId); } /** {@inheritDoc} */ @@ -261,11 +272,11 @@ public class UpgradingRowAdapter extends Row { public Float floatValueBoxed(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.FLOAT); - return mappedId < 0 ? (Float) column.defaultValue() : super.floatValueBoxed(mappedId); + return mappedId < 0 ? (Float) column.defaultValue() : row.floatValueBoxed(mappedId); } /** {@inheritDoc} */ @@ -273,11 +284,11 @@ public class UpgradingRowAdapter extends Row { public double doubleValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.DOUBLE); - return mappedId < 0 ? (double) column.defaultValue() : super.doubleValue(mappedId); + return mappedId < 0 ? (double) column.defaultValue() : row.doubleValue(mappedId); } @@ -286,37 +297,37 @@ public class UpgradingRowAdapter extends Row { public Double doubleValueBoxed(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); ensureTypeConversionAllowed(column.type().spec().asColumnType(), ColumnType.DOUBLE); - return mappedId < 0 ? (Double) column.defaultValue() : super.doubleValueBoxed(mappedId); + return mappedId < 0 ? (Double) column.defaultValue() : row.doubleValueBoxed(mappedId); } @Override public BigDecimal decimalValue(int colIdx) { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.DECIMAL != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (BigDecimal) column.defaultValue() : super.decimalValue(mappedId); + return mappedId < 0 ? (BigDecimal) column.defaultValue() : row.decimalValue(mappedId); } @Override public BigDecimal decimalValue(int colIdx, int scale) { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.DECIMAL != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (BigDecimal) column.defaultValue() : super.decimalValue(mappedId, scale); + return mappedId < 0 ? (BigDecimal) column.defaultValue() : row.decimalValue(mappedId, scale); } /** {@inheritDoc} */ @@ -324,13 +335,13 @@ public class UpgradingRowAdapter extends Row { public BigInteger numberValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.NUMBER != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (BigInteger) column.defaultValue() : super.numberValue(mappedId); + return mappedId < 0 ? (BigInteger) column.defaultValue() : row.numberValue(mappedId); } /** {@inheritDoc} */ @@ -338,13 +349,13 @@ public class UpgradingRowAdapter extends Row { public String stringValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.STRING != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (String) column.defaultValue() : super.stringValue(mappedId); + return mappedId < 0 ? (String) column.defaultValue() : row.stringValue(mappedId); } /** {@inheritDoc} */ @@ -352,13 +363,13 @@ public class UpgradingRowAdapter extends Row { public byte[] bytesValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.BYTES != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (byte[]) column.defaultValue() : super.bytesValue(mappedId); + return mappedId < 0 ? (byte[]) column.defaultValue() : row.bytesValue(mappedId); } /** {@inheritDoc} */ @@ -366,13 +377,13 @@ public class UpgradingRowAdapter extends Row { public UUID uuidValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.UUID != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (UUID) column.defaultValue() : super.uuidValue(mappedId); + return mappedId < 0 ? (UUID) column.defaultValue() : row.uuidValue(mappedId); } /** {@inheritDoc} */ @@ -380,13 +391,13 @@ public class UpgradingRowAdapter extends Row { public BitSet bitmaskValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.BITMASK != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (BitSet) column.defaultValue() : super.bitmaskValue(mappedId); + return mappedId < 0 ? (BitSet) column.defaultValue() : row.bitmaskValue(mappedId); } /** {@inheritDoc} */ @@ -394,13 +405,13 @@ public class UpgradingRowAdapter extends Row { public LocalDate dateValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.DATE != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (LocalDate) column.defaultValue() : super.dateValue(mappedId); + return mappedId < 0 ? (LocalDate) column.defaultValue() : row.dateValue(mappedId); } /** {@inheritDoc} */ @@ -408,13 +419,13 @@ public class UpgradingRowAdapter extends Row { public LocalTime timeValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.TIME != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (LocalTime) column.defaultValue() : super.timeValue(mappedId); + return mappedId < 0 ? (LocalTime) column.defaultValue() : row.timeValue(mappedId); } /** {@inheritDoc} */ @@ -422,13 +433,13 @@ public class UpgradingRowAdapter extends Row { public LocalDateTime dateTimeValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.DATETIME != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (LocalDateTime) column.defaultValue() : super.dateTimeValue(mappedId); + return mappedId < 0 ? (LocalDateTime) column.defaultValue() : row.dateTimeValue(mappedId); } /** {@inheritDoc} */ @@ -436,13 +447,13 @@ public class UpgradingRowAdapter extends Row { public Instant timestampValue(int colIdx) throws InvalidTypeException { int mappedId = mapColumn(colIdx); - Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : super.schema().column(mappedId); + Column column = mappedId < 0 ? mapper.mappedColumn(colIdx) : row.schema().column(mappedId); if (NativeTypeSpec.TIMESTAMP != column.type().spec()) { throw new SchemaException("Type conversion is not supported yet."); } - return mappedId < 0 ? (Instant) column.defaultValue() : super.timestampValue(mappedId); + return mappedId < 0 ? (Instant) column.defaultValue() : row.timestampValue(mappedId); } @Override @@ -451,9 +462,14 @@ public class UpgradingRowAdapter extends Row { return mappedId < 0 ? mapper.mappedColumn(colIdx).defaultValue() == null - : super.hasNullValue(mappedId); + : row.hasNullValue(mappedId); } + /** {@inheritDoc} */ + @Override + public int colocationHash() { + return row.colocationHash(); + } @Override public int elementCount() { @@ -470,7 +486,6 @@ public class UpgradingRowAdapter extends Row { /** {@inheritDoc} */ @Override public ByteBuffer byteBuffer() { - // TODO: IGNITE-22156 Replace inheritance with delegation and drop this code. int size = newBinaryTupleSchema.elementCount(); var builder = new BinaryTupleBuilder(size); diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java index 51e378ade3..34894a1fd6 100644 --- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java @@ -18,59 +18,26 @@ package org.apache.ignite.internal.schema.row; import java.math.BigDecimal; -import java.nio.ByteBuffer; import org.apache.ignite.internal.binarytuple.BinaryTupleContainer; -import org.apache.ignite.internal.binarytuple.BinaryTupleReader; import org.apache.ignite.internal.lang.InternalTuple; import org.apache.ignite.internal.schema.BinaryRow; import org.apache.ignite.internal.schema.BinaryRowEx; -import org.apache.ignite.internal.schema.BinaryTuple; import org.apache.ignite.internal.schema.BinaryTupleSchema; -import org.apache.ignite.internal.schema.Column; import org.apache.ignite.internal.schema.SchemaAware; import org.apache.ignite.internal.schema.SchemaDescriptor; -import org.apache.ignite.internal.util.ColocationUtils; -import org.apache.ignite.internal.util.HashCalculator; /** - * Schema-aware row. - * - * <p>The class contains non-generic methods to read boxed and unboxed primitives based on the schema column types. Any type conversions - * and coercions should be implemented outside the row by the key-value or query runtime. - * - * <p>When a non-boxed primitive is read from a null column value, it is converted to the primitive type default value. + * Schema-aware row interface. */ -public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, InternalTuple, BinaryTupleContainer { - /** Schema descriptor. */ - private final SchemaDescriptor schema; - - /** Binary row. */ - private final BinaryRow row; - - private final BinaryTupleSchema binaryTupleSchema; - - private final boolean keyOnly; - - /** Cached colocation hash value. */ - private int colocationHash; - - protected Row(boolean keyOnly, SchemaDescriptor schema, BinaryTupleSchema binaryTupleSchema, BinaryRow row) { - super(binaryTupleSchema.elementCount(), row.tupleSlice()); - - this.keyOnly = keyOnly; - this.row = row; - this.schema = schema; - this.binaryTupleSchema = binaryTupleSchema; - } - +public interface Row extends SchemaAware, BinaryRowEx, InternalTuple, BinaryTupleContainer { /** * Creates a row from a given {@code BinaryRow}. * * @param schema Schema. * @param binaryRow Binary row. */ - public static Row wrapBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { - return new Row(false, schema, BinaryTupleSchema.createRowSchema(schema), binaryRow); + static Row wrapBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { + return new RowImpl(false, schema, BinaryTupleSchema.createRowSchema(schema), binaryRow); } /** @@ -79,106 +46,25 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, * @param schema Schema. * @param binaryRow Binary row. */ - public static Row wrapKeyOnlyBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { - return new Row(true, schema, BinaryTupleSchema.createKeySchema(schema), binaryRow); + static Row wrapKeyOnlyBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { + return new RowImpl(true, schema, BinaryTupleSchema.createKeySchema(schema), binaryRow); } - /** - * Get row schema. - */ - @Override - public SchemaDescriptor schema() { - return schema; - } + /** Short-cut method that reads decimal value with a scale from the schema. */ + BigDecimal decimalValue(int col); /** - * Gets a value indicating whether the row contains only key columns. + * Reads value for specified column. * - * @return {@code true} if the row contains only key columns. + * @param colIdx Column index. + * @return Column value. */ - public boolean keyOnly() { - return keyOnly; - } + Object value(int colIdx); /** - * Reads value for specified column. + * Gets a value indicating whether the row contains only key columns. * - * @param col Column index. - * @return Column value. + * @return {@code true} if the row contains only key columns. */ - public Object value(int col) { - return binaryTupleSchema.value(this, col); - } - - public BigDecimal decimalValue(int col) { - return binaryTupleSchema.decimalValue(this, col); - } - - /** {@inheritDoc} */ - @Override - public int schemaVersion() { - return row.schemaVersion(); - } - - @Override - public ByteBuffer tupleSlice() { - return row.tupleSlice(); - } - - @Override - public int tupleSliceLength() { - return row.tupleSliceLength(); - } - - /** {@inheritDoc} */ - @Override - public int colocationHash() { - int h0 = colocationHash; - - if (h0 == 0) { - HashCalculator hashCalc = new HashCalculator(); - - for (Column c : schema.colocationColumns()) { - int idx = keyOnly - ? c.positionInKey() - : c.positionInRow(); - - assert idx >= 0 : c; - - ColocationUtils.append(hashCalc, value(idx), c.type()); - } - - colocationHash = h0 = hashCalc.hash(); - } - - return h0; - } - - @Override - public BinaryTuple binaryTuple() { - return new BinaryTuple(binaryTupleSchema.elementCount(), row.tupleSlice()); - } - - public BinaryTupleSchema binaryTupleSchema() { - return binaryTupleSchema; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Row row1 = (Row) o; - - return row.equals(row1.row); - } - - @Override - public int hashCode() { - return row.hashCode(); - } + boolean keyOnly(); } diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowImpl.java similarity index 71% copy from modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java copy to modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowImpl.java index 51e378ade3..592065f6fc 100644 --- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowImpl.java @@ -19,18 +19,16 @@ package org.apache.ignite.internal.schema.row; import java.math.BigDecimal; import java.nio.ByteBuffer; -import org.apache.ignite.internal.binarytuple.BinaryTupleContainer; import org.apache.ignite.internal.binarytuple.BinaryTupleReader; -import org.apache.ignite.internal.lang.InternalTuple; import org.apache.ignite.internal.schema.BinaryRow; import org.apache.ignite.internal.schema.BinaryRowEx; import org.apache.ignite.internal.schema.BinaryTuple; import org.apache.ignite.internal.schema.BinaryTupleSchema; import org.apache.ignite.internal.schema.Column; -import org.apache.ignite.internal.schema.SchemaAware; import org.apache.ignite.internal.schema.SchemaDescriptor; import org.apache.ignite.internal.util.ColocationUtils; import org.apache.ignite.internal.util.HashCalculator; +import org.jetbrains.annotations.Nullable; /** * Schema-aware row. @@ -40,7 +38,7 @@ import org.apache.ignite.internal.util.HashCalculator; * * <p>When a non-boxed primitive is read from a null column value, it is converted to the primitive type default value. */ -public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, InternalTuple, BinaryTupleContainer { +public class RowImpl extends BinaryTupleReader implements Row, BinaryRowEx { /** Schema descriptor. */ private final SchemaDescriptor schema; @@ -54,7 +52,7 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, /** Cached colocation hash value. */ private int colocationHash; - protected Row(boolean keyOnly, SchemaDescriptor schema, BinaryTupleSchema binaryTupleSchema, BinaryRow row) { + RowImpl(boolean keyOnly, SchemaDescriptor schema, BinaryTupleSchema binaryTupleSchema, BinaryRow row) { super(binaryTupleSchema.elementCount(), row.tupleSlice()); this.keyOnly = keyOnly; @@ -63,26 +61,6 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, this.binaryTupleSchema = binaryTupleSchema; } - /** - * Creates a row from a given {@code BinaryRow}. - * - * @param schema Schema. - * @param binaryRow Binary row. - */ - public static Row wrapBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { - return new Row(false, schema, BinaryTupleSchema.createRowSchema(schema), binaryRow); - } - - /** - * Creates a row from a given {@code BinaryRow} that only contains the key component. - * - * @param schema Schema. - * @param binaryRow Binary row. - */ - public static Row wrapKeyOnlyBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { - return new Row(true, schema, BinaryTupleSchema.createKeySchema(schema), binaryRow); - } - /** * Get row schema. */ @@ -91,26 +69,21 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, return schema; } - /** - * Gets a value indicating whether the row contains only key columns. - * - * @return {@code true} if the row contains only key columns. - */ + /** {@inheritDoc} */ + @Override public boolean keyOnly() { return keyOnly; } - /** - * Reads value for specified column. - * - * @param col Column index. - * @return Column value. - */ + /** {@inheritDoc} */ + @Override public Object value(int col) { return binaryTupleSchema.value(this, col); } - public BigDecimal decimalValue(int col) { + /** {@inheritDoc} */ + @Override + public @Nullable BigDecimal decimalValue(int col) { return binaryTupleSchema.decimalValue(this, col); } @@ -120,11 +93,13 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, return row.schemaVersion(); } + /** {@inheritDoc} */ @Override public ByteBuffer tupleSlice() { return row.tupleSlice(); } + /** {@inheritDoc} */ @Override public int tupleSliceLength() { return row.tupleSliceLength(); @@ -154,15 +129,13 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, return h0; } + /** {@inheritDoc} */ @Override - public BinaryTuple binaryTuple() { + public BinaryTupleReader binaryTuple() { return new BinaryTuple(binaryTupleSchema.elementCount(), row.tupleSlice()); } - public BinaryTupleSchema binaryTupleSchema() { - return binaryTupleSchema; - } - + /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) { @@ -172,11 +145,12 @@ public class Row extends BinaryTupleReader implements BinaryRowEx, SchemaAware, return false; } - Row row1 = (Row) o; + RowImpl row1 = (RowImpl) o; return row.equals(row1.row); } + /** {@inheritDoc} */ @Override public int hashCode() { return row.hashCode(); diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapterTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapterTest.java index 181e334f1d..12452ea111 100644 --- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapterTest.java +++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/registry/UpgradingRowAdapterTest.java @@ -34,12 +34,18 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; import org.apache.ignite.internal.logger.Loggers; import org.apache.ignite.internal.schema.BinaryRow; +import org.apache.ignite.internal.schema.BinaryRowImpl; import org.apache.ignite.internal.schema.Column; import org.apache.ignite.internal.schema.SchemaDescriptor; import org.apache.ignite.internal.schema.SchemaTestUtils; @@ -55,6 +61,7 @@ import org.junit.jupiter.api.Test; * Tests row assembling and reading. */ public class UpgradingRowAdapterTest { + public static final String NULL_COLUMN_NAME = "valNullCol"; /** Random. */ private Random rnd; @@ -71,38 +78,52 @@ public class UpgradingRowAdapterTest { } @Test - public void testVariousColumnTypes() { - SchemaDescriptor schema = new SchemaDescriptor(1, - new Column[]{new Column("keyUuidCol", NativeTypes.UUID, false)}, - new Column[]{ - new Column("valBooleanCol", BOOLEAN, true), - new Column("valByteCol", INT8, true), - new Column("valShortCol", INT16, true), - new Column("valIntCol", INT32, true), - new Column("valLongCol", INT64, true), - new Column("valFloatCol", FLOAT, true), - new Column("valDoubleCol", DOUBLE, true), - new Column("valDateCol", DATE, true), - new Column("valTimeCol", time(0), true), - new Column("valDateTimeCol", datetime(6), true), - new Column("valTimeStampCol", timestamp(6), true), - new Column("valBitmask1Col", NativeTypes.bitmaskOf(22), true), - new Column("valBytesCol", BYTES, false), - new Column("valStringCol", STRING, false), - new Column("valNumberCol", NativeTypes.numberOf(20), false), - new Column("valDecimalCol", NativeTypes.decimalOf(25, 5), false), - } + public void testUpgradeRowWithVariousColumnTypes() { + SchemaDescriptor schema = createSchemaDescriptorWithColumnsOfAllTypes(); + SchemaDescriptor schema2 = applyAddingValueColumn(schema, 1, new Column("added", INT8, true)); + + var schemaRegistry = new SchemaRegistryImpl( + v -> v == 1 ? schema : schema2, + schema2 ); - SchemaDescriptor schema2 = new SchemaDescriptor(2, - new Column[]{new Column("keyUuidCol", NativeTypes.UUID, false)}, - new Column[]{ - new Column("added", INT8, true), - new Column("valBooleanCol", BOOLEAN, true), + List<Object> values = generateRowValues(schema); + BinaryRow originalBinaryRow = serializeValuesToRow(schema, values); + + Row originalRow = Row.wrapBinaryRow(schema, originalBinaryRow); + Row resolvedRow = schemaRegistry.resolve(originalBinaryRow, schema2); + + // validate UpgradedRowAdapter methods. + assertThat("Colocation hash mismatch", resolvedRow.colocationHash(), equalTo(originalRow.colocationHash())); + assertThat("KeyOnly flag mismatch", resolvedRow.keyOnly(), equalTo(originalRow.keyOnly())); + assertThat("Unexpected element count", resolvedRow.elementCount(), equalTo(originalRow.elementCount() + 1)); + + assertNotNull(resolvedRow.byteBuffer()); + assertNull(resolvedRow.binaryTuple(), "Underlying binary tuple must never be used"); + assertThrows(UnsupportedOperationException.class, resolvedRow::tupleSlice, "Underlying binary tuple must never be used"); + assertThrows(UnsupportedOperationException.class, resolvedRow::tupleSliceLength, "Underlying binary tuple must never be used"); + + // Validate original row. + validateRow(values, originalRow); + + // Validate upgraded row. + values.add(1, null); + validateRow(values, resolvedRow); + + BinaryRowImpl restoredRow = new BinaryRowImpl(schema2.version(), resolvedRow.byteBuffer()); + assertThat(restoredRow.schemaVersion(), equalTo(schema2.version())); + validateRow(values, Row.wrapBinaryRow(schema2, restoredRow)); + } + + private static SchemaDescriptor createSchemaDescriptorWithColumnsOfAllTypes() { + return new SchemaDescriptor(1, + List.of(new Column("valBooleanCol", BOOLEAN, true), new Column("valByteCol", INT8, true), new Column("valShortCol", INT16, true), new Column("valIntCol", INT32, true), + new Column("keyUuidCol", NativeTypes.UUID, false), new Column("valLongCol", INT64, true), + new Column(NULL_COLUMN_NAME, INT64, true), new Column("valFloatCol", FLOAT, true), new Column("valDoubleCol", DOUBLE, true), new Column("valDateCol", DATE, true), @@ -113,21 +134,34 @@ public class UpgradingRowAdapterTest { new Column("valBytesCol", BYTES, false), new Column("valStringCol", STRING, false), new Column("valNumberCol", NativeTypes.numberOf(20), false), - new Column("valDecimalCol", NativeTypes.decimalOf(25, 5), false), - } + new Column("valDecimalCol", NativeTypes.decimalOf(25, 5), false)), + List.of("keyUuidCol"), + null + ); + } + + private static SchemaDescriptor applyAddingValueColumn(SchemaDescriptor desc, int position, Column newColumn) { + List<Column> columns = new ArrayList<>(desc.columns()); + columns.add(position, newColumn); + + SchemaDescriptor newSchema = new SchemaDescriptor( + desc.version() + 1, + columns, + desc.keyColumns().stream().map(Column::name).collect(Collectors.toList()), + desc.colocationColumns().stream().map(Column::name).collect(Collectors.toList()) ); - int addedColumnIndex = schema2.column("added").positionInRow(); + int addedColumnIndex = newSchema.column(newColumn.name()).positionInRow(); - schema2.columnMapping(new ColumnMapper() { + newSchema.columnMapping(new ColumnMapper() { @Override public ColumnMapper add(Column col) { - return null; + return fail(); } @Override public ColumnMapper add(int from, int to) { - return null; + return fail(); } @Override @@ -137,41 +171,20 @@ public class UpgradingRowAdapterTest { @Override public Column mappedColumn(int idx) { - return idx == addedColumnIndex ? schema2.column(idx) : null; + return idx == addedColumnIndex ? newSchema.column(idx) : null; } }); - List<Object> values = generateRowValues(schema); - - BinaryRow row = serializeValuesToRow(schema, values); - - var schemaRegistry = new SchemaRegistryImpl( - v -> v == 1 ? schema : schema2, - schema - ); - - // Validate row. - validateRow(values, schemaRegistry, row); - - // Validate upgraded row. - values.add(addedColumnIndex, null); - - var schema2Registry = new SchemaRegistryImpl( - v -> v == 1 ? schema : schema2, - schema2 - ); - - validateRow(values, schema2Registry, row); + return newSchema; } - private void validateRow(List<Object> values, SchemaRegistryImpl schemaRegistry, BinaryRow binaryRow) { - Row row = schemaRegistry.resolve(binaryRow, schemaRegistry.lastKnownSchemaVersion()); - + private static void validateRow(List<Object> values, Row row) { SchemaDescriptor schema = row.schema(); for (int i = 0; i < values.size(); i++) { Column col = schema.column(i); + assertThat("Failed for column: " + col, row.hasNullValue(col.positionInRow()), is(equalTo(values.get(i) == null))); assertThat("Failed for column: " + col, row.value(col.positionInRow()), is(equalTo(values.get(i)))); } } @@ -188,7 +201,11 @@ public class UpgradingRowAdapterTest { for (int i = 0; i < schema.length(); i++) { NativeType type = schema.column(i).type(); - res.add(SchemaTestUtils.generateRandomValue(rnd, type)); + if (NULL_COLUMN_NAME.equals(schema.column(i).name())) { + res.add(null); + } else { + res.add(SchemaTestUtils.generateRandomValue(rnd, type)); + } } return res; @@ -198,7 +215,7 @@ public class UpgradingRowAdapterTest { * Validates row values after serialization-then-deserialization. * * @param schema Row schema. - * @param vals Row values. + * @param vals Row values. * @return Row bytes. */ private static BinaryRow serializeValuesToRow(SchemaDescriptor schema, List<Object> vals) { diff --git a/modules/table/src/main/java/org/apache/ignite/internal/table/MutableRowTupleAdapter.java b/modules/table/src/main/java/org/apache/ignite/internal/table/MutableRowTupleAdapter.java index 931ebe9274..26a75378b8 100644 --- a/modules/table/src/main/java/org/apache/ignite/internal/table/MutableRowTupleAdapter.java +++ b/modules/table/src/main/java/org/apache/ignite/internal/table/MutableRowTupleAdapter.java @@ -27,7 +27,7 @@ import java.util.BitSet; import java.util.Iterator; import java.util.UUID; import org.apache.ignite.internal.binarytuple.BinaryTupleContainer; -import org.apache.ignite.internal.schema.BinaryTuple; +import org.apache.ignite.internal.binarytuple.BinaryTupleReader; import org.apache.ignite.internal.schema.SchemaDescriptor; import org.apache.ignite.internal.schema.row.Row; import org.apache.ignite.table.Tuple; @@ -299,7 +299,7 @@ public class MutableRowTupleAdapter extends AbstractRowTupleAdapter implements S /** {@inheritDoc} */ @Override - public @Nullable BinaryTuple binaryTuple() { + public @Nullable BinaryTupleReader binaryTuple() { return row == null ? null : row.binaryTuple(); } diff --git a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java index 711d12c8ae..f623b06efe 100644 --- a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java +++ b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java @@ -432,7 +432,7 @@ public class RecordViewImpl<R> extends AbstractTableView<R> implements RecordVie List<BinaryRowEx> rows = new ArrayList<>(recs.size()); for (R rec : recs) { - Row row = marsh.marshal(Objects.requireNonNull(rec)); + BinaryRowEx row = marsh.marshal(Objects.requireNonNull(rec)); rows.add(row); } @@ -451,7 +451,7 @@ public class RecordViewImpl<R> extends AbstractTableView<R> implements RecordVie for (R rec : recs) { boolean isDeleted = deleted != null && deleted.get(rows.size()); - Row row = isDeleted ? marsh.marshalKey(rec) : marsh.marshal(rec); + BinaryRowEx row = isDeleted ? marsh.marshalKey(rec) : marsh.marshal(rec); rows.add(row); } @@ -493,7 +493,7 @@ public class RecordViewImpl<R> extends AbstractTableView<R> implements RecordVie List<BinaryRowEx> rows = new ArrayList<>(recs.size()); for (R rec : recs) { - Row row = marsh.marshalKey(Objects.requireNonNull(rec)); + BinaryRowEx row = marsh.marshalKey(Objects.requireNonNull(rec)); rows.add(row); }
