Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,8 @@ public com.google.api.services.bigquery.model.QueryResponse call()
return job;
}

JobStatistics jobStatistics = JobStatistics.QueryStatistics.fromPb(results, schema);

if (results.getPageToken() != null) {
JobId jobId = JobId.fromPb(results.getJobReference());
String cursor = results.getPageToken();
Expand All @@ -2114,6 +2116,7 @@ public com.google.api.services.bigquery.model.QueryResponse call()
.setQueryId(results.getQueryId())
.setJobCreationReason(JobCreationReason.fromPb(results.getJobCreationReason()))
.setRowsInPage(results.getRows() != null ? (long) results.getRows().size() : 0L)
.setJobStatistics(jobStatistics)
.build();
}
// only 1 page of result
Expand All @@ -2134,6 +2137,7 @@ public com.google.api.services.bigquery.model.QueryResponse call()
.setQueryId(results.getQueryId())
.setJobCreationReason(JobCreationReason.fromPb(results.getJobCreationReason()))
.setRowsInPage(results.getRows() != null ? (long) results.getRows().size() : 0L)
.setJobStatistics(jobStatistics)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ public TableResult getQueryResults(QueryResultsOption... options)
: ImmutableList.copyOf(job.getStatus().getExecutionErrors()));
}

JobStatistics stats = job.getStatistics();

