From 2e239f7148c852b7b7e2de4af66e8e5707d9d049 Mon Sep 17 00:00:00 2001 From: Mike Kaplinskiy Date: Thu, 7 Feb 2019 08:00:29 -0800 Subject: [PATCH] Empty table results can have a schema (#4185) * Update EmptyTableResult.java * Update Job.java * add test case --- .../cloud/bigquery/EmptyTableResult.java | 5 +- .../java/com/google/cloud/bigquery/Job.java | 2 +- .../com/google/cloud/bigquery/JobTest.java | 49 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/EmptyTableResult.java b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/EmptyTableResult.java index 68112ef0b5ee..7cb5e1932fa3 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/EmptyTableResult.java +++ b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/EmptyTableResult.java @@ -18,6 +18,7 @@ import com.google.api.core.InternalApi; import com.google.cloud.PageImpl; +import javax.annotation.Nullable; public class EmptyTableResult extends TableResult { @@ -25,7 +26,7 @@ public class EmptyTableResult extends TableResult { /** An empty {@code TableResult} to avoid making API requests to unlistable tables. */ @InternalApi("Exposed for testing") - public EmptyTableResult() { - super(null, 0, new PageImpl(null, "", null)); + public EmptyTableResult(@Nullable Schema schema) { + super(schema, 0, new PageImpl(null, "", null)); } } diff --git a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java index 9a61192c4045..de018291d9d2 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java +++ b/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java @@ -305,7 +305,7 @@ public TableResult getQueryResults(QueryResultsOption... options) // Listing table data might fail, such as with CREATE VIEW queries. // Avoid a tabledata.list API request by returning an empty TableResult. if (response.getTotalRows() == 0) { - return new EmptyTableResult(); + return new EmptyTableResult(response.getSchema()); } TableId table = ((QueryJobConfiguration) getConfiguration()).getDestinationTable(); diff --git a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java index 57c6a1104eab..b259b237ea78 100644 --- a/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java +++ b/google-cloud-clients/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java @@ -302,6 +302,55 @@ public Iterable getValues() { verify(status, mockOptions); } + @Test + public void testWaitForAndGetQueryResultsEmptyWithSchema() throws InterruptedException { + QueryJobConfiguration jobConfig = + QueryJobConfiguration.newBuilder("CREATE VIEW").setDestinationTable(TABLE_ID1).build(); + QueryStatistics jobStatistics = + QueryStatistics.newBuilder() + .setCreationTimestamp(1L) + .setEndTime(3L) + .setStartTime(2L) + .build(); + JobInfo jobInfo = + JobInfo.newBuilder(jobConfig) + .setJobId(JOB_ID) + .setStatistics(jobStatistics) + .setJobId(JOB_ID) + .setEtag(ETAG) + .setGeneratedId(GENERATED_ID) + .setSelfLink(SELF_LINK) + .setUserEmail(EMAIL) + .setStatus(JOB_STATUS) + .build(); + + initializeExpectedJob(2, jobInfo); + JobStatus status = createStrictMock(JobStatus.class); + expect(bigquery.getOptions()).andReturn(mockOptions); + expect(mockOptions.getClock()).andReturn(CurrentMillisClock.getDefaultClock()).times(2); + Job completedJob = expectedJob.toBuilder().setStatus(status).build(); + QueryResponse completedQuery = + QueryResponse.newBuilder() + .setCompleted(true) + .setTotalRows(0) + .setSchema(Schema.of(Field.of("field1", LegacySQLTypeName.BOOLEAN))) + .setErrors(ImmutableList.of()) + .build(); + + expect(bigquery.getQueryResults(jobInfo.getJobId(), Job.DEFAULT_QUERY_WAIT_OPTIONS)) + .andReturn(completedQuery); + expect(bigquery.getJob(JOB_INFO.getJobId())).andReturn(completedJob); + expect(bigquery.getQueryResults(jobInfo.getJobId(), Job.DEFAULT_QUERY_WAIT_OPTIONS)) + .andReturn(completedQuery); + + replay(status, bigquery, mockOptions); + initializeJob(jobInfo); + assertThat(job.waitFor(TEST_RETRY_OPTIONS)).isSameAs(completedJob); + assertThat(job.getQueryResults().getSchema()) + .isEqualTo(Schema.of(Field.of("field1", LegacySQLTypeName.BOOLEAN))); + verify(status, mockOptions); + } + @Test public void testWaitForAndGetQueryResults() throws InterruptedException { QueryJobConfiguration jobConfig =