55import com .google .api .services .bigquery .model .JobStatistics4 ;
66import com .google .common .base .MoreObjects ;
77import com .google .common .base .MoreObjects .ToStringHelper ;
8+ import com .google .common .collect .Lists ;
89
910import java .io .Serializable ;
1011import java .util .List ;
@@ -242,13 +243,15 @@ public static class QueryStatistics extends JobStatistics {
242243 private final Boolean cacheHit ;
243244 private final Long totalBytesBilled ;
244245 private final Long totalBytesProcessed ;
246+ private final List <QueryStage > queryPlan ;
245247
246248 static final class Builder extends JobStatistics .Builder <QueryStatistics , Builder > {
247249
248250 private Integer billingTier ;
249251 private Boolean cacheHit ;
250252 private Long totalBytesBilled ;
251253 private Long totalBytesProcessed ;
254+ private List <QueryStage > queryPlan ;
252255
253256 private Builder () {}
254257
@@ -258,6 +261,10 @@ private Builder(com.google.api.services.bigquery.model.JobStatistics statisticsP
258261 this .cacheHit = statisticsPb .getQuery ().getCacheHit ();
259262 this .totalBytesBilled = statisticsPb .getQuery ().getTotalBytesBilled ();
260263 this .totalBytesProcessed = statisticsPb .getQuery ().getTotalBytesProcessed ();
264+ if (statisticsPb .getQuery ().getQueryPlan () != null ) {
265+ this .queryPlan =
266+ Lists .transform (statisticsPb .getQuery ().getQueryPlan (), QueryStage .FROM_PB_FUNCTION );
267+ }
261268 }
262269
263270 Builder billingTier (Integer billingTier ) {
@@ -280,6 +287,11 @@ Builder totalBytesProcessed(Long totalBytesProcessed) {
280287 return self ();
281288 }
282289
290+ Builder queryPlan (List <QueryStage > queryPlan ) {
291+ this .queryPlan = queryPlan ;
292+ return self ();
293+ }
294+
283295 @ Override
284296 QueryStatistics build () {
285297 return new QueryStatistics (this );
@@ -292,6 +304,7 @@ private QueryStatistics(Builder builder) {
292304 this .cacheHit = builder .cacheHit ;
293305 this .totalBytesBilled = builder .totalBytesBilled ;
294306 this .totalBytesProcessed = builder .totalBytesProcessed ;
307+ this .queryPlan = builder .queryPlan ;
295308 }
296309
297310 /**
@@ -325,13 +338,26 @@ public Long totalBytesProcessed() {
325338 return totalBytesProcessed ;
326339 }
327340
341+ /**
342+ * Returns the query plan as a list of stages. Each stage involves a number of steps that read
343+ * from data sources, perform a series of transformations on the input, and emit an output to a
344+ * future stage (or the final result). The query plan is available for a completed query job and
345+ * is retained for 7 days.
346+ *
347+ * @see <a href="https://cloud.google.com/bigquery/query-plan-explanation">Query Plan</a>
348+ */
349+ public List <QueryStage > queryPlan () {
350+ return queryPlan ;
351+ }
352+
328353 @ Override
329354 ToStringHelper toStringHelper () {
330355 return super .toStringHelper ()
331356 .add ("billingTier" , billingTier )
332357 .add ("cacheHit" , cacheHit )
333358 .add ("totalBytesBilled" , totalBytesBilled )
334- .add ("totalBytesProcessed" , totalBytesProcessed );
359+ .add ("totalBytesProcessed" , totalBytesProcessed )
360+ .add ("queryPlan" , queryPlan );
335361 }
336362
337363 @ Override
@@ -343,7 +369,7 @@ public boolean equals(Object obj) {
343369 @ Override
344370 public int hashCode () {
345371 return Objects .hash (super .hashCode (), billingTier , cacheHit , totalBytesBilled ,
346- totalBytesProcessed );
372+ totalBytesProcessed , queryPlan );
347373 }
348374
349375 @ Override
@@ -353,6 +379,9 @@ com.google.api.services.bigquery.model.JobStatistics toPb() {
353379 queryStatisticsPb .setCacheHit (cacheHit );
354380 queryStatisticsPb .setTotalBytesBilled (totalBytesBilled );
355381 queryStatisticsPb .setTotalBytesProcessed (totalBytesProcessed );
382+ if (queryPlan != null ) {
383+ queryStatisticsPb .setQueryPlan (Lists .transform (queryPlan , QueryStage .TO_PB_FUNCTION ));
384+ }
356385 return super .toPb ().setQuery (queryStatisticsPb );
357386 }
358387
0 commit comments