// If there are no rows in the result, this may have been a DDL query.
// Listing table data might fail, such as with CREATE VIEW queries.
// Avoid a tabledata.list API request by returning an empty TableResult.
Expand All @@ -425,6 +427,7 @@ public TableResult getQueryResults(QueryResultsOption... options)
.setTotalRows(0L)
.setPageNoSchema(new PageImpl<FieldValueList>(null, "", null))
.setRowsInPage(0L)
.setJobStatistics(stats)
.build();
return emptyTableResult;
}
Expand All @@ -436,7 +439,8 @@ public TableResult getQueryResults(QueryResultsOption... options)
TableResult tableResult =
bigquery.listTableData(
table, response.getSchema(), listOptions.toArray(new TableDataListOption[0]));
TableResult tableResultWithJobId = tableResult.toBuilder().setJobId(job.getJobId()).build();
TableResult tableResultWithJobId =
tableResult.toBuilder().setJobId(job.getJobId()).setJobStatistics(stats).build();
return tableResultWithJobId;
} finally {
if (getQueryResults != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.api.services.bigquery.model.JobStatistics4;
import com.google.api.services.bigquery.model.JobStatistics5;
import com.google.api.services.bigquery.model.QueryParameter;
import com.google.api.services.bigquery.model.QueryResponse;
import com.google.auto.value.AutoValue;
import com.google.cloud.StringEnumType;
import com.google.cloud.StringEnumValue;
Expand Down Expand Up @@ -1073,6 +1074,33 @@ static QueryStatistics fromPb(
com.google.api.services.bigquery.model.JobStatistics statisticPb) {
return new Builder(statisticPb).build();
}

/** Creates a {@code QueryStatistics} object from a {@link QueryResponse} and schema. */
static QueryStatistics fromPb(QueryResponse queryResponse, Schema schema) {
if (queryResponse == null) {
return null;
}
Builder builder = newBuilder();
if (queryResponse.getStatementType() != null) {
builder.setStatementType(queryResponse.getStatementType());
}
if (queryResponse.getTotalBytesBilled() != null) {
builder.setTotalBytesBilled(queryResponse.getTotalBytesBilled());
}
if (queryResponse.getTotalBytesProcessed() != null) {
builder.setTotalBytesProcessed(queryResponse.getTotalBytesProcessed());
}
if (queryResponse.getTotalSlotMs() != null) {
builder.setTotalSlotMs(queryResponse.getTotalSlotMs());
}
if (queryResponse.getNumDmlAffectedRows() != null) {
builder.setNumDmlAffectedRows(queryResponse.getNumDmlAffectedRows());
}
if (schema != null) {
builder.setSchema(schema);
}
return builder.build();
}
}

/** A Google BigQuery Script statistics. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public abstract static class Builder {

abstract TableResult.Builder setRowsInPage(Long rowsInPage);

public abstract TableResult.Builder setJobStatistics(JobStatistics jobStatistics);

/** Creates a @code TableResult} object. */
public abstract TableResult build();
}
Expand Down Expand Up @@ -87,6 +89,10 @@ public static Builder newBuilder() {
@Nullable
public abstract Long getRowsInPage();

/** Returns the statistics of the job/query that produced these results, if available. */
@Nullable
public abstract JobStatistics getJobStatistics();

@Override
public boolean hasNextPage() {
return getPageNoSchema().hasNextPage();
Expand All @@ -109,6 +115,7 @@ public TableResult getNextPage() {
.setQueryId(getQueryId())
.setJobCreationReason(getJobCreationReason())
.setRowsInPage(nextRows)
.setJobStatistics(getJobStatistics())
.build();
}
return null;
Expand Down Expand Up @@ -147,13 +154,19 @@ public String toString() {
.add("cursor", getNextPageToken())
.add("queryId", getQueryId())
.add("rowsInPage", getRowsInPage())
.add("jobStatistics", getJobStatistics())
.toString();
}

@Override
public final int hashCode() {
return Objects.hash(
getPageNoSchema(), getSchema(), getTotalRows(), getQueryId(), getRowsInPage());
getPageNoSchema(),
getSchema(),
getTotalRows(),
getQueryId(),
getRowsInPage(),
getJobStatistics());
}

@Override
Expand All @@ -170,6 +183,7 @@ public final boolean equals(Object obj) {
&& Objects.equals(getSchema(), response.getSchema())
&& getTotalRows() == response.getTotalRows()
&& Objects.equals(getQueryId(), response.getQueryId())
&& Objects.equals(getRowsInPage(), response.getRowsInPage());
&& Objects.equals(getRowsInPage(), response.getRowsInPage())
&& Objects.equals(getJobStatistics(), response.getJobStatistics());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
import com.google.cloud.bigquery.BigQuery.JobOption;
import com.google.cloud.bigquery.BigQuery.QueryResultsOption;
import com.google.cloud.bigquery.InsertAllRequest.RowToInsert;
import com.google.cloud.bigquery.JobStatistics.QueryStatistics;
import com.google.cloud.bigquery.JobStatistics.QueryStatistics.StatementType;
import com.google.cloud.bigquery.spi.BigQueryRpcFactory;
import com.google.cloud.bigquery.spi.v2.BigQueryRpc;
import com.google.cloud.bigquery.spi.v2.HttpBigQueryRpc;
Expand Down Expand Up @@ -2874,7 +2876,11 @@ void testQueryWithTimeoutSetsTimeout() throws InterruptedException, IOException
.setPageToken(null)
.setRows(ImmutableList.of(TABLE_ROW))
.setSchema(TABLE_SCHEMA.toPb())
.setStatementType("SELECT")
.setTotalBytesBilled(100L)
.setTotalBytesProcessed(42L)
.setTotalSlotMs(50L)
.setNumDmlAffectedRows(0L)
.setTotalRows(BigInteger.valueOf(1L));

when(bigqueryRpcMock.queryRpcSkipExceptionTranslation(eq(PROJECT), requestPbCapture.capture()))
Expand All @@ -2883,6 +2889,15 @@ void testQueryWithTimeoutSetsTimeout() throws InterruptedException, IOException
bigquery = options.getService();
Object result = bigquery.queryWithTimeout(QUERY_JOB_CONFIGURATION_FOR_QUERY, null, 1000L);
assertTrue(result instanceof TableResult);
TableResult tableResult = (TableResult) result;
assertNotNull(tableResult.getJobStatistics());
assertTrue(tableResult.getJobStatistics() instanceof QueryStatistics);
QueryStatistics stats = (QueryStatistics) tableResult.getJobStatistics();
assertEquals(StatementType.SELECT, stats.getStatementType());
assertEquals((Long) 100L, stats.getTotalBytesBilled());
assertEquals((Long) 42L, stats.getTotalBytesProcessed());
assertEquals((Long) 50L, stats.getTotalSlotMs());
assertEquals((Long) 0L, stats.getNumDmlAffectedRows());
QueryRequest requestPb = requestPbCapture.getValue();
assertEquals((Long) 1000L, requestPb.getTimeoutMs());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,120 @@ void testSchema() {
newFieldValueList("2").withSchema(SCHEMA.getFields()))
.inOrder();
}

@Test
void testJobStatistics() {
JobStatistics.QueryStatistics stats =
JobStatistics.QueryStatistics.newBuilder()
.setStatementType(JobStatistics.QueryStatistics.StatementType.SELECT)
.setTotalBytesBilled(1024L)
.setTotalBytesProcessed(2048L)
.setTotalSlotMs(500L)
.setNumDmlAffectedRows(0L)
.build();

TableResult result =
TableResult.newBuilder()
.setSchema(SCHEMA)
.setTotalRows(3L)
.setPageNoSchema(INNER_PAGE_0)
.setRowsInPage(2L)
.setJobStatistics(stats)
.build();

assertThat(result.getJobStatistics()).isEqualTo(stats);
assertThat(result.getJobStatistics()).isInstanceOf(JobStatistics.QueryStatistics.class);
JobStatistics.QueryStatistics queryStats =
(JobStatistics.QueryStatistics) result.getJobStatistics();
assertThat(queryStats.getStatementType())
.isEqualTo(JobStatistics.QueryStatistics.StatementType.SELECT);
assertThat(queryStats.getTotalBytesBilled()).isEqualTo(1024L);
assertThat(queryStats.getTotalBytesProcessed()).isEqualTo(2048L);
assertThat(queryStats.getTotalSlotMs()).isEqualTo(500L);
assertThat(queryStats.getNumDmlAffectedRows()).isEqualTo(0L);

TableResult next = result.getNextPage();
assertThat(next.getJobStatistics()).isEqualTo(stats);
}

@Test
void testToBuilder() {
JobStatistics.QueryStatistics stats1 =
JobStatistics.QueryStatistics.newBuilder()
.setStatementType(JobStatistics.QueryStatistics.StatementType.INSERT)
.setNumDmlAffectedRows(5L)
.build();

TableResult result =
TableResult.newBuilder()
.setSchema(SCHEMA)
.setTotalRows(3L)
.setPageNoSchema(INNER_PAGE_0)
.setRowsInPage(2L)
.setJobStatistics(stats1)
.build();

JobStatistics.QueryStatistics stats2 =
JobStatistics.QueryStatistics.newBuilder()
.setStatementType(JobStatistics.QueryStatistics.StatementType.UPDATE)
.setNumDmlAffectedRows(10L)
.build();

TableResult modified = result.toBuilder().setJobStatistics(stats2).build();

assertThat(modified.getJobStatistics()).isEqualTo(stats2);
}

@Test
void testEqualsAndHashCode() {
JobStatistics.QueryStatistics stats1 =
JobStatistics.QueryStatistics.newBuilder()
.setStatementType(JobStatistics.QueryStatistics.StatementType.SELECT)
.setTotalBytesBilled(100L)
.build();

JobStatistics.QueryStatistics stats2 =
JobStatistics.QueryStatistics.newBuilder()
.setStatementType(JobStatistics.QueryStatistics.StatementType.SELECT)
.setTotalBytesBilled(100L)
.build();

JobStatistics.QueryStatistics stats3 =
JobStatistics.QueryStatistics.newBuilder()
.setStatementType(JobStatistics.QueryStatistics.StatementType.DELETE)
.setTotalBytesBilled(100L)
.build();

TableResult result1 =
TableResult.newBuilder()
.setSchema(SCHEMA)
.setTotalRows(3L)
.setPageNoSchema(INNER_PAGE_0)
.setRowsInPage(2L)
.setJobStatistics(stats1)
.build();

TableResult result2 =
TableResult.newBuilder()
.setSchema(SCHEMA)
.setTotalRows(3L)
.setPageNoSchema(INNER_PAGE_0)
.setRowsInPage(2L)
.setJobStatistics(stats2)
.build();

TableResult result3 =
TableResult.newBuilder()
.setSchema(SCHEMA)
.setTotalRows(3L)
.setPageNoSchema(INNER_PAGE_0)
.setRowsInPage(2L)
.setJobStatistics(stats3)
.build();

assertThat(result1).isEqualTo(result2);
assertThat(result1.hashCode()).isEqualTo(result2.hashCode());
assertThat(result1).isNotEqualTo(result3);
assertThat(result1.toString()).contains("jobStatistics");
}
}
2 changes: 1 addition & 1 deletion java-bigquery/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<github.global.server>github</github.global.server>
<site.installationModule>google-cloud-bigquery-parent</site.installationModule>
<google-api-services-bigquery.version>v2-rev20251012-2.0.0</google-api-services-bigquery.version>
<google-api-services-bigquery.version>v2-rev20260731-2.0.0</google-api-services-bigquery.version>
</properties>

<dependencyManagement>
Expand Down
Loading