http://git-wip-us.apache.org/repos/asf/kudu/blob/4f34b69d/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java ---------------------------------------------------------------------- diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java index 1081cc6..f655222 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java @@ -31,6 +31,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.Closeable; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -47,9 +48,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.kudu.ColumnSchema; +import org.apache.kudu.ColumnTypeAttributes.ColumnTypeAttributesBuilder; import org.apache.kudu.Schema; import org.apache.kudu.Type; import org.apache.kudu.util.CapturingLogAppender; +import org.apache.kudu.util.DecimalUtil; public class TestKuduClient extends BaseKuduTest { private static final Logger LOG = LoggerFactory.getLogger(TestKuduClient.class); @@ -86,6 +89,21 @@ public class TestKuduClient extends BaseKuduTest { return new Schema(columns); } + private Schema createSchemaWithDecimalColumns() { + ArrayList<ColumnSchema> columns = new ArrayList<ColumnSchema>(); + columns.add(new ColumnSchema.ColumnSchemaBuilder("key", Type.DECIMAL).key(true) + .typeAttributes( + new ColumnTypeAttributesBuilder() + .precision(org.apache.kudu.util.DecimalUtil.MAX_DECIMAL64_PRECISION).build() + ).build()); + columns.add(new ColumnSchema.ColumnSchemaBuilder("c1", Type.DECIMAL).nullable(true) + .typeAttributes( + new ColumnTypeAttributesBuilder() + .precision(org.apache.kudu.util.DecimalUtil.MAX_DECIMAL128_PRECISION).build() + ).build()); + return new Schema(columns); + } + private static CreateTableOptions createTableOptions() { return new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("key")); } @@ -426,6 +444,48 @@ public class TestKuduClient extends BaseKuduTest { } /** + * Test inserting and retrieving decimal columns. + */ + @Test(timeout = 100000) + public void testDecimalColumns() throws Exception { + Schema schema = createSchemaWithDecimalColumns(); + syncClient.createTable(tableName, schema, createTableOptions()); + + List<Long> timestamps = new ArrayList<>(); + + KuduSession session = syncClient.newSession(); + KuduTable table = syncClient.openTable(tableName); + + // Verify ColumnTypeAttributes + assertEquals(DecimalUtil.MAX_DECIMAL128_PRECISION, + table.getSchema().getColumn("c1").getTypeAttributes().getPrecision()); + + for (int i = 0; i < 9; i++) { + Insert insert = table.newInsert(); + PartialRow row = insert.getRow(); + row.addDecimal("key", BigDecimal.valueOf(i)); + if (i % 2 == 1) { + row.addDecimal("c1", BigDecimal.valueOf(i)); + } + session.apply(insert); + } + session.flush(); + + List<String> rowStrings = scanTableToStrings(table); + assertEquals(9, rowStrings.size()); + for (int i = 0; i < rowStrings.size(); i++) { + StringBuilder expectedRow = new StringBuilder(); + expectedRow.append(String.format("DECIMAL key(18, 0)=%s, DECIMAL c1(38, 0)=", String.valueOf(i))); + if (i % 2 == 1) { + expectedRow.append(String.valueOf(i)); + } else { + expectedRow.append("NULL"); + } + assertEquals(expectedRow.toString(), rowStrings.get(i)); + } + } + + /** * Test scanning with predicates. */ @Test
http://git-wip-us.apache.org/repos/asf/kudu/blob/4f34b69d/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPredicate.java ---------------------------------------------------------------------- diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPredicate.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPredicate.java index d192be8..e7c40c0 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPredicate.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPredicate.java @@ -24,6 +24,7 @@ import static org.apache.kudu.client.KuduPredicate.ComparisonOp.LESS; import static org.apache.kudu.client.KuduPredicate.ComparisonOp.LESS_EQUAL; import static org.apache.kudu.client.KuduPredicate.PredicateType.RANGE; +import java.math.BigDecimal; import java.util.Arrays; import com.google.common.base.Preconditions; @@ -33,6 +34,7 @@ import org.junit.Test; import org.apache.kudu.ColumnSchema; import org.apache.kudu.Type; +import org.apache.kudu.util.DecimalUtil; public class TestKuduPredicate { @@ -63,6 +65,21 @@ public class TestKuduPredicate { private static final ColumnSchema binaryCol = new ColumnSchema.ColumnSchemaBuilder("binary", Type.BINARY).build(); + private static final ColumnSchema decimal32Col = + new ColumnSchema.ColumnSchemaBuilder("decimal32", Type.DECIMAL) + .typeAttributes(DecimalUtil.typeAttributes(DecimalUtil.MAX_DECIMAL32_PRECISION, 2)) + .build(); + + private static final ColumnSchema decimal64Col = + new ColumnSchema.ColumnSchemaBuilder("decimal64", Type.DECIMAL) + .typeAttributes(DecimalUtil.typeAttributes(DecimalUtil.MAX_DECIMAL64_PRECISION, 2)) + .build(); + + private static final ColumnSchema decimal128Col = + new ColumnSchema.ColumnSchemaBuilder("decimal128", Type.DECIMAL) + .typeAttributes(DecimalUtil.typeAttributes(DecimalUtil.MAX_DECIMAL128_PRECISION, 2)) + .build(); + private static KuduPredicate intRange(int lower, int upper) { Preconditions.checkArgument(lower < upper); return new KuduPredicate(RANGE, intCol, Bytes.fromInt(lower), Bytes.fromInt(upper)); @@ -844,6 +861,66 @@ public class TestKuduPredicate { KuduPredicate.newInListPredicate(doubleCol, ImmutableList.of(14d, 18d, 20d)), KuduPredicate.newInListPredicate(doubleCol, ImmutableList.of(14d, 18d))); + testMerge(KuduPredicate.newComparisonPredicate(decimal32Col, GREATER_EQUAL, + BigDecimal.valueOf(12345, 2)), + KuduPredicate.newComparisonPredicate(decimal32Col, LESS, + BigDecimal.valueOf(67890,2)), + new KuduPredicate(RANGE, + decimal32Col, + Bytes.fromBigDecimal(BigDecimal.valueOf(12345, 2), + DecimalUtil.MAX_DECIMAL32_PRECISION), + Bytes.fromBigDecimal(BigDecimal.valueOf(67890, 2), + DecimalUtil.MAX_DECIMAL32_PRECISION))); + + testMerge(KuduPredicate.newInListPredicate(decimal32Col, ImmutableList.of( + BigDecimal.valueOf(12345, 2), + BigDecimal.valueOf(45678, 2))), + KuduPredicate.newInListPredicate(decimal32Col, ImmutableList.of( + BigDecimal.valueOf(45678, 2), + BigDecimal.valueOf(98765, 2))), + KuduPredicate.newInListPredicate(decimal32Col, ImmutableList.of( + BigDecimal.valueOf(45678, 2)))); + + testMerge(KuduPredicate.newInListPredicate(decimal64Col, ImmutableList.of( + BigDecimal.valueOf(12345678910L, 2), + BigDecimal.valueOf(34567891011L, 2))), + KuduPredicate.newInListPredicate(decimal64Col, ImmutableList.of( + BigDecimal.valueOf(34567891011L, 2), + BigDecimal.valueOf(98765432111L, 2))), + KuduPredicate.newInListPredicate(decimal64Col, ImmutableList.of( + BigDecimal.valueOf(34567891011L, 2)))); + + testMerge(KuduPredicate.newComparisonPredicate(decimal64Col, GREATER_EQUAL, + BigDecimal.valueOf(12345678910L, 2)), + KuduPredicate.newComparisonPredicate(decimal64Col, LESS, + BigDecimal.valueOf(67890101112L,2)), + new KuduPredicate(RANGE, + decimal64Col, + Bytes.fromBigDecimal(BigDecimal.valueOf(12345678910L, 2), + DecimalUtil.MAX_DECIMAL64_PRECISION), + Bytes.fromBigDecimal(BigDecimal.valueOf(67890101112L, 2), + DecimalUtil.MAX_DECIMAL64_PRECISION))); + + testMerge(KuduPredicate.newInListPredicate(decimal128Col, ImmutableList.of( + new BigDecimal("1234567891011121314.15"), + new BigDecimal("3456789101112131415.16"))), + KuduPredicate.newInListPredicate(decimal128Col, ImmutableList.of( + new BigDecimal("3456789101112131415.16"), + new BigDecimal("9876543212345678910.11"))), + KuduPredicate.newInListPredicate(decimal128Col, ImmutableList.of( + new BigDecimal("3456789101112131415.16")))); + + testMerge(KuduPredicate.newComparisonPredicate(decimal128Col, GREATER_EQUAL, + new BigDecimal("1234567891011121314.15")), + KuduPredicate.newComparisonPredicate(decimal128Col, LESS, + new BigDecimal("67891011121314151617.18")), + new KuduPredicate(RANGE, + decimal128Col, + Bytes.fromBigDecimal(new BigDecimal("1234567891011121314.15"), + DecimalUtil.MAX_DECIMAL128_PRECISION), + Bytes.fromBigDecimal(new BigDecimal("67891011121314151617.18"), + DecimalUtil.MAX_DECIMAL128_PRECISION))); + testMerge(KuduPredicate.newComparisonPredicate(binaryCol, GREATER_EQUAL, new byte[] { 0, 1, 2, 3, 4, 5, 6 }), KuduPredicate.newComparisonPredicate(binaryCol, LESS, new byte[] { 10 }), @@ -871,11 +948,13 @@ public class TestKuduPredicate { KuduPredicate.newComparisonPredicate(floatCol, LESS, Math.nextAfter(12.345f, Float.POSITIVE_INFINITY))); Assert.assertEquals(KuduPredicate.newComparisonPredicate(doubleCol, LESS_EQUAL, 12.345), KuduPredicate.newComparisonPredicate(doubleCol, LESS, Math.nextAfter(12.345, Float.POSITIVE_INFINITY))); + Assert.assertEquals( + KuduPredicate.newComparisonPredicate(decimal32Col, LESS_EQUAL, BigDecimal.valueOf(12345,2)), + KuduPredicate.newComparisonPredicate(decimal32Col, LESS, BigDecimal.valueOf(12346,2))); Assert.assertEquals(KuduPredicate.newComparisonPredicate(stringCol, LESS_EQUAL, "a"), KuduPredicate.newComparisonPredicate(stringCol, LESS, "a\0")); Assert.assertEquals(KuduPredicate.newComparisonPredicate(binaryCol, LESS_EQUAL, new byte[] { (byte) 10 }), KuduPredicate.newComparisonPredicate(binaryCol, LESS, new byte[] { (byte) 10, (byte) 0 })); - Assert.assertEquals(KuduPredicate.newComparisonPredicate(byteCol, LESS_EQUAL, Byte.MAX_VALUE), KuduPredicate.newIsNotNullPredicate(byteCol)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(shortCol, LESS_EQUAL, Short.MAX_VALUE), @@ -908,6 +987,9 @@ public class TestKuduPredicate { KuduPredicate.newComparisonPredicate(floatCol, GREATER, 12.345f)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(doubleCol, GREATER_EQUAL, Math.nextAfter(12.345, Float.MAX_VALUE)), KuduPredicate.newComparisonPredicate(doubleCol, GREATER, 12.345)); + Assert.assertEquals( + KuduPredicate.newComparisonPredicate(decimal32Col, GREATER_EQUAL, BigDecimal.valueOf(12346, 2)), + KuduPredicate.newComparisonPredicate(decimal32Col, GREATER, BigDecimal.valueOf(12345, 2))); Assert.assertEquals(KuduPredicate.newComparisonPredicate(stringCol, GREATER_EQUAL, "a\0"), KuduPredicate.newComparisonPredicate(stringCol, GREATER, "a")); Assert.assertEquals(KuduPredicate.newComparisonPredicate(binaryCol, GREATER_EQUAL, new byte[] { (byte) 10, (byte) 0 }), @@ -945,6 +1027,15 @@ public class TestKuduPredicate { KuduPredicate.none(floatCol)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(doubleCol, LESS, Double.NEGATIVE_INFINITY), KuduPredicate.none(doubleCol)); + Assert.assertEquals(KuduPredicate.newComparisonPredicate(decimal32Col, LESS, + DecimalUtil.minValue(DecimalUtil.MAX_DECIMAL32_PRECISION, 2)), + KuduPredicate.none(decimal32Col)); + Assert.assertEquals(KuduPredicate.newComparisonPredicate(decimal64Col, LESS, + DecimalUtil.minValue(DecimalUtil.MAX_DECIMAL64_PRECISION, 2)), + KuduPredicate.none(decimal64Col)); + Assert.assertEquals(KuduPredicate.newComparisonPredicate(decimal128Col, LESS, + DecimalUtil.minValue(DecimalUtil.MAX_DECIMAL128_PRECISION, 2)), + KuduPredicate.none(decimal128Col)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(stringCol, LESS, ""), KuduPredicate.none(stringCol)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(binaryCol, LESS, new byte[] {}), @@ -965,6 +1056,15 @@ public class TestKuduPredicate { KuduPredicate.newIsNotNullPredicate(floatCol)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(doubleCol, GREATER_EQUAL, Double.NEGATIVE_INFINITY), KuduPredicate.newIsNotNullPredicate(doubleCol)); + Assert.assertEquals(KuduPredicate.newComparisonPredicate(decimal32Col, GREATER_EQUAL, + DecimalUtil.minValue(DecimalUtil.MAX_DECIMAL32_PRECISION, 2)), + KuduPredicate.newIsNotNullPredicate(decimal32Col)); + Assert.assertEquals(KuduPredicate.newComparisonPredicate(decimal64Col, GREATER_EQUAL, + DecimalUtil.minValue(DecimalUtil.MAX_DECIMAL64_PRECISION, 2)), + KuduPredicate.newIsNotNullPredicate(decimal64Col)); + Assert.assertEquals(KuduPredicate.newComparisonPredicate(decimal128Col, GREATER_EQUAL, + DecimalUtil.minValue(DecimalUtil.MAX_DECIMAL128_PRECISION, 2)), + KuduPredicate.newIsNotNullPredicate(decimal128Col)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(stringCol, GREATER_EQUAL, ""), KuduPredicate.newIsNotNullPredicate(stringCol)); Assert.assertEquals(KuduPredicate.newComparisonPredicate(binaryCol, GREATER_EQUAL, new byte[] {}), @@ -1000,6 +1100,15 @@ public class TestKuduPredicate { KuduPredicate.newComparisonPredicate(floatCol, EQUAL, 123.456f).toString()); Assert.assertEquals("`double` = 123.456", KuduPredicate.newComparisonPredicate(doubleCol, EQUAL, 123.456).toString()); + Assert.assertEquals("`decimal32` = 123.45", + KuduPredicate.newComparisonPredicate(decimal32Col, EQUAL, + BigDecimal.valueOf(12345, 2)).toString()); + Assert.assertEquals("`decimal64` = 123456789.10", + KuduPredicate.newComparisonPredicate(decimal64Col, EQUAL, + BigDecimal.valueOf(12345678910L, 2)).toString()); + Assert.assertEquals("`decimal128` = 1234567891011121314.15", + KuduPredicate.newComparisonPredicate(decimal128Col, EQUAL, + new BigDecimal("1234567891011121314.15")).toString()); Assert.assertEquals("`string` = \"my string\"", KuduPredicate.newComparisonPredicate(stringCol, EQUAL, "my string").toString()); Assert.assertEquals("`binary` = 0xAB01CD", KuduPredicate.newComparisonPredicate( http://git-wip-us.apache.org/repos/asf/kudu/blob/4f34b69d/java/kudu-client/src/test/java/org/apache/kudu/client/TestPartialRow.java ---------------------------------------------------------------------- diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestPartialRow.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestPartialRow.java index b4dd756..44e3c45 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestPartialRow.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestPartialRow.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.math.BigDecimal; import java.nio.ByteBuffer; import org.junit.Test; @@ -51,6 +52,7 @@ public class TestPartialRow { assertEquals(ByteBuffer.wrap(new byte[] { 5, 6, 7, 8, 9 }), partialRow.getBinary("binary-bytebuffer")); assertTrue(partialRow.isSet("null")); assertTrue(partialRow.isNull("null")); + assertEquals(BigDecimal.valueOf(12345, 3), partialRow.getDecimal("decimal")); } @Test(expected = IllegalArgumentException.class) @@ -199,6 +201,32 @@ public class TestPartialRow { partialRow.isSet(999); } + @Test(expected = IllegalArgumentException.class) + public void testAddInvalidPrecisionDecimal() { + PartialRow partialRow = getPartialRowWithAllTypes(); + partialRow.addDecimal("decimal", BigDecimal.valueOf(123456, 3)); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddInvalidScaleDecimal() { + PartialRow partialRow = getPartialRowWithAllTypes(); + partialRow.addDecimal("decimal", BigDecimal.valueOf(12345, 4)); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddInvalidCoercedScaleDecimal() { + PartialRow partialRow = getPartialRowWithAllTypes(); + partialRow.addDecimal("decimal", BigDecimal.valueOf(12345, 2)); + } + + @Test + public void testAddCoercedScaleAndPrecisionDecimal() { + PartialRow partialRow = getPartialRowWithAllTypes(); + partialRow.addDecimal("decimal", BigDecimal.valueOf(222, 1)); + BigDecimal decimal = partialRow.getDecimal("decimal"); + assertEquals("22.200", decimal.toString()); + } + @Test public void testToString() { Schema schema = BaseKuduTest.getSchemaWithAllTypes(); @@ -228,12 +256,96 @@ public class TestPartialRow { assertEquals("(int8 int8=42, int32 int32=42, double double=52.35, " + "string string=\"fun with ütf\\0\", binary binary-bytebuffer=[2, 3, 4])", row.toString()); + + row.addDecimal("decimal", BigDecimal.valueOf(12345, 3)); + assertEquals("(int8 int8=42, int32 int32=42, double double=52.35, " + + "string string=\"fun with ütf\\0\", binary binary-bytebuffer=[2, 3, 4], " + + "decimal(5, 3) decimal=12.345)", + row.toString()); + } + + @Test + public void testIncrementColumn() { + PartialRow partialRow = getPartialRowWithAllTypes(); + + // Boolean + int boolIndex = getColumnIndex(partialRow, "bool"); + partialRow.addBoolean(boolIndex, false); + assertTrue(partialRow.incrementColumn(boolIndex)); + assertEquals(true, partialRow.getBoolean(boolIndex)); + assertFalse(partialRow.incrementColumn(boolIndex)); + + // Int8 + int int8Index = getColumnIndex(partialRow, "int8"); + partialRow.addByte(int8Index, (byte)(Byte.MAX_VALUE - 1)); + assertTrue(partialRow.incrementColumn(int8Index)); + assertEquals(Byte.MAX_VALUE, partialRow.getByte(int8Index)); + assertFalse(partialRow.incrementColumn(int8Index)); + + // Int16 + int int16Index = getColumnIndex(partialRow, "int16"); + partialRow.addShort(int16Index, (short)(Short.MAX_VALUE - 1)); + assertTrue(partialRow.incrementColumn(int16Index)); + assertEquals(Short.MAX_VALUE, partialRow.getShort(int16Index)); + assertFalse(partialRow.incrementColumn(int16Index)); + + // Int32 + int int32Index = getColumnIndex(partialRow, "int32"); + partialRow.addInt(int32Index, Integer.MAX_VALUE - 1); + assertTrue(partialRow.incrementColumn(int32Index)); + assertEquals(Integer.MAX_VALUE, partialRow.getInt(int32Index)); + assertFalse(partialRow.incrementColumn(int32Index)); + + // Int64 + int int64Index = getColumnIndex(partialRow, "int64"); + partialRow.addLong(int64Index, Long.MAX_VALUE - 1); + assertTrue(partialRow.incrementColumn(int64Index)); + assertEquals(Long.MAX_VALUE, partialRow.getLong(int64Index)); + assertFalse(partialRow.incrementColumn(int64Index)); + + // Float + int floatIndex = getColumnIndex(partialRow, "float"); + partialRow.addFloat(floatIndex, Float.MAX_VALUE); + assertTrue(partialRow.incrementColumn(floatIndex)); + assertEquals(Float.POSITIVE_INFINITY, partialRow.getFloat(floatIndex), 0.0f); + assertFalse(partialRow.incrementColumn(floatIndex)); + + // Float + int doubleIndex = getColumnIndex(partialRow, "double"); + partialRow.addDouble(doubleIndex, Double.MAX_VALUE); + assertTrue(partialRow.incrementColumn(doubleIndex)); + assertEquals(Double.POSITIVE_INFINITY, partialRow.getDouble(doubleIndex), 0.0); + assertFalse(partialRow.incrementColumn(doubleIndex)); + + // Decimal + int decimalIndex = getColumnIndex(partialRow, "decimal"); + // Decimal with precision 5, scale 3 has a max of 99.999 + partialRow.addDecimal(decimalIndex, new BigDecimal("99.998")); + assertTrue(partialRow.incrementColumn(decimalIndex)); + assertEquals(new BigDecimal("99.999"), partialRow.getDecimal(decimalIndex)); + assertFalse(partialRow.incrementColumn(decimalIndex)); + + // String + int stringIndex = getColumnIndex(partialRow, "string"); + partialRow.addString(stringIndex, "hello"); + assertTrue(partialRow.incrementColumn(stringIndex)); + assertEquals("hello\0", partialRow.getString(stringIndex)); + + // Binary + int binaryIndex = getColumnIndex(partialRow, "binary-array"); + partialRow.addBinary(binaryIndex, new byte[] { 0, 1, 2, 3, 4 }); + assertTrue(partialRow.incrementColumn(binaryIndex)); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4, 0 }, partialRow.getBinaryCopy(binaryIndex)); + } + + private int getColumnIndex(PartialRow partialRow, String columnName) { + return partialRow.getSchema().getColumnIndex(columnName); } private PartialRow getPartialRowWithAllTypes() { Schema schema = BaseKuduTest.getSchemaWithAllTypes(); // Ensure we aren't missing any types - assertEquals(12, schema.getColumnCount()); + assertEquals(13, schema.getColumnCount()); PartialRow row = schema.newPartialRow(); row.addByte("int8", (byte) 42); @@ -249,6 +361,7 @@ public class TestPartialRow { ByteBuffer binaryBuffer = ByteBuffer.wrap(new byte[] { 5, 6, 7, 8, 9 }); row.addBinary("binary-bytebuffer", binaryBuffer); row.setNull("null"); + row.addDecimal("decimal", BigDecimal.valueOf(12345, 3)); return row; } @@ -270,6 +383,7 @@ public class TestPartialRow { case FLOAT: return partialRow.getFloat(columnName); case DOUBLE: return partialRow.getDouble(columnName); case BOOL: return partialRow.getBoolean(columnName); + case DECIMAL: return partialRow.getDecimal(columnName); default: throw new UnsupportedOperationException(); } @@ -287,6 +401,7 @@ public class TestPartialRow { case FLOAT: return partialRow.getFloat(columnIndex); case DOUBLE: return partialRow.getDouble(columnIndex); case BOOL: return partialRow.getBoolean(columnIndex); + case DECIMAL: return partialRow.getDecimal(columnIndex); default: throw new UnsupportedOperationException(); } @@ -304,6 +419,7 @@ public class TestPartialRow { case FLOAT: partialRow.addFloat(columnName, 52.35F); break; case DOUBLE: partialRow.addDouble(columnName, 53.35); break; case BOOL: partialRow.addBoolean(columnName, true); break; + case DECIMAL: partialRow.addDecimal(columnName, BigDecimal.valueOf(12345, 3)); break; default: throw new UnsupportedOperationException(); } @@ -321,6 +437,7 @@ public class TestPartialRow { case FLOAT: partialRow.addFloat(columnIndex, 52.35F); break; case DOUBLE: partialRow.addDouble(columnIndex, 53.35); break; case BOOL: partialRow.addBoolean(columnIndex, true); break; + case DECIMAL: partialRow.addDecimal(columnIndex, BigDecimal.valueOf(12345, 3)); break; default: throw new UnsupportedOperationException(); } http://git-wip-us.apache.org/repos/asf/kudu/blob/4f34b69d/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowResult.java ---------------------------------------------------------------------- diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowResult.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowResult.java index 223ddc4..5196eda 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowResult.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowResult.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.math.BigDecimal; import java.nio.ByteBuffer; import org.junit.BeforeClass; @@ -61,6 +62,7 @@ public class TestRowResult extends BaseKuduTest { row.addBinary(9, bb); row.setNull(10); row.addLong(11, 11l); + row.addDecimal(12, BigDecimal.valueOf(12345, 3)); KuduSession session = syncClient.newSession(); session.apply(insert); @@ -113,6 +115,9 @@ public class TestRowResult extends BaseKuduTest { assertEquals(11, rr.getLong(11)); assertEquals(11, rr.getLong(allTypesSchema.getColumnByIndex(11).getName())); + assertEquals(BigDecimal.valueOf(12345, 3), rr.getDecimal(12)); + assertEquals(BigDecimal.valueOf(12345, 3), rr.getDecimal(allTypesSchema.getColumnByIndex(12).getName())); + // We test with the column name once since it's the same method for all types, unlike above. assertEquals(Type.INT8, rr.getColumnType(allTypesSchema.getColumnByIndex(0).getName())); assertEquals(Type.INT8, rr.getColumnType(0)); @@ -125,6 +130,7 @@ public class TestRowResult extends BaseKuduTest { assertEquals(Type.STRING, rr.getColumnType(7)); assertEquals(Type.BINARY, rr.getColumnType(8)); assertEquals(Type.UNIXTIME_MICROS, rr.getColumnType(11)); + assertEquals(Type.DECIMAL, rr.getColumnType(12)); } } } http://git-wip-us.apache.org/repos/asf/kudu/blob/4f34b69d/java/kudu-client/src/test/java/org/apache/kudu/client/TestScanPredicate.java ---------------------------------------------------------------------- diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestScanPredicate.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestScanPredicate.java index d89800c..7682d6d 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestScanPredicate.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestScanPredicate.java @@ -17,6 +17,7 @@ package org.apache.kudu.client; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.NavigableSet; @@ -31,6 +32,7 @@ import org.apache.kudu.ColumnSchema; import org.apache.kudu.Schema; import org.apache.kudu.Type; import org.apache.kudu.client.KuduPredicate.ComparisonOp; +import org.apache.kudu.util.DecimalUtil; public class TestScanPredicate extends BaseKuduTest { @@ -170,6 +172,36 @@ public class TestScanPredicate extends BaseKuduTest { ); } + // Returns a vector of decimal(4, 2) numbers from -50.50 (inclusive) to 50.50 + // (exclusive) (100 values) and boundary values. + private NavigableSet<BigDecimal> createDecimalValues() { + NavigableSet<BigDecimal> values = new TreeSet<>(); + for (long i = -50; i < 50; i++) { + values.add(BigDecimal.valueOf(i * 100 + i, 2)); + } + + values.add(BigDecimal.valueOf(-9999, 2)); + values.add(BigDecimal.valueOf(-9998, 2)); + values.add(BigDecimal.valueOf(9998, 2)); + values.add(BigDecimal.valueOf(9999, 2)); + + return values; + } + + private List<BigDecimal> createDecimalTestValues() { + return ImmutableList.of( + BigDecimal.valueOf(-9999, 2), + BigDecimal.valueOf(-9998, 2), + BigDecimal.valueOf(5100, 2), + BigDecimal.valueOf(-5000, 2), + BigDecimal.valueOf(0, 2), + BigDecimal.valueOf(4900, 2), + BigDecimal.valueOf(5000, 2), + BigDecimal.valueOf(9998, 2), + BigDecimal.valueOf(9999, 2) + ); + } + private NavigableSet<String> createStringValues() { return ImmutableSortedSet.of("", "\0", "\0\0", "a", "a\0", "a\0a", "aa\0"); } @@ -520,6 +552,69 @@ public class TestScanPredicate extends BaseKuduTest { } @Test + public void testDecimalPredicates() throws Exception { + ColumnSchema key = new ColumnSchema.ColumnSchemaBuilder("key", Type.INT64).key(true).build(); + ColumnSchema val = new ColumnSchema.ColumnSchemaBuilder("value", Type.DECIMAL) + .typeAttributes(DecimalUtil.typeAttributes(4, 2)).nullable(true).build(); + Schema schema = new Schema(ImmutableList.of(key, val)); + + syncClient.createTable("decimal-table", schema, createTableOptions()); + KuduTable table = syncClient.openTable("decimal-table"); + + NavigableSet<BigDecimal> values = createDecimalValues(); + List<BigDecimal> testValues = createDecimalTestValues(); + KuduSession session = syncClient.newSession(); + session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH); + long i = 0; + for (BigDecimal value : values) { + Insert insert = table.newInsert(); + insert.getRow().addLong("key", i++); + insert.getRow().addDecimal("value", value); + session.apply(insert); + } + Insert nullInsert = table.newInsert(); + nullInsert.getRow().addLong("key", i++); + nullInsert.getRow().setNull("value"); + session.apply(nullInsert); + session.flush(); + + ColumnSchema col = table.getSchema().getColumn("value"); + Assert.assertEquals(values.size() + 1, countRows(table)); + + for (BigDecimal v : testValues) { + // value = v + KuduPredicate equal = KuduPredicate.newComparisonPredicate(col, ComparisonOp.EQUAL, v); + Assert.assertEquals(values.subSet(v, true, v, true).size(), countRows(table, equal)); + + // value >= v + KuduPredicate greaterEqual = + KuduPredicate.newComparisonPredicate(col, ComparisonOp.GREATER_EQUAL, v); + Assert.assertEquals(values.tailSet(v).size(), countRows(table, greaterEqual)); + + // value <= v + KuduPredicate lessEqual = + KuduPredicate.newComparisonPredicate(col, ComparisonOp.LESS_EQUAL, v); + Assert.assertEquals(values.headSet(v, true).size(), countRows(table, lessEqual)); + + // value > v + KuduPredicate greater = + KuduPredicate.newComparisonPredicate(col, ComparisonOp.GREATER, v); + Assert.assertEquals(values.tailSet(v, false).size(), countRows(table, greater)); + + // value < v + KuduPredicate less = + KuduPredicate.newComparisonPredicate(col, ComparisonOp.LESS, v); + Assert.assertEquals(values.headSet(v).size(), countRows(table, less)); + } + + KuduPredicate isNotNull = KuduPredicate.newIsNotNullPredicate(col); + Assert.assertEquals(values.size(), countRows(table, isNotNull)); + + KuduPredicate isNull = KuduPredicate.newIsNullPredicate(col); + Assert.assertEquals(1, countRows(table, isNull)); + } + + @Test public void testStringPredicates() throws Exception { Schema schema = createTableSchema(Type.STRING); syncClient.createTable("string-table", schema, createTableOptions());