From 2a0d86d2d07dd706fb7d943da6ebd5c9ac98dfca Mon Sep 17 00:00:00 2001 From: Stephanie Wang Date: Thu, 17 Sep 2020 08:44:03 -0400 Subject: [PATCH] fix: throw jobexception for invalid multiple statements query (#732) * fix: throw jobexception for invalid multiple statements query add another test case add exception checking Job class update reload() method * add unit test --- .../java/com/google/cloud/bigquery/Job.java | 11 +++++- .../com/google/cloud/bigquery/JobTest.java | 21 ++++++++++++ .../cloud/bigquery/it/ITBigQueryTest.java | 34 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java index 2d859b046..1a8c27ccd 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java @@ -401,7 +401,16 @@ public boolean shouldRetry(Throwable prevThrowable, Job prevResponse) { */ public Job reload(JobOption... options) { checkNotDryRun("reload"); - return bigquery.getJob(getJobId(), options); + Job job = bigquery.getJob(getJobId(), options); + if (job != null && job.getStatus().getError() != null) { + // TODO(pmakani): change to BigQueryException when fast query path change is merged + throw new JobException( + getJobId(), + job.getStatus().getExecutionErrors() == null + ? ImmutableList.of(job.getStatus().getError()) + : ImmutableList.copyOf(job.getStatus().getExecutionErrors())); + } + return job; } /** diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java index 1d34f4958..370b5d6d1 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java @@ -21,9 +21,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -36,6 +38,7 @@ import com.google.cloud.RetryOption; import com.google.cloud.bigquery.JobStatistics.CopyStatistics; import com.google.cloud.bigquery.JobStatistics.QueryStatistics; +import com.google.cloud.bigquery.JobStatus.State; import com.google.common.collect.ImmutableList; import java.util.Collections; import org.junit.Assert; @@ -436,6 +439,24 @@ public void testReload() { verify(bigquery).getJob(JOB_INFO.getJobId()); } + @Test + public void testReloadJobException() { + JobInfo updatedInfo = JOB_INFO.toBuilder().setEtag("etag").build(); + Job expectedJob = new Job(bigquery, new JobInfo.BuilderImpl(updatedInfo)); + BigQueryError bigQueryError = new BigQueryError("invalidQuery", "US", "invalidQuery"); + expectedJob = + expectedJob.toBuilder().setStatus(new JobStatus(State.DONE, bigQueryError, null)).build(); + ImmutableList bigQueryErrorList = ImmutableList.of(bigQueryError); + JobException jobException = new JobException(expectedJob.getJobId(), bigQueryErrorList); + when(bigquery.getJob(JOB_INFO.getJobId())).thenReturn(expectedJob).thenThrow(jobException); + try { + job.reload(); + fail("JobException expected"); + } catch (JobException e) { + assertNotNull(e.getErrors()); + } + } + @Test public void testReloadNull() { when(bigquery.getJob(JOB_INFO.getJobId())).thenReturn(null); diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 05c33894b..077c1e622 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -65,6 +65,7 @@ import com.google.cloud.bigquery.InsertAllRequest; import com.google.cloud.bigquery.InsertAllResponse; import com.google.cloud.bigquery.Job; +import com.google.cloud.bigquery.JobException; import com.google.cloud.bigquery.JobId; import com.google.cloud.bigquery.JobInfo; import com.google.cloud.bigquery.JobStatistics; @@ -1379,6 +1380,39 @@ public void testRoutineAPICreation() { assertEquals(routine.getRoutineType(), "SCALAR_FUNCTION"); } + @Test + public void testSingleStatementsQueryException() throws InterruptedException { + String invalidQuery = + String.format("INSERT %s.%s VALUES('3', 10);", DATASET, TABLE_ID.getTable()); + try { + bigquery.create(JobInfo.of(QueryJobConfiguration.of(invalidQuery))).waitFor(); + fail("BigQueryException was expected"); + } catch (BigQueryException e) { + BigQueryError error = e.getError(); + assertNotNull(error); + assertEquals("invalidQuery", error.getReason()); + assertNotNull(error.getMessage()); + } + } + + @Test + public void testMultipleStatementsQueryException() throws InterruptedException { + String invalidQuery = + String.format( + "INSERT %s.%s VALUES('3', 10); DELETE %s.%s where c2=3;", + DATASET, TABLE_ID.getTable(), DATASET, TABLE_ID.getTable()); + try { + bigquery.create(JobInfo.of(QueryJobConfiguration.of(invalidQuery))).waitFor(); + fail("JobException was expected"); + } catch (JobException e) { + for (BigQueryError error : e.getErrors()) { + assertNotNull(error); + assertEquals("invalidQuery", error.getReason()); + assertNotNull(error.getMessage()); + } + } + } + @Test public void testQuery() throws InterruptedException { String query = "SELECT TimestampField, StringField, BooleanField FROM " + TABLE_ID.getTable();