Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enable maxTimeTravelHours in BigQuery java client library #3555

Merged
merged 3 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions google-cloud-bigquery/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,9 @@
<className>com/google/cloud/bigquery/StandardTableDefinition*</className>
<method>*BigLakeConfiguration(*)</method>
</difference>
<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/bigquery/DatasetInfo*</className>
<method>*setMaxTimeTravelHours(*)</method>
</difference>
</differences>
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ public Builder setStorageBillingModel(String storageBillingModel) {
return this;
}

@Override
public Builder setMaxTimeTravelHours(Long maxTimeTravelHours) {
infoBuilder.setMaxTimeTravelHours(maxTimeTravelHours);
return this;
}

@Override
public Dataset build() {
return new Dataset(bigquery, infoBuilder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public Dataset apply(DatasetInfo datasetInfo) {
private final String defaultCollation;
private final ExternalDatasetReference externalDatasetReference;
private final String storageBillingModel;
private final Long maxTimeTravelHours;

/** A builder for {@code DatasetInfo} objects. */
public abstract static class Builder {
Expand Down Expand Up @@ -142,6 +143,12 @@ public abstract Builder setExternalDatasetReference(
*/
public abstract Builder setStorageBillingModel(String storageBillingModel);

/**
* Optional. Defines the time travel window in hours. The value can be from 48 to 168 hours (2
* to 7 days). The default value is 168 hours if this is not set. The value may be {@code null}.
*/
public abstract Builder setMaxTimeTravelHours(Long maxTimeTravelHours);

/**
* The default encryption key for all tables in the dataset. Once this property is set, all
* newly-created partitioned tables in the dataset will have encryption key set to this value,
Expand Down Expand Up @@ -200,6 +207,7 @@ static final class BuilderImpl extends Builder {
private String defaultCollation;
private ExternalDatasetReference externalDatasetReference;
private String storageBillingModel;
private Long maxTimeTravelHours;

BuilderImpl() {}

Expand All @@ -221,6 +229,7 @@ static final class BuilderImpl extends Builder {
this.defaultCollation = datasetInfo.defaultCollation;
this.externalDatasetReference = datasetInfo.externalDatasetReference;
this.storageBillingModel = datasetInfo.storageBillingModel;
this.maxTimeTravelHours = datasetInfo.maxTimeTravelHours;
}

BuilderImpl(com.google.api.services.bigquery.model.Dataset datasetPb) {
Expand Down Expand Up @@ -260,6 +269,7 @@ public Acl apply(Dataset.Access accessPb) {
ExternalDatasetReference.fromPb(datasetPb.getExternalDatasetReference());
}
this.storageBillingModel = datasetPb.getStorageBillingModel();
this.maxTimeTravelHours = datasetPb.getMaxTimeTravelHours();
}

@Override
Expand Down Expand Up @@ -372,6 +382,12 @@ public Builder setStorageBillingModel(String storageBillingModel) {
return this;
}

@Override
public Builder setMaxTimeTravelHours(Long maxTimeTravelHours) {
this.maxTimeTravelHours = maxTimeTravelHours;
return this;
}

@Override
public DatasetInfo build() {
return new DatasetInfo(this);
Expand All @@ -396,6 +412,7 @@ public DatasetInfo build() {
defaultCollation = builder.defaultCollation;
externalDatasetReference = builder.externalDatasetReference;
storageBillingModel = builder.storageBillingModel;
maxTimeTravelHours = builder.maxTimeTravelHours;
}

/** Returns the dataset identity. */
Expand Down Expand Up @@ -529,6 +546,14 @@ public String getStorageBillingModel() {
return storageBillingModel;
}

/**
* Returns the number of hours that deleted or updated data will be available to be queried for
* all tables in the dataset.
*/
public Long getMaxTimeTravelHours() {
return maxTimeTravelHours;
}

/**
* Returns information about the external metadata storage where the dataset is defined. Filled
* out when the dataset type is EXTERNAL.
Expand Down Expand Up @@ -562,6 +587,7 @@ public String toString() {
.add("defaultCollation", defaultCollation)
.add("externalDatasetReference", externalDatasetReference)
.add("storageBillingModel", storageBillingModel)
.add("maxTimeTravelHours", maxTimeTravelHours)
.toString();
}

Expand Down Expand Up @@ -646,6 +672,9 @@ public Dataset.Access apply(Acl acl) {
if (storageBillingModel != null) {
datasetPb.setStorageBillingModel(storageBillingModel);
}
if (maxTimeTravelHours != null) {
datasetPb.setMaxTimeTravelHours(maxTimeTravelHours);
}
return datasetPb;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.cloud.bigquery;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

Expand Down Expand Up @@ -59,6 +60,8 @@ public class DatasetInfoTest {
private static final EncryptionConfiguration DATASET_ENCRYPTION_CONFIGURATION =
EncryptionConfiguration.newBuilder().setKmsKeyName("KMS_KEY_1").build();
private static final String STORAGE_BILLING_MODEL = "LOGICAL";
private static final Long MAX_TIME_TRAVEL_HOURS_5_DAYS = 120L;
private static final Long MAX_TIME_TRAVEL_HOURS_7_DAYS = 168L;

private static final ExternalDatasetReference EXTERNAL_DATASET_REFERENCE =
ExternalDatasetReference.newBuilder()
Expand All @@ -81,6 +84,7 @@ public class DatasetInfoTest {
.setDefaultEncryptionConfiguration(DATASET_ENCRYPTION_CONFIGURATION)
.setDefaultPartitionExpirationMs(DEFAULT_PARTITION__EXPIRATION)
.setStorageBillingModel(STORAGE_BILLING_MODEL)
.setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS_7_DAYS)
.build();
private static final DatasetInfo DATASET_INFO_COMPLETE =
DATASET_INFO
Expand All @@ -92,6 +96,8 @@ public class DatasetInfoTest {
DATASET_INFO.toBuilder().setAcl(ACCESS_RULES_IAM_MEMBER).build();
private static final DatasetInfo DATASET_INFO_COMPLETE_WITH_EXTERNAL_DATASET_REFERENCE =
DATASET_INFO.toBuilder().setExternalDatasetReference(EXTERNAL_DATASET_REFERENCE).build();
private static final DatasetInfo DATASET_INFO_WITH_MAX_TIME_TRAVEL_5_DAYS =
DATASET_INFO.toBuilder().setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS_5_DAYS).build();

@Test
public void testToBuilder() {
Expand Down Expand Up @@ -173,6 +179,10 @@ public void testBuilder() {
EXTERNAL_DATASET_REFERENCE,
DATASET_INFO_COMPLETE_WITH_EXTERNAL_DATASET_REFERENCE.getExternalDatasetReference());
assertEquals(STORAGE_BILLING_MODEL, DATASET_INFO_COMPLETE.getStorageBillingModel());
assertEquals(MAX_TIME_TRAVEL_HOURS_7_DAYS, DATASET_INFO.getMaxTimeTravelHours());
assertEquals(
MAX_TIME_TRAVEL_HOURS_5_DAYS,
DATASET_INFO_WITH_MAX_TIME_TRAVEL_5_DAYS.getMaxTimeTravelHours());
}

@Test
Expand All @@ -194,6 +204,7 @@ public void testOf() {
assertTrue(datasetInfo.getLabels().isEmpty());
assertNull(datasetInfo.getExternalDatasetReference());
assertNull(datasetInfo.getStorageBillingModel());
assertNull(datasetInfo.getMaxTimeTravelHours());

datasetInfo = DatasetInfo.of(DATASET_ID);
assertEquals(DATASET_ID, datasetInfo.getDatasetId());
Expand All @@ -212,6 +223,7 @@ public void testOf() {
assertTrue(datasetInfo.getLabels().isEmpty());
assertNull(datasetInfo.getExternalDatasetReference());
assertNull(datasetInfo.getStorageBillingModel());
assertNull(datasetInfo.getMaxTimeTravelHours());
}

@Test
Expand All @@ -229,6 +241,16 @@ public void testSetProjectId() {
assertEquals(DATASET_INFO_COMPLETE, DATASET_INFO.setProjectId("project"));
}

@Test
public void testSetMaxTimeTravelHours() {
assertNotEquals(
DATASET_INFO_WITH_MAX_TIME_TRAVEL_5_DAYS.getMaxTimeTravelHours(),
DATASET_INFO.getMaxTimeTravelHours());
assertEquals(
DATASET_INFO_WITH_MAX_TIME_TRAVEL_5_DAYS,
DATASET_INFO.toBuilder().setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS_5_DAYS).build());
}

private void compareDatasets(DatasetInfo expected, DatasetInfo value) {
assertEquals(expected, value);
assertEquals(expected.getDatasetId(), value.getDatasetId());
Expand All @@ -249,5 +271,6 @@ private void compareDatasets(DatasetInfo expected, DatasetInfo value) {
expected.getDefaultPartitionExpirationMs(), value.getDefaultPartitionExpirationMs());
assertEquals(expected.getExternalDatasetReference(), value.getExternalDatasetReference());
assertEquals(expected.getStorageBillingModel(), value.getStorageBillingModel());
assertEquals(expected.getMaxTimeTravelHours(), value.getMaxTimeTravelHours());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class DatasetTest {
private static final DatasetInfo DATASET_INFO = DatasetInfo.newBuilder(DATASET_ID).build();
private static final Field FIELD = Field.of("FieldName", LegacySQLTypeName.INTEGER);
private static final String STORAGE_BILLING_MODEL = "LOGICAL";
private static final Long MAX_TIME_TRAVEL_HOURS = 168L;
private static final StandardTableDefinition TABLE_DEFINITION =
StandardTableDefinition.of(Schema.of(FIELD));
private static final ViewDefinition VIEW_DEFINITION = ViewDefinition.of("QUERY");
Expand Down Expand Up @@ -122,6 +123,7 @@ public void testBuilder() {
.setSelfLink(SELF_LINK)
.setLabels(LABELS)
.setStorageBillingModel(STORAGE_BILLING_MODEL)
.setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS)
.build();
assertEquals(DATASET_ID, builtDataset.getDatasetId());
assertEquals(ACCESS_RULES, builtDataset.getAcl());
Expand All @@ -136,6 +138,7 @@ public void testBuilder() {
assertEquals(SELF_LINK, builtDataset.getSelfLink());
assertEquals(LABELS, builtDataset.getLabels());
assertEquals(STORAGE_BILLING_MODEL, builtDataset.getStorageBillingModel());
assertEquals(MAX_TIME_TRAVEL_HOURS, builtDataset.getMaxTimeTravelHours());
}

@Test
Expand Down Expand Up @@ -344,6 +347,7 @@ public void testExternalDatasetReference() {
.setLabels(LABELS)
.setExternalDatasetReference(EXTERNAL_DATASET_REFERENCE)
.setStorageBillingModel(STORAGE_BILLING_MODEL)
.setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS)
.build();
assertEquals(
EXTERNAL_DATASET_REFERENCE,
Expand Down Expand Up @@ -374,5 +378,6 @@ private void compareDatasetInfo(DatasetInfo expected, DatasetInfo value) {
assertEquals(expected.getLastModified(), value.getLastModified());
assertEquals(expected.getExternalDatasetReference(), value.getExternalDatasetReference());
assertEquals(expected.getStorageBillingModel(), value.getStorageBillingModel());
assertEquals(expected.getMaxTimeTravelHours(), value.getMaxTimeTravelHours());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ public class ITBigQueryTest {
private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId();
private static final String RANDOM_ID = UUID.randomUUID().toString().substring(0, 8);
private static final String STORAGE_BILLING_MODEL = "LOGICAL";
private static final Long MAX_TIME_TRAVEL_HOURS = 120L;
private static final Long MAX_TIME_TRAVEL_HOURS_DEFAULT = 168L;
private static final String CLOUD_SAMPLES_DATA =
Optional.fromNullable(System.getenv("CLOUD_SAMPLES_DATA_BUCKET")).or("cloud-samples-data");
private static final Map<String, String> LABELS =
Expand Down Expand Up @@ -1214,6 +1216,7 @@ public void testGetDatasetWithSelectedFields() {
assertNull(dataset.getLocation());
assertNull(dataset.getSelfLink());
assertNull(dataset.getStorageBillingModel());
assertNull(dataset.getMaxTimeTravelHours());
}

@Test
Expand All @@ -1230,6 +1233,7 @@ public void testUpdateDataset() {
assertThat(dataset.getDescription()).isEqualTo("Some Description");
assertThat(dataset.getLabels()).containsExactly("a", "b");
assertThat(dataset.getStorageBillingModel()).isNull();
assertThat(dataset.getMaxTimeTravelHours()).isNull();

Map<String, String> updateLabels = new HashMap<>();
updateLabels.put("x", "y");
Expand All @@ -1241,10 +1245,12 @@ public void testUpdateDataset() {
.setDescription("Updated Description")
.setLabels(updateLabels)
.setStorageBillingModel("LOGICAL")
.setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS)
.build());
assertThat(updatedDataset.getDescription()).isEqualTo("Updated Description");
assertThat(updatedDataset.getLabels()).containsExactly("x", "y");
assertThat(updatedDataset.getStorageBillingModel()).isEqualTo("LOGICAL");
assertThat(updatedDataset.getMaxTimeTravelHours()).isEqualTo(MAX_TIME_TRAVEL_HOURS);

updatedDataset = bigquery.update(updatedDataset.toBuilder().setLabels(null).build());
assertThat(updatedDataset.getLabels()).isEmpty();
Expand Down Expand Up @@ -1275,6 +1281,7 @@ public void testUpdateDatasetWithSelectedFields() {
assertNull(updatedDataset.getLocation());
assertNull(updatedDataset.getSelfLink());
assertNull(updatedDataset.getStorageBillingModel());
assertNull(updatedDataset.getMaxTimeTravelHours());
assertTrue(dataset.delete());
}

Expand Down Expand Up @@ -1630,6 +1637,40 @@ public void testCreateDatasetWithSpecifiedStorageBillingModel() {
RemoteBigQueryHelper.forceDelete(bigquery, billingModelDataset);
}

@Test
public void testCreateDatasetWithSpecificMaxTimeTravelHours() {
String timeTravelDataset = RemoteBigQueryHelper.generateDatasetName();
DatasetInfo info =
DatasetInfo.newBuilder(timeTravelDataset)
.setDescription(DESCRIPTION)
.setMaxTimeTravelHours(MAX_TIME_TRAVEL_HOURS)
.setLabels(LABELS)
.build();
bigquery.create(info);

Dataset dataset = bigquery.getDataset(DatasetId.of(timeTravelDataset));
assertEquals(MAX_TIME_TRAVEL_HOURS, dataset.getMaxTimeTravelHours());

RemoteBigQueryHelper.forceDelete(bigquery, timeTravelDataset);
}

@Test
public void testCreateDatasetWithDefaultMaxTimeTravelHours() {
String timeTravelDataset = RemoteBigQueryHelper.generateDatasetName();
DatasetInfo info =
DatasetInfo.newBuilder(timeTravelDataset)
.setDescription(DESCRIPTION)
.setLabels(LABELS)
.build();
bigquery.create(info);

Dataset dataset = bigquery.getDataset(DatasetId.of(timeTravelDataset));
// In the backend, BigQuery sets the default Time Travel Window to be 168 hours (7 days).
assertEquals(MAX_TIME_TRAVEL_HOURS_DEFAULT, dataset.getMaxTimeTravelHours());

RemoteBigQueryHelper.forceDelete(bigquery, timeTravelDataset);
}

@Test
public void testCreateDatasetWithDefaultCollation() {
String collationDataset = RemoteBigQueryHelper.generateDatasetName();
Expand Down
Loading