Skip to content

Commit 40cd0a7

Browse files
authored
fix(bigquery-jdbc): explicitly set location when available for temporary dataset (#13508)
b/524850173
1 parent 341e51a commit 40cd0a7

3 files changed

Lines changed: 114 additions & 4 deletions

File tree

java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryStatement.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,11 +1419,14 @@ private void checkIfDatasetExistElseCreate(String datasetName) {
14191419
Dataset dataset = bigQuery.getDataset(DatasetId.of(datasetName));
14201420
if (dataset == null) {
14211421
LOG.info("Creating a hidden dataset: %s ", datasetName);
1422-
DatasetInfo datasetInfo =
1422+
DatasetInfo.Builder datasetInfoBuilder =
14231423
DatasetInfo.newBuilder(datasetName)
1424-
.setDefaultTableLifetime(this.querySettings.getDestinationDatasetExpirationTime())
1425-
.build();
1426-
bigQuery.create(datasetInfo);
1424+
.setDefaultTableLifetime(this.querySettings.getDestinationDatasetExpirationTime());
1425+
String location = this.connection.getLocation();
1426+
if (location != null && !location.isEmpty()) {
1427+
datasetInfoBuilder.setLocation(location);
1428+
}
1429+
bigQuery.create(datasetInfoBuilder.build());
14271430
}
14281431
}
14291432

java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryStatementTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import com.google.cloud.bigquery.BigQuery;
3535
import com.google.cloud.bigquery.BigQuery.QueryResultsOption;
3636
import com.google.cloud.bigquery.BigQueryOptions;
37+
import com.google.cloud.bigquery.DatasetId;
38+
import com.google.cloud.bigquery.DatasetInfo;
3739
import com.google.cloud.bigquery.Field;
3840
import com.google.cloud.bigquery.FieldList;
3941
import com.google.cloud.bigquery.FieldValueList;
@@ -711,4 +713,46 @@ public void testSetAndGetFetchSize() throws SQLException {
711713
bigQueryStatement.setFetchSize(100);
712714
assertEquals(100, bigQueryStatement.getFetchSize());
713715
}
716+
717+
@Test
718+
public void testTemporaryDatasetCreationRespectsConnectionLocation()
719+
throws SQLException, InterruptedException {
720+
// 1. Setup mock connection with location and destination dataset
721+
doReturn("europe-west3").when(bigQueryConnection).getLocation();
722+
doReturn("temp_dataset").when(bigQueryConnection).getDestinationDataset();
723+
724+
// Re-instantiate bigQueryStatement so it regenerates querySettings with these mocked connection
725+
// values
726+
BigQueryStatement statement = new BigQueryStatement(bigQueryConnection);
727+
BigQueryStatement statementSpy = Mockito.spy(statement);
728+
729+
// 2. Mock bigQuery.getDataset to return null (triggering creation)
730+
doReturn(null).when(bigquery).getDataset(eq(DatasetId.of("temp_dataset")));
731+
732+
// 2b. Mock bigQuery.create for dry run during getStatementType
733+
Job dryRunJobMock = getJobMock(null, null, StatementType.SELECT);
734+
doReturn(dryRunJobMock).when(bigquery).create(any(JobInfo.class));
735+
736+
// 3. Mock bigquery.queryWithTimeout(...) to return tableResult (so execution doesn't fail on
737+
// query execution)
738+
TableResult result = mock(TableResult.class);
739+
doReturn(result)
740+
.when(bigquery)
741+
.queryWithTimeout(any(QueryJobConfiguration.class), any(JobId.class), any());
742+
doReturn(mock(BigQueryJsonResultSet.class))
743+
.when(statementSpy)
744+
.processJsonResultSet(eq(result), any());
745+
746+
// 4. Capture DatasetInfo passed to bigQuery.create()
747+
ArgumentCaptor<DatasetInfo> datasetInfoCaptor = ArgumentCaptor.forClass(DatasetInfo.class);
748+
749+
// 5. Execute query
750+
statementSpy.executeQuery("SELECT 1");
751+
752+
// 6. Verify dataset was created with correct location
753+
verify(bigquery).create(datasetInfoCaptor.capture());
754+
DatasetInfo createdDatasetInfo = datasetInfoCaptor.getValue();
755+
assertEquals("temp_dataset", createdDatasetInfo.getDatasetId().getDataset());
756+
assertEquals("europe-west3", createdDatasetInfo.getLocation());
757+
}
714758
}

