diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java index e944efceb..a1bb4d406 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java @@ -113,6 +113,9 @@ private class BigQueryResultSet extends AbstractJdbcResultSet { @Override /*Advances the result set to the next row, returning false if no such row exists. Potentially blocking operation*/ public boolean next() throws SQLException { + if (buffer == null) { + return false; + } if (hasReachedEnd) { // if end of stream is reached then we can simply return false return false; } diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Connection.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Connection.java index afc8eb848..83ea0fc0d 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Connection.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Connection.java @@ -140,7 +140,7 @@ ListenableFuture executeSelectAsync(String sql) * @code * ConnectionSettings connectionSettings = * ConnectionSettings.newBuilder() - * ..setUseReadAPI(true) + * .setUseReadAPI(true) * .build(); * Connection connection = bigquery.createConnection(connectionSettings); * String selectQuery = diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ConnectionImplTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ConnectionImplTest.java index 58cb69ba7..7eea1570a 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ConnectionImplTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ConnectionImplTest.java @@ -411,7 +411,7 @@ public void testLegacyQuerySinglePage() throws BigQuerySQLException { // calls executeSelect with a nonFast query where the query returns an empty result. @Test - public void testLegacyQuerySinglePageEmptyResults() throws BigQuerySQLException { + public void testLegacyQuerySinglePageEmptyResults() throws BigQuerySQLException, SQLException { ConnectionImpl connectionSpy = Mockito.spy(connection); com.google.api.services.bigquery.model.Job jobResponseMock = new com.google.api.services.bigquery.model.Job() @@ -428,6 +428,10 @@ public void testLegacyQuerySinglePageEmptyResults() throws BigQuerySQLException BigQueryResult res = connectionSpy.executeSelect(SQL_QUERY); assertEquals(res.getTotalRows(), 0); assertEquals(QUERY_SCHEMA, res.getSchema()); + assertEquals( + false, + res.getResultSet() + .next()); // Validates that NPE does not occur when reading from empty ResultSet. verify(bigqueryRpcMock, times(1)) .createJobForQuery(any(com.google.api.services.bigquery.model.Job.class)); } 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 bf8d51314..24bf84f6e 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 @@ -3491,6 +3491,24 @@ public void testExecuteSelectDefaultConnectionSettings() throws SQLException { assertEquals(42, bigQueryResult.getTotalRows()); } + @Test + public void testExecuteSelectReadApiEmptyResultSet() throws SQLException { + ConnectionSettings connectionSettings = + ConnectionSettings.newBuilder() + .setJobTimeoutMs( + Long.MAX_VALUE) // Force executeSelect to use ReadAPI instead of fast query. + .setUseReadAPI(true) + .setUseQueryCache(false) + .build(); + Connection connection = bigquery.createConnection(connectionSettings); + String query = "SELECT TIMESTAMP '2022-01-24T23:54:25.095574Z' LIMIT 0"; + BigQueryResult bigQueryResult = connection.executeSelect(query); + + ResultSet rs = bigQueryResult.getResultSet(); + assertThat(rs.next()).isFalse(); + assertThat(bigQueryResult.getTotalRows()).isEqualTo(0); + } + @Test public void testExecuteSelectWithCredentials() throws SQLException { // This test validate that executeSelect uses the same credential provided by the BigQuery