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 4c3b2de

Browse files
authoredAug 11, 2021
feat: add support for transactioninfo in query statistics (#1497)
Fixes #1467
1 parent ec68c11 commit 4c3b2de

File tree

3 files changed

+128
-2
lines changed

3 files changed

+128
-2
lines changed
 

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

+90-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public abstract class JobStatistics implements Serializable {
4444
private final String parentJobId;
4545
private final ScriptStatistics scriptStatistics;
4646
private final List<ReservationUsage> reservationUsage;
47+
private final TransactionInfo transactionInfo;
4748

4849
/** A Google BigQuery Copy Job statistics. */
4950
public static class CopyStatistics extends JobStatistics {
@@ -1178,6 +1179,78 @@ static ReservationUsage fromPb(
11781179
}
11791180
}
11801181

1182+
// TransactionInfo contains information about a multi-statement transaction that may have
1183+
// associated with a job.
1184+
public static class TransactionInfo {
1185+
1186+
// TransactionID is the system-generated identifier for the transaction.
1187+
private final String transactionId;
1188+
1189+
public static class Builder {
1190+
1191+
private String transactionId;
1192+
1193+
private Builder() {};
1194+
1195+
Builder setTransactionId(String transactionId) {
1196+
this.transactionId = transactionId;
1197+
return this;
1198+
}
1199+
1200+
TransactionInfo build() {
1201+
return new TransactionInfo(this);
1202+
}
1203+
}
1204+
1205+
private TransactionInfo(Builder builder) {
1206+
this.transactionId = builder.transactionId;
1207+
}
1208+
1209+
public String getTransactionId() {
1210+
return transactionId;
1211+
}
1212+
1213+
static Builder newbuilder() {
1214+
return new Builder();
1215+
}
1216+
1217+
ToStringHelper toStringHelper() {
1218+
return MoreObjects.toStringHelper(this).add("transactionId", transactionId);
1219+
}
1220+
1221+
@Override
1222+
public String toString() {
1223+
return toStringHelper().toString();
1224+
}
1225+
1226+
@Override
1227+
public boolean equals(Object obj) {
1228+
return obj == this
1229+
|| obj != null
1230+
&& obj.getClass().equals(TransactionInfo.class)
1231+
&& Objects.equals(toPb(), ((TransactionInfo) obj).toPb());
1232+
}
1233+
1234+
@Override
1235+
public int hashCode() {
1236+
return Objects.hash(transactionId);
1237+
}
1238+
1239+
com.google.api.services.bigquery.model.TransactionInfo toPb() {
1240+
com.google.api.services.bigquery.model.TransactionInfo transactionInfo =
1241+
new com.google.api.services.bigquery.model.TransactionInfo();
1242+
transactionInfo.setTransactionId(transactionId);
1243+
return transactionInfo;
1244+
}
1245+
1246+
static TransactionInfo fromPb(
1247+
com.google.api.services.bigquery.model.TransactionInfo transactionInfo) {
1248+
Builder builder = newbuilder();
1249+
builder.setTransactionId(transactionInfo.getTransactionId());
1250+
return builder.build();
1251+
}
1252+
}
1253+
11811254
abstract static class Builder<T extends JobStatistics, B extends Builder<T, B>> {
11821255

11831256
private Long creationTime;
@@ -1187,6 +1260,7 @@ abstract static class Builder<T extends JobStatistics, B extends Builder<T, B>>
11871260
private String parentJobId;
11881261
private ScriptStatistics scriptStatistics;
11891262
private List<ReservationUsage> reservationUsage;
1263+
private TransactionInfo transactionInfo;
11901264

11911265
protected Builder() {}
11921266

@@ -1203,6 +1277,9 @@ protected Builder(com.google.api.services.bigquery.model.JobStatistics statistic
12031277
this.reservationUsage =
12041278
Lists.transform(statisticsPb.getReservationUsage(), ReservationUsage.FROM_PB_FUNCTION);
12051279
}
1280+
if (statisticsPb.getTransactionInfo() != null) {
1281+
this.transactionInfo = TransactionInfo.fromPb(statisticsPb.getTransactionInfo());
1282+
}
12061283
}
12071284

12081285
@SuppressWarnings("unchecked")
@@ -1236,6 +1313,7 @@ protected JobStatistics(Builder builder) {
12361313
this.parentJobId = builder.parentJobId;
12371314
this.scriptStatistics = builder.scriptStatistics;
12381315
this.reservationUsage = builder.reservationUsage;
1316+
this.transactionInfo = builder.transactionInfo;
12391317
}
12401318

12411319
/** Returns the creation time of the job in milliseconds since epoch. */
@@ -1279,6 +1357,11 @@ public List<ReservationUsage> getReservationUsage() {
12791357
return reservationUsage;
12801358
}
12811359

1360+
/** Info indicates the transaction ID associated with the job, if any. */
1361+
public TransactionInfo getTransactionInfo() {
1362+
return transactionInfo;
1363+
}
1364+
12821365
ToStringHelper toStringHelper() {
12831366
return MoreObjects.toStringHelper(this)
12841367
.add("creationTime", creationTime)
@@ -1287,7 +1370,8 @@ ToStringHelper toStringHelper() {
12871370
.add("numChildJobs", numChildJobs)
12881371
.add("parentJobId", parentJobId)
12891372
.add("scriptStatistics", scriptStatistics)
1290-
.add("reservationUsage", reservationUsage);
1373+
.add("reservationUsage", reservationUsage)
1374+
.add("transactionInfo", transactionInfo);
12911375
}
12921376

12931377
@Override
@@ -1303,7 +1387,8 @@ final int baseHashCode() {
13031387
numChildJobs,
13041388
parentJobId,
13051389
scriptStatistics,
1306-
reservationUsage);
1390+
reservationUsage,
1391+
transactionInfo);
13071392
}
13081393

13091394
final boolean baseEquals(JobStatistics jobStatistics) {
@@ -1325,6 +1410,9 @@ com.google.api.services.bigquery.model.JobStatistics toPb() {
13251410
statistics.setReservationUsage(
13261411
Lists.transform(reservationUsage, ReservationUsage.TO_PB_FUNCTION));
13271412
}
1413+
if (transactionInfo != null) {
1414+
statistics.setTransactionInfo(transactionInfo.toPb());
1415+
}
13281416
return statistics;
13291417
}
13301418

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

+16
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
import com.google.cloud.bigquery.JobStatistics.ReservationUsage;
2727
import com.google.cloud.bigquery.JobStatistics.ScriptStatistics;
2828
import com.google.cloud.bigquery.JobStatistics.ScriptStatistics.ScriptStackFrame;
29+
import com.google.cloud.bigquery.JobStatistics.TransactionInfo;
2930
import com.google.cloud.bigquery.QueryStage.QueryStep;
3031
import com.google.common.collect.ImmutableList;
3132
import java.util.List;
33+
import java.util.UUID;
3234
import org.junit.Test;
3335

3436
public class JobStatisticsTest {
@@ -70,6 +72,7 @@ public class JobStatisticsTest {
7072
private static final Long START_TIME = 15L;
7173
private static final String NAME = "reservation-name";
7274
private static final Long SLOTMS = 12545L;
75+
private static final String TRANSACTION_ID = UUID.randomUUID().toString().substring(0, 8);
7376
private static final CopyStatistics COPY_STATISTICS =
7477
CopyStatistics.newBuilder()
7578
.setCreationTimestamp(CREATION_TIME)
@@ -216,6 +219,9 @@ public class JobStatisticsTest {
216219
private static final ReservationUsage RESERVATION_USAGE =
217220
ReservationUsage.newBuilder().setName(NAME).setSlotMs(SLOTMS).build();
218221

222+
private static final TransactionInfo TRANSACTION_INFO =
223+
TransactionInfo.newbuilder().setTransactionId(TRANSACTION_ID).build();
224+
219225
@Test
220226
public void testBuilder() {
221227
assertEquals(CREATION_TIME, EXTRACT_STATISTICS.getCreationTime());
@@ -286,6 +292,7 @@ public void testBuilder() {
286292
ImmutableList.of(EXPRESSION_STACK_FRAME), EXPRESSION_SCRIPT_STATISTICS.getStackFrames());
287293
assertEquals(NAME, RESERVATION_USAGE.getName());
288294
assertEquals(SLOTMS, RESERVATION_USAGE.getSlotMs());
295+
assertEquals(TRANSACTION_ID, TRANSACTION_INFO.getTransactionId());
289296
}
290297

291298
@Test
@@ -311,6 +318,7 @@ public void testToPbAndFromPb() {
311318
compareStackFrames(stackFrame, ScriptStackFrame.fromPb(stackFrame.toPb()));
312319
}
313320
compareReservation(RESERVATION_USAGE, ReservationUsage.fromPb(RESERVATION_USAGE.toPb()));
321+
compareTransactionInfo(TRANSACTION_INFO, TransactionInfo.fromPb(TRANSACTION_INFO.toPb()));
314322
}
315323

316324
@Test
@@ -425,4 +433,12 @@ private void compareReservation(ReservationUsage expected, ReservationUsage valu
425433
assertEquals(expected.getName(), value.getName());
426434
assertEquals(expected.getSlotMs(), value.getSlotMs());
427435
}
436+
437+
private void compareTransactionInfo(TransactionInfo expected, TransactionInfo value) {
438+
assertEquals(expected, value);
439+
assertEquals(expected.hashCode(), value.hashCode());
440+
assertEquals(expected.toString(), value.toString());
441+
assertEquals(expected.toPb(), value.toPb());
442+
assertEquals(expected.getTransactionId(), value.getTransactionId());
443+
}
428444
}

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

+22
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import com.google.cloud.bigquery.JobInfo;
7272
import com.google.cloud.bigquery.JobStatistics;
7373
import com.google.cloud.bigquery.JobStatistics.LoadStatistics;
74+
import com.google.cloud.bigquery.JobStatistics.TransactionInfo;
7475
import com.google.cloud.bigquery.LegacySQLTypeName;
7576
import com.google.cloud.bigquery.LoadJobConfiguration;
7677
import com.google.cloud.bigquery.MaterializedViewDefinition;
@@ -2219,6 +2220,27 @@ public void testDmlStatistics() throws InterruptedException {
22192220
assertEquals(2L, statistics.getDmlStats().getUpdatedRowCount().longValue());
22202221
}
22212222

2223+
@Test
2224+
public void testTransactionInfo() throws InterruptedException {
2225+
String tableName = TABLE_ID_FASTQUERY.getTable();
2226+
String transaction =
2227+
String.format(
2228+
"BEGIN TRANSACTION;\n"
2229+
+ " UPDATE %s.%s SET StringField = 'hello' WHERE TRUE;\n"
2230+
+ " COMMIT TRANSACTION;\n",
2231+
DATASET, tableName);
2232+
QueryJobConfiguration config = QueryJobConfiguration.of(transaction);
2233+
Job remoteJob = bigquery.create(JobInfo.of(config));
2234+
JobInfo parentJobInfo = remoteJob.waitFor();
2235+
String parentJobId = parentJobInfo.getJobId().getJob();
2236+
Page<Job> childJobs = bigquery.listJobs(JobListOption.parentJobId(parentJobId));
2237+
for (Job job : childJobs.iterateAll()) {
2238+
// only those child jobs inside the transaction would have transactionInfo populated
2239+
TransactionInfo transactionInfo = job.getStatistics().getTransactionInfo();
2240+
assertNotNull(transactionInfo.getTransactionId());
2241+
}
2242+
}
2243+
22222244
@Test
22232245
public void testScriptStatistics() throws InterruptedException {
22242246
String script =

0 commit comments

Comments
 (0)
Failed to load comments.