Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b1fb57c

Browse files
authoredJun 25, 2021
feat: add support for parameterized type (#1390)
Fixes #1309
1 parent 95f1a6c commit b1fb57c

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed
 

‎google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Field.java

+88
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public TableFieldSchema apply(Field field) {
5959
private final String mode;
6060
private final String description;
6161
private final PolicyTags policyTags;
62+
private final Long maxLength;
63+
private final Long scale;
64+
private final Long precision;
6265

6366
/**
6467
* Mode for a BigQuery Table field. {@link Mode#NULLABLE} fields can be set to {@code null},
@@ -79,6 +82,9 @@ public static final class Builder {
7982
private String mode;
8083
private String description;
8184
private PolicyTags policyTags;
85+
private Long maxLength;
86+
private Long scale;
87+
private Long precision;
8288

8389
private Builder() {}
8490

@@ -89,6 +95,9 @@ private Builder(Field field) {
8995
this.mode = field.mode;
9096
this.description = field.description;
9197
this.policyTags = field.policyTags;
98+
this.maxLength = field.maxLength;
99+
this.scale = field.scale;
100+
this.precision = field.precision;
92101
}
93102

94103
/**
@@ -199,6 +208,43 @@ public Builder setPolicyTags(PolicyTags policyTags) {
199208
return this;
200209
}
201210

211+
/**
212+
* Sets the maximum length of the field for STRING or BYTES type.
213+
*
214+
* <p>It is invalid to set value for types other than STRING or BYTES.
215+
*
216+
* <p>For STRING type, this represents the maximum UTF-8 length of strings allowed in the field.
217+
* For BYTES type, this represents the maximum number of bytes in the field.
218+
*/
219+
public Builder setMaxLength(Long maxLength) {
220+
this.maxLength = maxLength;
221+
return this;
222+
}
223+
224+
/**
225+
* Scale can be used to constrain the maximum number of digits in the fractional part of a
226+
* NUMERIC or BIGNUMERIC type. If the Scale value is set, the Precision value must be set as
227+
* well. It is invalid to set values for Scale for types other than NUMERIC or BIGNUMERIC. See
228+
* the Precision field for additional guidance about valid values.
229+
*/
230+
public Builder setScale(Long scale) {
231+
this.scale = scale;
232+
return this;
233+
}
234+
235+
/**
236+
* Precision can be used to constrain the maximum number of total digits allowed for NUMERIC or
237+
* BIGNUMERIC types. It is invalid to set values for Precision for types other than // NUMERIC
238+
* or BIGNUMERIC. For NUMERIC type, acceptable values for Precision must be: 1 ≤ (Precision -
239+
* Scale) ≤ 29. Values for Scale must be: 0 ≤ Scale ≤ 9. For BIGNUMERIC type, acceptable values
240+
* for Precision must be: 1 ≤ (Precision - Scale) ≤ 38. Values for Scale must be: 0 ≤ Scale ≤
241+
* 38.
242+
*/
243+
public Builder setPrecision(Long precision) {
244+
this.precision = precision;
245+
return this;
246+
}
247+
202248
/** Creates a {@code Field} object. */
203249
public Field build() {
204250
return new Field(this);
@@ -212,6 +258,9 @@ private Field(Builder builder) {
212258
this.mode = builder.mode;
213259
this.description = builder.description;
214260
this.policyTags = builder.policyTags;
261+
this.maxLength = builder.maxLength;
262+
this.scale = builder.scale;
263+
this.precision = builder.precision;
215264
}
216265

217266
/** Returns the field name. */
@@ -244,6 +293,24 @@ public PolicyTags getPolicyTags() {
244293
return policyTags;
245294
}
246295

296+
/** Returns the maximum length of the field for STRING or BYTES type. */
297+
public Long getMaxLength() {
298+
return maxLength;
299+
}
300+
301+
/**
302+
* Returns the maximum number of digits set in the fractional part of a NUMERIC or BIGNUMERIC
303+
* type.
304+
*/
305+
public Long getScale() {
306+
return scale;
307+
}
308+
309+
/** Returns the maximum number of total digits allowed for NUMERIC or BIGNUMERIC types. */
310+
public Long getPrecision() {
311+
return precision;
312+
}
313+
247314
/**
248315
* Returns the list of sub-fields if {@link #getType()} is a {@link LegacySQLTypeName#RECORD}.
249316
* Returns {@code null} otherwise.
@@ -265,6 +332,9 @@ public String toString() {
265332
.add("mode", mode)
266333
.add("description", description)
267334
.add("policyTags", policyTags)
335+
.add("maxLength", maxLength)
336+
.add("scale", scale)
337+
.add("precision", precision)
268338
.toString();
269339
}
270340

@@ -335,6 +405,15 @@ TableFieldSchema toPb() {
335405
if (policyTags != null) {
336406
fieldSchemaPb.setPolicyTags(policyTags.toPb());
337407
}
408+
if (maxLength != null) {
409+
fieldSchemaPb.setMaxLength(maxLength);
410+
}
411+
if (scale != null) {
412+
fieldSchemaPb.setScale(scale);
413+
}
414+
if (precision != null) {
415+
fieldSchemaPb.setPrecision(precision);
416+
}
338417
if (getSubFields() != null) {
339418
List<TableFieldSchema> fieldsPb = Lists.transform(getSubFields(), TO_PB_FUNCTION);
340419
fieldSchemaPb.setFields(fieldsPb);
@@ -354,6 +433,15 @@ static Field fromPb(TableFieldSchema fieldSchemaPb) {
354433
if (fieldSchemaPb.getPolicyTags() != null) {
355434
fieldBuilder.setPolicyTags(PolicyTags.fromPb(fieldSchemaPb.getPolicyTags()));
356435
}
436+
if (fieldSchemaPb.getMaxLength() != null) {
437+
fieldBuilder.setMaxLength(fieldSchemaPb.getMaxLength());
438+
}
439+
if (fieldSchemaPb.getScale() != null) {
440+
fieldBuilder.setScale(fieldSchemaPb.getScale());
441+
}
442+
if (fieldSchemaPb.getPrecision() != null) {
443+
fieldBuilder.setPrecision(fieldSchemaPb.getPrecision());
444+
}
357445
FieldList subFields =
358446
fieldSchemaPb.getFields() != null
359447
? FieldList.of(Lists.transform(fieldSchemaPb.getFields(), FROM_PB_FUNCTION))

‎google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/SchemaTest.java

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public class SchemaTest {
3232
Field.newBuilder("StringField", LegacySQLTypeName.STRING)
3333
.setMode(Field.Mode.NULLABLE)
3434
.setDescription("FieldDescription1")
35+
.setPrecision(20L)
36+
.setScale(20L)
37+
.setMaxLength(10L)
3538
.build();
3639
private static final Field FIELD_SCHEMA2 =
3740
Field.newBuilder("IntegerField", LegacySQLTypeName.INTEGER)

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

+45
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
import com.google.cloud.bigquery.StandardSQLDataType;
9191
import com.google.cloud.bigquery.StandardSQLField;
9292
import com.google.cloud.bigquery.StandardSQLTableType;
93+
import com.google.cloud.bigquery.StandardSQLTypeName;
9394
import com.google.cloud.bigquery.StandardTableDefinition;
9495
import com.google.cloud.bigquery.Table;
9596
import com.google.cloud.bigquery.TableDataWriteChannel;
@@ -703,6 +704,50 @@ public void testCreateTableWithRangePartitioning() {
703704
}
704705
}
705706

707+
@Test
708+
public void testCreateTableWithConstraints() {
709+
String tableName = "test_create_table_with_constraints";
710+
TableId tableId = TableId.of(DATASET, tableName);
711+
Field stringFieldWithConstraint =
712+
Field.newBuilder("stringFieldWithConstraint", StandardSQLTypeName.STRING)
713+
.setMode(Field.Mode.NULLABLE)
714+
.setDescription("field has a constraint")
715+
.setMaxLength(10L)
716+
.build();
717+
Field byteFieldWithConstraint =
718+
Field.newBuilder("byteFieldWithConstraint", StandardSQLTypeName.BYTES)
719+
.setMode(Field.Mode.NULLABLE)
720+
.setDescription("field has a constraint")
721+
.setMaxLength(150L)
722+
.build();
723+
Field numericFieldWithConstraint =
724+
Field.newBuilder("numericFieldWithConstraint", StandardSQLTypeName.NUMERIC)
725+
.setMode(Field.Mode.NULLABLE)
726+
.setDescription("field has a constraint")
727+
.setPrecision(20L)
728+
.build();
729+
Field bigNumericFieldWithConstraint =
730+
Field.newBuilder("bigNumericFieldWithConstraint", StandardSQLTypeName.BIGNUMERIC)
731+
.setMode(Field.Mode.NULLABLE)
732+
.setDescription("field has a constraint")
733+
.setPrecision(30L)
734+
.setScale(5L)
735+
.build();
736+
Schema schema =
737+
Schema.of(
738+
stringFieldWithConstraint,
739+
byteFieldWithConstraint,
740+
numericFieldWithConstraint,
741+
bigNumericFieldWithConstraint);
742+
StandardTableDefinition tableDefinition =
743+
StandardTableDefinition.newBuilder().setSchema(schema).build();
744+
Table createdTable = bigquery.create(TableInfo.of(tableId, tableDefinition));
745+
assertNotNull(createdTable);
746+
Table remoteTable = bigquery.getTable(DATASET, tableName);
747+
assertEquals(schema, remoteTable.<StandardTableDefinition>getDefinition().getSchema());
748+
bigquery.delete(tableId);
749+
}
750+
706751
@Test
707752
public void testCreateAndUpdateTableWithPolicyTags() throws IOException {
708753
// Set up policy tags in the datacatalog service

0 commit comments

Comments
 (0)
Failed to load comments.