Skip to content

Commit 2186c64

Browse files
feat: add support for clone (#2553)
* feat add cupport for clone * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: fix test * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: Clone definition is not a table definition * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: remove CLONE from Table definition * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: fix license header * chore: check for null * πŸ¦‰ Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: add clirr ignored differences * chore: fix test --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 9daab17 commit 2186c64

File tree

9 files changed

+237
-5
lines changed

9 files changed

+237
-5
lines changed

β€ŽREADME.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ implementation 'com.google.cloud:google-cloud-bigquery'
5959
If you are using Gradle without BOM, add this to your dependencies:
6060

6161
```Groovy
62-
implementation 'com.google.cloud:google-cloud-bigquery:2.23.1'
62+
implementation 'com.google.cloud:google-cloud-bigquery:2.23.2'
6363
```
6464

6565
If you are using SBT, add this to your dependencies:
6666

6767
```Scala
68-
libraryDependencies += "com.google.cloud" % "google-cloud-bigquery" % "2.23.1"
68+
libraryDependencies += "com.google.cloud" % "google-cloud-bigquery" % "2.23.2"
6969
```
7070

7171
## Authentication

β€Žgoogle-cloud-bigquery/clirr-ignored-differences.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@
4444
<className>com/google/cloud/bigquery/TableInfo*</className>
4545
<method>*DefaultCollation(*)</method>
4646
</difference>
47+
48+
<difference>
49+
<differenceType>7013</differenceType>
50+
<className>com/google/cloud/bigquery/TableInfo*</className>
51+
<method>*CloneDefinition(*)</method>
52+
</difference>
4753
</differences>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.bigquery;
18+
19+
import com.google.api.client.util.DateTime;
20+
import com.google.api.core.BetaApi;
21+
import com.google.auto.value.AutoValue;
22+
import com.google.common.annotations.VisibleForTesting;
23+
import java.io.Serializable;
24+
import javax.annotation.Nullable;
25+
26+
@AutoValue
27+
@BetaApi
28+
public abstract class CloneDefinition implements Serializable {
29+
30+
private static final long serialVersionUID = 1460853787400450649L;
31+
32+
public static Builder newBuilder() {
33+
return new AutoValue_CloneDefinition.Builder();
34+
}
35+
36+
static CloneDefinition fromPb(
37+
com.google.api.services.bigquery.model.CloneDefinition cloneDefinition) {
38+
Builder builder = newBuilder();
39+
40+
if (cloneDefinition.getCloneTime() != null) {
41+
builder.setCloneTime(cloneDefinition.getCloneTime().toString());
42+
}
43+
if (cloneDefinition.getBaseTableReference() != null) {
44+
builder.setBaseTableId(TableId.fromPb(cloneDefinition.getBaseTableReference()));
45+
}
46+
47+
return builder.build();
48+
}
49+
50+
@Nullable
51+
public abstract TableId getBaseTableId();
52+
53+
@Nullable
54+
public abstract String getCloneTime();
55+
56+
/** Returns a builder for a Clone table definition. */
57+
@VisibleForTesting
58+
public abstract Builder toBuilder();
59+
60+
com.google.api.services.bigquery.model.CloneDefinition toPb() {
61+
62+
com.google.api.services.bigquery.model.CloneDefinition cloneDefinition =
63+
new com.google.api.services.bigquery.model.CloneDefinition();
64+
cloneDefinition.setBaseTableReference(getBaseTableId().toPb());
65+
cloneDefinition.setCloneTime(DateTime.parseRfc3339(getCloneTime()));
66+
67+
return cloneDefinition;
68+
}
69+
70+
@AutoValue.Builder
71+
public abstract static class Builder {
72+
73+
/** Reference describing the ID of the table that was Cloned. * */
74+
public abstract Builder setBaseTableId(TableId baseTableId);
75+
76+
/**
77+
* The time at which the base table was Cloned. This value is reported in the JSON response
78+
* using RFC3339 format. *
79+
*/
80+
public abstract Builder setCloneTime(String dateTime);
81+
82+
/** Creates a {@code CloneDefinition} object. */
83+
public abstract CloneDefinition build();
84+
}
85+
}

β€Žgoogle-cloud-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ public Builder setDestinationTable(TableId destinationTable) {
128128
}
129129

130130
/**
131-
* Sets the supported operation types (COPY, SNAPSHOT or RESTORE) in table copy job. More info:
132-
* https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#operationtype
131+
* Sets the supported operation types (COPY, CLONE, SNAPSHOT or RESTORE) in table copy job. More
132+
* info: https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#operationtype
133133
*/
134134
public Builder setOperationType(String operationType) {
135135
this.operationType = operationType;

β€Žgoogle-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Table.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ public Builder setDefaultCollation(String defaultCollation) {
162162
return this;
163163
}
164164

165+
@Override
166+
public TableInfo.Builder setCloneDefinition(CloneDefinition cloneDefinition) {
167+
infoBuilder.setCloneDefinition(cloneDefinition);
168+
return this;
169+
}
170+
165171
@Override
166172
public Table build() {
167173
return new Table(bigquery, infoBuilder);

β€Žgoogle-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public Table apply(TableInfo tableInfo) {
7474
private final Boolean requirePartitionFilter;
7575
private final String defaultCollation;
7676

77+
private final CloneDefinition cloneDefinition;
78+
7779
/** A builder for {@code TableInfo} objects. */
7880
public abstract static class Builder {
7981

@@ -138,6 +140,8 @@ public Builder setRequirePartitionFilter(Boolean requirePartitionFilter) {
138140
}
139141

140142
public abstract Builder setDefaultCollation(String defaultCollation);
143+
144+
public abstract Builder setCloneDefinition(CloneDefinition cloneDefinition);
141145
}
142146

143147
static class BuilderImpl extends Builder {
@@ -159,6 +163,7 @@ static class BuilderImpl extends Builder {
159163
private Labels labels = Labels.ZERO;
160164
private Boolean requirePartitionFilter;
161165
private String defaultCollation;
166+
private CloneDefinition cloneDefinition;
162167

163168
BuilderImpl() {}
164169

@@ -180,6 +185,7 @@ static class BuilderImpl extends Builder {
180185
this.labels = tableInfo.labels;
181186
this.requirePartitionFilter = tableInfo.requirePartitionFilter;
182187
this.defaultCollation = tableInfo.defaultCollation;
188+
this.cloneDefinition = tableInfo.cloneDefinition;
183189
}
184190

185191
BuilderImpl(Table tablePb) {
@@ -205,6 +211,9 @@ static class BuilderImpl extends Builder {
205211
this.labels = Labels.fromPb(tablePb.getLabels());
206212
this.requirePartitionFilter = tablePb.getRequirePartitionFilter();
207213
this.defaultCollation = tablePb.getDefaultCollation();
214+
if (tablePb.getCloneDefinition() != null) {
215+
this.cloneDefinition = CloneDefinition.fromPb(tablePb.getCloneDefinition());
216+
}
208217
}
209218

210219
@Override
@@ -309,6 +318,11 @@ public Builder setDefaultCollation(String defaultCollation) {
309318
return this;
310319
}
311320

321+
public Builder setCloneDefinition(CloneDefinition cloneDefinition) {
322+
this.cloneDefinition = cloneDefinition;
323+
return this;
324+
}
325+
312326
@Override
313327
public TableInfo build() {
314328
return new TableInfo(this);
@@ -333,6 +347,7 @@ public TableInfo build() {
333347
this.labels = builder.labels;
334348
this.requirePartitionFilter = builder.requirePartitionFilter;
335349
this.defaultCollation = builder.defaultCollation;
350+
this.cloneDefinition = builder.cloneDefinition;
336351
}
337352

338353
/** Returns the hash of the table resource. */
@@ -439,6 +454,10 @@ public String getDefaultCollation() {
439454
return defaultCollation;
440455
}
441456

457+
public CloneDefinition getCloneDefinition() {
458+
return cloneDefinition;
459+
}
460+
442461
/** Returns a builder for the table object. */
443462
public Builder toBuilder() {
444463
return new BuilderImpl(this);
@@ -464,6 +483,7 @@ public String toString() {
464483
.add("labels", labels)
465484
.add("requirePartitionFilter", requirePartitionFilter)
466485
.add("defaultCollation", defaultCollation)
486+
.add("cloneDefinition", cloneDefinition)
467487
.toString();
468488
}
469489

@@ -528,6 +548,9 @@ Table toPb() {
528548
if (defaultCollation != null) {
529549
tablePb.setDefaultCollation(defaultCollation);
530550
}
551+
if (cloneDefinition != null) {
552+
tablePb.setCloneDefinition(cloneDefinition.toPb());
553+
}
531554
return tablePb;
532555
}
533556

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.bigquery;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertTrue;
21+
22+
import org.junit.Test;
23+
24+
public class CloneDefinitionTest {
25+
private static final TableId BASE_TABLE_ID = TableId.of("DATASET_NAME", "BASE_TABLE_NAME");
26+
private static final String CLONE_TIME = "2021-05-19T11:32:26.553Z";
27+
private static final CloneDefinition CLONETABLE_DEFINITION =
28+
CloneDefinition.newBuilder().setBaseTableId(BASE_TABLE_ID).setCloneTime(CLONE_TIME).build();
29+
30+
@Test
31+
public void testToBuilder() {
32+
compareCloneTableDefinition(CLONETABLE_DEFINITION, CLONETABLE_DEFINITION.toBuilder().build());
33+
CloneDefinition cloneTableDefinition =
34+
CLONETABLE_DEFINITION.toBuilder().setCloneTime("2021-05-20T11:32:26.553Z").build();
35+
assertEquals("2021-05-20T11:32:26.553Z", cloneTableDefinition.getCloneTime());
36+
}
37+
38+
@Test
39+
public void testBuilder() {
40+
assertEquals(BASE_TABLE_ID, CLONETABLE_DEFINITION.getBaseTableId());
41+
assertEquals(CLONE_TIME, CLONETABLE_DEFINITION.getCloneTime());
42+
CloneDefinition cloneDefinition =
43+
CloneDefinition.newBuilder().setBaseTableId(BASE_TABLE_ID).setCloneTime(CLONE_TIME).build();
44+
assertEquals(CLONETABLE_DEFINITION, cloneDefinition);
45+
}
46+
47+
@Test
48+
public void testToAndFromPb() {
49+
CloneDefinition cloneDefinition = CLONETABLE_DEFINITION.toBuilder().build();
50+
assertTrue(CloneDefinition.fromPb(cloneDefinition.toPb()) instanceof CloneDefinition);
51+
compareCloneTableDefinition(cloneDefinition, CloneDefinition.fromPb(cloneDefinition.toPb()));
52+
}
53+
54+
private void compareCloneTableDefinition(CloneDefinition expected, CloneDefinition value) {
55+
assertEquals(expected.getBaseTableId(), value.getBaseTableId());
56+
assertEquals(expected.getCloneTime(), value.getCloneTime());
57+
}
58+
}

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import com.google.cloud.bigquery.BigQueryException;
5555
import com.google.cloud.bigquery.BigQueryResult;
5656
import com.google.cloud.bigquery.BigQuerySQLException;
57+
import com.google.cloud.bigquery.CloneDefinition;
5758
import com.google.cloud.bigquery.Clustering;
5859
import com.google.cloud.bigquery.Connection;
5960
import com.google.cloud.bigquery.ConnectionProperty;
@@ -4334,6 +4335,7 @@ public void testSnapshotTableCopyJob() throws InterruptedException {
43344335
assertNotNull(snapshotTable);
43354336
assertEquals(snapshotTableId.getDataset(), snapshotTable.getTableId().getDataset());
43364337
assertEquals(snapshotTableName, snapshotTable.getTableId().getTable());
4338+
System.out.println(snapshotTable.getDefinition());
43374339
assertTrue(snapshotTable.getDefinition() instanceof SnapshotTableDefinition);
43384340
assertEquals(DDL_TABLE_SCHEMA, snapshotTable.getDefinition().getSchema());
43394341
assertNotNull(((SnapshotTableDefinition) snapshotTable.getDefinition()).getSnapshotTime());
@@ -5179,4 +5181,56 @@ public void testCreateExternalTableWithReferenceFileSchemaParquet() {
51795181
boolean success = bigquery.delete(tableId);
51805182
assertEquals(true, success);
51815183
}
5184+
5185+
@Test
5186+
public void testCloneTableCopyJob() throws InterruptedException {
5187+
String sourceTableName = "test_copy_job_base_table";
5188+
String ddlTableName = TABLE_ID_DDL.getTable();
5189+
String cloneTableName = String.format("test_clone_table");
5190+
// Create source table with some data in it
5191+
String ddlQuery =
5192+
String.format(
5193+
"CREATE OR REPLACE TABLE %s ("
5194+
+ "TimestampField TIMESTAMP OPTIONS(description='TimestampDescription'), "
5195+
+ "StringField STRING OPTIONS(description='StringDescription'), "
5196+
+ "BooleanField BOOLEAN OPTIONS(description='BooleanDescription') "
5197+
+ ") AS SELECT * FROM %s",
5198+
sourceTableName, ddlTableName);
5199+
QueryJobConfiguration ddlConfig =
5200+
QueryJobConfiguration.newBuilder(ddlQuery).setDefaultDataset(DatasetId.of(DATASET)).build();
5201+
TableId sourceTableId = TableId.of(DATASET, sourceTableName);
5202+
TableResult result = bigquery.query(ddlConfig);
5203+
assertEquals(DDL_TABLE_SCHEMA, result.getSchema());
5204+
Table remoteTable = bigquery.getTable(DATASET, sourceTableName);
5205+
assertNotNull(remoteTable);
5206+
5207+
// Create clone table using source table as the base table
5208+
TableId cloneTableId = TableId.of(DATASET, cloneTableName);
5209+
CopyJobConfiguration cloneConfiguration =
5210+
CopyJobConfiguration.newBuilder(cloneTableId, sourceTableId)
5211+
.setOperationType("CLONE")
5212+
.build();
5213+
Job createdJob = bigquery.create(JobInfo.of(cloneConfiguration));
5214+
CopyJobConfiguration createdConfiguration = createdJob.getConfiguration();
5215+
assertNotNull(createdConfiguration.getSourceTables());
5216+
assertNotNull(createdConfiguration.getOperationType());
5217+
assertNotNull(createdConfiguration.getDestinationTable());
5218+
Job completedJob = createdJob.waitFor();
5219+
assertNull(completedJob.getStatus().getError());
5220+
5221+
Table cloneTable = bigquery.getTable(DATASET, cloneTableName);
5222+
assertNotNull(cloneTable);
5223+
assertEquals(cloneTableId.getDataset(), cloneTable.getTableId().getDataset());
5224+
assertEquals(cloneTableName, cloneTable.getTableId().getTable());
5225+
assertEquals(TableDefinition.Type.TABLE, cloneTable.getDefinition().getType());
5226+
assertTrue(cloneTable.getDefinition() instanceof StandardTableDefinition);
5227+
assertEquals(DDL_TABLE_SCHEMA, cloneTable.getDefinition().getSchema());
5228+
assertTrue(cloneTable.getCloneDefinition() instanceof CloneDefinition);
5229+
assertEquals(sourceTableName, cloneTable.getCloneDefinition().getBaseTableId().getTable());
5230+
assertNotNull(cloneTable.getCloneDefinition().getCloneTime());
5231+
5232+
// Clean up
5233+
assertTrue(remoteTable.delete());
5234+
assertTrue(cloneTable.delete());
5235+
}
51825236
}

β€Žgoogle-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITRemoteUDFTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class ITRemoteUDFTest {
4747

4848
private static final String ID = UUID.randomUUID().toString().substring(0, 8);
4949
private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId();
50-
private static final String CONNECTION_ID = "test-connectin-id-" + ID;
50+
private static final String CONNECTION_ID = "test-connection-id-" + ID;
5151
private static final String LOCATION = "US";
5252
private static final String PARENT = LocationName.of(PROJECT_ID, LOCATION).toString();
5353
private static final String REMOTE_ENDPOINT = "https://aaabbbccc-uc.a.run.app";

0 commit comments

Comments
 (0)