Skip to content

Commit

Permalink
Update tests of DecimalType/DecimalValue
Browse files Browse the repository at this point in the history
  • Loading branch information
alex268 committed Dec 24, 2024
1 parent cca97f3 commit 2e52743
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 35 deletions.
66 changes: 66 additions & 0 deletions table/src/test/java/tech/ydb/table/integration/ValuesReadTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import tech.ydb.table.result.ValueReader;
import tech.ydb.table.rpc.grpc.GrpcTableRpc;
import tech.ydb.table.transaction.TxControl;
import tech.ydb.table.values.DecimalType;
import tech.ydb.table.values.DecimalValue;
import tech.ydb.table.values.NullType;
import tech.ydb.table.values.NullValue;
import tech.ydb.table.values.PrimitiveType;
Expand Down Expand Up @@ -157,4 +159,68 @@ public void timestampReadTest() {
Assert.assertEquals("Invalid value \"2106-01-01T00:00:00.000000Z\" for type Timestamp", issues[1].getMessage());

}

@Test
public void decimalReadTest() {
DataQueryResult result = CTX.supplyResult(
s -> s.executeDataQuery("SELECT "
+ "Decimal('9', 1, 0) AS d1, "
+ "Decimal('-9', 1, 0) AS d2, "
+ "Decimal('99999999999999999999999999999999999', 35, 0) AS d3, "
+ "Decimal('-99999999999999999999999999999999999', 35, 0) AS d4, "
+ "Decimal('9999999999999999999999999.9999999999', 35, 10) AS d5, "
+ "Decimal('-9999999999999999999999999.9999999999', 35, 10) AS d6, "
+ "Decimal('9.6', 1, 0) AS d7, "
+ "Decimal('-9.6', 1, 0) AS d8, "
+ "Decimal('99999999999999999999999999999999999.6', 35, 0) AS d9, "
+ "Decimal('-99999999999999999999999999999999999.6', 35, 0) AS d10, "
+ "Decimal('9999999999999999999999999.99999999996', 35, 10) AS d11, "
+ "Decimal('-9999999999999999999999999.99999999996', 35, 10) AS d12;",
TxControl.serializableRw()
)
).join().getValue();

Assert.assertEquals(1, result.getResultSetCount());

ResultSetReader rs = result.getResultSet(0);
Assert.assertTrue(rs.next());

DecimalValue d1 = rs.getColumn("d1").getDecimal();
DecimalValue d2 = rs.getColumn("d2").getDecimal();
DecimalValue d3 = rs.getColumn("d3").getDecimal();
DecimalValue d4 = rs.getColumn("d4").getDecimal();
DecimalValue d5 = rs.getColumn("d5").getDecimal();
DecimalValue d6 = rs.getColumn("d6").getDecimal();
DecimalValue d7 = rs.getColumn("d7").getDecimal();
DecimalValue d8 = rs.getColumn("d8").getDecimal();
DecimalValue d9 = rs.getColumn("d9").getDecimal();
DecimalValue d10 = rs.getColumn("d10").getDecimal();
DecimalValue d11 = rs.getColumn("d11").getDecimal();
DecimalValue d12 = rs.getColumn("d12").getDecimal();

Assert.assertEquals(DecimalType.of(1).newValue(9), d1);
Assert.assertEquals(DecimalType.of(1).newValue(-9), d2);
Assert.assertEquals(DecimalType.of(35).newValue("99999999999999999999999999999999999"), d3);
Assert.assertEquals(DecimalType.of(35).newValue("-99999999999999999999999999999999999"), d4);
Assert.assertEquals(DecimalType.of(35, 10).newValue("9999999999999999999999999.9999999999"), d5);
Assert.assertEquals(DecimalType.of(35, 10).newValue("-9999999999999999999999999.9999999999"), d6);

Assert.assertEquals(DecimalType.of(1).getInf(), d7);
Assert.assertEquals(DecimalType.of(1).getNegInf(), d8);
Assert.assertEquals(DecimalType.of(35).getInf(), d9);
Assert.assertEquals(DecimalType.of(35).getNegInf(), d10);
Assert.assertEquals(DecimalType.of(35, 10).getInf(), d11);
Assert.assertEquals(DecimalType.of(35, 10).getNegInf(), d12);

// All infinity values have the same high & low parts
Assert.assertEquals(d7.getHigh(), d9.getHigh());
Assert.assertEquals(d7.getHigh(), d11.getHigh());
Assert.assertEquals(d7.getLow(), d9.getLow());
Assert.assertEquals(d7.getLow(), d11.getLow());

Assert.assertEquals(d8.getHigh(), d10.getHigh());
Assert.assertEquals(d8.getHigh(), d12.getHigh());
Assert.assertEquals(d8.getLow(), d10.getLow());
Assert.assertEquals(d8.getLow(), d12.getLow());
}
}
143 changes: 108 additions & 35 deletions table/src/test/java/tech/ydb/table/values/DecimalValueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,35 @@ public void bigDecimalConv() {

@Test
public void contract() {
DecimalType type = DecimalType.of(13, 2);
DecimalType type = DecimalType.of(20, 2);
DecimalValue value = DecimalValue.fromBits(type, 0x0001, 0x0002);

Assert.assertEquals(DecimalType.of(13, 2), value.getType());
Assert.assertEquals(DecimalType.of(20, 2), value.getType());
Assert.assertEquals(0x0001, value.getHigh());
Assert.assertEquals(0x0002, value.getLow());

// equals
Assert.assertEquals(value, DecimalValue.fromBits(type, 0x0001, 0x0002));
Assert.assertEquals(value, DecimalValue.fromBits(DecimalType.of(13, 2), 0x0001, 0x0002));
Assert.assertEquals(value, DecimalValue.fromBits(DecimalType.of(20, 2), 0x0001, 0x0002));

Assert.assertNotEquals(value, DecimalValue.fromBits(type, 0x0001, 0x0003));
Assert.assertNotEquals(value, DecimalValue.fromBits(type, 0x0002, 0x0002));
Assert.assertNotEquals(value, DecimalValue.fromBits(DecimalType.of(12, 2), 0x0001, 0x0002));
Assert.assertNotEquals(value, DecimalValue.fromBits(DecimalType.of(13, 1), 0x0001, 0x0002));
Assert.assertNotEquals(value, DecimalValue.fromBits(DecimalType.of(21, 2), 0x0001, 0x0002));
Assert.assertNotEquals(value, DecimalValue.fromBits(DecimalType.of(20, 1), 0x0001, 0x0002));

// hashCode
Assert.assertEquals(value.hashCode(), DecimalValue.fromBits(type, 0x0001, 0x0002).hashCode());
Assert.assertEquals(value.hashCode(), DecimalValue.fromBits(DecimalType.of(13, 2), 0x0001, 0x0002).hashCode());
Assert.assertEquals(value.hashCode(), DecimalValue.fromBits(DecimalType.of(20, 2), 0x0001, 0x0002).hashCode());

Assert.assertNotEquals(value.hashCode(), DecimalValue.fromBits(type, 0x0001, 0x0003).hashCode());
Assert.assertNotEquals(value.hashCode(), DecimalValue.fromBits(type, 0x0002, 0x0002).hashCode());
Assert.assertNotEquals(value.hashCode(), DecimalValue.fromBits(DecimalType.of(12, 2), 0x0001, 0x0002).hashCode());
Assert.assertNotEquals(value.hashCode(), DecimalValue.fromBits(DecimalType.of(13, 1), 0x0001, 0x0002).hashCode());
Assert.assertNotEquals(value.hashCode(), DecimalValue.fromBits(DecimalType.of(21, 2), 0x0001, 0x0002).hashCode());
Assert.assertNotEquals(value.hashCode(), DecimalValue.fromBits(DecimalType.of(20, 1), 0x0001, 0x0002).hashCode());
}

@Test
public void protobuf() {
DecimalType type = DecimalType.of(13, 2);
DecimalType type = DecimalType.of(20, 2);
DecimalValue value = DecimalValue.fromBits(type, 0x0001, 0x0002);

ValueProtos.Value valuePb = value.toPb();
Expand Down Expand Up @@ -128,11 +128,83 @@ public void inf() {
DecimalValue value = type.newValue(inf);
Assert.assertTrue(value.isInf());
Assert.assertFalse(value.isNegative());
Assert.assertEquals(DecimalValue.INF, value);
Assert.assertEquals(type.getInf(), value);
inf = inf.add(k);
}
}

private void assertIsValid(DecimalValue v) {
Assert.assertFalse("Non expected Nan for " + v, v.isNan());
Assert.assertFalse("Non expected Inf for " + v, v.isInf());
Assert.assertFalse("Non expected -Inf for " + v, v.isNegativeInf());
}

private void assertIsNan(DecimalValue v) {
Assert.assertTrue("Expected Nan for " + v, v.isNan());
Assert.assertFalse("Non expected Inf for " + v, v.isInf());
Assert.assertFalse("Non expected -Inf for " + v, v.isNegativeInf());

Assert.assertEquals(DecimalValue.NAN_LOW, v.getLow());
Assert.assertEquals(DecimalValue.NAN_HIGH, v.getHigh());
}

private void assertIsInf(DecimalValue v) {
Assert.assertFalse("Non expected Nan for " + v, v.isNan());
Assert.assertTrue("Expected Inf for " + v, v.isInf());
Assert.assertFalse("Non expected -Inf for " + v, v.isNegativeInf());

Assert.assertEquals(DecimalValue.INF_LOW, v.getLow());
Assert.assertEquals(DecimalValue.INF_HIGH, v.getHigh());
}

private void assertIsNegInf(DecimalValue v) {
Assert.assertFalse("Non expected Nan for " + v, v.isNan());
Assert.assertFalse("Non expected Inf for " + v, v.isInf());
Assert.assertTrue("Expected -Inf for " + v, v.isNegativeInf());

Assert.assertEquals(DecimalValue.NEG_INF_LOW, v.getLow());
Assert.assertEquals(DecimalValue.NEG_INF_HIGH, v.getHigh());
}

@Test
public void allTypeInfiniteAndNan() {
BigInteger inf = BigInteger.ONE;
BigInteger nan = new BigInteger("100000000000000000000000000000000001");
int[] scales = new int[] { 1, 9, 35 };
for (int precision = 1; precision <= DecimalType.MAX_PRECISION; precision++) {
inf = inf.multiply(BigInteger.TEN);

DecimalType type = DecimalType.of(precision);

assertIsInf(type.newValue(inf));
assertIsNegInf(type.newValue(inf.negate()));
assertIsNan(type.newValue(nan));

assertIsValid(type.newValue(inf.subtract(BigInteger.ONE)));
assertIsValid(type.newValue(inf.negate().add(BigInteger.ONE)));

for (int scale : scales) {
if (scale > precision) {
continue;
}

DecimalType scaled = DecimalType.of(precision, scale);
BigDecimal scaledInf = new BigDecimal(inf, scale);
BigDecimal scaledNan = new BigDecimal(nan, scale);

System.out.println("Nan for " + scaled + " -> " + scaledNan);

assertIsInf(scaled.newValue(scaledInf));
assertIsNegInf(scaled.newValue(scaledInf.negate()));

assertIsValid(scaled.newValue(scaledInf.subtract(BigDecimal.valueOf(1, scale))));
assertIsValid(scaled.newValue(scaledInf.negate().add(BigDecimal.valueOf(1, scale))));

assertIsNan(scaled.newValue(scaledNan));
}
}
}

@Test
public void infDefaulttype() {
DecimalType type = DecimalType.getDefault();
Expand All @@ -143,7 +215,7 @@ public void infDefaulttype() {
DecimalValue value = type.newValue(inf);
Assert.assertTrue(value.isInf());
Assert.assertFalse(value.isNegative());
Assert.assertNotEquals(DecimalValue.INF, value);
Assert.assertEquals(type.getInf(), value);
inf = inf.add(k);
}
}
Expand All @@ -158,7 +230,7 @@ public void negativeInf() {
DecimalValue value = type.newValue(inf);
Assert.assertTrue(value.isNegativeInf());
Assert.assertTrue(value.isNegative());
Assert.assertEquals(DecimalValue.NEG_INF, value);
Assert.assertEquals(type.getNegInf(), value);
inf = inf.subtract(k);
}
}
Expand All @@ -173,7 +245,7 @@ public void negativeInfDefaultType() {
DecimalValue value = type.newValue(inf);
Assert.assertTrue(value.isNegativeInf());
Assert.assertTrue(value.isNegative());
Assert.assertNotEquals(DecimalValue.NEG_INF, value);
Assert.assertEquals(type.getNegInf(), value);
inf = inf.subtract(k);
}
}
Expand Down Expand Up @@ -258,7 +330,7 @@ public void ofString() {

@Test
public void ofUnsigned() {
DecimalType t = DecimalType.getDefault();
DecimalType t = DecimalType.of(31, 9);
String zeros = "." + String.join("", Collections.nCopies(t.getScale(), "0"));

Assert.assertTrue(t.newValueUnsigned(0).isZero());
Expand All @@ -278,7 +350,7 @@ public void ofUnsigned() {

@Test
public void ofLong() {
DecimalType t = DecimalType.getDefault();
DecimalType t = DecimalType.of(31, 9);
String zeros = "." + String.join("", Collections.nCopies(t.getScale(), "0"));

Assert.assertTrue(t.newValue(0).isZero());
Expand Down Expand Up @@ -575,25 +647,25 @@ public void toUnscaledBigInteger() {

// (2) positive numbers: 1, 12, 123, ...
String s = "";
for (int i = 1; i < DecimalType.MAX_PRECISION; i++) {
for (int i = 1; i < t.getPrecision(); i++) {
s += Integer.toString(i % 10);
BigInteger value = new BigInteger(s);
Assert.assertEquals(value, t.newValueUnscaled(value).toUnscaledBigInteger());
}

// (3) negative numbers: -1, -12, -123, ...
s = "-";
for (int i = 1; i < DecimalType.MAX_PRECISION; i++) {
for (int i = 1; i < t.getPrecision(); i++) {
s += Integer.toString(i % 10);
BigInteger value = new BigInteger(s);
Assert.assertEquals(value, t.newValueUnscaled(value).toUnscaledBigInteger());
}

// (4) -inf, +inf, nan
BigInteger inf = BigInteger.TEN.pow(DecimalType.MAX_PRECISION);
Assert.assertEquals(DecimalValue.INF.toUnscaledBigInteger(), inf);
Assert.assertEquals(DecimalValue.NEG_INF.toUnscaledBigInteger(), inf.negate());
Assert.assertEquals(DecimalValue.NAN.toUnscaledBigInteger(), inf.add(BigInteger.ONE));
Assert.assertEquals(t.getInf().toUnscaledBigInteger(), inf);
Assert.assertEquals(t.getNegInf().toUnscaledBigInteger(), inf.negate());
Assert.assertEquals(t.getNaN().toUnscaledBigInteger(), inf.add(BigInteger.ONE));
}

@Test
Expand Down Expand Up @@ -627,18 +699,19 @@ public void toBigInteger() {

// (4) -inf, +inf, nan
BigInteger inf = BigInteger.TEN.pow(DecimalType.MAX_PRECISION);
Assert.assertEquals(DecimalValue.INF.toBigInteger(), inf);
Assert.assertEquals(DecimalValue.NEG_INF.toBigInteger(), inf.negate());
Assert.assertEquals(DecimalValue.NAN.toBigInteger(), inf.add(BigInteger.ONE));
Assert.assertEquals(t.getInf().toBigInteger(), inf);
Assert.assertEquals(t.getNegInf().toBigInteger(), inf.negate());
Assert.assertEquals(t.getNaN().toBigInteger(), inf.add(BigInteger.ONE));
}

@Test
public void toBigDecimal() {
// (1) special values
BigDecimal inf = BigDecimal.TEN.pow(DecimalType.MAX_PRECISION);
Assert.assertEquals(DecimalValue.INF.toBigDecimal(), inf);
Assert.assertEquals(DecimalValue.NEG_INF.toBigDecimal(), inf.negate());
Assert.assertEquals(DecimalValue.NAN.toBigDecimal(), inf.add(BigDecimal.ONE));
BigDecimal inf = BigDecimal.ONE.scaleByPowerOfTen(DecimalType.MAX_PRECISION);
DecimalType type = DecimalType.getDefault();
Assert.assertEquals(type.getInf().toBigDecimal(), inf.setScale(type.getScale()));
Assert.assertEquals(type.getNegInf().toBigDecimal(), inf.negate().setScale(type.getScale()));
Assert.assertEquals(type.getNaN().toBigDecimal(), inf.add(BigDecimal.ONE).setScale(type.getScale()));

// (2) positive numbers
Assert.assertEquals(newDecimal(1234567890L, 0).toBigDecimal(), BigDecimal.valueOf(1234567890L, 0));
Expand Down Expand Up @@ -682,30 +755,30 @@ public void toUnscaledString() {

// (2) positive numbers: 1, 12, 123, ...
String s = "";
for (int i = 1; i < DecimalType.MAX_PRECISION; i++) {
for (int i = 1; i < t.getPrecision(); i++) {
s += Integer.toString(i % 10);
Assert.assertEquals(s, t.newValueUnscaled(new BigInteger(s)).toUnscaledString());
}

// (3) negative numbers: -1, -12, -123, ...
s = "-";
for (int i = 1; i < DecimalType.MAX_PRECISION; i++) {
for (int i = 1; i < t.getPrecision(); i++) {
s += Integer.toString(i % 10);
Assert.assertEquals(s, t.newValueUnscaled(new BigInteger(s)).toUnscaledString());
}

// (4) -inf, +inf, nan
Assert.assertEquals("100000000000000000000000000000000000", DecimalValue.INF.toUnscaledString()); // 10^35
Assert.assertEquals("-100000000000000000000000000000000000", DecimalValue.NEG_INF.toUnscaledString()); // -10^35
Assert.assertEquals("100000000000000000000000000000000001", DecimalValue.NAN.toUnscaledString()); // 10^35 + 1
Assert.assertEquals("100000000000000000000000000000000000", t.getInf().toUnscaledString()); // 10^35
Assert.assertEquals("-100000000000000000000000000000000000", t.getNegInf().toUnscaledString()); // -10^35
Assert.assertEquals("100000000000000000000000000000000001", t.getNaN().toUnscaledString()); // 10^35 + 1
}

@Test
public void toStringTest() {
// (1) special values
Assert.assertEquals("inf", DecimalValue.INF.toString());
Assert.assertEquals("-inf", DecimalValue.NEG_INF.toString());
Assert.assertEquals("nan", DecimalValue.NAN.toString());
Assert.assertEquals("inf", DecimalType.getDefault().getInf().toString());
Assert.assertEquals("-inf", DecimalType.getDefault().getNegInf().toString());
Assert.assertEquals("nan", DecimalType.getDefault().getNaN().toString());

// (2) positive numbers
Assert.assertEquals("1234567890", newDecimal(1234567890L, 0).toString());
Expand Down

0 comments on commit 2e52743

Please sign in to comment.