java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/it/ITStatementTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,15 @@
2424
import static org.junit.jupiter.api.Assertions.assertThrows;
2525
import static org.junit.jupiter.api.Assertions.assertTrue;
2626

27+
import com.google.api.gax.paging.Page;
2728
import com.google.cloud.ServiceOptions;
29+
import com.google.cloud.bigquery.BigQuery;
30+
import com.google.cloud.bigquery.BigQueryOptions;
31+
import com.google.cloud.bigquery.Dataset;
32+
import com.google.cloud.bigquery.DatasetId;
33+
import com.google.cloud.bigquery.FieldValueList;
34+
import com.google.cloud.bigquery.Table;
35+
import com.google.cloud.bigquery.TableResult;
2836
import java.sql.Connection;
2937
import java.sql.DriverManager;
3038
import java.sql.ResultSet;
@@ -412,4 +420,59 @@ int getSizeOfResultSet(ResultSet resultSet) throws SQLException {
412420
}
413421
return count;
414422
}
423+
424+
@Test
425+
public void testTemporaryDatasetLocation() throws SQLException, InterruptedException {
426+
String projectId = DEFAULT_CATALOG;
427+
String location = "europe-west3";
428+
String randomSuffix = String.valueOf(100 + new Random().nextInt(900));
429+
String tempDatasetName = "jdbc_temp_dataset_" + System.currentTimeMillis() + "_" + randomSuffix;
430+
431+
String customConnectionUrl =
432+
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId="
433+
+ projectId
434+
+ ";OAuthType=3;Timeout=3600;Location="
435+
+ location
436+
+ ";AllowLargeResults=true;LargeResultDataset="
437+
+ tempDatasetName
438+
+ ";";
439+
440+
BigQuery bigQuery = BigQueryOptions.getDefaultInstance().getService();
441+
try (Connection connection = DriverManager.getConnection(customConnectionUrl)) {
442+
Statement statement = connection.createStatement();
443+
String query = "SELECT 1 as val;";
444+
try (ResultSet rs = statement.executeQuery(query)) {
445+
assertTrue(rs.next());
446+
assertEquals(1, rs.getInt("val"));
447+
}
448+
449+
Dataset dataset = bigQuery.getDataset(DatasetId.of(tempDatasetName));
450+
assertNotNull(dataset);
451+
assertEquals(location, dataset.getLocation());
452+
453+
// Validate that the query results were written to a table in this dataset
454+
Page<Table> tables = dataset.list();
455+
boolean tableFound = false;
456+
for (Table table : tables.iterateAll()) {
457+
if (table.getTableId().getTable().startsWith("temp_table_")) {
458+
tableFound = true;
459+
TableResult tableData = bigQuery.listTableData(table.getTableId());
460+
assertNotNull(tableData);
461+
assertEquals(1, tableData.getTotalRows());
462+
for (FieldValueList row : tableData.iterateAll()) {
463+
assertEquals(1, row.get(0).getLongValue());
464+
}
465+
break;
466+
}
467+
}
468+
assertTrue(tableFound, "Expected temporary table was not found in the dataset");
469+
} finally {
470+
try {
471+
bigQuery.delete(
472+
DatasetId.of(tempDatasetName), BigQuery.DatasetDeleteOption.deleteContents());
473+
} catch (Exception e) {
474+
// Ignore cleanup exceptions to avoid masking the primary test failure
475+
}
476+
}
477+
}
415478
}

0 commit comments

Comments
 (0)