You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2022/09/19 14:56:16 UTC
[ignite-3] branch main updated: IGNITE-17632 Support decimal scale in client schema (#1097)
This is an automated email from the ASF dual-hosted git repository.
ptupitsyn 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 fc959a42eb IGNITE-17632 Support decimal scale in client schema (#1097)
fc959a42eb is described below
commit fc959a42eb21987feffa0319a99aa63fed2dc00e
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Mon Sep 19 17:56:10 2022 +0300
IGNITE-17632 Support decimal scale in client schema (#1097)
* Require `scale` in `BinaryTupleBuilder#appendDecimalNotNull` to ensure correct value round-trip.
* Add decimal scale to client schema to fix serialization and deserialization of `BigDecimal` values.
---
.../internal/binarytuple/BinaryTupleBuilder.java | 11 +++---
.../internal/binarytuple/BinaryTupleTest.java | 20 ++++++++++-
.../client/proto/ClientBinaryTupleUtils.java | 6 ++--
.../handler/requests/table/ClientTableCommon.java | 13 +++++--
.../ignite/internal/client/table/ClientColumn.java | 27 ++++++++++++++
.../ignite/internal/client/table/ClientSchema.java | 2 +-
.../ignite/internal/client/table/ClientTable.java | 7 ++--
.../client/table/ClientTupleSerializer.java | 16 ++++-----
.../marshaller/ClientMarshallerReader.java | 5 ++-
.../marshaller/ClientMarshallerWriter.java | 4 +--
.../ignite/client/ClientKeyValueViewTest.java | 4 +--
.../apache/ignite/client/ClientRecordViewTest.java | 4 +--
.../ignite/client/fakes/FakeIgniteTables.java | 2 +-
.../ignite/internal/marshaller/FieldAccessor.java | 41 +++++++++++++++-------
.../internal/marshaller/MarshallerColumn.java | 14 ++++++--
.../internal/marshaller/MarshallerReader.java | 2 +-
.../internal/marshaller/MarshallerWriter.java | 4 +--
.../internal/marshaller/FieldAccessorTest.java | 4 +--
.../ignite/internal/schema/BinaryConverter.java | 2 +-
.../index/impl/BinaryTupleRowSerializer.java | 2 +-
20 files changed, 135 insertions(+), 55 deletions(-)
diff --git a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java
index 873ba1d3f4..7f09077556 100644
--- a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java
+++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.binarytuple;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
@@ -326,10 +327,11 @@ public class BinaryTupleBuilder {
* Append a value for the current element.
*
* @param value Element value.
+ * @param scale Decimal scale.
* @return {@code this} for chaining.
*/
- public BinaryTupleBuilder appendDecimalNotNull(@NotNull BigDecimal value) {
- putBytes(value.unscaledValue().toByteArray());
+ public BinaryTupleBuilder appendDecimalNotNull(@NotNull BigDecimal value, int scale) {
+ putBytes(value.setScale(scale, RoundingMode.HALF_UP).unscaledValue().toByteArray());
return proceed();
}
@@ -337,10 +339,11 @@ public class BinaryTupleBuilder {
* Append a value for the current element.
*
* @param value Element value.
+ * @param scale Decimal scale.
* @return {@code this} for chaining.
*/
- public BinaryTupleBuilder appendDecimal(BigDecimal value) {
- return value == null ? appendNull() : appendDecimalNotNull(value);
+ public BinaryTupleBuilder appendDecimal(BigDecimal value, int scale) {
+ return value == null ? appendNull() : appendDecimalNotNull(value, scale);
}
/**
diff --git a/modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java b/modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java
index 95b50bf8b7..969ba0acf6 100644
--- a/modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java
+++ b/modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java
@@ -354,12 +354,30 @@ public class BinaryTupleTest {
BigDecimal value = new BigDecimal(BigInteger.valueOf(12345), 100);
BinaryTupleBuilder builder = BinaryTupleBuilder.create(1, false);
- ByteBuffer bytes = builder.appendDecimal(value).build();
+ ByteBuffer bytes = builder.appendDecimal(value, 100).build();
BinaryTupleReader reader = new BinaryTupleReader(1, bytes);
assertEquals(value, reader.decimalValue(0, 100));
}
+ /**
+ * Test big decimal value encoding with different scale in value and schema.
+ */
+ @Test
+ public void decimalScaleTest() {
+ int schemaScale = 10;
+ int valueScale = 3;
+ BigDecimal value = BigDecimal.valueOf(123456, valueScale);
+
+ BinaryTupleBuilder builder = BinaryTupleBuilder.create(1, false);
+ ByteBuffer bytes = builder.appendDecimal(value, schemaScale).build();
+
+ BinaryTupleReader reader = new BinaryTupleReader(1, bytes);
+ BigDecimal res = reader.decimalValue(0, schemaScale);
+
+ assertEquals(value.doubleValue(), res.doubleValue());
+ }
+
/**
* Test string value encoding.
*/
diff --git a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
index 5d28a5667d..1038532ddd 100644
--- a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
+++ b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
@@ -41,7 +41,8 @@ public class ClientBinaryTupleUtils {
int readerIndex,
Tuple tuple,
String columnName,
- int clientDataType) {
+ int clientDataType,
+ int decimalScale) {
if (reader.hasNullValue(readerIndex)) {
tuple.set(columnName, null);
return;
@@ -73,8 +74,7 @@ public class ClientBinaryTupleUtils {
break;
case ClientDataType.DECIMAL:
- // TODO IGNITE-17632: Get scale from schema.
- tuple.set(columnName, reader.decimalValue(readerIndex, 100));
+ tuple.set(columnName, reader.decimalValue(readerIndex, decimalScale));
break;
case ClientDataType.UUID:
diff --git a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
index 5c8452d9c6..1ab66e4521 100644
--- a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
+++ b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
@@ -40,6 +40,8 @@ import org.apache.ignite.internal.client.proto.ClientMessagePacker;
import org.apache.ignite.internal.client.proto.ClientMessageUnpacker;
import org.apache.ignite.internal.client.proto.TuplePart;
import org.apache.ignite.internal.schema.Column;
+import org.apache.ignite.internal.schema.DecimalNativeType;
+import org.apache.ignite.internal.schema.NativeType;
import org.apache.ignite.internal.schema.NativeTypeSpec;
import org.apache.ignite.internal.schema.SchemaAware;
import org.apache.ignite.internal.schema.SchemaDescriptor;
@@ -81,11 +83,12 @@ public class ClientTableCommon {
for (var colIdx = 0; colIdx < colCnt; colIdx++) {
var col = schema.column(colIdx);
- packer.packArrayHeader(4);
+ packer.packArrayHeader(5);
packer.packString(col.name());
packer.packInt(getClientDataType(col.type().spec()));
packer.packBoolean(schema.isKeyColumn(colIdx));
packer.packBoolean(col.nullable());
+ packer.packInt(getDecimalScale(col.type()));
}
}
@@ -285,7 +288,7 @@ public class ClientTableCommon {
Column column = schema.column(i);
ClientBinaryTupleUtils.readAndSetColumnValue(
- binaryTupleReader, i, tuple, column.name(), getClientDataType(column.type().spec()));
+ binaryTupleReader, i, tuple, column.name(), getClientDataType(column.type().spec()), getDecimalScale(column.type()));
}
return tuple;
@@ -461,7 +464,7 @@ public class ClientTableCommon {
break;
case DECIMAL:
- builder.appendDecimalNotNull((BigDecimal) val);
+ builder.appendDecimalNotNull((BigDecimal) val, getDecimalScale(col.type()));
break;
case NUMBER:
@@ -517,4 +520,8 @@ public class ClientTableCommon {
packer.packBinaryHeader(buf.limit() - buf.position());
packer.writePayload(buf);
}
+
+ private static int getDecimalScale(NativeType type) {
+ return type instanceof DecimalNativeType ? ((DecimalNativeType) type).scale() : 0;
+ }
}
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientColumn.java b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientColumn.java
index dd7728cbe0..2a1368c3f2 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientColumn.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientColumn.java
@@ -38,6 +38,9 @@ public class ClientColumn {
/** Index of the column in the schema. */
private final int schemaIndex;
+ /** value scale, if applicable. */
+ private final int scale;
+
/**
* Constructor.
*
@@ -48,6 +51,20 @@ public class ClientColumn {
* @param schemaIndex Index of the column in the schema.
*/
public ClientColumn(String name, int type, boolean nullable, boolean isKey, int schemaIndex) {
+ this(name, type, nullable, isKey, schemaIndex, 0);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name Column name.
+ * @param type Column type code.
+ * @param nullable Nullable flag.
+ * @param isKey Key column flag.
+ * @param schemaIndex Index of the column in the schema.
+ * @param scale Scale of the column, if applicable.
+ */
+ public ClientColumn(String name, int type, boolean nullable, boolean isKey, int schemaIndex, int scale) {
assert name != null;
assert schemaIndex >= 0;
@@ -56,6 +73,7 @@ public class ClientColumn {
this.nullable = nullable;
this.isKey = isKey;
this.schemaIndex = schemaIndex;
+ this.scale = scale;
}
public String name() {
@@ -97,4 +115,13 @@ public class ClientColumn {
public int schemaIndex() {
return schemaIndex;
}
+
+ /**
+ * Gets the decimal scale of the column, if applicable.
+ *
+ * @return Decimal scale.
+ */
+ public int scale() {
+ return scale;
+ }
}
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientSchema.java b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientSchema.java
index 04e30bab4a..89fe3345b2 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientSchema.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientSchema.java
@@ -164,7 +164,7 @@ public class ClientSchema {
for (int i = 0; i < colCount; i++) {
var col = columns[i + firstColIdx];
- cols[i] = new MarshallerColumn(col.name(), mode(col.type()));
+ cols[i] = new MarshallerColumn(col.name(), mode(col.type()), null, col.scale());
}
return Marshaller.createMarshaller(cols, mapper, part == TuplePart.KEY);
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
index 47b3bc11b2..2d1ec8da30 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
@@ -175,17 +175,18 @@ public class ClientTable implements Table {
for (int i = 0; i < colCnt; i++) {
var propCnt = in.unpackArrayHeader();
- assert propCnt >= 4;
+ assert propCnt >= 5;
var name = in.unpackString();
var type = in.unpackInt();
var isKey = in.unpackBoolean();
var isNullable = in.unpackBoolean();
+ var scale = in.unpackInt();
// Skip unknown extra properties, if any.
- in.skipValues(propCnt - 4);
+ in.skipValues(propCnt - 5);
- var column = new ClientColumn(name, type, isNullable, isKey, i);
+ var column = new ClientColumn(name, type, isNullable, isKey, i, scale);
columns[i] = column;
}
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
index 3397d24dc2..79b30172d9 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
@@ -241,7 +241,7 @@ public class ClientTupleSerializer {
for (var i = 0; i < colCnt; i++) {
ClientColumn column = schema.columns()[i];
- ClientBinaryTupleUtils.readAndSetColumnValue(binTuple, i, tuple, column.name(), column.type());
+ ClientBinaryTupleUtils.readAndSetColumnValue(binTuple, i, tuple, column.name(), column.type(), column.scale());
}
return tuple;
@@ -257,7 +257,8 @@ public class ClientTupleSerializer {
if (i < schema.keyColumnCount()) {
tuple.setInternal(i, keyTuple.value(col.name()));
} else {
- ClientBinaryTupleUtils.readAndSetColumnValue(binTuple, i - schema.keyColumnCount(), tuple, col.name(), col.type());
+ ClientBinaryTupleUtils.readAndSetColumnValue(
+ binTuple, i - schema.keyColumnCount(), tuple, col.name(), col.type(), col.scale());
}
}
@@ -274,7 +275,7 @@ public class ClientTupleSerializer {
for (var i = keyColCnt; i < colCnt; i++) {
ClientColumn col = schema.columns()[i];
ClientBinaryTupleUtils.readAndSetColumnValue(
- binTupleReader, i - keyColCnt, valTuple, col.name(), col.type());
+ binTupleReader, i - keyColCnt, valTuple, col.name(), col.type(), col.scale());
}
return valTuple;
@@ -291,12 +292,9 @@ public class ClientTupleSerializer {
for (var i = 0; i < colCnt; i++) {
ClientColumn col = schema.columns()[i];
+ var targetTuple = i < keyColCnt ? keyTuple : valTuple;
- if (i < keyColCnt) {
- ClientBinaryTupleUtils.readAndSetColumnValue(binTuple, i, keyTuple, col.name(), col.type());
- } else {
- ClientBinaryTupleUtils.readAndSetColumnValue(binTuple, i, valTuple, col.name(), col.type());
- }
+ ClientBinaryTupleUtils.readAndSetColumnValue(binTuple, i, targetTuple, col.name(), col.type(), col.scale());
}
return new IgniteBiTuple<>(keyTuple, valTuple);
@@ -395,7 +393,7 @@ public class ClientTupleSerializer {
return;
case ClientDataType.DECIMAL:
- builder.appendDecimalNotNull((BigDecimal) v);
+ builder.appendDecimalNotNull((BigDecimal) v, col.scale());
return;
case ClientDataType.UUID:
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerReader.java b/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerReader.java
index 17576a8a11..dcfe309f2d 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerReader.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerReader.java
@@ -168,10 +168,9 @@ public class ClientMarshallerReader implements MarshallerReader {
/** {@inheritDoc} */
@Override
- public BigDecimal readBigDecimal() {
- // TODO IGNITE-17632: Get scale from schema.
+ public BigDecimal readBigDecimal(int scale) {
var idx = index++;
- return unpacker.hasNullValue(idx) ? null : unpacker.decimalValue(idx, 100);
+ return unpacker.hasNullValue(idx) ? null : unpacker.decimalValue(idx, scale);
}
/** {@inheritDoc} */
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerWriter.java b/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerWriter.java
index 7a1fc7ea86..84b9ad79bf 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerWriter.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/marshaller/ClientMarshallerWriter.java
@@ -129,8 +129,8 @@ public class ClientMarshallerWriter implements MarshallerWriter {
/** {@inheritDoc} */
@Override
- public void writeBigDecimal(BigDecimal val) {
- packer.appendDecimal(val);
+ public void writeBigDecimal(BigDecimal val, int scale) {
+ packer.appendDecimal(val, scale);
}
/** {@inheritDoc} */
diff --git a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
index 222dd16860..371b5a8d59 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
@@ -136,7 +136,7 @@ public class ClientKeyValueViewTest extends AbstractClientTableTest {
assertEquals("foo", res.zstring);
assertArrayEquals(new byte[]{1, 2}, res.zbytes);
assertEquals(BitSet.valueOf(new byte[]{32}), res.zbitmask);
- assertEquals(21, res.zdecimal.unscaledValue().longValue()); // TODO: IGNITE-17632 check correct round-trip
+ assertEquals(21, res.zdecimal.longValue());
assertEquals(22, res.znumber.longValue());
assertEquals(uuid, res.zuuid);
}
@@ -191,7 +191,7 @@ public class ClientKeyValueViewTest extends AbstractClientTableTest {
assertEquals("119", res.stringValue("zstring"));
assertEquals(120, ((byte[]) res.value("zbytes"))[0]);
assertEquals(BitSet.valueOf(new byte[]{121}), res.bitmaskValue("zbitmask"));
- assertEquals(122, ((BigDecimal) res.value("zdecimal")).unscaledValue().longValue()); // TODO: IGNITE-17632 check correct round-trip
+ assertEquals(122, ((BigDecimal) res.value("zdecimal")).longValue());
assertEquals(BigInteger.valueOf(123), res.value("znumber"));
assertEquals(uuid, res.uuidValue("zuuid"));
}
diff --git a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
index 413370477b..d98a924f6c 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
@@ -136,7 +136,7 @@ public class ClientRecordViewTest extends AbstractClientTableTest {
assertEquals("foo", res.zstring);
assertArrayEquals(new byte[]{1, 2}, res.zbytes);
assertEquals(BitSet.valueOf(new byte[]{32}), res.zbitmask);
- assertEquals(21, res.zdecimal.unscaledValue().longValue()); // TODO: IGNITE-17632 check correct round-trip
+ assertEquals(21, res.zdecimal.longValue());
assertEquals(22, res.znumber.longValue());
assertEquals(uuid, res.zuuid);
}
@@ -189,7 +189,7 @@ public class ClientRecordViewTest extends AbstractClientTableTest {
assertEquals("119", res.stringValue("zstring"));
assertEquals(120, ((byte[]) res.value("zbytes"))[0]);
assertEquals(BitSet.valueOf(new byte[]{121}), res.bitmaskValue("zbitmask"));
- assertEquals(122, ((BigDecimal) res.value("zdecimal")).unscaledValue().longValue());
+ assertEquals(122, ((BigDecimal) res.value("zdecimal")).longValue());
assertEquals(BigInteger.valueOf(123), res.value("znumber"));
assertEquals(uuid, res.uuidValue("zuuid"));
}
diff --git a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
index 1ce0880260..3b430425ca 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
@@ -241,7 +241,7 @@ public class FakeIgniteTables implements IgniteTables, IgniteTablesInternal {
new Column("zbytes".toUpperCase(), NativeTypes.BYTES, true),
new Column("zuuid".toUpperCase(), NativeTypes.UUID, true),
new Column("zbitmask".toUpperCase(), NativeTypes.bitmaskOf(16), true),
- new Column("zdecimal".toUpperCase(), NativeTypes.decimalOf(20, 100), true),
+ new Column("zdecimal".toUpperCase(), NativeTypes.decimalOf(20, 10), true),
new Column("znumber".toUpperCase(), NativeTypes.numberOf(24), true),
});
}
diff --git a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/FieldAccessor.java b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/FieldAccessor.java
index 25da0cc471..6783ddfd6f 100644
--- a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/FieldAccessor.java
+++ b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/FieldAccessor.java
@@ -45,6 +45,9 @@ abstract class FieldAccessor {
*/
protected final int colIdx;
+ /** Scale. */
+ protected final int scale;
+
public Object get(Object obj) {
return varHandle.get(obj);
}
@@ -112,7 +115,7 @@ abstract class FieldAccessor {
case DATE:
case DATETIME:
case TIMESTAMP:
- return new ReferenceFieldAccessor(varHandle, colIdx, mode);
+ return new ReferenceFieldAccessor(varHandle, colIdx, mode, col.scale());
default:
assert false : "Invalid mode " + mode;
@@ -176,7 +179,7 @@ abstract class FieldAccessor {
* @param mode Binary read mode.
* @return Read value object.
*/
- private static Object readRefValue(MarshallerReader reader, int colIdx, BinaryMode mode) {
+ private static Object readRefValue(MarshallerReader reader, int colIdx, BinaryMode mode, int scale) {
assert reader != null;
assert colIdx >= 0;
@@ -239,7 +242,7 @@ abstract class FieldAccessor {
break;
case DECIMAL:
- val = reader.readBigDecimal();
+ val = reader.readBigDecimal(scale);
break;
@@ -277,7 +280,7 @@ abstract class FieldAccessor {
* @param writer Writer.
* @param mode Write binary mode.
*/
- private static void writeRefObject(Object val, MarshallerWriter writer, BinaryMode mode) {
+ private static void writeRefObject(Object val, MarshallerWriter writer, BinaryMode mode, int scale) {
assert writer != null;
if (val == null) {
@@ -343,7 +346,7 @@ abstract class FieldAccessor {
break;
case DECIMAL:
- writer.writeBigDecimal((BigDecimal) val);
+ writer.writeBigDecimal((BigDecimal) val, scale);
break;
@@ -378,13 +381,26 @@ abstract class FieldAccessor {
* @param varHandle Field var-handle.
* @param colIdx Column index.
* @param mode Read/write mode.
+ * @param scale Scale.
*/
- protected FieldAccessor(VarHandle varHandle, int colIdx, BinaryMode mode) {
+ protected FieldAccessor(VarHandle varHandle, int colIdx, BinaryMode mode, int scale) {
assert colIdx >= 0;
this.colIdx = colIdx;
this.mode = Objects.requireNonNull(mode);
this.varHandle = Objects.requireNonNull(varHandle);
+ this.scale = scale;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param varHandle Field var-handle.
+ * @param colIdx Column index.
+ * @param mode Read/write mode.
+ */
+ protected FieldAccessor(VarHandle varHandle, int colIdx, BinaryMode mode) {
+ this(varHandle, colIdx, mode, 0);
}
/**
@@ -399,6 +415,7 @@ abstract class FieldAccessor {
this.colIdx = colIdx;
this.mode = mode;
varHandle = null;
+ scale = 0;
}
/**
@@ -522,7 +539,7 @@ abstract class FieldAccessor {
/** {@inheritDoc} */
@Override
protected void write0(MarshallerWriter writer, Object obj) {
- writeRefObject(obj, writer, mode);
+ writeRefObject(obj, writer, mode, scale);
}
/** {@inheritDoc} */
@@ -534,7 +551,7 @@ abstract class FieldAccessor {
/** {@inheritDoc} */
@Override
public Object read(MarshallerReader reader) {
- return readRefValue(reader, colIdx, mode);
+ return readRefValue(reader, colIdx, mode, scale);
}
/** {@inheritDoc} */
@@ -741,8 +758,8 @@ abstract class FieldAccessor {
* @param colIdx Column index.
* @param mode Read/write mode.
*/
- ReferenceFieldAccessor(VarHandle varHandle, int colIdx, BinaryMode mode) {
- super(Objects.requireNonNull(varHandle), colIdx, mode);
+ ReferenceFieldAccessor(VarHandle varHandle, int colIdx, BinaryMode mode, int scale) {
+ super(Objects.requireNonNull(varHandle), colIdx, mode, scale);
}
/** {@inheritDoc} */
@@ -759,13 +776,13 @@ abstract class FieldAccessor {
return;
}
- writeRefObject(val, writer, mode);
+ writeRefObject(val, writer, mode, scale);
}
/** {@inheritDoc} */
@Override
public void read0(MarshallerReader reader, Object obj) {
- Object val = readRefValue(reader, colIdx, mode);
+ Object val = readRefValue(reader, colIdx, mode, scale);
varHandle.set(obj, val);
}
diff --git a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerColumn.java b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerColumn.java
index f2b782d4fe..73ec221f25 100644
--- a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerColumn.java
+++ b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerColumn.java
@@ -38,6 +38,11 @@ public class MarshallerColumn {
*/
private final BinaryMode type;
+ /**
+ * Scale.
+ */
+ private final int scale;
+
/**
* Default value supplier.
*/
@@ -51,7 +56,7 @@ public class MarshallerColumn {
* @param type An instance of column data type.
*/
public MarshallerColumn(String name, BinaryMode type) {
- this(name, type, null);
+ this(name, type, null, 0);
}
/**
@@ -61,10 +66,11 @@ public class MarshallerColumn {
* @param type An instance of column data type.
* @param defValSup Default value supplier.
*/
- public MarshallerColumn(String name, BinaryMode type, @Nullable Supplier<Object> defValSup) {
+ public MarshallerColumn(String name, BinaryMode type, @Nullable Supplier<Object> defValSup, int scale) {
this.name = name;
this.type = type;
this.defValSup = defValSup == null ? NULL_SUPPLIER : defValSup;
+ this.scale = scale;
}
public String name() {
@@ -78,4 +84,8 @@ public class MarshallerColumn {
public Object defaultValue() {
return defValSup.get();
}
+
+ public int scale() {
+ return scale;
+ }
}
diff --git a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerReader.java b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerReader.java
index 58f188b24a..654fe0b70f 100644
--- a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerReader.java
+++ b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerReader.java
@@ -159,7 +159,7 @@ public interface MarshallerReader {
*
* @return Value.
*/
- BigDecimal readBigDecimal();
+ BigDecimal readBigDecimal(int scale);
/**
* Reads a date.
diff --git a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerWriter.java b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerWriter.java
index 8c966c3cd0..100a05b53f 100644
--- a/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerWriter.java
+++ b/modules/marshaller-common/src/main/java/org/apache/ignite/internal/marshaller/MarshallerWriter.java
@@ -125,7 +125,7 @@ public interface MarshallerWriter {
*
* @param val Value.
*/
- void writeBigDecimal(BigDecimal val);
+ void writeBigDecimal(BigDecimal val, int scale);
/**
* Writes date.
@@ -245,7 +245,7 @@ public interface MarshallerWriter {
break;
}
case DECIMAL: {
- writeBigDecimal((BigDecimal) val);
+ writeBigDecimal((BigDecimal) val, col.scale());
break;
}
diff --git a/modules/marshaller-common/src/test/java/org/apache/ignite/internal/marshaller/FieldAccessorTest.java b/modules/marshaller-common/src/test/java/org/apache/ignite/internal/marshaller/FieldAccessorTest.java
index 69d556f755..7b74e941d9 100644
--- a/modules/marshaller-common/src/test/java/org/apache/ignite/internal/marshaller/FieldAccessorTest.java
+++ b/modules/marshaller-common/src/test/java/org/apache/ignite/internal/marshaller/FieldAccessorTest.java
@@ -266,7 +266,7 @@ public class FieldAccessorTest {
Mockito.doAnswer(asmAnswer).when(mockedAsm).writeString(Mockito.anyString());
Mockito.doAnswer(asmAnswer).when(mockedAsm).writeBytes(Mockito.any(byte[].class));
Mockito.doAnswer(asmAnswer).when(mockedAsm).writeBigInt(Mockito.any(BigInteger.class));
- Mockito.doAnswer(asmAnswer).when(mockedAsm).writeBigDecimal(Mockito.any(BigDecimal.class));
+ Mockito.doAnswer(asmAnswer).when(mockedAsm).writeBigDecimal(Mockito.any(BigDecimal.class), Mockito.anyInt());
Mockito.doAnswer(asmAnswer).when(mockedAsm).writeDate(Mockito.any(LocalDate.class));
Mockito.doAnswer(asmAnswer).when(mockedAsm).writeDateTime(Mockito.any(LocalDateTime.class));
@@ -296,7 +296,7 @@ public class FieldAccessorTest {
Mockito.doAnswer(rowAnswer).when(mockedRow).readString();
Mockito.doAnswer(rowAnswer).when(mockedRow).readBytes();
Mockito.doAnswer(rowAnswer).when(mockedRow).readBigInt();
- Mockito.doAnswer(rowAnswer).when(mockedRow).readBigDecimal();
+ Mockito.doAnswer(rowAnswer).when(mockedRow).readBigDecimal(0);
return new Pair<>(mockedAsm, mockedRow);
}
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java
index 5b592216d7..259b82f2a3 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java
@@ -154,7 +154,7 @@ public class BinaryConverter {
builder.appendNumberNotNull(row.numberValue(columnIndex));
break;
case DECIMAL:
- builder.appendDecimalNotNull(row.decimalValue(columnIndex));
+ builder.appendDecimalNotNull(row.decimalValue(columnIndex), elt.decimalScale);
break;
case STRING:
case BYTES:
diff --git a/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java b/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java
index 4dbb2cc66e..798d70bd22 100644
--- a/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java
+++ b/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java
@@ -173,7 +173,7 @@ public class BinaryTupleRowSerializer {
case NUMBER:
return builder.appendNumberNotNull((BigInteger) value);
case DECIMAL:
- return builder.appendDecimalNotNull((BigDecimal) value);
+ return builder.appendDecimalNotNull((BigDecimal) value, element.decimalScale());
case UUID:
return builder.appendUuidNotNull((UUID) value);
case BYTES: