You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by ja...@apache.org on 2020/05/20 14:24:07 UTC

[flink] branch release-1.11 updated: [FLINK-16922][table-common] Fix DecimalData.toUnscaledBytes() should be consistent with BigDecimla.unscaledValue.toByteArray()

This is an automated email from the ASF dual-hosted git repository.

jark pushed a commit to branch release-1.11
in repository https://gitbox.apache.org/repos/asf/flink.git


The following commit(s) were added to refs/heads/release-1.11 by this push:
     new f735656  [FLINK-16922][table-common] Fix DecimalData.toUnscaledBytes() should be consistent with BigDecimla.unscaledValue.toByteArray()
f735656 is described below

commit f7356560145f2bb862d1608264de3cf476f4abba
Author: Jark Wu <ja...@apache.org>
AuthorDate: Wed May 20 22:22:46 2020 +0800

    [FLINK-16922][table-common] Fix DecimalData.toUnscaledBytes() should be consistent with BigDecimla.unscaledValue.toByteArray()
    
    This closes #12265
---
 .../org/apache/flink/table/data/DecimalData.java   |  26 +---
 .../apache/flink/table/data/DecimalDataTest.java   | 154 ++++++++++++---------
 2 files changed, 90 insertions(+), 90 deletions(-)

diff --git a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/DecimalData.java b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/DecimalData.java
index 38bba78..5f513bf 100644
--- a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/DecimalData.java
+++ b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/DecimalData.java
@@ -138,18 +138,7 @@ public final class DecimalData implements Comparable<DecimalData> {
 	 * @return the unscaled byte array of this {@link DecimalData}.
 	 */
 	public byte[] toUnscaledBytes() {
-		if (!isCompact()) {
-			return toBigDecimal().unscaledValue().toByteArray();
-		}
-
-		// big endian; consistent with BigInteger.toByteArray()
-		byte[] bytes = new byte[8];
-		long l = longVal;
-		for (int i = 0; i < 8; i++) {
-			bytes[7 - i] = (byte) l;
-			l >>>= 8;
-		}
-		return bytes;
+		return toBigDecimal().unscaledValue().toByteArray();
 	}
 
 	/**
@@ -231,17 +220,8 @@ public final class DecimalData implements Comparable<DecimalData> {
 	 * and scale.
 	 */
 	public static DecimalData fromUnscaledBytes(byte[] unscaledBytes, int precision, int scale) {
-		if (precision > MAX_COMPACT_PRECISION) {
-			BigDecimal bd = new BigDecimal(new BigInteger(unscaledBytes), scale);
-			return new DecimalData(precision, scale, -1, bd);
-		}
-		assert unscaledBytes.length == 8;
-		long l = 0;
-		for (int i = 0; i < 8; i++) {
-			l <<= 8;
-			l |= (unscaledBytes[i] & (0xff));
-		}
-		return new DecimalData(precision, scale, l, null);
+		BigDecimal bd = new BigDecimal(new BigInteger(unscaledBytes), scale);
+		return fromBigDecimal(bd, precision, scale);
 	}
 
 	/**
diff --git a/flink-table/flink-table-runtime-blink/src/test/java/org/apache/flink/table/data/DecimalDataTest.java b/flink-table/flink-table-runtime-blink/src/test/java/org/apache/flink/table/data/DecimalDataTest.java
index bfa51ca..e054104 100644
--- a/flink-table/flink-table-runtime-blink/src/test/java/org/apache/flink/table/data/DecimalDataTest.java
+++ b/flink-table/flink-table-runtime-blink/src/test/java/org/apache/flink/table/data/DecimalDataTest.java
@@ -18,7 +18,6 @@
 
 package org.apache.flink.table.data;
 
-import org.junit.Assert;
 import org.junit.Test;
 
 import java.math.BigDecimal;
@@ -46,6 +45,10 @@ import static org.apache.flink.table.data.DecimalDataUtils.sign;
 import static org.apache.flink.table.data.DecimalDataUtils.signum;
 import static org.apache.flink.table.data.DecimalDataUtils.sround;
 import static org.apache.flink.table.data.DecimalDataUtils.subtract;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test for {@link DecimalData}.
@@ -55,55 +58,72 @@ public class DecimalDataTest {
 	@SuppressWarnings("ConstantConditions")
 	@Test
 	public void testNormal() {
+		BigDecimal bigDecimal1 = new BigDecimal("13145678.90123");
+		BigDecimal bigDecimal2 = new BigDecimal("1234567890.0987654321");
+		// fromUnscaledBytes
+		assertEquals(
+			DecimalData.fromBigDecimal(bigDecimal1, 15, 5),
+			DecimalData.fromUnscaledBytes(bigDecimal1.unscaledValue().toByteArray(), 15, 5));
+		assertEquals(
+			DecimalData.fromBigDecimal(bigDecimal2, 23, 10),
+			DecimalData.fromUnscaledBytes(bigDecimal2.unscaledValue().toByteArray(), 23, 10));
+		// toUnscaledBytes
+		assertArrayEquals(
+			bigDecimal1.unscaledValue().toByteArray(),
+			DecimalData.fromUnscaledBytes(bigDecimal1.unscaledValue().toByteArray(), 15, 5).toUnscaledBytes());
+		assertArrayEquals(
+			bigDecimal2.unscaledValue().toByteArray(),
+			DecimalData.fromUnscaledBytes(bigDecimal2.unscaledValue().toByteArray(), 23, 10).toUnscaledBytes());
+
 		DecimalData decimal1 = DecimalData.fromUnscaledLong(10, 5, 0);
 		DecimalData decimal2 = DecimalData.fromUnscaledLong(15, 5, 0);
-		Assert.assertEquals(decimal1.hashCode(),
+		assertEquals(decimal1.hashCode(),
 				DecimalData.fromBigDecimal(new BigDecimal(10), 5, 0).hashCode());
-		Assert.assertEquals(decimal1, decimal1.copy());
-		Assert.assertEquals(decimal1, DecimalData.fromUnscaledLong(decimal1.toUnscaledLong(), 5, 0));
-		Assert.assertEquals(decimal1, DecimalData.fromUnscaledBytes(decimal1.toUnscaledBytes(), 5, 0));
-		Assert.assertTrue(decimal1.compareTo(decimal2) < 0);
-		Assert.assertEquals(1, signum(decimal1));
-		Assert.assertEquals(10.5, doubleValue(castFrom(10.5, 5, 1)), 0.0);
-		Assert.assertEquals(DecimalData.fromUnscaledLong(-10, 5, 0), negate(decimal1));
-		Assert.assertEquals(decimal1, abs(decimal1));
-		Assert.assertEquals(decimal1, abs(negate(decimal1)));
-		Assert.assertEquals(25, add(decimal1, decimal2, 5, 0).toUnscaledLong());
-		Assert.assertEquals(-5, subtract(decimal1, decimal2, 5, 0).toUnscaledLong());
-		Assert.assertEquals(150, multiply(decimal1, decimal2, 5, 0).toUnscaledLong());
-		Assert.assertEquals(0.67, doubleValue(divide(decimal1, decimal2, 5, 2)), 0.0);
-		Assert.assertEquals(decimal1, mod(decimal1, decimal2, 5, 0));
-		Assert.assertEquals(5, divideToIntegralValue(
+		assertEquals(decimal1, decimal1.copy());
+		assertEquals(decimal1, DecimalData.fromUnscaledLong(decimal1.toUnscaledLong(), 5, 0));
+		assertEquals(decimal1, DecimalData.fromUnscaledBytes(decimal1.toUnscaledBytes(), 5, 0));
+		assertTrue(decimal1.compareTo(decimal2) < 0);
+		assertEquals(1, signum(decimal1));
+		assertEquals(10.5, doubleValue(castFrom(10.5, 5, 1)), 0.0);
+		assertEquals(DecimalData.fromUnscaledLong(-10, 5, 0), negate(decimal1));
+		assertEquals(decimal1, abs(decimal1));
+		assertEquals(decimal1, abs(negate(decimal1)));
+		assertEquals(25, add(decimal1, decimal2, 5, 0).toUnscaledLong());
+		assertEquals(-5, subtract(decimal1, decimal2, 5, 0).toUnscaledLong());
+		assertEquals(150, multiply(decimal1, decimal2, 5, 0).toUnscaledLong());
+		assertEquals(0.67, doubleValue(divide(decimal1, decimal2, 5, 2)), 0.0);
+		assertEquals(decimal1, mod(decimal1, decimal2, 5, 0));
+		assertEquals(5, divideToIntegralValue(
 				decimal1, DecimalData.fromUnscaledLong(2, 5, 0), 5, 0).toUnscaledLong());
-		Assert.assertEquals(10, castToIntegral(decimal1));
-		Assert.assertTrue(castToBoolean(decimal1));
-		Assert.assertEquals(0, compare(decimal1, 10));
-		Assert.assertTrue(compare(decimal1, 5) > 0);
-		Assert.assertEquals(castFrom(1.0, 10, 5), sign(castFrom(5.556, 10, 5)));
+		assertEquals(10, castToIntegral(decimal1));
+		assertTrue(castToBoolean(decimal1));
+		assertEquals(0, compare(decimal1, 10));
+		assertTrue(compare(decimal1, 5) > 0);
+		assertEquals(castFrom(1.0, 10, 5), sign(castFrom(5.556, 10, 5)));
 
-		Assert.assertNull(DecimalData.fromBigDecimal(new BigDecimal(Long.MAX_VALUE), 5, 0));
-		Assert.assertEquals(0, DecimalData.zero(5, 2).toBigDecimal().intValue());
-		Assert.assertEquals(0, DecimalData.zero(20, 2).toBigDecimal().intValue());
+		assertNull(DecimalData.fromBigDecimal(new BigDecimal(Long.MAX_VALUE), 5, 0));
+		assertEquals(0, DecimalData.zero(5, 2).toBigDecimal().intValue());
+		assertEquals(0, DecimalData.zero(20, 2).toBigDecimal().intValue());
 
-		Assert.assertEquals(DecimalData.fromUnscaledLong(10, 5, 0), floor(castFrom(10.5, 5, 1)));
-		Assert.assertEquals(DecimalData.fromUnscaledLong(11, 5, 0), ceil(castFrom(10.5, 5, 1)));
-		Assert.assertEquals("5.00", castToDecimal(castFrom(5.0, 10, 1), 10, 2).toString());
+		assertEquals(DecimalData.fromUnscaledLong(10, 5, 0), floor(castFrom(10.5, 5, 1)));
+		assertEquals(DecimalData.fromUnscaledLong(11, 5, 0), ceil(castFrom(10.5, 5, 1)));
+		assertEquals("5.00", castToDecimal(castFrom(5.0, 10, 1), 10, 2).toString());
 
-		Assert.assertTrue(castToBoolean(castFrom(true, 5, 0)));
-		Assert.assertEquals(5, castToIntegral(castFrom(5, 5, 0)));
-		Assert.assertEquals(5, castToIntegral(castFrom("5", 5, 0)));
-		Assert.assertEquals(5000, castToTimestamp(castFrom("5", 5, 0)));
+		assertTrue(castToBoolean(castFrom(true, 5, 0)));
+		assertEquals(5, castToIntegral(castFrom(5, 5, 0)));
+		assertEquals(5, castToIntegral(castFrom("5", 5, 0)));
+		assertEquals(5000, castToTimestamp(castFrom("5", 5, 0)));
 
 		DecimalData newDecimal = castFrom(castFrom(10, 5, 2), 10, 4);
-		Assert.assertEquals(10, newDecimal.precision());
-		Assert.assertEquals(4, newDecimal.scale());
+		assertEquals(10, newDecimal.precision());
+		assertEquals(4, newDecimal.scale());
 
-		Assert.assertTrue(is32BitDecimal(6));
-		Assert.assertTrue(is64BitDecimal(11));
-		Assert.assertTrue(isByteArrayDecimal(20));
+		assertTrue(is32BitDecimal(6));
+		assertTrue(is64BitDecimal(11));
+		assertTrue(isByteArrayDecimal(20));
 
-		Assert.assertEquals(6, sround(castFrom(5.555, 5, 0), 1).toUnscaledLong());
-		Assert.assertEquals(56, sround(castFrom(5.555, 5, 3), 1).toUnscaledLong());
+		assertEquals(6, sround(castFrom(5.555, 5, 0), 1).toUnscaledLong());
+		assertEquals(56, sround(castFrom(5.555, 5, 3), 1).toUnscaledLong());
 	}
 
 	@SuppressWarnings("ConstantConditions")
@@ -111,41 +131,41 @@ public class DecimalDataTest {
 	public void testNotCompact() {
 		DecimalData decimal1 = DecimalData.fromBigDecimal(new BigDecimal(10), 20, 0);
 		DecimalData decimal2 = DecimalData.fromBigDecimal(new BigDecimal(15), 20, 0);
-		Assert.assertEquals(decimal1.hashCode(),
+		assertEquals(decimal1.hashCode(),
 				DecimalData.fromBigDecimal(new BigDecimal(10), 20, 0).hashCode());
-		Assert.assertEquals(decimal1, decimal1.copy());
-		Assert.assertEquals(decimal1, DecimalData.fromBigDecimal(decimal1.toBigDecimal(), 20, 0));
-		Assert.assertEquals(decimal1, DecimalData.fromUnscaledBytes(decimal1.toUnscaledBytes(), 20, 0));
-		Assert.assertTrue(decimal1.compareTo(decimal2) < 0);
-		Assert.assertEquals(1, signum(decimal1));
-		Assert.assertEquals(10.5, doubleValue(castFrom(10.5, 20, 1)), 0.0);
-		Assert.assertEquals(DecimalData.fromBigDecimal(new BigDecimal(-10), 20, 0), negate(decimal1));
-		Assert.assertEquals(decimal1, abs(decimal1));
-		Assert.assertEquals(decimal1, abs(negate(decimal1)));
-		Assert.assertEquals(25, add(decimal1, decimal2, 20, 0).toBigDecimal().longValue());
-		Assert.assertEquals(-5, subtract(decimal1, decimal2, 20, 0).toBigDecimal().longValue());
-		Assert.assertEquals(150, multiply(decimal1, decimal2, 20, 0).toBigDecimal().longValue());
-		Assert.assertEquals(0.67, doubleValue(divide(decimal1, decimal2, 20, 2)), 0.0);
-		Assert.assertEquals(decimal1, mod(decimal1, decimal2, 20, 0));
-		Assert.assertEquals(5, divideToIntegralValue(
+		assertEquals(decimal1, decimal1.copy());
+		assertEquals(decimal1, DecimalData.fromBigDecimal(decimal1.toBigDecimal(), 20, 0));
+		assertEquals(decimal1, DecimalData.fromUnscaledBytes(decimal1.toUnscaledBytes(), 20, 0));
+		assertTrue(decimal1.compareTo(decimal2) < 0);
+		assertEquals(1, signum(decimal1));
+		assertEquals(10.5, doubleValue(castFrom(10.5, 20, 1)), 0.0);
+		assertEquals(DecimalData.fromBigDecimal(new BigDecimal(-10), 20, 0), negate(decimal1));
+		assertEquals(decimal1, abs(decimal1));
+		assertEquals(decimal1, abs(negate(decimal1)));
+		assertEquals(25, add(decimal1, decimal2, 20, 0).toBigDecimal().longValue());
+		assertEquals(-5, subtract(decimal1, decimal2, 20, 0).toBigDecimal().longValue());
+		assertEquals(150, multiply(decimal1, decimal2, 20, 0).toBigDecimal().longValue());
+		assertEquals(0.67, doubleValue(divide(decimal1, decimal2, 20, 2)), 0.0);
+		assertEquals(decimal1, mod(decimal1, decimal2, 20, 0));
+		assertEquals(5, divideToIntegralValue(
 				decimal1, DecimalData.fromBigDecimal(new BigDecimal(2), 20, 0), 20, 0).toBigDecimal().longValue());
-		Assert.assertEquals(10, castToIntegral(decimal1));
-		Assert.assertTrue(castToBoolean(decimal1));
-		Assert.assertEquals(0, compare(decimal1, 10));
-		Assert.assertTrue(compare(decimal1, 5) > 0);
-		Assert.assertTrue(compare(DecimalData.fromBigDecimal(new BigDecimal("10.5"), 20, 2), 10) > 0);
-		Assert.assertEquals(castFrom(1.0, 20, 5), sign(castFrom(5.556, 20, 5)));
-
-		Assert.assertNull(DecimalData.fromBigDecimal(new BigDecimal(Long.MAX_VALUE), 5, 0));
-		Assert.assertEquals(0, DecimalData.zero(20, 2).toBigDecimal().intValue());
-		Assert.assertEquals(0, DecimalData.zero(20, 2).toBigDecimal().intValue());
+		assertEquals(10, castToIntegral(decimal1));
+		assertTrue(castToBoolean(decimal1));
+		assertEquals(0, compare(decimal1, 10));
+		assertTrue(compare(decimal1, 5) > 0);
+		assertTrue(compare(DecimalData.fromBigDecimal(new BigDecimal("10.5"), 20, 2), 10) > 0);
+		assertEquals(castFrom(1.0, 20, 5), sign(castFrom(5.556, 20, 5)));
+
+		assertNull(DecimalData.fromBigDecimal(new BigDecimal(Long.MAX_VALUE), 5, 0));
+		assertEquals(0, DecimalData.zero(20, 2).toBigDecimal().intValue());
+		assertEquals(0, DecimalData.zero(20, 2).toBigDecimal().intValue());
 	}
 
 	@Test
 	public void testToString() {
 		String val = "0.0000000000000000001";
-		Assert.assertEquals(val, castFrom(val, 39, val.length() - 2).toString());
+		assertEquals(val, castFrom(val, 39, val.length() - 2).toString());
 		val = "123456789012345678901234567890123456789";
-		Assert.assertEquals(val, castFrom(val, 39, 0).toString());
+		assertEquals(val, castFrom(val, 39, 0).toString());
 	}
 }