Skip to content

Commit f021dde

Browse files
feat: add BIGNUMERIC support
update IT testcase nit
1 parent 127414c commit f021dde

File tree

7 files changed

+80
-12
lines changed

7 files changed

+80
-12
lines changed

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public LegacySQLTypeName apply(String constant) {
6161
*/
6262
public static final LegacySQLTypeName NUMERIC =
6363
type.createAndRegister("NUMERIC").setStandardType(StandardSQLTypeName.NUMERIC);
64+
/** A decimal value with 38 digits of precision and 38 digits of scale. */
65+
public static final LegacySQLTypeName BIGNUMERIC =
66+
type.createAndRegister("BIGNUMERIC").setStandardType(StandardSQLTypeName.BIGNUMERIC);
6467
/** A Boolean value (true or false). */
6568
public static final LegacySQLTypeName BOOLEAN =
6669
type.createAndRegister("BOOLEAN").setStandardType(StandardSQLTypeName.BOOL);

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
* <li>Double: StandardSQLTypeName.FLOAT64
6161
* <li>Float: StandardSQLTypeName.FLOAT64
6262
* <li>BigDecimal: StandardSQLTypeName.NUMERIC
63+
* <li>BigNumeric: StandardSQLTypeName.BIGNUMERIC
6364
* </ul>
6465
*
6566
* <p>No other types are supported through that entry point. The other types can be created by
@@ -197,7 +198,10 @@ public Map<String, QueryParameterValue> getStructTypes() {
197198
@Nullable
198199
abstract Map<String, QueryParameterValue> getStructTypesInner();
199200

200-
/** Creates a {@code QueryParameterValue} object with the given value and type. */
201+
/**
202+
* Creates a {@code QueryParameterValue} object with the given value and type. Note: this does not
203+
* support BigNumeric
204+
*/
201205
public static <T> QueryParameterValue of(T value, Class<T> type) {
202206
return of(value, classToType(type));
203207
}
@@ -240,6 +244,11 @@ public static QueryParameterValue numeric(BigDecimal value) {
240244
return of(value, StandardSQLTypeName.NUMERIC);
241245
}
242246

247+
/** Creates a {@code QueryParameterValue} object with a type of BIGNUMERIC. */
248+
public static QueryParameterValue bigNumeric(BigDecimal value) {
249+
return of(value, StandardSQLTypeName.BIGNUMERIC);
250+
}
251+
243252
/** Creates a {@code QueryParameterValue} object with a type of STRING. */
244253
public static QueryParameterValue string(String value) {
245254
return of(value, StandardSQLTypeName.STRING);
@@ -363,6 +372,7 @@ private static <T> String valueToStringOrNull(T value, StandardSQLTypeName type)
363372
}
364373
break;
365374
case NUMERIC:
375+
case BIGNUMERIC:
366376
if (value instanceof BigDecimal) {
367377
return value.toString();
368378
}

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public enum StandardSQLTypeName {
3232
FLOAT64,
3333
/** A decimal value with 38 digits of precision and 9 digits of scale. */
3434
NUMERIC,
35+
/** A decimal value with 38 digits of precision and 38 digits of scale. */
36+
BIGNUMERIC,
3537
/** Variable-length character (Unicode) data. */
3638
STRING,
3739
/** Variable-length binary data. */

google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueListTest.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ public class FieldValueListTest {
4949
LegacySQLTypeName.RECORD,
5050
Field.of("first", LegacySQLTypeName.FLOAT),
5151
Field.of("second", LegacySQLTypeName.TIMESTAMP)),
52-
Field.of("tenth", LegacySQLTypeName.NUMERIC));
52+
Field.of("tenth", LegacySQLTypeName.NUMERIC),
53+
Field.of("eleventh", LegacySQLTypeName.BIGNUMERIC));
5354

5455
private final Map<String, String> integerPb = ImmutableMap.of("v", "1");
5556
private final Map<String, String> floatPb = ImmutableMap.of("v", "1.5");
@@ -62,6 +63,9 @@ public class FieldValueListTest {
6263
private final Map<String, Object> recordPb =
6364
ImmutableMap.<String, Object>of("f", ImmutableList.<Object>of(floatPb, timestampPb));
6465
private final Map<String, String> numericPb = ImmutableMap.of("v", "123456789.123456789");
66+
private final Map<String, String> bigNumericPb =
67+
ImmutableMap.of(
68+
"v", "99999999999999999999999999999999999999.99999999999999999999999999999999999999");
6569

6670
private final FieldValue booleanFv = FieldValue.of(Attribute.PRIMITIVE, "false");
6771
private final FieldValue integerFv = FieldValue.of(Attribute.PRIMITIVE, "1");
@@ -78,6 +82,10 @@ public class FieldValueListTest {
7882
FieldValueList.of(
7983
ImmutableList.of(floatFv, timestampFv), schema.get("ninth").getSubFields()));
8084
private final FieldValue numericFv = FieldValue.of(Attribute.PRIMITIVE, "123456789.123456789");
85+
private final FieldValue bigNumericFv =
86+
FieldValue.of(
87+
Attribute.PRIMITIVE,
88+
"99999999999999999999999999999999999999.99999999999999999999999999999999999999");
8189

8290
private final List<?> fieldValuesPb =
8391
ImmutableList.of(
@@ -90,7 +98,8 @@ public class FieldValueListTest {
9098
nullPb,
9199
repeatedPb,
92100
recordPb,
93-
numericPb);
101+
numericPb,
102+
bigNumericPb);
94103

95104
private final FieldValueList fieldValues =
96105
FieldValueList.of(
@@ -104,7 +113,8 @@ public class FieldValueListTest {
104113
nullFv,
105114
repeatedFv,
106115
recordFv,
107-
numericFv),
116+
numericFv,
117+
bigNumericFv),
108118
schema);
109119

110120
@Test
@@ -116,7 +126,7 @@ public void testFromPb() {
116126

117127
@Test
118128
public void testGetByIndex() {
119-
assertEquals(10, fieldValues.size());
129+
assertEquals(11, fieldValues.size());
120130
assertEquals(booleanFv, fieldValues.get(0));
121131
assertEquals(integerFv, fieldValues.get(1));
122132
assertEquals(floatFv, fieldValues.get(2));
@@ -133,11 +143,12 @@ public void testGetByIndex() {
133143
assertEquals(floatFv, fieldValues.get(8).getRecordValue().get(0));
134144
assertEquals(timestampFv, fieldValues.get(8).getRecordValue().get(1));
135145
assertEquals(numericFv, fieldValues.get(9));
146+
assertEquals(bigNumericFv, fieldValues.get(10));
136147
}
137148

138149
@Test
139150
public void testGetByName() {
140-
assertEquals(10, fieldValues.size());
151+
assertEquals(11, fieldValues.size());
141152
assertEquals(booleanFv, fieldValues.get("first"));
142153
assertEquals(integerFv, fieldValues.get("second"));
143154
assertEquals(floatFv, fieldValues.get("third"));
@@ -154,6 +165,7 @@ public void testGetByName() {
154165
assertEquals(floatFv, fieldValues.get("ninth").getRecordValue().get("first"));
155166
assertEquals(timestampFv, fieldValues.get("ninth").getRecordValue().get("second"));
156167
assertEquals(numericFv, fieldValues.get("tenth"));
168+
assertEquals(bigNumericFv, fieldValues.get("eleventh"));
157169
}
158170

159171
@Test
@@ -170,7 +182,8 @@ public void testNullSchema() {
170182
nullFv,
171183
repeatedFv,
172184
recordFv,
173-
numericFv));
185+
numericFv,
186+
bigNumericFv));
174187

175188
assertEquals(fieldValues, fieldValuesNoSchema);
176189

google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.cloud.bigquery.TimePartitioning.Type;
2828
import com.google.common.collect.ImmutableList;
2929
import com.google.common.collect.ImmutableMap;
30+
import java.math.BigDecimal;
3031
import java.util.List;
3132
import java.util.Map;
3233
import org.junit.Test;
@@ -101,8 +102,10 @@ public class QueryJobConfigurationTest {
101102
QueryParameterValue.string("stringValue");
102103
private static final QueryParameterValue TIMESTAMP_PARAMETER =
103104
QueryParameterValue.timestamp("2014-01-01 07:00:00.000000+00:00");
105+
private static final QueryParameterValue BIGNUMERIC_PARAMETER =
106+
QueryParameterValue.bigNumeric(new BigDecimal(1 / 3));
104107
private static final List<QueryParameterValue> POSITIONAL_PARAMETER =
105-
ImmutableList.of(STRING_PARAMETER, TIMESTAMP_PARAMETER);
108+
ImmutableList.of(STRING_PARAMETER, TIMESTAMP_PARAMETER, BIGNUMERIC_PARAMETER);
106109
private static final Map<String, QueryParameterValue> NAME_PARAMETER =
107110
ImmutableMap.of("string", STRING_PARAMETER, "timestamp", TIMESTAMP_PARAMETER);
108111
private static final QueryJobConfiguration QUERY_JOB_CONFIGURATION =

google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,31 @@ public void testNumeric() {
141141
assertThat(value.getArrayValues()).isNull();
142142
}
143143

144+
@Test
145+
public void testBigNumeric() {
146+
QueryParameterValue value =
147+
QueryParameterValue.bigNumeric(new BigDecimal("0.33333333333333333333333333333333333333"));
148+
QueryParameterValue value1 =
149+
QueryParameterValue.bigNumeric(new BigDecimal("0.50000000000000000000000000000000000000"));
150+
QueryParameterValue value2 =
151+
QueryParameterValue.bigNumeric(new BigDecimal("0.00000000500000000000000000000000000000"));
152+
QueryParameterValue value3 =
153+
QueryParameterValue.bigNumeric(new BigDecimal("-0.00000000500000000000000000000000000000"));
154+
QueryParameterValue value4 =
155+
QueryParameterValue.bigNumeric(
156+
new BigDecimal("0.33333333333333333333333333333333333333888888888888888"));
157+
158+
assertThat(value.getValue()).isEqualTo("0.33333333333333333333333333333333333333");
159+
assertThat(value1.getValue()).isEqualTo("0.50000000000000000000000000000000000000");
160+
assertThat(value2.getValue()).isEqualTo("5.00000000000000000000000000000E-9");
161+
assertThat(value3.getValue()).isEqualTo("-5.00000000000000000000000000000E-9");
162+
assertThat(value4.getValue())
163+
.isEqualTo("0.33333333333333333333333333333333333333888888888888888");
164+
assertThat(value.getType()).isEqualTo(StandardSQLTypeName.BIGNUMERIC);
165+
assertThat(value.getArrayType()).isNull();
166+
assertThat(value.getArrayValues()).isNull();
167+
}
168+
144169
@Test
145170
public void testString() {
146171
QueryParameterValue value = QueryParameterValue.string("foo");

google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ public class ITBigQueryTest {
208208
.setMode(Field.Mode.NULLABLE)
209209
.setDescription("NumericDescription")
210210
.build();
211+
private static final Field BIGNUMERIC_FIELD_SCHEMA =
212+
Field.newBuilder("BigNumericField", LegacySQLTypeName.BIGNUMERIC)
213+
.setMode(Field.Mode.NULLABLE)
214+
.setDescription("BigNumericDescription")
215+
.build();
211216
private static final Field STRING_FIELD_SCHEMA_WITH_POLICY =
212217
Field.newBuilder("StringFieldWithPolicy", LegacySQLTypeName.STRING)
213218
.setMode(Field.Mode.NULLABLE)
@@ -225,7 +230,8 @@ public class ITBigQueryTest {
225230
INTEGER_FIELD_SCHEMA,
226231
FLOAT_FIELD_SCHEMA,
227232
GEOGRAPHY_FIELD_SCHEMA,
228-
NUMERIC_FIELD_SCHEMA);
233+
NUMERIC_FIELD_SCHEMA,
234+
BIGNUMERIC_FIELD_SCHEMA);
229235
private static final Schema SIMPLE_SCHEMA = Schema.of(STRING_FIELD_SCHEMA);
230236
private static final Schema POLICY_SCHEMA =
231237
Schema.of(STRING_FIELD_SCHEMA, STRING_FIELD_SCHEMA_WITH_POLICY, INTEGER_FIELD_SCHEMA);
@@ -283,7 +289,8 @@ public class ITBigQueryTest {
283289
+ " \"IntegerField\": \"3\","
284290
+ " \"FloatField\": \"1.2\","
285291
+ " \"GeographyField\": \"POINT(-122.35022 47.649154)\","
286-
+ " \"NumericField\": \"123456.789012345\""
292+
+ " \"NumericField\": \"123456.789012345\","
293+
+ " \"BigNumericField\": \"0.33333333333333333333333333333333333333\""
287294
+ "}\n"
288295
+ "{"
289296
+ " \"TimestampField\": \"2014-08-19 07:41:35.220 -05:00\","
@@ -305,7 +312,8 @@ public class ITBigQueryTest {
305312
+ " \"IntegerField\": \"3\","
306313
+ " \"FloatField\": \"1.2\","
307314
+ " \"GeographyField\": \"POINT(-122.35022 47.649154)\","
308-
+ " \"NumericField\": \"123456.789012345\""
315+
+ " \"NumericField\": \"123456.789012345\","
316+
+ " \"BigNumericField\": \"0.33333333333333333333333333333333333333\""
309317
+ "}";
310318
private static final String KEY = "time_zone";
311319
private static final String VALUE = "US/Eastern";
@@ -1477,7 +1485,8 @@ public void testPositionalQueryParameters() throws InterruptedException {
14771485
+ " AND IntegerField IN UNNEST(?)"
14781486
+ " AND IntegerField < ?"
14791487
+ " AND FloatField > ?"
1480-
+ " AND NumericField < ?";
1488+
+ " AND NumericField < ?"
1489+
+ " AND BigNumericField = ?";
14811490
QueryParameterValue stringParameter = QueryParameterValue.string("stringValue");
14821491
QueryParameterValue timestampParameter =
14831492
QueryParameterValue.timestamp("2014-01-01 07:00:00.000000+00:00");
@@ -1487,6 +1496,8 @@ public void testPositionalQueryParameters() throws InterruptedException {
14871496
QueryParameterValue float64Parameter = QueryParameterValue.float64(0.5);
14881497
QueryParameterValue numericParameter =
14891498
QueryParameterValue.numeric(new BigDecimal("234567890.123456"));
1499+
QueryParameterValue bigNumericParameter =
1500+
QueryParameterValue.bigNumeric(new BigDecimal("0.33333333333333333333333333333333333333"));
14901501
QueryJobConfiguration config =
14911502
QueryJobConfiguration.newBuilder(query)
14921503
.setDefaultDataset(DatasetId.of(DATASET))
@@ -1497,6 +1508,7 @@ public void testPositionalQueryParameters() throws InterruptedException {
14971508
.addPositionalParameter(int64Parameter)
14981509
.addPositionalParameter(float64Parameter)
14991510
.addPositionalParameter(numericParameter)
1511+
.addPositionalParameter(bigNumericParameter)
15001512
.build();
15011513
TableResult result = bigquery.query(config);
15021514
assertEquals(QUERY_RESULT_SCHEMA, result.getSchema());

0 commit comments

Comments
 (0)