diff --git a/google-cloud-bigquery/clirr-ignored-differences.xml b/google-cloud-bigquery/clirr-ignored-differences.xml
index 9c69fd6a68..b6546847fe 100644
--- a/google-cloud-bigquery/clirr-ignored-differences.xml
+++ b/google-cloud-bigquery/clirr-ignored-differences.xml
@@ -129,4 +129,9 @@
com/google/cloud/bigquery/StandardTableDefinition*
*BigLakeConfiguration(*)
+
+ 7013
+ com/google/cloud/bigquery/DatasetInfo*
+ *setMaxTimeTravelHours(*)
+
\ No newline at end of file
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java
index daadb9a857..4fc8577853 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java
@@ -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);
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java
index b5fabe97d1..f9b7f03e17 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java
@@ -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 {
@@ -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,
@@ -200,6 +207,7 @@ static final class BuilderImpl extends Builder {
private String defaultCollation;
private ExternalDatasetReference externalDatasetReference;
private String storageBillingModel;
+ private Long maxTimeTravelHours;
BuilderImpl() {}
@@ -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) {
@@ -260,6 +269,7 @@ public Acl apply(Dataset.Access accessPb) {
ExternalDatasetReference.fromPb(datasetPb.getExternalDatasetReference());
}
this.storageBillingModel = datasetPb.getStorageBillingModel();
+ this.maxTimeTravelHours = datasetPb.getMaxTimeTravelHours();
}
@Override
@@ -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);
@@ -396,6 +412,7 @@ public DatasetInfo build() {
defaultCollation = builder.defaultCollation;
externalDatasetReference = builder.externalDatasetReference;
storageBillingModel = builder.storageBillingModel;
+ maxTimeTravelHours = builder.maxTimeTravelHours;
}
/** Returns the dataset identity. */
@@ -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.
@@ -562,6 +587,7 @@ public String toString() {
.add("defaultCollation", defaultCollation)
.add("externalDatasetReference", externalDatasetReference)
.add("storageBillingModel", storageBillingModel)
+ .add("maxTimeTravelHours", maxTimeTravelHours)
.toString();
}
@@ -646,6 +672,9 @@ public Dataset.Access apply(Acl acl) {
if (storageBillingModel != null) {
datasetPb.setStorageBillingModel(storageBillingModel);
}
+ if (maxTimeTravelHours != null) {
+ datasetPb.setMaxTimeTravelHours(maxTimeTravelHours);
+ }
return datasetPb;
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java
index df62b7dac8..49a392baf7 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java
@@ -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;
@@ -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()
@@ -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
@@ -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() {
@@ -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
@@ -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());
@@ -212,6 +223,7 @@ public void testOf() {
assertTrue(datasetInfo.getLabels().isEmpty());
assertNull(datasetInfo.getExternalDatasetReference());
assertNull(datasetInfo.getStorageBillingModel());
+ assertNull(datasetInfo.getMaxTimeTravelHours());
}
@Test
@@ -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());
@@ -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());
}
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java
index bc42976b23..e2d7c635ce 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java
@@ -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");
@@ -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());
@@ -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
@@ -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,
@@ -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());
}
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
index b1cb8d8451..86ccd7c7d8 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
@@ -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 LABELS =
@@ -1214,6 +1216,7 @@ public void testGetDatasetWithSelectedFields() {
assertNull(dataset.getLocation());
assertNull(dataset.getSelfLink());
assertNull(dataset.getStorageBillingModel());
+ assertNull(dataset.getMaxTimeTravelHours());
}
@Test
@@ -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 updateLabels = new HashMap<>();
updateLabels.put("x", "y");
@@ -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();
@@ -1275,6 +1281,7 @@ public void testUpdateDatasetWithSelectedFields() {
assertNull(updatedDataset.getLocation());
assertNull(updatedDataset.getSelfLink());
assertNull(updatedDataset.getStorageBillingModel());
+ assertNull(updatedDataset.getMaxTimeTravelHours());
assertTrue(dataset.delete());
}
@@ -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();