diff --git a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java index 42d1993900a5..4d6d303aae2c 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java +++ b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java @@ -24,6 +24,7 @@ import com.google.common.base.MoreObjects; import com.google.common.io.BaseEncoding; import java.io.Serializable; +import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Objects; @@ -48,7 +49,8 @@ public enum Attribute { * A primitive field value. A {@code FieldValue} is primitive when the corresponding field has * type {@link LegacySQLTypeName#BYTES}, {@link LegacySQLTypeName#BOOLEAN}, * {@link LegacySQLTypeName#STRING}, {@link LegacySQLTypeName#FLOAT}, - * {@link LegacySQLTypeName#INTEGER}, {@link LegacySQLTypeName#TIMESTAMP} or the value is set to + * {@link LegacySQLTypeName#INTEGER}, {@link LegacySQLTypeName#NUMERIC}, + * {@link LegacySQLTypeName#TIMESTAMP}, or the value is set to * {@code null}. */ PRIMITIVE, @@ -76,7 +78,8 @@ private FieldValue(Attribute attribute, Object value) { * @return {@link Attribute#PRIMITIVE} if the field is a primitive type * ({@link LegacySQLTypeName#BYTES}, {@link LegacySQLTypeName#BOOLEAN}, {@link LegacySQLTypeName#STRING}, * {@link LegacySQLTypeName#FLOAT}, {@link LegacySQLTypeName#INTEGER}, - * {@link LegacySQLTypeName#TIMESTAMP}) or is {@code null}. Returns {@link Attribute#REPEATED} if + * {@link LegacySQLTypeName#NUMERIC}, {@link LegacySQLTypeName#TIMESTAMP}) + * or is {@code null}. Returns {@link Attribute#REPEATED} if * the corresponding field has ({@link Field.Mode#REPEATED}) mode. Returns * {@link Attribute#RECORD} if the corresponding field is a * {@link LegacySQLTypeName#RECORD} type. @@ -107,7 +110,7 @@ public Object getValue() { * corresponding field has primitive type ({@link LegacySQLTypeName#BYTES}, * {@link LegacySQLTypeName#BOOLEAN}, {@link LegacySQLTypeName#STRING}, * {@link LegacySQLTypeName#FLOAT}, {@link LegacySQLTypeName#INTEGER}, - * {@link LegacySQLTypeName#TIMESTAMP}). + * {@link LegacySQLTypeName#NUMERIC} {@link LegacySQLTypeName#TIMESTAMP}). * * @throws ClassCastException if the field is not a primitive type * @throws NullPointerException if {@link #isNull()} returns {@code true} @@ -198,6 +201,21 @@ public long getTimestampValue() { } + /** + * Returns this field's value as a {@link java.math.BigDecimal}. This method should only be used if the + * corresponding field has {@link LegacySQLTypeName#NUMERIC} type. + * + * @throws ClassCastException if the field is not a primitive type + * @throws NumberFormatException if the field's value could not be converted to + * {@link java.math.BigDecimal} + * @throws NullPointerException if {@link #isNull()} returns {@code true} + */ + @SuppressWarnings("unchecked") + public BigDecimal getNumericValue() { + return new BigDecimal(getStringValue()); + } + + /** * Returns this field's value as a list of {@link FieldValue}. This method should only be used if * the corresponding field has {@link Field.Mode#REPEATED} mode (i.e. {@link #getAttribute()} is diff --git a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java index e99fbe21438b..a0f6da6c992e 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java +++ b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java @@ -49,6 +49,11 @@ public LegacySQLTypeName apply(String constant) { public static final LegacySQLTypeName INTEGER = type.createAndRegister("INTEGER").setStandardType(StandardSQLTypeName.INT64); /** A 64-bit IEEE binary floating-point value. */ public static final LegacySQLTypeName FLOAT = type.createAndRegister("FLOAT").setStandardType(StandardSQLTypeName.FLOAT64); + /** + * A decimal value with 38 digits of precision and 9 digits of scale. + * Note, support for this type is limited in legacy SQL. + */ + public static final LegacySQLTypeName NUMERIC = type.createAndRegister("NUMERIC").setStandardType(StandardSQLTypeName.NUMERIC); /** A Boolean value (true or false). */ public static final LegacySQLTypeName BOOLEAN = type.createAndRegister("BOOLEAN").setStandardType(StandardSQLTypeName.BOOL); /** Represents an absolute point in time, with microsecond precision. */ diff --git a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java index 3038db96e724..56b62cd45b6e 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java +++ b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java @@ -24,6 +24,7 @@ import com.google.common.collect.Lists; import com.google.common.io.BaseEncoding; import java.io.Serializable; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; @@ -47,6 +48,7 @@ *
  • Long: StandardSQLTypeName.INT64 *
  • Double: StandardSQLTypeName.FLOAT64 *
  • Float: StandardSQLTypeName.FLOAT64 + *
  • BigDecimal: StandardSQLTypeName.NUMERIC * * *

    No other types are supported through that entry point. The other types can be created by @@ -164,6 +166,11 @@ public static QueryParameterValue float64(Float value) { return of(value, StandardSQLTypeName.FLOAT64); } + /** Creates a {@code QueryParameterValue} object with a type of NUMERIC. */ + public static QueryParameterValue numeric(BigDecimal value) { + return of(value, StandardSQLTypeName.NUMERIC); + } + /** Creates a {@code QueryParameterValue} object with a type of STRING. */ public static QueryParameterValue string(String value) { return of(value, StandardSQLTypeName.STRING); @@ -245,6 +252,8 @@ private static StandardSQLTypeName classToType(Class type) { return StandardSQLTypeName.FLOAT64; } else if (Float.class.isAssignableFrom(type)) { return StandardSQLTypeName.FLOAT64; + } else if (BigDecimal.class.isAssignableFrom(type)) { + return StandardSQLTypeName.NUMERIC; } throw new IllegalArgumentException("Unsupported object type for QueryParameter: " + type); } @@ -269,6 +278,11 @@ private static String valueToStringOrNull(T value, StandardSQLTypeName type) return value.toString(); } break; + case NUMERIC: + if (value instanceof BigDecimal) { + return value.toString(); + } + break; case BYTES: if (value instanceof byte[]) { return BaseEncoding.base64().encode((byte[]) value); diff --git a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java index a250c1fc1509..e6f43b0b776f 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java +++ b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java @@ -29,6 +29,8 @@ public enum StandardSQLTypeName { INT64, /** A 64-bit IEEE binary floating-point value. */ FLOAT64, + /** A decimal value with 38 digits of precision and 9 digits of scale. */ + NUMERIC, /** Variable-length character (Unicode) data. */ STRING, /** Variable-length binary data. */ diff --git a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueListTest.java b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueListTest.java index c59f5c94a5c4..e0f8e0ef65a3 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueListTest.java +++ b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueListTest.java @@ -48,7 +48,8 @@ public class FieldValueListTest { "ninth", LegacySQLTypeName.RECORD, Field.of("first", LegacySQLTypeName.FLOAT), - Field.of("second", LegacySQLTypeName.TIMESTAMP))); + Field.of("second", LegacySQLTypeName.TIMESTAMP)), + Field.of("tenth", LegacySQLTypeName.NUMERIC)); private final Map integerPb = ImmutableMap.of("v", "1"); private final Map floatPb = ImmutableMap.of("v", "1.5"); @@ -60,6 +61,7 @@ public class FieldValueListTest { ImmutableMap.of("v", ImmutableList.of(integerPb, integerPb)); private final Map recordPb = ImmutableMap.of("f", ImmutableList.of(floatPb, timestampPb)); + private final Map numericPb = ImmutableMap.of("v", "123456789.123456789"); private final FieldValue booleanFv = FieldValue.of(Attribute.PRIMITIVE, "false"); private final FieldValue integerFv = FieldValue.of(Attribute.PRIMITIVE, "1"); @@ -75,6 +77,7 @@ public class FieldValueListTest { Attribute.RECORD, FieldValueList.of( ImmutableList.of(floatFv, timestampFv), schema.get("ninth").getSubFields())); + private final FieldValue numericFv = FieldValue.of(Attribute.PRIMITIVE, "123456789.123456789"); private final List fieldValuesPb = ImmutableList.of( @@ -86,7 +89,8 @@ public class FieldValueListTest { bytesPb, nullPb, repeatedPb, - recordPb); + recordPb, + numericPb); private final FieldValueList fieldValues = FieldValueList.of( @@ -99,7 +103,8 @@ public class FieldValueListTest { bytesFv, nullFv, repeatedFv, - recordFv), + recordFv, + numericFv), schema); @Test @@ -111,7 +116,7 @@ public void testFromPb() { @Test public void testGetByIndex() { - assertEquals(9, fieldValues.size()); + assertEquals(10, fieldValues.size()); assertEquals(booleanFv, fieldValues.get(0)); assertEquals(integerFv, fieldValues.get(1)); assertEquals(floatFv, fieldValues.get(2)); @@ -127,11 +132,12 @@ public void testGetByIndex() { assertEquals(2, fieldValues.get(8).getRecordValue().size()); assertEquals(floatFv, fieldValues.get(8).getRecordValue().get(0)); assertEquals(timestampFv, fieldValues.get(8).getRecordValue().get(1)); + assertEquals(numericFv, fieldValues.get(9)); } @Test public void testGetByName() { - assertEquals(9, fieldValues.size()); + assertEquals(10, fieldValues.size()); assertEquals(booleanFv, fieldValues.get("first")); assertEquals(integerFv, fieldValues.get("second")); assertEquals(floatFv, fieldValues.get("third")); @@ -147,6 +153,7 @@ public void testGetByName() { assertEquals(2, fieldValues.get("ninth").getRecordValue().size()); assertEquals(floatFv, fieldValues.get("ninth").getRecordValue().get("first")); assertEquals(timestampFv, fieldValues.get("ninth").getRecordValue().get("second")); + assertEquals(numericFv, fieldValues.get("tenth")); } @Test @@ -161,7 +168,8 @@ public void testNullSchema() { bytesFv, nullFv, repeatedFv, - recordFv)); + recordFv, + numericFv)); assertEquals(fieldValues, fieldValuesNoSchema); diff --git a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java index f01a23d80a6f..e5afcedcbfad 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java +++ b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java @@ -29,6 +29,7 @@ import org.junit.Test; +import java.math.BigDecimal; import java.util.Map; public class FieldValueTest { @@ -38,6 +39,8 @@ public class FieldValueTest { private static final TableCell BOOLEAN_FIELD = new TableCell().setV("false"); private static final Map INTEGER_FIELD = ImmutableMap.of("v", "1"); private static final Map FLOAT_FIELD = ImmutableMap.of("v", "1.5"); + private static final Map NUMERIC_FIELD = + ImmutableMap.of("v", "123456789.123456789"); private static final Map STRING_FIELD = ImmutableMap.of("v", "string"); private static final Map TIMESTAMP_FIELD = ImmutableMap.of("v", "42"); private static final Map BYTES_FIELD = ImmutableMap.of("v", BYTES_BASE64); @@ -59,6 +62,9 @@ public void testFromPb() { value = FieldValue.fromPb(FLOAT_FIELD); assertEquals(FieldValue.Attribute.PRIMITIVE, value.getAttribute()); assertEquals(1.5, value.getDoubleValue(), 0); + value = FieldValue.fromPb(NUMERIC_FIELD); + assertEquals(FieldValue.Attribute.PRIMITIVE, value.getAttribute()); + assertEquals(new BigDecimal("123456789.123456789"), value.getNumericValue()); value = FieldValue.fromPb(STRING_FIELD); assertEquals(FieldValue.Attribute.PRIMITIVE, value.getAttribute()); assertEquals("string", value.getStringValue()); @@ -95,6 +101,11 @@ public void testEquals() { assertEquals(floatValue, FieldValue.fromPb(FLOAT_FIELD)); assertEquals(floatValue.hashCode(), FieldValue.fromPb(FLOAT_FIELD).hashCode()); + FieldValue numericValue = + FieldValue.of(FieldValue.Attribute.PRIMITIVE, "123456789.123456789"); + assertEquals(numericValue, FieldValue.fromPb(NUMERIC_FIELD)); + assertEquals(numericValue.hashCode(), FieldValue.fromPb(NUMERIC_FIELD).hashCode()); + FieldValue stringValue = FieldValue.of(FieldValue.Attribute.PRIMITIVE, "string"); assertEquals(stringValue, FieldValue.fromPb(STRING_FIELD)); assertEquals(stringValue.hashCode(), FieldValue.fromPb(STRING_FIELD).hashCode()); diff --git a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java index f804923bf7c1..5b024e3f8948 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java +++ b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java @@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.api.services.bigquery.model.QueryParameterType; +import java.math.BigDecimal; import java.util.List; import org.junit.Test; @@ -69,6 +70,15 @@ public void testFloat64FromFloat() { assertThat(value.getArrayValues()).isNull(); } + @Test + public void testNumeric() { + QueryParameterValue value = QueryParameterValue.numeric(new BigDecimal("123.456")); + assertThat(value.getValue()).isEqualTo("123.456"); + assertThat(value.getType()).isEqualTo(StandardSQLTypeName.NUMERIC); + assertThat(value.getArrayType()).isNull(); + assertThat(value.getArrayValues()).isNull(); + } + @Test public void testString() { QueryParameterValue value = QueryParameterValue.string("foo"); @@ -132,6 +142,16 @@ public void testFloat64ArrayFromFloats() { assertArrayDataEquals(new String[]{"2.6", "5.4"}, StandardSQLTypeName.FLOAT64, value.getArrayValues()); } + @Test + public void testNumericArray() { + QueryParameterValue value = QueryParameterValue.array( + new BigDecimal[] {new BigDecimal("3.14"), new BigDecimal("1.59")}, BigDecimal.class); + assertThat(value.getValue()).isNull(); + assertThat(value.getType()).isEqualTo(StandardSQLTypeName.ARRAY); + assertThat(value.getArrayType()).isEqualTo(StandardSQLTypeName.NUMERIC); + assertArrayDataEquals(new String[]{"3.14", "1.59"}, StandardSQLTypeName.NUMERIC, value.getArrayValues()); + } + @Test public void testStringArray() { QueryParameterValue value = QueryParameterValue.array(new String[] {"Ana", "Marv"}, String.class); diff --git a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 29d4c19ed74e..bd88f9e5f8bd 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -84,6 +84,7 @@ import com.google.common.collect.Sets; import com.google.common.io.BaseEncoding; import java.io.IOException; +import java.math.BigDecimal; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Collections; @@ -164,9 +165,14 @@ public class ITBigQueryTest { .setMode(Field.Mode.NULLABLE) .setDescription("FloatDescription") .build(); + private static final Field NUMERIC_FIELD_SCHEMA = + Field.newBuilder("NumericField", LegacySQLTypeName.NUMERIC) + .setMode(Field.Mode.NULLABLE) + .setDescription("NumericDescription") + .build(); private static final Schema TABLE_SCHEMA = Schema.of(TIMESTAMP_FIELD_SCHEMA, STRING_FIELD_SCHEMA, INTEGER_ARRAY_FIELD_SCHEMA, BOOLEAN_FIELD_SCHEMA, BYTES_FIELD_SCHEMA, RECORD_FIELD_SCHEMA, - INTEGER_FIELD_SCHEMA, FLOAT_FIELD_SCHEMA); + INTEGER_FIELD_SCHEMA, FLOAT_FIELD_SCHEMA, NUMERIC_FIELD_SCHEMA); private static final Schema SIMPLE_SCHEMA = Schema.of(STRING_FIELD_SCHEMA); private static final Schema QUERY_RESULT_SCHEMA = Schema.of( Field.newBuilder("TimestampField", LegacySQLTypeName.TIMESTAMP) @@ -198,7 +204,8 @@ public class ITBigQueryTest { + " \"BytesField\": \"" + BYTES_BASE64 + "\"" + " }," + " \"IntegerField\": \"3\"," - + " \"FloatField\": \"1.2\"" + + " \"FloatField\": \"1.2\"," + + " \"NumericField\": \"3.14\"" + "}\n" + "{" + " \"TimestampField\": \"2014-08-19 07:41:35.220 -05:00\"," @@ -214,7 +221,8 @@ public class ITBigQueryTest { + " \"BytesField\": \"" + BYTES_BASE64 + "\"" + " }," + " \"IntegerField\": \"3\"," - + " \"FloatField\": \"1.2\"" + + " \"FloatField\": \"1.2\"," + + " \"NumericField\": \"123456.789012345\"" + "}"; private static final Set PUBLIC_DATASETS = ImmutableSet.of("github_repos", "hacker_news", @@ -642,6 +650,7 @@ public void testInsertAll() throws IOException { "BytesField", BYTES_BASE64)); builder1.put("IntegerField", 5); builder1.put("FloatField", 1.2); + builder1.put("NumericField", new BigDecimal("123456789.123456789")); ImmutableMap.Builder builder2 = ImmutableMap.builder(); builder2.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); builder2.put("StringField", "stringValue"); @@ -655,6 +664,7 @@ public void testInsertAll() throws IOException { "BytesField", BYTES_BASE64)); builder2.put("IntegerField", 5); builder2.put("FloatField", 1.2); + builder2.put("NumericField", new BigDecimal("123456789.123456789")); InsertAllRequest request = InsertAllRequest.newBuilder(tableInfo.getTableId()) .addRow(builder1.build()) .addRow(builder2.build()) @@ -684,6 +694,7 @@ public void testInsertAllWithSuffix() throws InterruptedException { "BytesField", BYTES_BASE64)); builder1.put("IntegerField", 5); builder1.put("FloatField", 1.2); + builder1.put("NumericField", new BigDecimal("123456789.123456789")); ImmutableMap.Builder builder2 = ImmutableMap.builder(); builder2.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); builder2.put("StringField", "stringValue"); @@ -697,6 +708,7 @@ public void testInsertAllWithSuffix() throws InterruptedException { "BytesField", BYTES_BASE64)); builder2.put("IntegerField", 5); builder2.put("FloatField", 1.2); + builder2.put("NumericField", new BigDecimal("123456789.123456789")); InsertAllRequest request = InsertAllRequest.newBuilder(tableInfo.getTableId()) .addRow(builder1.build()) .addRow(builder2.build()) @@ -735,6 +747,7 @@ public void testInsertAllWithErrors() { "BytesField", BYTES_BASE64)); builder1.put("IntegerField", 5); builder1.put("FloatField", 1.2); + builder1.put("NumericField", new BigDecimal("123456789.123456789")); ImmutableMap.Builder builder2 = ImmutableMap.builder(); builder2.put("TimestampField", "invalidDate"); builder2.put("StringField", "stringValue"); @@ -748,6 +761,7 @@ public void testInsertAllWithErrors() { "BytesField", BYTES_BASE64)); builder2.put("IntegerField", 5); builder2.put("FloatField", 1.2); + builder2.put("NumericField", new BigDecimal("123456789.123456789")); ImmutableMap.Builder builder3 = ImmutableMap.builder(); builder3.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); builder3.put("StringField", "stringValue"); @@ -781,6 +795,7 @@ public void testListAllTableData() { FieldValue recordCell = row.get(5); FieldValue integerCell = row.get(6); FieldValue floatCell = row.get(7); + FieldValue numericCell = row.get(8); assertEquals(FieldValue.Attribute.PRIMITIVE, timestampCell.getAttribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, stringCell.getAttribute()); assertEquals(FieldValue.Attribute.REPEATED, integerArrayCell.getAttribute()); @@ -789,6 +804,7 @@ public void testListAllTableData() { assertEquals(FieldValue.Attribute.RECORD, recordCell.getAttribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, integerCell.getAttribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, floatCell.getAttribute()); + assertEquals(FieldValue.Attribute.PRIMITIVE, numericCell.getAttribute()); assertEquals(1408452095220000L, timestampCell.getTimestampValue()); assertEquals("stringValue", stringCell.getStringValue()); assertEquals(0, integerArrayCell.getRepeatedValue().get(0).getLongValue()); @@ -802,6 +818,7 @@ public void testListAllTableData() { assertEquals(true, recordCell.getRecordValue().get(3).getBooleanValue()); assertEquals(3, integerCell.getLongValue()); assertEquals(1.2, floatCell.getDoubleValue(), 0.0001); + assertEquals(new BigDecimal("123456789.123456789"), numericCell.getNumericValue()); rowCount++; } assertEquals(2, rowCount); @@ -849,7 +866,8 @@ public void testPositionalQueryParameters() throws InterruptedException { " AND TimestampField > ?" + " AND IntegerField IN UNNEST(?)" + " AND IntegerField < ?" + - " AND FloatField > ?"; + " AND FloatField > ?" + + " AND NumericField < ?"; QueryParameterValue stringParameter = QueryParameterValue.string("stringValue"); QueryParameterValue timestampParameter = QueryParameterValue.timestamp("2014-01-01 07:00:00.000000+00:00"); @@ -857,6 +875,8 @@ public void testPositionalQueryParameters() throws InterruptedException { QueryParameterValue.array(new Integer[] {3, 4}, Integer.class); QueryParameterValue int64Parameter = QueryParameterValue.int64(5); QueryParameterValue float64Parameter = QueryParameterValue.float64(0.5); + QueryParameterValue numericParameter = + QueryParameterValue.numeric(new BigDecimal("234567890.123456")); QueryJobConfiguration config = QueryJobConfiguration.newBuilder(query) .setDefaultDataset(DatasetId.of(DATASET)) .setUseLegacySql(false) @@ -865,6 +885,7 @@ public void testPositionalQueryParameters() throws InterruptedException { .addPositionalParameter(intArrayParameter) .addPositionalParameter(int64Parameter) .addPositionalParameter(float64Parameter) + .addPositionalParameter(numericParameter) .build(); TableResult result = bigquery.query(config); assertEquals(QUERY_RESULT_SCHEMA, result.getSchema()); @@ -1191,6 +1212,7 @@ public void testInsertFromFile() throws InterruptedException, IOException, Timeo FieldValue recordCell = row.get(5); FieldValue integerCell = row.get(6); FieldValue floatCell = row.get(7); + FieldValue numericCell = row.get(8); assertEquals(FieldValue.Attribute.PRIMITIVE, timestampCell.getAttribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, stringCell.getAttribute()); assertEquals(FieldValue.Attribute.REPEATED, integerArrayCell.getAttribute()); @@ -1199,6 +1221,7 @@ public void testInsertFromFile() throws InterruptedException, IOException, Timeo assertEquals(FieldValue.Attribute.RECORD, recordCell.getAttribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, integerCell.getAttribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, floatCell.getAttribute()); + assertEquals(FieldValue.Attribute.PRIMITIVE, numericCell.getAttribute()); assertEquals(1408452095220000L, timestampCell.getTimestampValue()); assertEquals("stringValue", stringCell.getStringValue()); assertEquals(0, integerArrayCell.getRepeatedValue().get(0).getLongValue()); @@ -1212,6 +1235,7 @@ public void testInsertFromFile() throws InterruptedException, IOException, Timeo assertEquals(true, recordCell.getRecordValue().get(3).getBooleanValue()); assertEquals(3, integerCell.getLongValue()); assertEquals(1.2, floatCell.getDoubleValue(), 0.0001); + assertEquals(new BigDecimal("123456789.123456789"), floatCell.getNumericValue()); rowCount++; } assertEquals(2, rowCount);