Skip to content

Commit

Permalink
feat: add BIGNUMERIC support
Browse files Browse the repository at this point in the history
update IT testcase

nit
  • Loading branch information
stephaniewang526 committed Aug 28, 2020
1 parent 127414c commit f021dde
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 12 deletions.
Expand Up @@ -61,6 +61,9 @@ public LegacySQLTypeName apply(String constant) {
*/
public static final LegacySQLTypeName NUMERIC =
type.createAndRegister("NUMERIC").setStandardType(StandardSQLTypeName.NUMERIC);
/** A decimal value with 38 digits of precision and 38 digits of scale. */
public static final LegacySQLTypeName BIGNUMERIC =
type.createAndRegister("BIGNUMERIC").setStandardType(StandardSQLTypeName.BIGNUMERIC);
/** A Boolean value (true or false). */
public static final LegacySQLTypeName BOOLEAN =
type.createAndRegister("BOOLEAN").setStandardType(StandardSQLTypeName.BOOL);
Expand Down
Expand Up @@ -60,6 +60,7 @@
* <li>Double: StandardSQLTypeName.FLOAT64
* <li>Float: StandardSQLTypeName.FLOAT64
* <li>BigDecimal: StandardSQLTypeName.NUMERIC
* <li>BigNumeric: StandardSQLTypeName.BIGNUMERIC
* </ul>
*
* <p>No other types are supported through that entry point. The other types can be created by
Expand Down Expand Up @@ -197,7 +198,10 @@ public Map<String, QueryParameterValue> getStructTypes() {
@Nullable
abstract Map<String, QueryParameterValue> getStructTypesInner();

/** Creates a {@code QueryParameterValue} object with the given value and type. */
/**
* Creates a {@code QueryParameterValue} object with the given value and type. Note: this does not
* support BigNumeric
*/
public static <T> QueryParameterValue of(T value, Class<T> type) {
return of(value, classToType(type));
}
Expand Down Expand Up @@ -240,6 +244,11 @@ public static QueryParameterValue numeric(BigDecimal value) {
return of(value, StandardSQLTypeName.NUMERIC);
}

/** Creates a {@code QueryParameterValue} object with a type of BIGNUMERIC. */
public static QueryParameterValue bigNumeric(BigDecimal value) {
return of(value, StandardSQLTypeName.BIGNUMERIC);
}

/** Creates a {@code QueryParameterValue} object with a type of STRING. */
public static QueryParameterValue string(String value) {
return of(value, StandardSQLTypeName.STRING);
Expand Down Expand Up @@ -363,6 +372,7 @@ private static <T> String valueToStringOrNull(T value, StandardSQLTypeName type)
}
break;
case NUMERIC:
case BIGNUMERIC:
if (value instanceof BigDecimal) {
return value.toString();
}
Expand Down
Expand Up @@ -32,6 +32,8 @@ public enum StandardSQLTypeName {
FLOAT64,
/** A decimal value with 38 digits of precision and 9 digits of scale. */
NUMERIC,
/** A decimal value with 38 digits of precision and 38 digits of scale. */
BIGNUMERIC,
/** Variable-length character (Unicode) data. */
STRING,
/** Variable-length binary data. */
Expand Down
Expand Up @@ -49,7 +49,8 @@ public class FieldValueListTest {
LegacySQLTypeName.RECORD,
Field.of("first", LegacySQLTypeName.FLOAT),
Field.of("second", LegacySQLTypeName.TIMESTAMP)),
Field.of("tenth", LegacySQLTypeName.NUMERIC));
Field.of("tenth", LegacySQLTypeName.NUMERIC),
Field.of("eleventh", LegacySQLTypeName.BIGNUMERIC));

private final Map<String, String> integerPb = ImmutableMap.of("v", "1");
private final Map<String, String> floatPb = ImmutableMap.of("v", "1.5");
Expand All @@ -62,6 +63,9 @@ public class FieldValueListTest {
private final Map<String, Object> recordPb =
ImmutableMap.<String, Object>of("f", ImmutableList.<Object>of(floatPb, timestampPb));
private final Map<String, String> numericPb = ImmutableMap.of("v", "123456789.123456789");
private final Map<String, String> bigNumericPb =
ImmutableMap.of(
"v", "99999999999999999999999999999999999999.99999999999999999999999999999999999999");

private final FieldValue booleanFv = FieldValue.of(Attribute.PRIMITIVE, "false");
private final FieldValue integerFv = FieldValue.of(Attribute.PRIMITIVE, "1");
Expand All @@ -78,6 +82,10 @@ public class FieldValueListTest {
FieldValueList.of(
ImmutableList.of(floatFv, timestampFv), schema.get("ninth").getSubFields()));
private final FieldValue numericFv = FieldValue.of(Attribute.PRIMITIVE, "123456789.123456789");
private final FieldValue bigNumericFv =
FieldValue.of(
Attribute.PRIMITIVE,
"99999999999999999999999999999999999999.99999999999999999999999999999999999999");

private final List<?> fieldValuesPb =
ImmutableList.of(
Expand All @@ -90,7 +98,8 @@ public class FieldValueListTest {
nullPb,
repeatedPb,
recordPb,
numericPb);
numericPb,
bigNumericPb);

private final FieldValueList fieldValues =
FieldValueList.of(
Expand All @@ -104,7 +113,8 @@ public class FieldValueListTest {
nullFv,
repeatedFv,
recordFv,
numericFv),
numericFv,
bigNumericFv),
schema);

@Test
Expand All @@ -116,7 +126,7 @@ public void testFromPb() {

@Test
public void testGetByIndex() {
assertEquals(10, fieldValues.size());
assertEquals(11, fieldValues.size());
assertEquals(booleanFv, fieldValues.get(0));
assertEquals(integerFv, fieldValues.get(1));
assertEquals(floatFv, fieldValues.get(2));
Expand All @@ -133,11 +143,12 @@ public void testGetByIndex() {
assertEquals(floatFv, fieldValues.get(8).getRecordValue().get(0));
assertEquals(timestampFv, fieldValues.get(8).getRecordValue().get(1));
assertEquals(numericFv, fieldValues.get(9));
assertEquals(bigNumericFv, fieldValues.get(10));
}

@Test
public void testGetByName() {
assertEquals(10, fieldValues.size());
assertEquals(11, fieldValues.size());
assertEquals(booleanFv, fieldValues.get("first"));
assertEquals(integerFv, fieldValues.get("second"));
assertEquals(floatFv, fieldValues.get("third"));
Expand All @@ -154,6 +165,7 @@ public void testGetByName() {
assertEquals(floatFv, fieldValues.get("ninth").getRecordValue().get("first"));
assertEquals(timestampFv, fieldValues.get("ninth").getRecordValue().get("second"));
assertEquals(numericFv, fieldValues.get("tenth"));
assertEquals(bigNumericFv, fieldValues.get("eleventh"));
}

@Test
Expand All @@ -170,7 +182,8 @@ public void testNullSchema() {
nullFv,
repeatedFv,
recordFv,
numericFv));
numericFv,
bigNumericFv));

assertEquals(fieldValues, fieldValuesNoSchema);

Expand Down
Expand Up @@ -27,6 +27,7 @@
import com.google.cloud.bigquery.TimePartitioning.Type;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import org.junit.Test;
Expand Down Expand Up @@ -101,8 +102,10 @@ public class QueryJobConfigurationTest {
QueryParameterValue.string("stringValue");
private static final QueryParameterValue TIMESTAMP_PARAMETER =
QueryParameterValue.timestamp("2014-01-01 07:00:00.000000+00:00");
private static final QueryParameterValue BIGNUMERIC_PARAMETER =
QueryParameterValue.bigNumeric(new BigDecimal(1 / 3));
private static final List<QueryParameterValue> POSITIONAL_PARAMETER =
ImmutableList.of(STRING_PARAMETER, TIMESTAMP_PARAMETER);
ImmutableList.of(STRING_PARAMETER, TIMESTAMP_PARAMETER, BIGNUMERIC_PARAMETER);
private static final Map<String, QueryParameterValue> NAME_PARAMETER =
ImmutableMap.of("string", STRING_PARAMETER, "timestamp", TIMESTAMP_PARAMETER);
private static final QueryJobConfiguration QUERY_JOB_CONFIGURATION =
Expand Down
Expand Up @@ -141,6 +141,31 @@ public void testNumeric() {
assertThat(value.getArrayValues()).isNull();
}

@Test
public void testBigNumeric() {
QueryParameterValue value =
QueryParameterValue.bigNumeric(new BigDecimal("0.33333333333333333333333333333333333333"));
QueryParameterValue value1 =
QueryParameterValue.bigNumeric(new BigDecimal("0.50000000000000000000000000000000000000"));
QueryParameterValue value2 =
QueryParameterValue.bigNumeric(new BigDecimal("0.00000000500000000000000000000000000000"));
QueryParameterValue value3 =
QueryParameterValue.bigNumeric(new BigDecimal("-0.00000000500000000000000000000000000000"));
QueryParameterValue value4 =
QueryParameterValue.bigNumeric(
new BigDecimal("0.33333333333333333333333333333333333333888888888888888"));

assertThat(value.getValue()).isEqualTo("0.33333333333333333333333333333333333333");
assertThat(value1.getValue()).isEqualTo("0.50000000000000000000000000000000000000");
assertThat(value2.getValue()).isEqualTo("5.00000000000000000000000000000E-9");
assertThat(value3.getValue()).isEqualTo("-5.00000000000000000000000000000E-9");
assertThat(value4.getValue())
.isEqualTo("0.33333333333333333333333333333333333333888888888888888");
assertThat(value.getType()).isEqualTo(StandardSQLTypeName.BIGNUMERIC);
assertThat(value.getArrayType()).isNull();
assertThat(value.getArrayValues()).isNull();
}

@Test
public void testString() {
QueryParameterValue value = QueryParameterValue.string("foo");
Expand Down
Expand Up @@ -208,6 +208,11 @@ public class ITBigQueryTest {
.setMode(Field.Mode.NULLABLE)
.setDescription("NumericDescription")
.build();
private static final Field BIGNUMERIC_FIELD_SCHEMA =
Field.newBuilder("BigNumericField", LegacySQLTypeName.BIGNUMERIC)
.setMode(Field.Mode.NULLABLE)
.setDescription("BigNumericDescription")
.build();
private static final Field STRING_FIELD_SCHEMA_WITH_POLICY =
Field.newBuilder("StringFieldWithPolicy", LegacySQLTypeName.STRING)
.setMode(Field.Mode.NULLABLE)
Expand All @@ -225,7 +230,8 @@ public class ITBigQueryTest {
INTEGER_FIELD_SCHEMA,
FLOAT_FIELD_SCHEMA,
GEOGRAPHY_FIELD_SCHEMA,
NUMERIC_FIELD_SCHEMA);
NUMERIC_FIELD_SCHEMA,
BIGNUMERIC_FIELD_SCHEMA);
private static final Schema SIMPLE_SCHEMA = Schema.of(STRING_FIELD_SCHEMA);
private static final Schema POLICY_SCHEMA =
Schema.of(STRING_FIELD_SCHEMA, STRING_FIELD_SCHEMA_WITH_POLICY, INTEGER_FIELD_SCHEMA);
Expand Down Expand Up @@ -283,7 +289,8 @@ public class ITBigQueryTest {
+ " \"IntegerField\": \"3\","
+ " \"FloatField\": \"1.2\","
+ " \"GeographyField\": \"POINT(-122.35022 47.649154)\","
+ " \"NumericField\": \"123456.789012345\""
+ " \"NumericField\": \"123456.789012345\","
+ " \"BigNumericField\": \"0.33333333333333333333333333333333333333\""
+ "}\n"
+ "{"
+ " \"TimestampField\": \"2014-08-19 07:41:35.220 -05:00\","
Expand All @@ -305,7 +312,8 @@ public class ITBigQueryTest {
+ " \"IntegerField\": \"3\","
+ " \"FloatField\": \"1.2\","
+ " \"GeographyField\": \"POINT(-122.35022 47.649154)\","
+ " \"NumericField\": \"123456.789012345\""
+ " \"NumericField\": \"123456.789012345\","
+ " \"BigNumericField\": \"0.33333333333333333333333333333333333333\""
+ "}";
private static final String KEY = "time_zone";
private static final String VALUE = "US/Eastern";
Expand Down Expand Up @@ -1477,7 +1485,8 @@ public void testPositionalQueryParameters() throws InterruptedException {
+ " AND IntegerField IN UNNEST(?)"
+ " AND IntegerField < ?"
+ " AND FloatField > ?"
+ " AND NumericField < ?";
+ " AND NumericField < ?"
+ " AND BigNumericField = ?";
QueryParameterValue stringParameter = QueryParameterValue.string("stringValue");
QueryParameterValue timestampParameter =
QueryParameterValue.timestamp("2014-01-01 07:00:00.000000+00:00");
Expand All @@ -1487,6 +1496,8 @@ public void testPositionalQueryParameters() throws InterruptedException {
QueryParameterValue float64Parameter = QueryParameterValue.float64(0.5);
QueryParameterValue numericParameter =
QueryParameterValue.numeric(new BigDecimal("234567890.123456"));
QueryParameterValue bigNumericParameter =
QueryParameterValue.bigNumeric(new BigDecimal("0.33333333333333333333333333333333333333"));
QueryJobConfiguration config =
QueryJobConfiguration.newBuilder(query)
.setDefaultDataset(DatasetId.of(DATASET))
Expand All @@ -1497,6 +1508,7 @@ public void testPositionalQueryParameters() throws InterruptedException {
.addPositionalParameter(int64Parameter)
.addPositionalParameter(float64Parameter)
.addPositionalParameter(numericParameter)
.addPositionalParameter(bigNumericParameter)
.build();
TableResult result = bigquery.query(config);
assertEquals(QUERY_RESULT_SCHEMA, result.getSchema());
Expand Down

0 comments on commit f021dde

Please sign in to comment.