Skip to content

Commit

Permalink
feat: Add decimal target type (#2166)
Browse files Browse the repository at this point in the history
* Add getDecimalTargetTypes and getDecimalTargetTypes

* Add getDecimalTargetTypes and getDecimalTargetTypes

* Modified unit test cases for DecimalTargetTypes

* Adding getDecimalTargetTypes and getDecimalTargetTypes as clirr exceptions. Removed previous exceptions

* Adding testInsertWithDecimalTargetTypes IT
  • Loading branch information
prash-mi committed Jul 20, 2022
1 parent c98d22b commit ebbd8f5
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 28 deletions.
30 changes: 5 additions & 25 deletions google-cloud-bigquery/clirr-ignored-differences.xml
Expand Up @@ -2,34 +2,14 @@
<!-- see http://www.mojohaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
<differences>
<!-- TODO: REMOVE AFTER RELEASE -->
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/bigquery/BigQuery</className>
<method>com.google.cloud.bigquery.Connection createConnection(com.google.cloud.bigquery.ConnectionSettings)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/bigquery/BigQuery</className>
<method>com.google.cloud.bigquery.Connection createConnection()</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/bigquery/spi/v2/BigQueryRpc</className>
<method>com.google.api.services.bigquery.model.Job createJobForQuery(com.google.api.services.bigquery.model.Job)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/bigquery/spi/v2/BigQueryRpc</className>
<method>com.google.api.services.bigquery.model.Job getQueryJob(java.lang.String, java.lang.String, java.lang.String)</method>
</difference>
<difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/bigquery/spi/v2/BigQueryRpc</className>
<method>com.google.api.services.bigquery.model.GetQueryResultsResponse getQueryResultsWithRowLimit(java.lang.String, java.lang.String, java.lang.String, java.lang.Integer)</method>
<className>com/google/cloud/bigquery/LoadConfiguration</className>
<method>java.util.List getDecimalTargetTypes()</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/bigquery/spi/v2/BigQueryRpc</className>
<method>com.google.api.services.bigquery.model.TableDataList listTableDataWithRowLimit(java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.String)</method>
<className>com/google/cloud/bigquery/LoadConfiguration$Builder</className>
<method>com.google.cloud.bigquery.LoadConfiguration$Builder setDecimalTargetTypes(java.util.List)</method>
</difference>
</differences>
Expand Up @@ -125,6 +125,17 @@ interface Builder {
*/
Builder setUseAvroLogicalTypes(Boolean useAvroLogicalTypes);

/**
* Defines the list of possible SQL data types to which the source decimal values are converted.
* This list and the precision and the scale parameters of the decimal field determine the
* target type. In the order of NUMERIC, BIGNUMERIC, and STRING, a type is picked if it is in
* the specified list and if it supports the precision and the scale. STRING supports all
* precision and scale values.
*
* @param decimalTargetTypes decimalTargetType or {@code null} for none
*/
Builder setDecimalTargetTypes(List<String> decimalTargetTypes);

LoadConfiguration build();
}

Expand Down Expand Up @@ -214,6 +225,15 @@ interface Builder {
/** Returns True/False. Indicates whether the logical type is interpreted. */
Boolean getUseAvroLogicalTypes();

/**
* Returns the list of possible SQL data types to which the source decimal values are converted.
* This list and the precision and the scale parameters of the decimal field determine the target
* type. In the order of NUMERIC, BIGNUMERIC, and STRING, a type is picked if it is in the
* specified list and if it supports the precision and the scale. STRING supports all precision
* and scale values.
*/
List<String> getDecimalTargetTypes();

/** Returns a builder for the load configuration object. */
Builder toBuilder();
}
Expand Up @@ -55,6 +55,7 @@ public final class WriteChannelConfiguration implements LoadConfiguration, Seria
private final Clustering clustering;
private final Boolean useAvroLogicalTypes;
private final Map<String, String> labels;
private List<String> decimalTargetTypes;

public static final class Builder implements LoadConfiguration.Builder {

Expand All @@ -73,6 +74,7 @@ public static final class Builder implements LoadConfiguration.Builder {
private Clustering clustering;
private Boolean useAvroLogicalTypes;
private Map<String, String> labels;
private List<String> decimalTargetTypes;

private Builder() {}

Expand All @@ -93,6 +95,7 @@ private Builder(WriteChannelConfiguration writeChannelConfiguration) {
this.clustering = writeChannelConfiguration.clustering;
this.useAvroLogicalTypes = writeChannelConfiguration.useAvroLogicalTypes;
this.labels = writeChannelConfiguration.labels;
this.decimalTargetTypes = writeChannelConfiguration.decimalTargetTypes;
}

private Builder(com.google.api.services.bigquery.model.JobConfiguration configurationPb) {
Expand Down Expand Up @@ -169,6 +172,9 @@ private Builder(com.google.api.services.bigquery.model.JobConfiguration configur
if (configurationPb.getLabels() != null) {
this.labels = configurationPb.getLabels();
}
if (loadConfigurationPb.getDecimalTargetTypes() != null) {
this.decimalTargetTypes = loadConfigurationPb.getDecimalTargetTypes();
}
}

@Override
Expand Down Expand Up @@ -262,6 +268,12 @@ public Builder setLabels(Map<String, String> labels) {
return this;
}

@Override
public Builder setDecimalTargetTypes(List<String> decimalTargetTypes) {
this.decimalTargetTypes = decimalTargetTypes;
return this;
}

@Override
public WriteChannelConfiguration build() {
return new WriteChannelConfiguration(this);
Expand All @@ -284,6 +296,7 @@ protected WriteChannelConfiguration(Builder builder) {
this.clustering = builder.clustering;
this.useAvroLogicalTypes = builder.useAvroLogicalTypes;
this.labels = builder.labels;
this.decimalTargetTypes = builder.decimalTargetTypes;
}

@Override
Expand Down Expand Up @@ -372,6 +385,11 @@ public Map<String, String> getLabels() {
return labels;
}

@Override
public List<String> getDecimalTargetTypes() {
return decimalTargetTypes;
}

@Override
public Builder toBuilder() {
return new Builder(this);
Expand All @@ -393,7 +411,8 @@ MoreObjects.ToStringHelper toStringHelper() {
.add("timePartitioning", timePartitioning)
.add("clustering", clustering)
.add("useAvroLogicalTypes", useAvroLogicalTypes)
.add("labels", labels);
.add("labels", labels)
.add("decimalTargetTypes", decimalTargetTypes);
}

@Override
Expand Down Expand Up @@ -424,7 +443,8 @@ public int hashCode() {
timePartitioning,
clustering,
useAvroLogicalTypes,
labels);
labels,
decimalTargetTypes);
}

WriteChannelConfiguration setProjectId(String projectId) {
Expand Down Expand Up @@ -495,6 +515,9 @@ com.google.api.services.bigquery.model.JobConfiguration toPb() {
if (labels != null) {
jobConfiguration.setLabels(labels);
}
if (decimalTargetTypes != null) {
loadConfigurationPb.setDecimalTargetTypes(decimalTargetTypes);
}
jobConfiguration.setLoad(loadConfigurationPb);
return jobConfiguration;
}
Expand Down
Expand Up @@ -59,6 +59,8 @@ public class WriteChannelConfigurationTest {
Clustering.newBuilder().setFields(ImmutableList.of("Foo", "Bar")).build();
private static final Map<String, String> LABELS =
ImmutableMap.of("test-job-name", "test-write-channel");
private static final List<String> DECIMAL_TARGET_TYPES =
ImmutableList.of("NUMERIC", "BIGNUMERIC");
private static final WriteChannelConfiguration LOAD_CONFIGURATION_CSV =
WriteChannelConfiguration.newBuilder(TABLE_ID)
.setCreateDisposition(CREATE_DISPOSITION)
Expand All @@ -73,6 +75,7 @@ public class WriteChannelConfigurationTest {
.setTimePartitioning(TIME_PARTITIONING)
.setClustering(CLUSTERING)
.setLabels(LABELS)
.setDecimalTargetTypes(DECIMAL_TARGET_TYPES)
.build();

private static final DatastoreBackupOptions BACKUP_OPTIONS =
Expand Down Expand Up @@ -104,6 +107,7 @@ public class WriteChannelConfigurationTest {
.setTimePartitioning(TIME_PARTITIONING)
.setClustering(CLUSTERING)
.setUseAvroLogicalTypes(USERAVROLOGICALTYPES)
.setDecimalTargetTypes(DECIMAL_TARGET_TYPES)
.build();

@Test
Expand Down Expand Up @@ -169,7 +173,8 @@ public void testBuilder() {
.setMaxBadRecords(MAX_BAD_RECORDS)
.setSchemaUpdateOptions(SCHEMA_UPDATE_OPTIONS)
.setSchema(TABLE_SCHEMA)
.setAutodetect(AUTODETECT);
.setAutodetect(AUTODETECT)
.setDecimalTargetTypes(DECIMAL_TARGET_TYPES);
WriteChannelConfiguration loadConfigurationCSV = builder.build();
assertEquals(TABLE_ID, loadConfigurationCSV.getDestinationTable());
assertEquals(CREATE_DISPOSITION, loadConfigurationCSV.getCreateDisposition());
Expand All @@ -182,6 +187,7 @@ public void testBuilder() {
assertEquals(TABLE_SCHEMA, loadConfigurationCSV.getSchema());
assertEquals(SCHEMA_UPDATE_OPTIONS, loadConfigurationCSV.getSchemaUpdateOptions());
assertEquals(AUTODETECT, loadConfigurationCSV.getAutodetect());
assertEquals(DECIMAL_TARGET_TYPES, loadConfigurationCSV.getDecimalTargetTypes());
builder.setFormatOptions(BACKUP_OPTIONS);
WriteChannelConfiguration loadConfigurationBackup = builder.build();
assertEquals(BACKUP_OPTIONS, loadConfigurationBackup.getDatastoreBackupOptions());
Expand Down Expand Up @@ -225,5 +231,6 @@ private void compareLoadConfiguration(
assertEquals(expected.getClustering(), value.getClustering());
assertEquals(expected.getUseAvroLogicalTypes(), value.getUseAvroLogicalTypes());
assertEquals(expected.getLabels(), value.getLabels());
assertEquals(expected.getDecimalTargetTypes(), value.getDecimalTargetTypes());
}
}
Expand Up @@ -4374,6 +4374,32 @@ public void testInsertFromFileWithLabels()
assertTrue(bigquery.delete(tableId));
}

@Test
public void testInsertWithDecimalTargetTypes()
throws InterruptedException, IOException, TimeoutException {
String destinationTableName = "test_insert_from_file_table_with_decimal_target_type";
TableId tableId = TableId.of(DATASET, destinationTableName);
WriteChannelConfiguration configuration =
WriteChannelConfiguration.newBuilder(tableId)
.setCreateDisposition(JobInfo.CreateDisposition.CREATE_IF_NEEDED)
.setAutodetect(true)
.setDecimalTargetTypes(ImmutableList.of("STRING", "NUMERIC", "BIGNUMERIC"))
.build();
TableDataWriteChannel channel = bigquery.writer(configuration);
try {
channel.write(ByteBuffer.wrap("foo".getBytes(StandardCharsets.UTF_8)));
} finally {
channel.close();
}
Job job = channel.getJob().waitFor();
LoadJobConfiguration jobConfiguration = job.getConfiguration();
assertNull(job.getStatus().getError());
assertEquals(
ImmutableList.of("STRING", "NUMERIC", "BIGNUMERIC"),
jobConfiguration.getDecimalTargetTypes());
assertTrue(bigquery.delete(tableId));
}

@Test
public void testLocation() throws Exception {
String location = "EU";
Expand Down

0 comments on commit ebbd8f5

Please sign in to comment.