From f149302336582c9d9e8566b8c6127496d2d7abce Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Wed, 1 Apr 2026 13:34:50 -0400 Subject: [PATCH 1/9] chore: move bigquery jdbc external test to monorepo --- java-bigquery/.cloudbuild/jdbc_external.yaml | 28 + .../.cloudbuild/scripts/jdbc-external.sh | 8 + .../bigquery-external-jdbc-tests/Dockerfile | 19 + .../bigquery-external-jdbc-tests/Makefile | 62 + .../bigquery-external-jdbc-tests/pom.xml | 107 ++ .../src/main/java/JdbcStarter.java | 39 + .../bigquery/jdbc/BaseDatabaseMetadata.java | 585 ++++++ .../bigquery/jdbc/JdbcConnectionHelper.java | 132 ++ .../ITJdbcAuthenticationTest.java | 133 ++ .../jdbc/connection/ITJdbcConnectionTest.java | 495 +++++ .../jdbc/connection/ITJdbcDriverTest.java | 121 ++ .../metadata/ITJdbcDatabaseMetadataTest.java | 266 +++ .../metadata/ITJdbcResultSetMetadataTest.java | 84 + .../jdbc/statement/ITBigQueryJDBCTest.java | 1655 +++++++++++++++++ .../jdbc/statement/ITJdbcStatementTest.java | 413 ++++ 15 files changed, 4147 insertions(+) create mode 100644 java-bigquery/.cloudbuild/jdbc_external.yaml create mode 100644 java-bigquery/.cloudbuild/scripts/jdbc-external.sh create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Dockerfile create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Makefile create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/JdbcStarter.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java create mode 100644 java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java diff --git a/java-bigquery/.cloudbuild/jdbc_external.yaml b/java-bigquery/.cloudbuild/jdbc_external.yaml new file mode 100644 index 000000000000..b0aa3c1a13e9 --- /dev/null +++ b/java-bigquery/.cloudbuild/jdbc_external.yaml @@ -0,0 +1,28 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# Github action job to test core java library features on +# downstream client libraries before they are released. + +steps: +- name: 'gcr.io/cloud-devrel-public-resources/java11' + entrypoint: 'bash' + args: ['java-bigquery/.cloudbuild/scripts/jdbc-external.sh'', "${_VERSION}"] + secretEnv: ['SA_SECRET'] +availableSecrets: + secretManager: + - versionName: projects/$PROJECT_ID/secrets/GoogleJDBCServiceAccountSecret/versions/latest + env: 'SA_SECRET' +options: + workerPool: 'projects/bigquery-devtools-drivers/locations/us-east1/workerPools/java-bigquery-jdbc-pool' + logging: CLOUD_LOGGING_ONLY \ No newline at end of file diff --git a/java-bigquery/.cloudbuild/scripts/jdbc-external.sh b/java-bigquery/.cloudbuild/scripts/jdbc-external.sh new file mode 100644 index 000000000000..944106a3a851 --- /dev/null +++ b/java-bigquery/.cloudbuild/scripts/jdbc-external.sh @@ -0,0 +1,8 @@ +ROOT_FOLDER=$(git rev-parse --show-toplevel) + +cd ${ROOT_FOLDER} +source .kokoro/common.sh +install_modules java-bigquery + +cd ${ROOT_FOLDER}/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests +make integration-test \ No newline at end of file diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Dockerfile b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Dockerfile new file mode 100644 index 000000000000..4586a37d2c33 --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Dockerfile @@ -0,0 +1,19 @@ +FROM gcr.io/cloud-devrel-public-resources/java11 + +ARG JDBC_VERSION +ARG JDBC_JAR_PATH + +ENV container_jdbc_jar_path=/jdbc/simba/GoogleBigQueryJDBC42.jar + +COPY ./pom.xml /src/pom.xml +COPY ${JDBC_JAR_PATH} ${container_jdbc_jar_path} + +# Override SIMBA_JDBC_JAR_PATH with path inside the container +ENV JDBC_VERSION=${JDBC_VERSION} +ENV JDBC_JAR_PATH=${container_jdbc_jar_path} +ENV JDBC_DOCKER_ENV=true + +WORKDIR /src +RUN mvn install + +ENTRYPOINT [] diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Makefile b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Makefile new file mode 100644 index 000000000000..188895345ba8 --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/Makefile @@ -0,0 +1,62 @@ +# GOOGLE_APPLICATION_CREDENTIALS is required when running certain tests +SECRET=`cat $(GOOGLE_APPLICATION_CREDENTIALS)` + +SIMBA_JDBC_VERSION=${_VERSION} +SIMBA_ZIP_FILE="SimbaJDBCDriverforGoogleBigQuery42_$(SIMBA_JDBC_VERSION).zip" + +# Driver under test configuration +JDBC_FOLDER=drivers +JDBC_JAR_NAME=GoogleBigQueryJDBC42.jar +JDBC_JAR_PATH="$(JDBC_FOLDER)/$(JDBC_JAR_NAME)" +JDBC_VERSION=$(SIMBA_JDBC_VERSION) + +skipSurefire ?= true + +# Container name used during this test +CONTAINER_NAME=jdbc_test + +# no indentation for ifndef\endif due to their evaluation before execution +.check-env: | +ifndef GOOGLE_APPLICATION_CREDENTIALS + $(error GOOGLE_APPLICATION_CREDENTIALS is required to run tests) +endif + +# Important: By default, this command will skip unittests. +# To include unit tests, run: make integration-test skipSurefire=false +integration-test: + mvn -B -ntp \ + -Penable-integration-tests \ + -DtrimStackTrace=false \ + -DskipSurefire=$(skipSurefire) \ + -Dclirr.skip=true \ + -Denforcer.skip=true \ + -Dit.failIfNoSpecifiedTests=true \ + -Dit.test=$(test) \ + integration-test + +.docker-run: | + docker run -it \ + -v $(GOOGLE_APPLICATION_CREDENTIALS):/auth/application_creds.json \ + -e "GOOGLE_APPLICATION_CREDENTIALS=/auth/application_creds.json" \ + -v "$(GOOGLE_APPLICATION_CREDENTIALS).p12":/auth/application_creds.p12 \ + -v $(PWD):/src \ + -e "SA_SECRET=$(SECRET)" \ + -e "SA_SECRET_P12=/auth/application_creds.p12" \ + $(CONTAINER_NAME) $(args) + +download-simba: + mkdir -p $(JDBC_FOLDER) + gsutil -m cp gs://bq-dev-tools-simba-drivers-testing/simba-jdbc/$(SIMBA_ZIP_FILE) $(JDBC_FOLDER) + unzip -p ./$(JDBC_FOLDER)/$(SIMBA_ZIP_FILE) $(JDBC_JAR_NAME) > $(JDBC_JAR_PATH) + +docker-build: | + docker build --build-arg JDBC_JAR_PATH=$(JDBC_JAR_PATH) --build-arg JDBC_VERSION=$(JDBC_VERSION) -t $(CONTAINER_NAME) . + +docker-test-authentication: .check-env | + $(MAKE) .docker-run args="mvn -Dtest=ITJdbcAuthenticationTest test" + +docker-test test: .check-env | + $(MAKE) .docker-run args="mvn test -Dtest=$(test)" + +docker-test-all: .check-env | + $(MAKE) .docker-run args="mvn test" diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml new file mode 100644 index 000000000000..1d53b4484f6a --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml @@ -0,0 +1,107 @@ + + + + 4.0.0 + + org.example + bigquery-external-jdbc-tests + 1.0-SNAPSHOT + + + 11 + 11 + UTF-8 + + + + + com.google.cloud + libraries-bom + 26.58.0 + pom + import + + + + + + com.google.cloud + google-cloud-bigquery + + + + com.google.cloud + JDBC + ${env.JDBC_VERSION} + system + ${env.JDBC_JAR_PATH} + + + + + com.google.cloud + google-cloud-core + + + org.apache.avro + avro + 1.11.4 + + + junit + junit + test + 4.13.2 + + + com.google.truth + truth + test + 1.1.3 + + + org.mockito + mockito-core + test + 1.10.19 + + + joda-time + joda-time + test + 2.14.0 + + + + + + + docker + + + env.JDBC_DOCKER_ENV + + + + + /mvn/test-target + + + + diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/JdbcStarter.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/JdbcStarter.java new file mode 100644 index 000000000000..c7bd59288a6b --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/JdbcStarter.java @@ -0,0 +1,39 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.google.cloud.ServiceOptions; +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +public class JdbcStarter { + + public static void main(String[] args) throws SQLException { + final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + final String oauthType = "3"; // Google Application Credentials + + String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=" + + DEFAULT_CATALOG + + ";OAuthType=" + + oauthType + + ";Timeout=3600;"; + Connection connection = DriverManager.getConnection(connectionUrl); + Statement statement = connection.createStatement(); + statement.execute("SELECT 1;"); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java new file mode 100644 index 000000000000..2a7a9a2fcd09 --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java @@ -0,0 +1,585 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc; + +import static java.sql.Types.TIME; +import static java.sql.Types.TIMESTAMP; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class BaseDatabaseMetadata { + + public static int getSizeOfResultSet(ResultSet rs) throws SQLException { + int count = 0; + while (rs.next()) { + count++; + } + return count; + } + + public static List getInfoBySQL(Connection connection, String sqlCmd) + throws SQLException { + List result = new ArrayList<>(); + try { + Statement st = connection.createStatement(); + ResultSet rs = st.executeQuery(sqlCmd); + while (rs.next()) { + result.add(rs.getString(1)); + } + } catch (SQLException e) { + throw e; + } + return result; + } + + protected void verifyAllBooleanMethods(DatabaseMetaData metaData) throws SQLException { + assertFalse(metaData.allProceduresAreCallable()); // false + assertTrue(metaData.allTablesAreSelectable()); // true + + assertFalse(metaData.nullsAreSortedHigh()); // false + assertTrue(metaData.nullsAreSortedLow()); // true + assertFalse(metaData.nullsAreSortedAtEnd()); // false + assertFalse(metaData.nullsAreSortedAtStart()); // false + assertTrue(metaData.nullPlusNonNullIsNull()); // true + + assertFalse(metaData.usesLocalFiles()); // false + assertFalse(metaData.usesLocalFilePerTable()); // false + assertFalse(metaData.storesUpperCaseIdentifiers()); // false + assertFalse(metaData.storesLowerCaseIdentifiers()); // false + assertTrue(metaData.supportsMixedCaseQuotedIdentifiers()); + assertFalse(metaData.storesUpperCaseQuotedIdentifiers()); // false + assertFalse(metaData.storesLowerCaseQuotedIdentifiers()); // false + assertFalse(metaData.storesMixedCaseQuotedIdentifiers()); // false + + assertFalse(metaData.supportsAlterTableWithAddColumn()); // false + assertFalse(metaData.supportsAlterTableWithDropColumn()); // false + assertTrue(metaData.supportsColumnAliasing()); + assertTrue(metaData.nullPlusNonNullIsNull()); + assertFalse(metaData.supportsConvert()); // false + assertFalse(metaData.supportsConvert(TIME, TIMESTAMP)); // false + assertTrue(metaData.supportsTableCorrelationNames()); + assertTrue(metaData.supportsExpressionsInOrderBy()); + assertFalse(metaData.supportsOrderByUnrelated()); // false + assertTrue(metaData.supportsGroupBy()); + assertFalse(metaData.supportsGroupByUnrelated()); // false + assertTrue(metaData.supportsGroupByBeyondSelect()); + + assertTrue(metaData.supportsMultipleTransactions()); + assertFalse(metaData.supportsNonNullableColumns()); + assertTrue(metaData.supportsMinimumSQLGrammar()); + assertTrue(metaData.supportsCoreSQLGrammar()); + assertFalse(metaData.supportsExtendedSQLGrammar()); + assertTrue(metaData.supportsANSI92EntryLevelSQL()); + assertFalse(metaData.supportsANSI92IntermediateSQL()); + assertFalse(metaData.supportsANSI92FullSQL()); + assertFalse(metaData.supportsFullOuterJoins()); + assertFalse(metaData.supportsLimitedOuterJoins()); + assertTrue(metaData.isCatalogAtStart()); + assertTrue(metaData.supportsSchemasInDataManipulation()); + + assertTrue(metaData.supportsSchemasInTableDefinitions()); + assertTrue(metaData.supportsSchemasInIndexDefinitions()); + assertTrue(metaData.supportsSchemasInPrivilegeDefinitions()); + assertTrue(metaData.supportsCatalogsInDataManipulation()); + assertFalse(metaData.supportsPositionedDelete()); + assertFalse(metaData.supportsPositionedUpdate()); + + assertFalse(metaData.supportsSelectForUpdate()); + assertTrue(metaData.supportsStoredProcedures()); + assertTrue(metaData.supportsSubqueriesInComparisons()); + assertTrue(metaData.supportsSubqueriesInExists()); + assertTrue(metaData.supportsSubqueriesInIns()); + assertTrue(metaData.supportsSubqueriesInQuantifieds()); + assertTrue(metaData.supportsCorrelatedSubqueries()); + assertFalse(metaData.supportsOpenCursorsAcrossCommit()); + + assertFalse(metaData.supportsOpenCursorsAcrossRollback()); + assertTrue(metaData.supportsOpenStatementsAcrossCommit()); + assertTrue(metaData.supportsOpenStatementsAcrossRollback()); + + assertFalse( + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED)); // f + + assertFalse( + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ)); // f + assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE)); // f + assertFalse(metaData.supportsDifferentTableCorrelationNames()); // f + + assertFalse(metaData.dataDefinitionIgnoredInTransactions()); + assertFalse(metaData.doesMaxRowSizeIncludeBlobs()); + + assertTrue(metaData.supportsResultSetType(ResultSet.TYPE_FORWARD_ONLY)); // t + assertFalse(metaData.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE)); // f + assertFalse(metaData.supportsResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE)); // f + + assertTrue( + metaData.supportsResultSetConcurrency( + ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)); // t + assertFalse( + metaData.supportsResultSetConcurrency( + ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)); // f + assertFalse( + metaData.supportsResultSetConcurrency( + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)); + assertFalse( + metaData.supportsResultSetConcurrency( + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)); + assertFalse( + metaData.supportsResultSetConcurrency( + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)); + assertFalse( + metaData.supportsResultSetConcurrency( + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)); + + assertFalse(metaData.ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.ownDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.ownInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.ownInsertsAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.ownInsertsAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.othersUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.othersUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.othersUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.othersDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.othersDeletesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.othersDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.othersInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.othersInsertsAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.othersInsertsAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.updatesAreDetected(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.updatesAreDetected(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.updatesAreDetected(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.deletesAreDetected(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.deletesAreDetected(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.deletesAreDetected(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertFalse(metaData.insertsAreDetected(ResultSet.TYPE_FORWARD_ONLY)); + assertFalse(metaData.insertsAreDetected(ResultSet.TYPE_SCROLL_INSENSITIVE)); + assertFalse(metaData.insertsAreDetected(ResultSet.TYPE_SCROLL_SENSITIVE)); + + assertTrue(metaData.supportsBatchUpdates()); + assertFalse(metaData.supportsSavepoints()); + assertFalse(metaData.supportsNamedParameters()); + assertFalse(metaData.supportsMultipleOpenResults()); + assertFalse(metaData.supportsGetGeneratedKeys()); + + assertFalse(metaData.generatedKeyAlwaysReturned()); + assertFalse(metaData.supportsIntegrityEnhancementFacility()); + assertFalse(metaData.supportsDataDefinitionAndDataManipulationTransactions()); + assertFalse(metaData.isReadOnly()); + } + + protected void verifyIntMethods(DatabaseMetaData metaData) throws SQLException { + assertEquals(0, metaData.getMaxBinaryLiteralLength()); // 0 + assertEquals(0, metaData.getMaxCharLiteralLength()); // 0 + assertEquals(0, metaData.getMaxColumnsInGroupBy()); // 0 + assertEquals(0, metaData.getMaxColumnsInIndex()); // 0 + assertEquals(0, metaData.getMaxColumnsInOrderBy()); // 0 + assertEquals(0, metaData.getMaxColumnsInSelect()); // 0 + assertEquals(0, metaData.getMaxConnections()); // 0 + assertEquals(0, metaData.getMaxCursorNameLength()); // 0 + assertEquals(0, metaData.getMaxIndexLength()); // 0 + assertEquals(0, metaData.getMaxProcedureNameLength()); // 0 + assertEquals(0, metaData.getMaxRowSize()); // 0 + assertEquals(0, metaData.getMaxStatementLength()); // 0 + assertEquals(0, metaData.getMaxStatements()); // 0 + assertEquals(1000, metaData.getMaxTablesInSelect()); // 1000 + assertEquals(0, metaData.getMaxUserNameLength()); // 0 + } + + protected void verifyAllStringMethods(DatabaseMetaData metaData, String procedure) + throws SQLException { + assertEquals("`", metaData.getIdentifierQuoteString()); + assertTrue(procedure.equalsIgnoreCase(metaData.getProcedureTerm())); + } + + protected void verifyGetPrimaryKeys( + Connection connection, DatabaseMetaData metaData, String dataset) throws SQLException { + final String jdbctesttable = "JDBCTESTPRIMARYKEY"; + connection + .createStatement() + .execute( + "create or replace table " + + dataset + + "." + + jdbctesttable + + "(KEYCOLUMN int NOT NULL, SECONDCOLUMN string, THIRDCOLUMN timestamp);"); + ResultSet resultSet = + metaData.getPrimaryKeys(JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable); + assertFalse(resultSet.next()); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } + + protected void verifyTestProcedure(DatabaseMetaData metaData, String expectedProcedure) + throws SQLException { + assertEquals(expectedProcedure, metaData.getProcedureTerm()); + assertTrue(metaData.supportsStoredProcedures()); + ResultSet resultSet; + resultSet = metaData.getProcedureColumns("%", "%", "%", "%"); + assertEquals(0, getSizeOfResultSet(resultSet)); + resultSet = metaData.getProcedures("%", "%", "%"); + assertEquals(0, getSizeOfResultSet(resultSet)); + } + + protected void verifyDriverMetadata( + DatabaseMetaData metaData, + int expectedMajorVer, + int expectedMinorVersion, + String expectedDatabaseProductName, + String expectedDriverName, + Pattern versionPattern) + throws SQLException { + + assertEquals(expectedMajorVer, metaData.getJDBCMajorVersion()); + assertEquals(expectedMinorVersion, metaData.getJDBCMinorVersion()); + assertEquals(expectedDatabaseProductName, metaData.getDatabaseProductName()); + assertEquals(expectedDriverName, metaData.getDriverName()); + String driverVersion = metaData.getDriverVersion(); + Matcher m = versionPattern.matcher(driverVersion); + assertTrue(m.matches()); + int majorVersion = metaData.getDriverMajorVersion(); + int minorVersion = metaData.getDriverMinorVersion(); + assertEquals(Integer.parseInt(m.group(1)), majorVersion); + assertEquals(Integer.parseInt(m.group(2)), minorVersion); + } + + protected void verifyCatalogHelper( + DatabaseMetaData metaData, + String expectedCatalogSeparator, + String expectedCatalogTerm, + int expectedCatalogNameLength, + String defaultCatalog, + boolean isBeforeFirstSupported, + boolean isFirstSupported) + throws SQLException { + assertEquals(expectedCatalogSeparator, metaData.getCatalogSeparator()); + // Simba BQ JDBC driver maps Catalogs to projects + assertEquals(expectedCatalogTerm, metaData.getCatalogTerm()); + assertEquals(expectedCatalogNameLength, metaData.getMaxCatalogNameLength()); + + // This should return the project name of the connection + ResultSet resultSet = metaData.getCatalogs(); + + // Compares ResultSetMetadata. + // verifyResultSetMetaDataColumns(resultSet, DBMetadataResultSetMetadata.GET_CATALOGS); + if (isBeforeFirstSupported) { + assertTrue(resultSet.isBeforeFirst()); + } + + int count = 0; + boolean defaultCatalogFound = false; + while (resultSet.next()) { + if (count == 0 && isFirstSupported) { + assertTrue(resultSet.isFirst()); + } + ++count; + if (defaultCatalog.equals(resultSet.getString(1))) { + defaultCatalogFound = true; + break; + } + } + assertTrue(defaultCatalogFound); + resultSet.close(); + } + + protected void verifySchemaHelper( + Connection connection, + DatabaseMetaData metaData, + String schemaTerm, + int maxSchemaNameLength, + boolean isBeforeFirstSupported, + boolean isFirstSupported) + throws SQLException { + // Simba BQ JDBC driver maps Table Datasets to Schemas + assertEquals(schemaTerm, metaData.getSchemaTerm()); + assertEquals(maxSchemaNameLength, metaData.getMaxSchemaNameLength()); + // This should return all the datasets in the project of the connection + ResultSet resultSet = metaData.getSchemas(); + // Compares ResultSetMetadata. + // verifyResultSetMetaDataColumns(resultSet, DBMetadataResultSetMetadata.GET_CATALOGS); + if (isBeforeFirstSupported) { + assertTrue(resultSet.isBeforeFirst()); + } + + int count = 0; + Set allVisibleDatasets = new HashSet<>(); + while (resultSet.next()) { + allVisibleDatasets.add(resultSet.getString(1)); + if (count == 0 && isFirstSupported) { + assertTrue(resultSet.isFirst()); + } + ++count; + } + assertTrue(count >= 1); + List allAccessibleDatasets = + getInfoBySQL(connection, "SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA;"); + assertTrue(allVisibleDatasets.containsAll(allAccessibleDatasets)); + assertTrue(count >= allAccessibleDatasets.size()); + resultSet.close(); + } + + protected void verifyTableTypes(DatabaseMetaData metaData, Collection expectedTypes) + throws SQLException { + ResultSet resultSet = metaData.getTableTypes(); + Set types = new HashSet<>(); + while (resultSet.next()) { + String col = resultSet.getString(1); + types.add(col); + } + assertTrue(types.size() > 0); + assertTrue(types.containsAll(expectedTypes)); + } + + protected void verifyGetTables(Connection connection, DatabaseMetaData metaData, String dataset) + throws SQLException { + final String jdbctesttable = "JDBCTESTTABLE"; + final String jdbctestview = "JDBCTESTVIEW"; + + Statement statement = connection.createStatement(); + statement.execute( + String.format( + "create or replace table `%s.%s.%s` " + + "(INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);", + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable)); + statement.execute( + String.format( + "create or replace view `%s.%s.%s` " + " as select 1 as VIEWCOLUMN;", + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctestview)); + + ResultSet resultSet; + + // Pattern match for table + resultSet = + metaData.getTables( + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, "%", new String[] {"TABLE"}); + // verifyResultSetMetaDataColumns(resultSet, DBMetadataResultSetMetadata.GET_TABLES); + Set tables = new HashSet<>(); + while (resultSet.next()) { + tables.add(resultSet.getString(3)); + } + assertTrue(tables.contains("JDBCTESTTABLE")); + + // exact match for tablename + resultSet = + metaData.getTables( + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable, new String[] {"TABLE"}); + tables = new HashSet<>(); + while (resultSet.next()) { + tables.add(resultSet.getString(3)); + } + assertEquals(jdbctesttable, tables.iterator().next()); + + // Pattern match for view + resultSet = + metaData.getTables( + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, "%", new String[] {"VIEW"}); + Set views = new HashSet<>(); + while (resultSet.next()) { + views.add(resultSet.getString(3)); + } + assertTrue(views.contains(jdbctestview)); + + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + connection.createStatement().execute("drop view if exists " + dataset + "." + jdbctestview); + } + + // GetTablePrivileges not supported for JDBC and ODBC datasource. + // Returns empty resultset + protected void verifyGetTablePrivileges( + Connection connection, DatabaseMetaData metaData, String dataset) throws SQLException { + final String jdbctesttable = "JDBCTESTPRIVILEGETABLE"; + + Statement statement = connection.createStatement(); + statement.execute( + String.format( + "create or replace table `%s.%s.%s` (INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);", + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable)); + + ResultSet resultSet = + metaData.getTablePrivileges(JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable); + int cols = resultSet.getMetaData().getColumnCount(); + assertTrue(cols > 0); + int count = 0; + while (resultSet.next()) { + for (int i = 1; i <= cols; i++) { + assertNotNull(resultSet.getMetaData().getColumnName(i)); + assertNotNull(resultSet.getString(i)); + } + ++count; + } + assertEquals(0, count); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } + + protected void verifyGetColumnPrivileges( + Connection connection, DatabaseMetaData metaData, String dataset) throws SQLException { + final String jdbctesttable = "JDBCTESTPRIVILEGETABLE"; + + connection + .createStatement() + .execute( + "create or replace table " + + dataset + + "." + + jdbctesttable + + "(INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);"); + + ResultSet resultSet = + metaData.getColumnPrivileges( + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable, "%"); + int cols = resultSet.getMetaData().getColumnCount(); + assertTrue(cols > 0); + int count = 0; + while (resultSet.next()) { + for (int i = 1; i <= cols; i++) { + assertNotNull(resultSet.getMetaData().getColumnName(i)); + assertNotNull(resultSet.getString(i)); + } + ++count; + } + assertEquals(0, count); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } + + protected void verifyForeignKeys(Connection connection, DatabaseMetaData metaData, String dataset) + throws SQLException { + final String jdbctesttable = "JDBCTESTTABLEFOREIGNKEYS"; + + connection + .createStatement() + .execute( + "create or replace table " + + dataset + + "." + + jdbctesttable + + "(INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);"); + + ResultSet resultSet = + metaData.getImportedKeys(JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable); + int cols = resultSet.getMetaData().getColumnCount(); + assertTrue(cols > 0); + int count = 0; + while (resultSet.next()) { + for (int i = 1; i <= cols; i++) { + assertNotNull(resultSet.getMetaData().getColumnName(i)); + assertNotNull(resultSet.getString(i)); + } + ++count; + } + assertEquals(0, count); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } + + protected void verifyGetColumns(Connection connection, DatabaseMetaData metaData, String dataset) + throws SQLException { + final String jdbctesttable = "JDBCTESTCOLUMNS"; + Statement statement = connection.createStatement(); + statement.execute( + String.format( + "create or replace table `%s.%s.%s` (INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);", + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable)); + ResultSet resultSet = + metaData.getColumns( + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable, "%COLUMN"); + int cols = resultSet.getMetaData().getColumnCount(); + assertTrue(cols > 0); + // Resultset is not empty + int count = 0; + while (resultSet.next()) { + for (int i = 1; i <= cols; i++) { + assertNotNull(resultSet.getMetaData().getColumnName(i)); + } + ++count; + } + resultSet.close(); + assertTrue(count > 0); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } + + protected void verifyVersionColumns( + Connection connection, + DatabaseMetaData metaData, + String dataset, + int expectedNumCols, + Collection expectedColNames) + throws SQLException { + final String jdbctesttable = "JDBCTESTCOLUMNS"; + connection + .createStatement() + .execute( + "create or replace table " + + dataset + + "." + + jdbctesttable + + "(INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);"); + ResultSet resultSet = + metaData.getVersionColumns(JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable); + int numCols = resultSet.getMetaData().getColumnCount(); + assertEquals(expectedNumCols, numCols); + List colNames = new ArrayList<>(); + for (int i = 1; i <= numCols; i++) { + colNames.add(resultSet.getMetaData().getColumnName(i)); + } + assertTrue(colNames.containsAll(expectedColNames)); + resultSet.close(); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } + + protected void verifyIndexInfo(Connection connection, DatabaseMetaData metaData, String dataset) + throws SQLException { + final String jdbctesttable = "JDBCTESTTABLE"; + connection + .createStatement() + .execute( + "create or replace table " + + dataset + + "." + + jdbctesttable + + "(INTCOLUMN int, STRINGCOLUMN string, TIMECOLUMN timestamp);"); + ResultSet rs = + metaData.getIndexInfo( + JdbcConnectionHelper.DEFAULT_CATALOG, dataset, jdbctesttable, false, false); + assertFalse(rs.next()); // no index defined. + rs.close(); + connection.createStatement().execute("drop table if exists " + dataset + "." + jdbctesttable); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java new file mode 100644 index 000000000000..4e2b63da99ed --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java @@ -0,0 +1,132 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc; + +import com.google.cloud.ServiceOptions; +import com.google.cloud.bigquery.BigQuery; +import com.google.cloud.bigquery.BigQueryOptions; +import com.google.cloud.bigquery.QueryJobConfiguration; + +public class JdbcConnectionHelper { + + public static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + public static String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=" + + DEFAULT_CATALOG + + ";OAuthType=3;Timeout=3600;"; + + public static final String createDatasetQuery = + "CREATE SCHEMA IF NOT EXISTS `%s.%s` OPTIONS(default_table_expiration_days = 5)"; + public static final String dropSchema = "DROP SCHEMA IF EXISTS `%s.%s` CASCADE;"; + public static final String createTableQuery = + "CREATE OR REPLACE TABLE " + + " `%s.%s.%s` " + + " (\n" + + "`StringField` STRING,\n" + + "`BytesField` BYTES,\n" + + "`IntegerField` INTEGER,\n" + + "`FloatField` FLOAT64,\n" + + "`NumericField` NUMERIC,\n" + + "`BigNumericField` BIGNUMERIC,\n" + + "`BooleanField` BOOLEAN,\n" + + "`TimestampField` TIMESTAMP,\n" + + "`DateField` DATE,\n" + + "`TimeField` TIME,\n" + + "`DateTimeField` DATETIME,\n" + + "`GeographyField` GEOGRAPHY,\n" + + "`RecordField` STRUCT,\n" + + "`JsonField` JSON,\n" + + ");"; + public static final String insertQuery1 = + "INSERT INTO " + + " `%s.%s.%s` " + + " (\n" + + "StringField, BytesField,IntegerField,FloatField,NumericField,BigNumericField,BooleanField,\n" + + "TimestampField,DateField,TimeField,DateTimeField,GeographyField,RecordField,JsonField )\n" + + "VALUES('string1',CAST ('string1' AS BYTES),111,1.1, CAST('11.1E11' AS NUMERIC), \n" + + "CAST('1.1E37' AS BIGNUMERIC), TRUE,CAST('2001-05-1 8:05:01' AS TIMESTAMP), \n" + + "CAST('2001-05-1' AS DATE),CAST('5:1:11.041' AS TIME), CAST('2001-05-1 11:31:45' AS DATETIME), \n" + + "CAST(ST_GEOGFROMTEXT('POINT(1.500989010415034 -1.11471081311336843)') AS GEOGRAPHY), \n" + + "CAST(('name1', 1) AS STRUCT), \n" + + " JSON \"\"\"{\n" + + " \"name\": \"Alice1\",\n" + + " \"items\": [\n" + + " {\"product\": \"book1\", \"price\": 1},\n" + + " {\"product\": \"food1\", \"price\": 1}\n" + + " ]\n" + + " }\"\"\"\n" + + ");"; + public static final String insertQuery2 = + "INSERT INTO " + + " `%s.%s.%s` " + + " (\n" + + " StringField, BytesField,IntegerField,FloatField,NumericField,BigNumericField,BooleanField,\n" + + " TimestampField,DateField,TimeField,DateTimeField,GeographyField,RecordField,JsonField )\n" + + " VALUES('string2',CAST ('string2' AS BYTES),222,2.2, CAST('22.2E22' AS NUMERIC),\n" + + " CAST('2.2E37' AS BIGNUMERIC), TRUE,CAST('2002-05-2 8:05:02' AS TIMESTAMP),\n" + + " CAST('2002-05-2' AS DATE),CAST('5:2:22.042' AS TIME), CAST('2002-05-2 22:32:45' AS DATETIME),\n" + + " CAST(ST_GEOGFROMTEXT('POINT(2.500989020425034 -2.22472082322336843)') AS GEOGRAPHY),\n" + + " CAST(('name2', 2) AS STRUCT),\n" + + " JSON \"\"\"{\n" + + " \"name\": \"Alice2\",\n" + + " \"items\": [\n" + + " {\"product\": \"book2\", \"price\": 2},\n" + + " {\"product\": \"food2\", \"price\": 2}\n" + + " ]\n" + + " }\"\"\"\n" + + " );"; + + public static final String createProcedure = + "CREATE OR REPLACE PROCEDURE `%s.%s`.create_customer() \n" + + "\tBEGIN\n" + + "\t\tDECLARE id STRING;\n" + + "\t\tSET id = GENERATE_UUID();\n" + + "\t\tINSERT INTO `%s.%s.%s` (StringField) VALUES(id);\n" + + "\t\tSELECT FORMAT(\"Created customer.\");\n" + + "\tEND"; + + public static void setUpProcedure(String dataset, String table) throws InterruptedException { + { + BigQuery bigQuery = BigQueryOptions.getDefaultInstance().getService(); + bigQuery.query( + QueryJobConfiguration.of( + String.format( + createProcedure, DEFAULT_CATALOG, dataset, DEFAULT_CATALOG, dataset, table))); + } + } + + public static void setUpDataset(String dataset) throws InterruptedException { + BigQuery bigQuery = BigQueryOptions.getDefaultInstance().getService(); + bigQuery.query( + QueryJobConfiguration.of(String.format(createDatasetQuery, DEFAULT_CATALOG, dataset))); + } + + public static void setUpTable(String dataset, String table) throws InterruptedException { + BigQuery bigQuery = BigQueryOptions.getDefaultInstance().getService(); + bigQuery.query( + QueryJobConfiguration.of(String.format(createTableQuery, DEFAULT_CATALOG, dataset, table))); + bigQuery.query( + QueryJobConfiguration.of(String.format(insertQuery1, DEFAULT_CATALOG, dataset, table))); + bigQuery.query( + QueryJobConfiguration.of(String.format(insertQuery2, DEFAULT_CATALOG, dataset, table))); + } + + public static void cleanUp(String dataset) throws InterruptedException { + BigQuery bigQuery = BigQueryOptions.getDefaultInstance().getService(); + bigQuery.query(QueryJobConfiguration.of(String.format(dropSchema, DEFAULT_CATALOG, dataset))); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java new file mode 100644 index 000000000000..d0eedb2de980 --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java @@ -0,0 +1,133 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.authentication; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import java.io.File; +import com.google.cloud.ServiceOptions; +import java.sql.Connection; +import java.sql.DriverManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import java.sql.PreparedStatement; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class ITJdbcAuthenticationTest { + Connection connection = null; + + private static String connectionUriBase = "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;OAuthType=0;"; + + @Before + public void beforeTest(){ + connection = null; + } + + @After + public void afterTest() throws Exception { + if (connection != null){ + connection.close(); + } + connection = null; + } + + private static String requireEnvVar(String varName) { + String value = System.getenv(varName); + assertNotNull( + "Environment variable " + varName + " is required to perform these tests.", + System.getenv(varName)); + return value; + } + + private JsonObject getAuthJson() throws Exception { + final String secret = requireEnvVar("SA_SECRET"); + JsonObject authJson = JsonParser.parseString(secret).getAsJsonObject(); + + assertTrue(authJson.has("client_email")); + assertTrue(authJson.has("private_key")); + assertTrue(authJson.has("project_id")); + return authJson; + } + + private void validateConnectionUri(String connectionUri) throws Exception { + connection = + DriverManager.getConnection(connectionUri); + assertFalse(connection.isClosed()); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1"); + assertNotNull(preparedStatement); + preparedStatement.execute(); + preparedStatement.close(); + connection.close(); + } + + @Test + public void testConnectOAuthPvtKeyPath() throws Exception { + final JsonObject authJson = getAuthJson(); + File tempFile = File.createTempFile("auth", ".json"); + tempFile.deleteOnExit(); + Files.write(tempFile.toPath(), authJson.toString().getBytes()); + + final String connectionUri = connectionUriBase + + ";ProjectId=" + authJson.get("project_id").getAsString() + + ";OAuthServiceAcctEmail=" + + ";OAuthPvtKeyPath=" + tempFile.toPath(); + validateConnectionUri(connectionUri); + } + + @Test + public void testConnectOAuthPvtKeyAsPath() throws Exception { + final JsonObject authJson = getAuthJson(); + File tempFile = File.createTempFile("auth", ".json"); + tempFile.deleteOnExit(); + Files.write(tempFile.toPath(), authJson.toString().getBytes()); + + final String connectionUri = connectionUriBase + + ";ProjectId=" + authJson.get("project_id").getAsString() + + ";OAuthServiceAcctEmail=" + + ";OAuthPvtKey=" + tempFile.toPath(); + validateConnectionUri(connectionUri); + } + + @Test + public void testConnectOAuthPvtKeyAsJson() throws Exception { + final JsonObject authJson = getAuthJson(); + final String connectionUri = connectionUriBase + + ";ProjectId=" + authJson.get("project_id").getAsString() + + ";OAuthServiceAcctEmail=" + + ";OAuthPvtKey=" + authJson.toString(); + validateConnectionUri(connectionUri); + } + + @Disabled("Disabled until p12 file can be supplied") + @Test + public void testConnectOAuthPvtKeyP12() throws Exception { + final JsonObject authJson = getAuthJson(); + final String p12_file = requireEnvVar("SA_SECRET_P12"); + + final String connectionUri = connectionUriBase + + ";ProjectId=" + authJson.get("project_id").getAsString() + + ";OAuthServiceAcctEmail=" + authJson.get("client_email").getAsString() + + ";OAuthPvtKeyPath=" + p12_file; + validateConnectionUri(connectionUri); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java new file mode 100644 index 000000000000..6b2524dab96d --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java @@ -0,0 +1,495 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.connection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.ServiceOptions; +import java.sql.Array; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Statement; +import java.util.Properties; +import java.util.Random; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ITJdbcConnectionTest { + + private static final String DATASET = "EXT_JDBC_CONNECTION_TEST_DATASET"; + private static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + static Random random = new Random(); + static int randomNumber = random.nextInt(999); + private static final String TABLE_NAME = "EXT_JDBC_CONNECTION_TEST_TABLE" + randomNumber; + + private static String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=%s;OAuthType=3;Timeout=3600;"; + + @BeforeClass + public static void beforeClass() throws InterruptedException { + + JdbcConnectionHelper.setUpDataset(DATASET); + JdbcConnectionHelper.setUpTable(DATASET, TABLE_NAME); + JdbcConnectionHelper.setUpProcedure(DATASET, TABLE_NAME); + } + + @AfterClass + public static void afterClass() throws InterruptedException { + JdbcConnectionHelper.cleanUp(DATASET); + } + + @Test + public void testGetMetaData() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertFalse(connection.isClosed()); + DatabaseMetaData metaData = connection.getMetaData(); + assertNotNull(metaData); + assertEquals("Google BigQuery", metaData.getDatabaseProductName()); + assertEquals(4, metaData.getJDBCMajorVersion()); + assertEquals(2, metaData.getJDBCMinorVersion()); + assertEquals("Google BigQuery", metaData.getDatabaseProductName()); + assertEquals("SimbaJDBCDriverforGoogleBigQuery", metaData.getDriverName()); + } + + @Test + public void testCreateStatement() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertFalse(connection.isClosed()); + Statement statement = connection.createStatement(); + assertNotNull(statement); + statement.close(); + connection.close(); + } + + @Test + public void testPrepareStatement1() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1"); + assertNotNull(preparedStatement); + preparedStatement.execute(); + preparedStatement.close(); + connection.close(); + } + + @Test + public void testPrepareStatement2() throws SQLException { + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + PreparedStatement preparedStatement = + connection.prepareStatement("SELECT 1", Statement.NO_GENERATED_KEYS); + assertNotNull(preparedStatement); + preparedStatement.execute(); + preparedStatement.close(); + connection.close(); + } + + @Test + public void testPrepareStatement3() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> connection.prepareStatement("SELECT 1", new int[] {1, 2, 3})); + } + + @Test + public void testPrepareStatement4() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + PreparedStatement preparedStatement = + connection.prepareStatement( + "SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + assertNotNull(preparedStatement); + preparedStatement.execute(); + preparedStatement.close(); + connection.close(); + } + + @Test + public void testPrepareStatement5() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> + connection.prepareStatement( + "SELECT 1", + ResultSet.TYPE_FORWARD_ONLY, + ResultSet.CONCUR_READ_ONLY, + ResultSet.HOLD_CURSORS_OVER_COMMIT)); + } + + @Test + public void testPrepareStatement6() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> connection.prepareStatement("SELECT 1", new String[] {"a", "b"})); + } + + @Test + public void testPrepareCall1() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + try { + CallableStatement callableStatement = + connection.prepareCall( + String.format("call `%s.%s`.create_customer()", DEFAULT_CATALOG, DATASET)); + + assertNotNull(callableStatement); + callableStatement.execute(); + callableStatement.close(); + + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testPrepareCall2() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + try { + + CallableStatement callableStatement1 = + connection.prepareCall( + String.format("call `%s.%s`.create_customer()", DEFAULT_CATALOG, DATASET), + ResultSet.TYPE_FORWARD_ONLY, + ResultSet.CONCUR_READ_ONLY); + assertNotNull(callableStatement1); + callableStatement1.execute(); + assertNull(callableStatement1.getResultSet()); + callableStatement1.close(); + + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testPrepareCall3() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> + connection.prepareCall( + String.format("call %s.%s.create_customer()", DEFAULT_CATALOG, DATASET), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY, + ResultSet.HOLD_CURSORS_OVER_COMMIT)); + } + + @Test + public void testSetAutoCommit() throws SQLException { + Properties properties = new Properties(); + properties.setProperty("EnableSession", "1"); + + Connection connection1 = + DriverManager.getConnection(JdbcConnectionHelper.connectionUrl, properties); + connection1.setAutoCommit(false); + assertFalse(connection1.getAutoCommit()); + connection1.setAutoCommit(true); + assertTrue(connection1.getAutoCommit()); + connection1.close(); + } + + @Test + public void testCommitAndRollback() throws SQLException { + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + Properties properties = new Properties(); + properties.setProperty("EnableSession", "1"); + + Connection connection1 = + DriverManager.getConnection(JdbcConnectionHelper.connectionUrl, properties); + connection1.setAutoCommit(false); + Statement statement1 = connection1.createStatement(); + statement.execute( + String.format( + "CREATE TABLE IF NOT EXISTS %s.%s.autocommit_test_table (id INT)", + DEFAULT_CATALOG, DATASET)); + connection1.commit(); + + statement1.executeUpdate( + String.format( + "INSERT INTO %s.%s.autocommit_test_table (id) VALUES (1)", DEFAULT_CATALOG, DATASET)); + connection1.rollback(); + + ResultSet resultSet = + statement1.executeQuery( + String.format( + "SELECT COUNT(*) FROM %s.%s.autocommit_test_table", DEFAULT_CATALOG, DATASET)); + resultSet.next(); + assertEquals(0, resultSet.getInt(1)); // Table should be empty due to rollback + + connection1.setAutoCommit(true); + statement1.executeUpdate( + String.format( + "DROP TABLE IF EXISTS %s.%s.autocommit_test_table", DEFAULT_CATALOG, DATASET)); + statement1.close(); + connection1.close(); + statement.close(); + connection.close(); + } + + @Test + public void testSetCatalog() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + try { + String catalog = connection.getCatalog(); + if (catalog != null) { + connection.setCatalog(catalog); + assertEquals(catalog, connection.getCatalog()); + } + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testSetSchema() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + try { + String schema = connection.getSchema(); + if (schema != null) { + connection.setSchema(schema); + assertEquals(schema, connection.getSchema()); + } + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testSetClientInfo() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = databaseMetaData.getClientInfoProperties(); + while (resultSet.next()) { + assertNotNull(resultSet.getString("NAME")); + assertNull(resultSet.getString("DEFAULT_VALUE")); + } + connection.setClientInfo("APPLICATIONNAME", "MyTestApp"); + assertEquals("MyTestApp", connection.getClientInfo("APPLICATIONNAME")); + connection.setClientInfo("CLIENTUSER", "test"); + assertEquals("test", connection.getClientInfo("CLIENTUSER")); + + // Test setClientInfo with Properties + java.util.Properties properties = new java.util.Properties(); + properties.setProperty("CLIENTHOSTNAME", "testHost"); + connection.setClientInfo(properties); + assertEquals("testHost", connection.getClientInfo("CLIENTHOSTNAME")); + connection.setClientInfo("CLIENTHOSTNAME", "testHost23"); + assertEquals("testHost23", connection.getClientInfo("CLIENTHOSTNAME")); + connection.close(); + } + + @Test + public void testSetNetworkTimeout() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> connection.setNetworkTimeout(null, 1000)); // 1 second timeout + } + + @Test + public void testCreateClob() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows(SQLFeatureNotSupportedException.class, () -> connection.createClob()); + } + + @Test + public void testCreateBlob() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows(SQLFeatureNotSupportedException.class, () -> connection.createBlob()); + } + + @Test + public void testCreateNClob() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows(SQLFeatureNotSupportedException.class, () -> connection.createNClob()); + } + + @Test + public void testCreateSQLXML() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows(SQLFeatureNotSupportedException.class, () -> connection.createSQLXML()); + } + + @Test + public void testCreateArray() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + try { + Array array = connection.createArrayOf("INTEGER", new Object[] {1, 2, 3}); + assertNotNull(array); + + array.free(); // Remember to free resources + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testCreateStruct() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> connection.createStruct("ADDRESS", new Object[] {"123 Main St", "Anytown"})); + } + + @Test + public void testNativeSQL() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + String sql = "SELECT 1"; + String nativeSql = connection.nativeSQL(sql); + assertEquals(sql, nativeSql); + assertNotNull(nativeSql); + connection.close(); + } + + @Test + public void testSetSavepoint() throws SQLException { + Properties properties = new Properties(); + properties.setProperty("EnableSession", "1"); + + Connection connection1 = + DriverManager.getConnection(JdbcConnectionHelper.connectionUrl, properties); + connection1.setAutoCommit(false); + Statement statement = connection1.createStatement(); + statement.execute("SELECT 1; SELECT 2; SELECT 3;"); + assertThrows(SQLFeatureNotSupportedException.class, () -> connection1.setSavepoint()); + assertThrows( + SQLFeatureNotSupportedException.class, () -> connection1.setSavepoint("mySavepoint")); + assertThrows( + SQLFeatureNotSupportedException.class, + () -> connection1.releaseSavepoint(connection1.setSavepoint())); + connection1.setAutoCommit(true); + connection1.close(); + } + + // TODO:rewrite test + @Test + public void testAbort() throws SQLException, InterruptedException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + // This test is tricky to automate fully, as it involves asynchronous behavior + // We'll just test that we can call it without throwing an exception immediately + + // Create an ExecutorService to simulate asynchronous operation + java.util.concurrent.ExecutorService executor = + java.util.concurrent.Executors.newSingleThreadExecutor(); + executor.submit( + () -> { + try { + // This will likely throw an exception as the connection is already open + // But we mainly want to test that calling abort doesn't cause a direct error + assertFalse(connection.isClosed()); + assertTrue(connection.isClosed()); + System.out.println(connection.isClosed()); + connection.abort(java.util.concurrent.Executors.newSingleThreadExecutor()); + System.out.println(connection.isClosed()); + assertTrue(connection.isClosed()); + } catch (SQLException e) { + e.printStackTrace(); + // It's expected that calling abort might cause an exception + // depending on the state of the connection and driver. + System.out.println("Abort test threw an exception, which is expected in some cases."); + } + }); + + // Give the thread a short time to execute + Thread.sleep(100); + + // Shutdown the executor + executor.shutdown(); + executor.awaitTermination(100, java.util.concurrent.TimeUnit.MILLISECONDS); + connection.close(); + } + + @Test + public void testIsWrapperFor() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertTrue(connection.isWrapperFor(Connection.class)); + connection.close(); + } + + @Test + public void testIsValid() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + assertTrue(connection.isValid(0)); // 0 seconds timeout + connection.close(); + } + + @Test + public void testSimbaConnectionImpl() throws SQLException { + String OAUTH_TYPE = "3"; + String CONNECTION_URL = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=" + + DEFAULT_CATALOG + + ";OAuthType=" + + OAUTH_TYPE + + ";EnableSession=1;"; + + Connection connection = DriverManager.getConnection(CONNECTION_URL); + assertFalse(connection.isClosed()); + Statement statement = + connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + assertEquals(ResultSet.FETCH_FORWARD, statement.getFetchDirection()); + assertFalse(connection.isReadOnly()); + connection.setAutoCommit(false); + connection.close(); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java new file mode 100644 index 000000000000..92db3717f88b --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.connection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.ServiceOptions; +import com.google.cloud.bigquery.BigQuery; +import com.google.cloud.bigquery.BigQueryOptions; +import com.google.cloud.bigquery.Dataset; +import com.google.cloud.bigquery.DatasetId; +import java.sql.Driver; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import java.util.Random; +import org.junit.Test; + +public class ITJdbcDriverTest { + + private static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + static Random random = new Random(); + static int randomNumber = random.nextInt(999); + String createDataset = "CREATE SCHEMA `%s.%s` OPTIONS(default_table_expiration_days = 5);"; + String createQuery = + "CREATE OR REPLACE TABLE `%s.%s.%s` " + + " (\n" + + "`StringField` STRING,\n" + + "`BytesField` BYTES,\n" + + "`IntegerField` INTEGER" + + ");"; + String insertQuery1 = + "INSERT INTO `%s.%s.%s` " + + " (StringField, BytesField,IntegerField) " + + "VALUES('string1', CAST('string1' AS BYTES),111);"; + + String selectQuery = "SELECT * FROM `%s.%s.%s` ;"; + + @Test + public void testJDBCDriver() throws SQLException, InterruptedException { + String OAUTH_TYPE = "3"; + String CONNECTION_URL = + "jdbc:bigquery://https://bigquery.googleapis.com/bigquery/v2/:443;ProjectId=" + + DEFAULT_CATALOG + + ";OAuthType=" + + OAUTH_TYPE + + ";LOCATION=US;"; + + String dataset = "EXT_JDBC_DRIVER_TEST_DATASET" + random.nextInt(999); + String tableName = "EXT_JDBC_DRIVER_TEST_TABLE" + randomNumber; + + Driver driver = DriverManager.getDriver(CONNECTION_URL); + + Connection con = driver.connect(CONNECTION_URL, new Properties()); + assertTrue(driver.acceptsURL(CONNECTION_URL)); + assertFalse(driver.jdbcCompliant()); + assertEquals(1, driver.getMajorVersion()); + assertEquals(6, driver.getMinorVersion()); + + Statement statement = con.createStatement(); + statement.execute(String.format(createDataset, DEFAULT_CATALOG, dataset)); + statement.execute(String.format(createQuery, DEFAULT_CATALOG, dataset, tableName)); + boolean insertResult = + statement.execute(String.format(insertQuery1, DEFAULT_CATALOG, dataset, tableName)); + assertFalse(insertResult); + statement.execute(String.format(selectQuery, DEFAULT_CATALOG, dataset, tableName)); + ResultSet res = statement.getResultSet(); + assertTrue(res.next()); + JdbcConnectionHelper.cleanUp(dataset); + con.close(); + } + + @Test + public void testDriverLocation() throws SQLException, InterruptedException { + + String datasetUS = "EXT_JDBC_DRIVER_US_TEST_DATASET" + random.nextInt(999); + String tableNameUS = "EXT_JDBC_DRIVER_US_TEST_TABLE" + randomNumber; + String OAUTH_TYPE = "3"; + String CONNECTION_URL = + "jdbc:bigquery://https://bigquery.googleapis.com/bigquery/v2/:443;ProjectId=%s;OAuthType=%s;LOCATION=%s;"; + + // US Connection + Connection connectionUS = + DriverManager.getConnection( + String.format(CONNECTION_URL, DEFAULT_CATALOG, OAUTH_TYPE, "us-east5")); + Statement statementUS = connectionUS.createStatement(); + statementUS.execute(String.format(createDataset, DEFAULT_CATALOG, datasetUS)); + statementUS.execute(String.format(createQuery, DEFAULT_CATALOG, datasetUS, tableNameUS)); + boolean insertResult = + statementUS.execute(String.format(insertQuery1, DEFAULT_CATALOG, datasetUS, tableNameUS)); + assertFalse(insertResult); + statementUS.execute(String.format(selectQuery, DEFAULT_CATALOG, datasetUS, tableNameUS)); + ResultSet res = statementUS.getResultSet(); + assertTrue(res.next()); + + BigQuery bigQuery = BigQueryOptions.getDefaultInstance().getService(); + Dataset retrievedDataset = bigQuery.getDataset(DatasetId.of(DEFAULT_CATALOG, datasetUS)); + assertEquals("us-east5", retrievedDataset.getLocation()); + JdbcConnectionHelper.cleanUp(datasetUS); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java new file mode 100644 index 000000000000..436d1de0c030 --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java @@ -0,0 +1,266 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.metadata; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.bigquery.jdbc.BaseDatabaseMetadata; +import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.ServiceOptions; +import com.google.cloud.bigquery.BigQuery; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Random; +import java.util.regex.Pattern; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ITJdbcDatabaseMetadataTest extends BaseDatabaseMetadata { + + private static final Pattern VERSION_PATTERN = + Pattern.compile("^(\\d+)\\.(\\d+)(?:\\.\\d+)+\\s*.*"); + private static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + private static final String DATASET = "EXT_JDBC_DBMETADATA_TEST_DATASET"; + static Random random = new Random(); + static int randomNumber = random.nextInt(999); + private static final String TABLE_NAME = "EXT_JDBC_DBMETADATA_TEST_TABLE" + randomNumber; + private static String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=%s;OAuthType=3;Timeout=3600;"; + private static BigQuery bigQuery; + + @BeforeClass + public static void beforeClass() throws InterruptedException { + // Set up Dataset + JdbcConnectionHelper.setUpDataset(DATASET); + JdbcConnectionHelper.setUpTable(DATASET, TABLE_NAME); + } + + @AfterClass + public static void afterClass() throws InterruptedException { + JdbcConnectionHelper.cleanUp(DATASET); + } + + @Test + public void testGetCatalogs() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifyCatalogHelper(metaData, ".", "Project", 128, DEFAULT_CATALOG, true, true); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + // This test is throwing the following error: [Simba][BigQueryJDBCDriver](100068) Error fetching + // metadata + @Test + public void testGetSchemas() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifySchemaHelper(connection, metaData, "Dataset", 1024, true, true); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testGetTableTypes() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + // this is either 3 or 4 in different projects + + verifyTableTypes(metaData, Arrays.asList("EXTERNAL", "TABLE", "VIEW")); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testGetTables() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifyGetTables(connection, metaData, DATASET); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + // this currently returns empty. + // TODO: Make it return non-empty + @Test + public void testGetTablePrivileges() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifyGetTablePrivileges(connection, metaData, DATASET); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testGetClientInfoProperties() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + ResultSet resultSet = metaData.getClientInfoProperties(); + // Resultset is not empty + assertTrue(resultSet.next()); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testGetColumns() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifyGetColumns(connection, metaData, DATASET); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testDriverMetadataInfo() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifyDriverMetadata( + metaData, 4, 2, "Google BigQuery", "SimbaJDBCDriverforGoogleBigQuery", VERSION_PATTERN); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testProcedure() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + + verifyTestProcedure(metaData, "procedure"); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testAllBooleanMethods() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + // This method toggles between true and false in different environments + assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE)); // f + assertFalse( + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)); + assertFalse( + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED)); // f + + assertFalse( + metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ)); // f + assertTrue(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE)); + assertEquals(Connection.TRANSACTION_SERIALIZABLE, metaData.getDefaultTransactionIsolation()); + assertTrue(metaData.supportsTransactions()); + + verifyAllBooleanMethods(metaData); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testAllIntMethods() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + verifyIntMethods(metaData); + assertEquals(2, metaData.getResultSetHoldability()); // 2 + assertEquals(2, metaData.getDatabaseMajorVersion()); // 2 + assertEquals(0, metaData.getDatabaseMinorVersion()); // 0 + assertEquals(2, metaData.getSQLStateType()); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testAllStringMethods() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + verifyAllStringMethods(metaData, "procedure"); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } + + @Test + public void testGetPrimaryKeys() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + DatabaseMetaData metaData = connection.getMetaData(); + try { + verifyGetPrimaryKeys(connection, metaData, DATASET); + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java new file mode 100644 index 000000000000..02dc4eecacbc --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.metadata; + +import static org.junit.Assert.assertEquals; + +import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.ServiceOptions; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Random; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ITJdbcResultSetMetadataTest { + + private static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + static Random random = new Random(); + static int randomNumber = random.nextInt(999); + private static final String TABLE_NAME = "EXT_JDBC_RSMETADATA_TEST_TABLE" + randomNumber; + private static final String DATASET = "EXT_JDBC_RSMETADATA_TEST_DATASET"; + private static ResultSetMetaData metaData; + + @BeforeClass + public static void beforeClass() throws InterruptedException { + JdbcConnectionHelper.setUpDataset(DATASET); + JdbcConnectionHelper.setUpTable(DATASET, TABLE_NAME); + } + + @AfterClass + public static void afterClass() throws InterruptedException { + JdbcConnectionHelper.cleanUp(DATASET); + } + + @Test + public void testResultSetMetadata() throws SQLException { + String selectData = "SELECT * FROM " + DATASET + "." + TABLE_NAME + ";"; + Connection connection = + DriverManager.getConnection( + String.format(JdbcConnectionHelper.connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(selectData); + metaData = resultSet.getMetaData(); + try { + assertEquals(DEFAULT_CATALOG, metaData.getCatalogName(1)); + + assertEquals(14, metaData.getColumnCount()); + + assertEquals("StringField", metaData.getColumnName(1)); + assertEquals("StringField", metaData.getColumnLabel(1)); + assertEquals("java.lang.String", metaData.getColumnClassName(1)); + assertEquals(65535, metaData.getColumnDisplaySize(1)); + assertEquals("STRING", metaData.getColumnTypeName(1)); + assertEquals(12, metaData.getColumnType(1)); + + assertEquals(26, metaData.getColumnDisplaySize(8)); + assertEquals("TIMESTAMP", metaData.getColumnTypeName(8)); + assertEquals(93, metaData.getColumnType(8)); + + } catch (SQLException e) { + e.printStackTrace(); + } + connection.close(); + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java new file mode 100644 index 000000000000..227c210aab5c --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java @@ -0,0 +1,1655 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.statement; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.ServiceOptions; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.Date; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Properties; +import java.util.Random; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +public class ITBigQueryJDBCTest { + + static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + private static String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=%s;OAuthType=3;Timeout=3600;"; + private static String noReadAPIConnectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=%s;OAuthType=3;Timeout=3600;" + + "EnableHighThroughputAPI=0;HighThroughputActivationRatio=30;HighThroughputMinTableSize=200000000;"; + static final String session_enabled_connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3;EnableSession=1"; + private static final String BASE_QUERY = + "SELECT * FROM bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2017 order by" + + " trip_distance asc LIMIT %s"; + private static final String CONSTRAINTS_DATASET = "JDBC_CONSTRAINTS_TEST_DATASET"; + private static final String CONSTRAINTS_TABLE_NAME = "JDBC_CONSTRAINTS_TEST_TABLE"; + private static final String CONSTRAINTS_TABLE_NAME2 = "JDBC_CONSTRAINTS_TEST_TABLE2"; + private static final String CONSTRAINTS_TABLE_NAME3 = "JDBC_CONSTRAINTS_TEST_TABLE3"; + private static final String DATASET = "JDBC_BIGQUERY_TEST_DATASET"; + static Random random = new Random(); + static int randomNumber = random.nextInt(999); + private static final String TABLE_NAME = "EXT_JDBC_BIGQUERY_TEST_TABLE" + randomNumber; + + @BeforeClass + public static void beforeClass() throws InterruptedException { + JdbcConnectionHelper.setUpDataset(DATASET); + JdbcConnectionHelper.setUpTable(DATASET, TABLE_NAME); + JdbcConnectionHelper.setUpProcedure(DATASET, TABLE_NAME); + } + + @AfterClass + public static void afterClass() throws InterruptedException { + JdbcConnectionHelper.cleanUp(DATASET); + } + + @Test + public void testValidApplicationDefaultCredentialsAuthentication() throws SQLException { + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=" + + DEFAULT_CATALOG + + ";"; + + Connection connection = DriverManager.getConnection(connection_uri); + assertNotNull(connection); + assertFalse(connection.isClosed()); + connection.close(); + } + + @Test + public void testFastQueryPathSmall() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + String query = + "SELECT DISTINCT repository_name FROM `bigquery-public-data.samples.github_timeline` LIMIT" + + " 850"; + ResultSet jsonResultSet = bigQueryStatement.executeQuery(query); + assertEquals(850, resultSetRowCount(jsonResultSet)); + connection.close(); + } + + @Test + public void testFastQueryPathEmpty() throws SQLException { + String query = + "SELECT DISTINCT repository_name FROM `bigquery-public-data.samples.github_timeline` LIMIT" + + " 0"; + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + ResultSet jsonResultSet = bigQueryStatement.executeQuery(query); + assertEquals(0, resultSetRowCount(jsonResultSet)); + connection.close(); + } + + @Test + public void testStatelessQueryPathSmall() throws SQLException { + Properties jobCreationMode = new Properties(); + jobCreationMode.setProperty("JobCreationMode", "2"); + Connection connectionUseStateless = + DriverManager.getConnection(JdbcConnectionHelper.connectionUrl, jobCreationMode); + + Statement statement = connectionUseStateless.createStatement(); + + String query = + "SELECT DISTINCT repository_name FROM `bigquery-public-data.samples.github_timeline` LIMIT" + + " 850"; + ResultSet jsonResultSet = statement.executeQuery(query); + assertEquals(850, resultSetRowCount(jsonResultSet)); + + String queryEmpty = + "SELECT DISTINCT repository_name FROM `bigquery-public-data.samples.github_timeline` LIMIT" + + " 0"; + ResultSet jsonResultSetEmpty = statement.executeQuery(queryEmpty); + assertEquals(0, resultSetRowCount(jsonResultSetEmpty)); + connectionUseStateless.close(); + } + + @Test + public void testFastQueryPathMedium() throws SQLException { + String query = + "SELECT repository_name FROM `bigquery-public-data.samples.github_timeline` LIMIT 9000"; + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + ResultSet jsonResultSet = bigQueryStatement.executeQuery(query); + assertEquals(9000, resultSetRowCount(jsonResultSet)); + connection.close(); + } + + @Test + public void testFastQueryPathLarge() throws SQLException { + String query = + "SELECT repository_name FROM `bigquery-public-data.samples.github_timeline` LIMIT 18000"; + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + ResultSet jsonResultSet = bigQueryStatement.executeQuery(query); + assertEquals(18000, resultSetRowCount(jsonResultSet)); + connection.close(); + } + + @Test + // reads using ReadAPI and makes sure that they are in order, which implies threads worked + // correctly + public void testIterateOrderArrowMultiThread() throws SQLException { + int expectedCnt = 200000; + String longQuery = String.format(BASE_QUERY, expectedCnt); + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + ResultSet rs = bigQueryStatement.executeQuery(longQuery); + int cnt = 0; + double oldTriDis = 0.0d; + while (rs.next()) { + double tripDis = rs.getDouble("trip_distance"); + ++cnt; + assertTrue(oldTriDis <= tripDis); + oldTriDis = tripDis; + } + assertEquals(expectedCnt, cnt); // all the records were retrieved + connection.close(); + } + + @Test + public void testReadAPIPathLarge() throws SQLException { + Properties withReadApi = new Properties(); + withReadApi.setProperty("EnableHighThroughputAPI", "1"); + withReadApi.setProperty("HighThroughputActivationRatio", "2"); + withReadApi.setProperty("HighThroughputMinTableSize", "1000"); + withReadApi.setProperty("MaxResults", "300"); + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG), withReadApi); + Statement statement = connection.createStatement(); + int expectedCnt = 5000; + String longQuery = String.format(BASE_QUERY, expectedCnt); + ResultSet arrowResultSet = statement.executeQuery(longQuery); + assertEquals(expectedCnt, resultSetRowCount(arrowResultSet)); + arrowResultSet.close(); + connection.close(); + } + + @Test + public void testReadAPIPathLargeWithThresholdParameters() throws SQLException { + String connectionUri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3;MaxResults=300;HighThroughputActivationRatio=2;" + + "HighThroughputMinTableSize=100;EnableHighThroughputAPI=1"; + Connection connection = DriverManager.getConnection(connectionUri); + Statement statement = connection.createStatement(); + int expectedCnt = 1000; + String longQuery = String.format(BASE_QUERY, expectedCnt); + ResultSet arrowResultSet = statement.executeQuery(longQuery); + assertEquals(expectedCnt, resultSetRowCount(arrowResultSet)); + arrowResultSet.close(); + connection.close(); + } + + @Test + public void testReadAPIPathLargeWithThresholdNotMet() throws SQLException { + String connectionUri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3;HighThroughputActivationRatio=4;" + + "HighThroughputMinTableSize=100;EnableHighThroughputAPI=1"; + Connection connection = DriverManager.getConnection(connectionUri); + Statement statement = connection.createStatement(); + int expectedCnt = 5000; + String longQuery = String.format(BASE_QUERY, expectedCnt); + ResultSet arrowResultSet = statement.executeQuery(longQuery); + assertEquals(expectedCnt, resultSetRowCount(arrowResultSet)); + arrowResultSet.close(); + connection.close(); + } + + @Test + public void testSmallSelectAndVerifyResults() throws SQLException { + String query = + "SELECT repository_name FROM `bigquery-public-data.samples.github_timeline` WHERE" + + " repository_name LIKE 'X%' LIMIT 10"; + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + ResultSet resultSet = bigQueryStatement.executeQuery(query); + int rowCount = 0; + while (resultSet.next()) { + assertTrue(resultSet.getString(1).startsWith("X")); + rowCount++; + } + assertEquals(10, rowCount); + connection.close(); + } + + @Test + public void testInvalidQuery() throws SQLException { + String query = "SELECT *"; + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + + try { + bigQueryStatement.executeQuery(query); + Assert.fail(); + } catch (Exception e) { + assertTrue(e.getMessage().contains("SELECT * must have a FROM clause")); + } + connection.close(); + } + + @Test + public void testLocation() throws SQLException { + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3;LOCATION=EU"; + + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + assertTrue(connection.isValid(1)); + + Statement statement = connection.createStatement(); + + // Query a dataset in the EU + String query = + "SELECT name FROM `bigquery-public-data.covid19_italy_eu.data_by_province` LIMIT 100"; + ResultSet resultSet = statement.executeQuery(query); + assertEquals(100, resultSetRowCount(resultSet)); + + String connection_uri_null_location = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3"; + + Connection connection2 = + DriverManager.getConnection(connection_uri_null_location, new Properties()); + assertNotNull(connection2); + assertTrue(connection2.isValid(1)); + connection.close(); + + connection2.close(); + } + + @Test + public void testIncorrectLocation() throws SQLException { + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3;LOCATION=europe-west3"; + + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + assertTrue(connection.isValid(1)); + + // Query a dataset in the US + Statement statement = connection.createStatement(); + String query = "SELECT * FROM `bigquery-public-data.samples.github_timeline` LIMIT 180"; + Exception ex = assertThrows(Exception.class, () -> statement.executeQuery(query)); + assertNotNull(ex); + assertTrue(ex.getMessage().contains("Access Denied")); + connection.close(); + } + + @Test + public void testRollbackOnConnectionClosed() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE1" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (15, 'Farhan', %s);", + DATASET, TRANSACTION_TABLE, randomNumber); + String updateQuery = + String.format( + "UPDATE %s.%s SET age = 12 WHERE age = %s;", DATASET, TRANSACTION_TABLE, randomNumber); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s WHERE id = 12;", DATASET, TRANSACTION_TABLE); + + Connection connection1 = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection1.createStatement(); + bigQueryStatement.execute(createTransactionTable); + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + connection.setAutoCommit(false); + Statement statement = connection.createStatement(); + + boolean status = statement.execute(insertQuery); + assertFalse(status); + int rows = statement.executeUpdate(updateQuery); + assertEquals(1, rows); + status = statement.execute(selectQuery); + assertTrue(status); + connection.close(); + + // Separate query to check if transaction rollback worked + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + assertFalse(resultSet.next()); + + bigQueryStatement.execute( + String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TRANSACTION_TABLE)); + connection.close(); + } + + @Test + public void testSingleStatementTransaction() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE2" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String beginTransaction = "BEGIN TRANSACTION; "; + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (12, 'Farhan', %s);", + DATASET, TRANSACTION_TABLE, randomNumber); + String updateQuery = + String.format( + "UPDATE %s.%s SET age = 14 WHERE age = %s;", DATASET, TRANSACTION_TABLE, randomNumber); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s WHERE id = 12;", DATASET, TRANSACTION_TABLE); + String commitTransaction = "COMMIT TRANSACTION;"; + + String transactionQuery = + beginTransaction + + insertQuery + + insertQuery + + updateQuery + + selectQuery + + commitTransaction; + + Connection connection1 = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection1.createStatement(); + bigQueryStatement.execute(createTransactionTable); + + // Run the transaction + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + Statement statement = connection.createStatement(); + statement.execute(transactionQuery); + + // Test each query's result with getMoreResults + int resultsCount = 0; + boolean hasMoreResult = statement.getMoreResults(); + while (hasMoreResult || statement.getUpdateCount() != -1) { + if (statement.getUpdateCount() == -1) { + ResultSet result = statement.getResultSet(); + assertTrue(result.next()); + assertEquals(-1, statement.getUpdateCount()); + } else { + assertTrue(statement.getUpdateCount() > -1); + } + hasMoreResult = statement.getMoreResults(); + resultsCount++; + } + + // Check the transaction was actually committed. + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + int rowCount = 0; + while (resultSet.next()) { + rowCount++; + assertEquals(14, resultSet.getInt(3)); + } + assertEquals(2, rowCount); + + bigQueryStatement.execute( + String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TRANSACTION_TABLE)); + connection.close(); + } + + @Test + public void testConnectionWithMultipleTransactionCommits() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_MULTI_COMMIT_TABLE" + randomNumber; + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (12, 'DwightShrute', %s);", + DATASET, TRANSACTION_TABLE, randomNumber); + String updateQuery = + String.format( + "UPDATE %s.%s SET age = 14 WHERE age = %s;", DATASET, TRANSACTION_TABLE, randomNumber); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s WHERE id = 12;", DATASET, TRANSACTION_TABLE); + + Connection setupConnection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement setupStatement = setupConnection.createStatement(); + setupStatement.execute(createTransactionTable); + setupStatement.close(); + setupConnection.close(); + + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + connection.setAutoCommit(false); + + Statement statement = connection.createStatement(); + statement.execute(insertQuery); + statement.execute(updateQuery); + connection.commit(); // First transaction + + // After commit, a new transaction should have started. + // Executing another query and then rolling it back. + String insertQuery2 = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (15, 'MichaelScott', 25);", + DATASET, TRANSACTION_TABLE); + statement.execute(insertQuery2); + connection.rollback(); // Second transaction + + // Verify state with a separate connection + Connection verifyConnection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement verifyStatement = verifyConnection.createStatement(); + ResultSet resultSet = verifyStatement.executeQuery(selectQuery); + int count = 0; + while (resultSet.next()) { + count++; + assertEquals(14, resultSet.getInt("age")); + } + assertEquals(1, count); // Only first transaction should be committed. + + // Verify the second insert was rolled back + ResultSet rs2 = + verifyStatement.executeQuery( + String.format("SELECT * FROM %s.%s WHERE id=15", DATASET, TRANSACTION_TABLE)); + assertFalse(rs2.next()); + + verifyStatement.execute( + String.format("DROP TABLE IF EXISTS %s.%s", DATASET, TRANSACTION_TABLE)); + + verifyStatement.close(); + verifyConnection.close(); + statement.close(); + connection.close(); + } + + @Test + public void testScript() throws SQLException { + String BASE_QUERY = + "SELECT * FROM bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2017 order by" + + " trip_distance asc LIMIT %s;"; + String query1 = String.format(BASE_QUERY, 5000); + String query2 = String.format(BASE_QUERY, 7000); + String query3 = String.format(BASE_QUERY, 9000); + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + bigQueryStatement.execute(query1 + query2 + query3); + ResultSet resultSet = bigQueryStatement.getResultSet(); + assertEquals(5000, resultSetRowCount(resultSet)); + + boolean hasMoreResult = bigQueryStatement.getMoreResults(); + assertTrue(hasMoreResult); + resultSet = bigQueryStatement.getResultSet(); + assertEquals(7000, resultSetRowCount(resultSet)); + + hasMoreResult = bigQueryStatement.getMoreResults(); + assertTrue(hasMoreResult); + resultSet = bigQueryStatement.getResultSet(); + assertEquals(9000, resultSetRowCount(resultSet)); + connection.close(); + } + + @Test + public void testMultiStatementTransactionRollbackByUser() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE3" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (12, 'Farhan', %s);", + DATASET, TRANSACTION_TABLE, randomNumber); + String updateQuery = + String.format( + "UPDATE %s.%s SET age = 14 WHERE age = %s;", DATASET, TRANSACTION_TABLE, randomNumber); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s WHERE id = 12;", DATASET, TRANSACTION_TABLE); + + Connection connection1 = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection1.createStatement(); + bigQueryStatement.execute(createTransactionTable); + + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + connection.setAutoCommit(false); + Statement statement = connection.createStatement(); + + boolean status = statement.execute(insertQuery); + assertFalse(status); + int rows = statement.executeUpdate(updateQuery); + assertEquals(1, rows); + status = statement.execute(selectQuery); + assertTrue(status); + connection.rollback(); + + // Separate query to check if transaction rollback worked + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + assertFalse(resultSet.next()); + + bigQueryStatement.execute( + String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TRANSACTION_TABLE)); + connection.close(); + } + + @Test + public void testMultiStatementTransactionDoesNotCommitWithoutCommit() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE4" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (12, 'Farhan', %s);", + DATASET, TRANSACTION_TABLE, randomNumber); + String updateQuery = + String.format( + "UPDATE %s.%s SET age = 14 WHERE age = %s;", DATASET, TRANSACTION_TABLE, randomNumber); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s WHERE id = 12;", DATASET, TRANSACTION_TABLE); + + Connection connection1 = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection1.createStatement(); + bigQueryStatement.execute(createTransactionTable); + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + connection.setAutoCommit(false); + Statement statement = connection.createStatement(); + + boolean status = statement.execute(insertQuery); + assertFalse(status); + int rows = statement.executeUpdate(updateQuery); + assertEquals(1, rows); + status = statement.execute(selectQuery); + assertTrue(status); + + // Separate query to check nothing committed + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + assertFalse(resultSet.next()); + + bigQueryStatement.execute( + String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TRANSACTION_TABLE)); + statement.close(); + connection.close(); + } + + @Test + public void testValidMultiStatementTransactionCommits() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE5" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (12, 'Farhan', %s);", + DATASET, TRANSACTION_TABLE, randomNumber); + String updateQuery = + String.format( + "UPDATE %s.%s SET age = 14 WHERE age = %s;", DATASET, TRANSACTION_TABLE, randomNumber); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s WHERE id = 12;", DATASET, TRANSACTION_TABLE); + + Connection connection1 = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection1.createStatement(); + bigQueryStatement.execute(createTransactionTable); + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + connection.setAutoCommit(false); + Statement statement = connection.createStatement(); + + boolean status = statement.execute(insertQuery); + assertFalse(status); + status = statement.execute(updateQuery); + assertFalse(status); + status = statement.execute(selectQuery); + assertTrue(status); + connection.commit(); + + // Separate query to check inserted and updated data committed + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + assertTrue(resultSet.next()); + assertEquals(14, resultSet.getInt(3)); + + bigQueryStatement.execute( + String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TRANSACTION_TABLE)); + statement.close(); + connection.close(); + } + + @Test + public void testTransactionRollbackOnError() throws SQLException { + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE6" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String selectQuery = + String.format("SELECT id, name, age FROM %s.%s ;", DATASET, TRANSACTION_TABLE); + + Connection connection1 = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection1.createStatement(); + bigQueryStatement.execute(createTransactionTable); + String transactionOnError = + "BEGIN\n" + + "\n" + + " BEGIN TRANSACTION;\n" + + " INSERT INTO " + + DATASET + + "." + + TRANSACTION_TABLE + + "\n" + + " VALUES (39, 'Drake', 123);\n" + + " SELECT 1/0;\n" + + " COMMIT TRANSACTION;\n" + + "\n" + + "EXCEPTION WHEN ERROR THEN\n" + + " SELECT @@error.message;\n" + + " ROLLBACK TRANSACTION;\n" + + "END;"; + Connection connection = DriverManager.getConnection(session_enabled_connection_uri); + Statement statement = connection.createStatement(); + statement.execute(transactionOnError); + + // do a check to see if no vals inserted + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + assertFalse(resultSet.next()); + + bigQueryStatement.execute( + String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TRANSACTION_TABLE)); + connection.close(); + connection1.close(); + } + + @Test + public void testValidLegacySQLStatement() throws SQLException { + String legacyJoinQuery = + "SELECT\n" + + " repo_name\n" + + "FROM\n" + + " [bigquery-public-data.github_repos.commits],\n" + + " [bigquery-public-data.github_repos.sample_commits] LIMIT 10"; + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=BIG_QUERY;"; + Connection connection = DriverManager.getConnection(connection_uri); + Statement statement = connection.createStatement(); + + boolean result = statement.execute(legacyJoinQuery); + assertTrue(result); + connection.close(); + } + + @Test + public void testExecuteUpdate() throws SQLException { + String TABLE_NAME = "EXT_JDBC_EXECUTE_UPDATE_TABLE_" + randomNumber; + String createQuery = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`StringField` STRING, `IntegerField` INTEGER);", + DATASET, TABLE_NAME); + String insertQuery = + String.format( + "INSERT INTO %s.%s (StringField, IntegerField) " + + "VALUES ('string1',111 ), ('string2',111 ), ('string3',222 ), ('string4',333 );", + DATASET, TABLE_NAME); + String updateQuery = + String.format( + "UPDATE %s.%s SET StringField='Jane Doe' WHERE IntegerField=111", DATASET, TABLE_NAME); + String dropQuery = String.format("DROP TABLE %s.%s", DATASET, TABLE_NAME); + String selectQuery = String.format("SELECT * FROM %s.%s", DATASET, TABLE_NAME); + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + int createStatus = bigQueryStatement.executeUpdate(createQuery); + assertEquals(0, createStatus); + + int insertStatus = bigQueryStatement.executeUpdate(insertQuery); + assertEquals(4, insertStatus); + + bigQueryStatement.executeQuery(selectQuery); + int selectStatus = bigQueryStatement.getUpdateCount(); + assertEquals(-1, selectStatus); + + int updateStatus = bigQueryStatement.executeUpdate(updateQuery); + assertEquals(2, updateStatus); + + int dropStatus = bigQueryStatement.executeUpdate(dropQuery); + assertEquals(0, dropStatus); + + bigQueryStatement.execute(String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TABLE_NAME)); + connection.close(); + } + + @Test + public void testExecuteMethod() throws SQLException { + + String TABLE_NAME = "EXT_JDBC_EXECUTE_TABLE_" + randomNumber; + String createQuery = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`StringField` STRING, `IntegerField` INTEGER);", + DATASET, TABLE_NAME); + String insertQuery = + String.format( + "INSERT INTO %s.%s (StringField, IntegerField) " + + "VALUES ('string1',111 ), ('string2',111 ), ('string3',222 ), ('string4',333 );", + DATASET, TABLE_NAME); + String updateQuery = + String.format( + "UPDATE %s.%s SET StringField='Jane Doe' WHERE IntegerField=111", DATASET, TABLE_NAME); + String dropQuery = String.format("DROP TABLE %s.%s", DATASET, TABLE_NAME); + String selectQuery = String.format("SELECT * FROM %s.%s", DATASET, TABLE_NAME); + + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + boolean createStatus = bigQueryStatement.execute(createQuery); + assertFalse(createStatus); + + boolean insertStatus = bigQueryStatement.execute(insertQuery); + assertFalse(insertStatus); + + boolean selectStatus = bigQueryStatement.execute(selectQuery); + assertTrue(selectStatus); + int selectCount = bigQueryStatement.getUpdateCount(); + assertEquals(-1, selectCount); + ResultSet resultSet = bigQueryStatement.getResultSet(); + assertNotNull(resultSet); + + boolean updateStatus = bigQueryStatement.execute(updateQuery); + assertFalse(updateStatus); + + boolean dropStatus = bigQueryStatement.execute(dropQuery); + assertFalse(dropStatus); + connection.close(); + } + + @Test + public void testPreparedExecuteMethod() throws SQLException { + + String TABLE_NAME = "EXT_JDBC_PREPARED_EXECUTE_TABLE_" + randomNumber; + String createQuery = + String.format( + "CREATE OR REPLACE TABLE `%s.%s` (`StringField` STRING, `IntegerField` INTEGER);", + DATASET, TABLE_NAME); + String insertQuery = + String.format( + "INSERT INTO `%s.%s` (StringField, IntegerField) VALUES (?,?), (?,?), (?,?), (?,?);", + DATASET, TABLE_NAME); + String updateQuery = + String.format("UPDATE `%s.%s` SET StringField=? WHERE IntegerField=?", DATASET, TABLE_NAME); + String dropQuery = String.format("DROP TABLE `%s.%s`", DATASET, TABLE_NAME); + String selectQuery = String.format("SELECT StringField FROM `%s.%s`", DATASET, TABLE_NAME); + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + boolean createStatus = bigQueryStatement.execute(createQuery); + assertFalse(createStatus); + + PreparedStatement insertStmt = connection.prepareStatement(insertQuery); + insertStmt.setString(1, "String1"); + insertStmt.setInt(2, 111); + insertStmt.setString(3, "String2"); + insertStmt.setInt(4, 222); + insertStmt.setString(5, "String3"); + insertStmt.setInt(6, 333); + insertStmt.setString(7, "String4"); + insertStmt.setInt(8, 444); + + boolean insertStatus = insertStmt.execute(); + assertFalse(insertStatus); + + Statement selectStmt = connection.createStatement(); + boolean selectStatus = selectStmt.execute(selectQuery); + assertTrue(selectStatus); + + int selectCount = selectStmt.getUpdateCount(); + assertEquals(-1, selectCount); + ResultSet resultSet = selectStmt.getResultSet(); + assertNotNull(resultSet); + + PreparedStatement updateStmt = connection.prepareStatement(updateQuery); + updateStmt.setString(1, "Jane Doe"); + updateStmt.setInt(2, 222); + boolean updateStatus = updateStmt.execute(); + assertFalse(updateStatus); + + boolean dropStatus = bigQueryStatement.execute(dropQuery); + assertFalse(dropStatus); + connection.close(); + } + + @Test + public void testPreparedStatementThrowsJdbcException() throws SQLException { + String TABLE_NAME = "EXT_JDBC_PREPARED_MISSING_PARAM_TABLE_" + randomNumber; + String createQuery = + String.format( + "CREATE OR REPLACE TABLE %s.%s (StringField STRING, IntegerField INTEGER);", + DATASET, TABLE_NAME); + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement bigQueryStatement = connection.createStatement(); + boolean createStatus = bigQueryStatement.execute(createQuery); + assertFalse(createStatus); + + String insertQuery = + String.format( + "INSERT INTO %s.%s (StringField, IntegerField) " + "VALUES (?,?), (?,?);", + DATASET, TABLE_NAME); + PreparedStatement insertStmt = connection.prepareStatement(insertQuery); + insertStmt.setString(1, "String1"); + insertStmt.setInt(2, 111); + assertThrows(SQLException.class, insertStmt::execute); + + bigQueryStatement.execute(String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TABLE_NAME)); + connection.close(); + } + + @Test + public void testValidExecuteBatch() throws SQLException { + // setup + String BATCH_TABLE = "EXT_JDBC_EXECUTE_BATCH_TABLE_" + random.nextInt(99); + String createBatchTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, BATCH_TABLE); + + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement statement = connection.createStatement(); + statement.execute(createBatchTable); + // act + // batch bypasses the 16 concurrent limit + int[] results; + for (int i = 0; i < 3; i++) { + String insertQuery = + "INSERT INTO " + + DATASET + + "." + + BATCH_TABLE + + " (id, name, age) " + + "VALUES (12, 'Farhan', " + + randomNumber + + i + + "); "; + statement.addBatch(insertQuery); + } + results = statement.executeBatch(); + + // assertions + assertEquals(3, results.length); + for (int updateCount : results) { + assertEquals(1, updateCount); + } + statement.execute(String.format("DROP TABLE IF EXISTS %S.%s", DATASET, BATCH_TABLE)); + connection.close(); + } + + @Test + public void testAddBatchWithoutSemicolon() throws SQLException { + // setup + String BATCH_TABLE = "EXT_JDBC_EXECUTE_BATCH_TABLE_MISSING_SEMICOLON_" + random.nextInt(99); + String createBatchTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, BATCH_TABLE); + + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement statement = connection.createStatement(); + statement.execute(createBatchTable); + + // act + // batch bypasses the 16 concurrent limit + String insertQuery = + "INSERT INTO " + + DATASET + + "." + + BATCH_TABLE + + " (id, name, age) " + + "VALUES (12, 'Farhan', 4)"; + statement.addBatch(insertQuery); + statement.addBatch(insertQuery); + int[] results = statement.executeBatch(); + + // assertions + assertEquals(2, results.length); + for (int updateCount : results) { + assertEquals(1, updateCount); + } + statement.execute(String.format("DROP TABLE IF EXISTS %S.%s", DATASET, BATCH_TABLE)); + connection.close(); + connection.close(); + } + + // Array and Struct not tested. + @Test + public void testValidAllDataTypesSerializationFromSelectQuery() throws SQLException { + String DATASET = "JDBC_INTEGRATION_DATASET"; + String TABLE_NAME = "JDBC_DATATYPES_INTEGRATION_TEST_TABLE"; + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME; + + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement bigQueryStatement = connection.createStatement(); + ResultSet resultSet = bigQueryStatement.executeQuery(selectQuery); + assertNotNull(resultSet); + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); + resultSet.next(); + assertEquals(16, resultSetMetaData.getColumnCount()); + assertTrue(resultSet.getBoolean(1)); + assertEquals(33, resultSet.getInt(2)); + assertEquals(50.05f, resultSet.getFloat(3), 0.0); + assertEquals(123.456, resultSet.getDouble(4), 0.0); + assertEquals(123.456789, resultSet.getDouble(5), 0.0); + assertEquals("testString", resultSet.getString(6)); + assertEquals("Test String", new String(resultSet.getBytes(7), StandardCharsets.UTF_8)); + assertEquals(Timestamp.valueOf("2020-04-27 18:07:25.356456"), resultSet.getObject(10)); + assertEquals(Date.valueOf("2019-1-12"), resultSet.getObject(11)); + assertEquals(Time.valueOf("14:00:00"), resultSet.getObject(12)); + assertEquals(Timestamp.valueOf("2019-02-17 11:24:00.0"), resultSet.getObject(13)); + assertEquals("POINT(1 2)", resultSet.getString(14)); + assertEquals("{\"class\":{\"students\":[{\"name\":\"Jane\"}]}}", resultSet.getString(15)); + assertEquals("123-7 -19 0:24:12.000006", resultSet.getString(16)); + connection.close(); + } + + // Array and Struct not tested. + @Test + public void testValidAllDataTypesSerializationFromSelectQueryArrowDataset() throws SQLException { + String DATASET = "JDBC_INTEGRATION_DATASET"; + String TABLE_NAME = "JDBC_INTEGRATION_ARROW_TEST_TABLE"; + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME + " LIMIT 5000;"; + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=" + + DEFAULT_CATALOG + + ";EnableHighThroughputAPI=1;" + + "HighThroughputActivationRatio=2;" + + "HighThroughputMinTableSize=1000;"; + + // Read data via JDBC + Connection connection = DriverManager.getConnection(connection_uri); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(selectQuery); + assertNotNull(resultSet); + + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); + resultSet.next(); + assertEquals(15, resultSetMetaData.getColumnCount()); + assertTrue(resultSet.getBoolean(1)); + assertEquals(33, resultSet.getInt(2)); + assertEquals(50.05f, resultSet.getFloat(3), 0.0); + assertEquals(123.456, resultSet.getDouble(4), 0.0); + assertEquals(123.456789, resultSet.getDouble(5), 0.0); + assertEquals("testString", resultSet.getString(6)); + assertEquals("Test String", new String(resultSet.getBytes(7), StandardCharsets.UTF_8)); + assertEquals(Timestamp.valueOf("2020-04-27 18:07:25.356"), resultSet.getObject(10)); + assertEquals(Timestamp.valueOf("2020-04-27 18:07:25.356"), resultSet.getTimestamp(10)); + assertEquals(Date.valueOf("2019-1-12"), resultSet.getObject(11)); + assertEquals(Date.valueOf("2019-1-12"), resultSet.getDate(11)); + assertEquals(Time.valueOf("14:00:00"), resultSet.getObject(12)); + assertEquals(Time.valueOf("14:00:00"), resultSet.getTime(12)); + assertEquals(Timestamp.valueOf("2022-01-22 22:22:12.142265"), resultSet.getObject(13)); + assertEquals("POINT(1 2)", resultSet.getString(14)); + assertEquals("{\"class\":{\"students\":[{\"name\":\"Jane\"}]}}", resultSet.getString(15)); + connection.close(); + connection.close(); + } + + @Test + public void testUnsupportedHTAPIFallbacksToStandardQueriesWithRange() throws SQLException { + String selectQuery = "select * from `DATATYPERANGETEST.RangeIntervalTestTable` LIMIT 5000;"; + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=" + + DEFAULT_CATALOG + + ";MaxResults=500;HighThroughputActivationRatio=1;" + + "HighThroughputMinTableSize=100;" + + "EnableHighThroughputAPI=1;UnsupportedHTAPIFallback=1;JobCreationMode=1;"; + + // Read data via JDBC + Connection connection = DriverManager.getConnection(connection_uri); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(selectQuery); + assertNotNull(resultSet); + + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); + resultSet.next(); + assertEquals(3, resultSetMetaData.getColumnCount()); + connection.close(); + connection.close(); + } + + @Test + public void testValidLEPEndpointQuery() throws SQLException, InterruptedException { + String DATASET = "JDBC_REGIONAL_DATASET"; + String TABLE_NAME = "REGIONAL_TABLE"; + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME; + String connection_uri = + "jdbc:bigquery://https://googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";" + + "EndpointOverrides=BIGQUERY=https://us-east4-bigquery.googleapis.com;"; + + // Read data via JDBC + Connection connection = DriverManager.getConnection(connection_uri); + JdbcConnectionHelper.setUpDataset(DATASET); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(selectQuery); + assertNotNull(resultSet.getMetaData()); + connection.close(); + } + + @Test + public void testValidEndpointWithInvalidBQPortThrows() throws SQLException { + String TABLE_NAME = "EXT_JDBC_REGIONAL_TABLE_" + randomNumber; + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME; + String connection_uri = + "jdbc:bigquery://https://googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";" + + "EndpointOverrides=BIGQUERY=https://us-east4-bigquery.googleapis.com:12312312;"; + + // Read data via JDBC + Connection connection = DriverManager.getConnection(connection_uri); + Statement statement = connection.createStatement(); + assertThrows(SQLException.class, () -> statement.executeQuery(selectQuery)); + connection.close(); + } + + @Test + public void testValidREPEndpointQuery() throws SQLException, InterruptedException { + String DATASET = "JDBC_REGIONAL_DATASET"; + String TABLE_NAME = "REGIONAL_TABLE"; + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME; + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";" + + "EndpointOverrides=BIGQUERY=https://bigquery.us-east4.rep.googleapis.com;"; + + // Read data via JDBC + Connection connection = DriverManager.getConnection(connection_uri); + JdbcConnectionHelper.setUpDataset(DATASET); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(selectQuery); + assertNotNull(resultSet.getMetaData()); + connection.close(); + } + + @Test + public void testCloseStatement() throws SQLException { + String query = "SELECT * FROM `bigquery-public-data.samples.github_timeline` LIMIT 10"; + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement statement = connection.createStatement(); + ResultSet jsonResultSet = statement.executeQuery(query); + assertEquals(10, resultSetRowCount(jsonResultSet)); + statement.close(); + assertTrue(statement.isClosed()); + connection.close(); + } + + @Test + public void testPreparedStatementSmallSelect() throws SQLException { + String query = + "SELECT * FROM `bigquery-public-data.samples.github_timeline` where repository_language=?" + + " LIMIT 1000"; + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setString(1, "Java"); + + ResultSet jsonResultSet = preparedStatement.executeQuery(); + + int rowCount = resultSetRowCount(jsonResultSet); + assertEquals(1000, rowCount); + connection.close(); + } + + @Test + public void testPreparedStatementExecuteUpdate() throws SQLException { + Random random = new Random(); + String DATASET = "JDBC_INTEGRATION_DATASET"; + String TABLE_NAME1 = "Inventory" + random.nextInt(9999); + String TABLE_NAME2 = "DetailedInventory" + random.nextInt(9999); + + String createQuery = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`product` STRING, `quantity` INTEGER);", + DATASET, TABLE_NAME1); + + String createQuery2 = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`product` STRING, `quantity` INTEGER," + + " `supply_constrained` BOOLEAN, `comment` STRING);", + DATASET, TABLE_NAME2); + + String insertQuery2 = + String.format( + "INSERT INTO %s.%s (product, quantity, supply_constrained, comment) " + + "VALUES ('countertop microwave', 20, NULL,'[]' )," + + " ('front load washer', 20, false,'[]' ), " + + " ('microwave', 20, false,'[]' ), " + + " ('refrigerator', 10, false,'[]' );", + DATASET, TABLE_NAME2); + + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement bigQueryStatement = connection.createStatement(); + bigQueryStatement.execute(createQuery); + bigQueryStatement.execute(createQuery2); + bigQueryStatement.execute(insertQuery2); + + String insertQuery = + String.format( + "INSERT INTO %s.%s (product, quantity) " + "VALUES (?,? ), (?,? );", + DATASET, TABLE_NAME1); + PreparedStatement insertPs = connection.prepareStatement(insertQuery); + insertPs.setString(1, "dishwasher"); + insertPs.setInt(2, 30); + insertPs.setString(3, "dryer"); + insertPs.setInt(4, 30); + + int insertStatus = insertPs.executeUpdate(); + assertEquals(2, insertStatus); + + String updateQuery = + String.format("UPDATE %s.%s SET quantity=? WHERE product=?", DATASET, TABLE_NAME1); + PreparedStatement updatePs = connection.prepareStatement(updateQuery); + updatePs.setString(2, "dryer"); + updatePs.setInt(1, 35); + + int updateStatus = updatePs.executeUpdate(); + assertEquals(1, updateStatus); + + String deleteQuery = String.format("DELETE FROM %s.%s WHERE product=?", DATASET, TABLE_NAME1); + PreparedStatement deletePs = connection.prepareStatement(deleteQuery); + deletePs.setString(1, "dishwasher"); + + int deleteStatus = deletePs.executeUpdate(); + assertEquals(1, deleteStatus); + + String mergeQuery = + String.format( + "MERGE %s.%s T\n" + + "USING %s.%s S\n" + + "ON T.product = S.product\n" + + "WHEN NOT MATCHED AND quantity < ? THEN\n" + + " INSERT(product, quantity, supply_constrained, comment)\n" + + " VALUES(product, quantity, true, ?)\n" + + "WHEN NOT MATCHED THEN\n" + + " INSERT(product, quantity, supply_constrained)\n" + + " VALUES(product, quantity, false)", + DATASET, TABLE_NAME2, DATASET, TABLE_NAME1); + PreparedStatement mergePs = connection.prepareStatement(mergeQuery); + mergePs.setInt(1, 20); + mergePs.setString(2, "comment" + random.nextInt(999)); + + int mergeStatus = mergePs.executeUpdate(); + assertEquals(1, mergeStatus); + + ResultSet rs = + bigQueryStatement.executeQuery( + String.format("SELECT COUNT(*) AS row_count\n" + "FROM %s.%s", DATASET, TABLE_NAME2)); + rs.next(); + assertEquals(5, rs.getInt(1)); + + String dropQuery = String.format("DROP TABLE %s.%s", DATASET, TABLE_NAME1); + int dropStatus = bigQueryStatement.executeUpdate(dropQuery); + assertEquals(0, dropStatus); + bigQueryStatement.execute(String.format("DROP TABLE %s.%s", DATASET, TABLE_NAME2)); + connection.close(); + } + + @Test + public void testUseLegacySQLWithLargeResultsNotAllowedQueries() throws SQLException { + // setup + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=BIG_QUERY;AllowLargeResults=0;"; + String selectLegacyQuery = + "SELECT * FROM [bigquery-public-data.deepmind_alphafold.metadata] LIMIT 250000;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act + ResultSet resultSet = statement.executeQuery(selectLegacyQuery); + + // assertion + assertNotNull(resultSet); + connection.close(); + } + + @Test + public void testUseLegacySQLWithLargeResultsAllowedWithNoDestinationTableDefaults() + throws SQLException { + // setup + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=BIG_QUERY;AllowLargeResults=1;"; + String selectLegacyQuery = + "SELECT * FROM [bigquery-public-data.deepmind_alphafold.metadata] LIMIT 250000;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act + ResultSet resultSet = statement.executeQuery(selectLegacyQuery); + + // assertion + assertNotNull(resultSet); + connection.close(); + } + + @Test + public void testValidDestinationTableSavesQueriesWithLegacySQL() throws SQLException { + // setup + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=BIG_QUERY;" + + "AllowLargeResults=1;" + + "LargeResultTable=destination_table_test_legacy;" + + "LargeResultDataset=INTEGRATION_TESTS;"; + String selectLegacyQuery = + "SELECT * FROM [bigquery-public-data.deepmind_alphafold.metadata] LIMIT 200;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act + ResultSet resultSet = statement.executeQuery(selectLegacyQuery); + + // assertion + assertNotNull(resultSet); + String selectQuery = "SELECT * FROM `INTEGRATION_TESTS.destination_table_test_legacy`;"; + Connection connection1 = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement bigQueryStatement = connection1.createStatement(); + ResultSet actualResultSet = bigQueryStatement.executeQuery(selectQuery); + assertTrue(0 < resultSetRowCount(actualResultSet)); + + // clean up + String deleteRows = "DELETE FROM `INTEGRATION_TESTS.destination_table_test_legacy` WHERE 1=1;"; + bigQueryStatement.execute(deleteRows); + connection.close(); + } + + @Test + public void testValidDestinationTableSavesQueriesWithStandardSQL() throws SQLException { + // setup + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=SQL;" + + "LargeResultTable=destination_table_test;" + + "LargeResultDataset=INTEGRATION_TESTS;"; + String selectLegacyQuery = + "SELECT * FROM `bigquery-public-data.deepmind_alphafold.metadata` LIMIT 200;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act + ResultSet resultSet = statement.executeQuery(selectLegacyQuery); + + // assertion + assertNotNull(resultSet); + String selectQuery = "SELECT * FROM INTEGRATION_TESTS.destination_table_test;"; + Connection connection1 = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement bigQueryStatement = connection1.createStatement(); + ResultSet actualResultSet = bigQueryStatement.executeQuery(selectQuery); + assertEquals(200, resultSetRowCount(actualResultSet)); + + // clean up + String deleteRows = "DELETE FROM `INTEGRATION_TESTS.destination_table_test` WHERE 1=1;"; + bigQueryStatement.execute(deleteRows); + connection.close(); + } + + @Test + public void testDestinationTableAndDestinationDatasetThatDoesNotExistsCreates() + throws SQLException { + // setup + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=BIG_QUERY;" + + "AllowLargeResults=1;" + + "LargeResultTable=FakeTable;" + + "LargeResultDataset=FakeDataset;"; + String selectLegacyQuery = + "SELECT * FROM [bigquery-public-data.deepmind_alphafold.metadata] LIMIT 200;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act + ResultSet resultSet = statement.executeQuery(selectLegacyQuery); + + // assertion + assertNotNull(resultSet); + String separateQuery = "SELECT * FROM FakeDataset.FakeTable;"; + Connection connection1 = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement bigQueryStatement = connection1.createStatement(); + boolean result = bigQueryStatement.execute(separateQuery); + assertTrue(result); + + // clean up + bigQueryStatement.execute("DROP SCHEMA FakeDataset CASCADE;"); + connection.close(); + } + + @Test + public void testNonSelectForStandardDestinationTableDoesNotThrow() throws SQLException { + // setup + String TRANSACTION_TABLE = "EXT_JDBC_TRANSACTION_TABLE8" + random.nextInt(99); + String createTransactionTable = + String.format( + "CREATE OR REPLACE TABLE %s.%s (`id` INTEGER, `name` STRING, `age` INTEGER);", + DATASET, TRANSACTION_TABLE); + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryDialect=SQL;" + + "AllowLargeResults=1;" + + "LargeResultTable=destination_table_test;" + + "LargeResultDataset=INTEGRATION_TESTS;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act & assertion + statement.execute(createTransactionTable); + connection.close(); + } + + @Test + public void testNonEnabledUseLegacySQLThrowsSyntaxError() throws SQLException { + // setup + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";"; + String selectLegacyQuery = + "SELECT * FROM [bigquery-public-data.deepmind_alphafold.metadata] LIMIT 20000000;"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act & assertion + assertThrows(SQLException.class, () -> statement.execute(selectLegacyQuery)); + connection.close(); + } + + // result order is wrong here, simba will fix this in a future release + // b/356365421 + @Test + @Ignore + public void testTableConstraints() throws SQLException { + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + ResultSet primaryKey1 = + connection + .getMetaData() + .getPrimaryKeys(DEFAULT_CATALOG, CONSTRAINTS_DATASET, CONSTRAINTS_TABLE_NAME); + primaryKey1.next(); + assertEquals("id", primaryKey1.getString(4)); + assertFalse(primaryKey1.next()); + + ResultSet primaryKey2 = + connection + .getMetaData() + .getPrimaryKeys(DEFAULT_CATALOG, CONSTRAINTS_DATASET, CONSTRAINTS_TABLE_NAME2); + primaryKey2.next(); + assertEquals("first_name", primaryKey2.getString(4)); + primaryKey2.next(); + assertEquals("last_name", primaryKey2.getString(4)); + assertFalse(primaryKey2.next()); + + ResultSet foreignKeys = + connection + .getMetaData() + .getImportedKeys(DEFAULT_CATALOG, CONSTRAINTS_DATASET, CONSTRAINTS_TABLE_NAME); + foreignKeys.next(); + assertEquals(CONSTRAINTS_TABLE_NAME2, foreignKeys.getString(3)); + assertEquals("first_name", foreignKeys.getString(4)); + assertEquals("name", foreignKeys.getString(8)); + foreignKeys.next(); + assertEquals(CONSTRAINTS_TABLE_NAME2, foreignKeys.getString(3)); + assertEquals("last_name", foreignKeys.getString(4)); + assertEquals("second_name", foreignKeys.getString(8)); + foreignKeys.next(); + assertEquals(CONSTRAINTS_TABLE_NAME3, foreignKeys.getString(3)); + assertEquals("address", foreignKeys.getString(4)); + assertEquals("address", foreignKeys.getString(8)); + assertFalse(foreignKeys.next()); + + ResultSet crossReference = + connection + .getMetaData() + .getCrossReference( + DEFAULT_CATALOG, + CONSTRAINTS_DATASET, + CONSTRAINTS_TABLE_NAME2, + DEFAULT_CATALOG, + CONSTRAINTS_DATASET, + CONSTRAINTS_TABLE_NAME); + crossReference.next(); + assertEquals(CONSTRAINTS_TABLE_NAME2, crossReference.getString(3)); + assertEquals("first_name", crossReference.getString(4)); + assertEquals("name", crossReference.getString(8)); + crossReference.next(); + assertEquals("last_name", crossReference.getString(4)); + assertEquals("second_name", crossReference.getString(8)); + connection.close(); + } + + @Test + public void testDatabaseMetadataGetProcedures() throws SQLException { + String DATASET = "JDBC_INTEGRATION_DATASET"; + String procedureName = "create_customer"; + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = databaseMetaData.getProcedures(DEFAULT_CATALOG, DATASET, procedureName); + while (resultSet.next()) { + assertEquals(DEFAULT_CATALOG, resultSet.getString("PROCEDURE_CAT")); + assertEquals(DATASET, resultSet.getString("PROCEDURE_SCHEM")); + assertEquals(procedureName, resultSet.getString("PROCEDURE_NAME")); + assertEquals(procedureName, resultSet.getString("SPECIFIC_NAME")); + } + connection.close(); + } + + @Test + public void testDatabaseMetadataGetProcedureColumns() throws SQLException { + String DATASET = "JDBC_INTEGRATION_DATASET"; + String procedureName = "create_customer"; + String parameterName = "id"; + + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = + databaseMetaData.getProcedureColumns( + DEFAULT_CATALOG, DATASET, procedureName, parameterName); + while (resultSet.next()) { + assertEquals(DEFAULT_CATALOG, resultSet.getString("PROCEDURE_CAT")); + assertEquals(DATASET, resultSet.getString("PROCEDURE_SCHEM")); + assertEquals(procedureName, resultSet.getString("PROCEDURE_NAME")); + assertEquals(procedureName, resultSet.getString("SPECIFIC_NAME")); + assertEquals(parameterName, resultSet.getString("COLUMN_NAME")); + assertEquals(65535, resultSet.getInt("PRECISION")); + assertEquals(2, resultSet.getShort("NULLABLE")); + } + connection.close(); + } + + @Test + public void testAlterTable() throws SQLException { + String TABLE_NAME = "EXT_JDBC_ALTER_TABLE_" + randomNumber; + String createQuery = + String.format("CREATE OR REPLACE TABLE %s.%s (`StringField` STRING);", DATASET, TABLE_NAME); + String addColumnQuery = + String.format("ALTER TABLE %s.%s ADD COLUMN `IntegerField` INTEGER;", DATASET, TABLE_NAME); + String dropColumnQuery = + String.format( + "UPDATE %s.%s SET StringField='Jane Doe' WHERE IntegerField=111", DATASET, TABLE_NAME); + String dropQuery = String.format("DROP TABLE %s.%s", DATASET, TABLE_NAME); + String selectQuery = String.format("SELECT * FROM %s.%s", DATASET, TABLE_NAME); + + Connection connection = + DriverManager.getConnection( + String.format(connectionUrl, DEFAULT_CATALOG), new Properties()); + Statement bigQueryStatement = connection.createStatement(); + int createStatus = bigQueryStatement.executeUpdate(createQuery); + assertEquals(0, createStatus); + + int addColumnStatus = bigQueryStatement.executeUpdate(addColumnQuery); + assertEquals(0, addColumnStatus); + + bigQueryStatement.executeQuery(selectQuery); + int selectStatus = bigQueryStatement.getUpdateCount(); + assertEquals(-1, selectStatus); + + int dropColumnStatus = bigQueryStatement.executeUpdate(dropColumnQuery); + assertEquals(0, dropColumnStatus); + + int dropStatus = bigQueryStatement.executeUpdate(dropQuery); + assertEquals(0, dropStatus); + + bigQueryStatement.execute(String.format("DROP TABLE IF EXISTS %S.%s", DATASET, TABLE_NAME)); + connection.close(); + } + + @Test + public void testQueryPropertyDataSetProjectIdQueriesToIncorrectDatasetThrows() + throws SQLException { + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryProperties=dataset_project_id=bigquerytestdefault" + + ";"; + String insertQuery = + String.format( + "INSERT INTO %s.%s (id, name, age) VALUES (15, 'Farhan', 25);", + "INTEGRATION_TESTS", "Test_Table"); + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act & assertion + assertThrows(SQLException.class, () -> statement.execute(insertQuery)); + connection.close(); + } + + @Test + public void testQueryPropertyTimeZoneQueries() throws SQLException { + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;" + + "ProjectId=" + + DEFAULT_CATALOG + + ";QueryProperties=time_zone=America/New_York;"; + String query = "SELECT * FROM `bigquery-public-data.samples.github_timeline` LIMIT 180"; + Connection connection = DriverManager.getConnection(connection_uri, new Properties()); + Statement statement = connection.createStatement(); + + // act + ResultSet resultSet = statement.executeQuery(query); + + // assertions + assertNotNull(resultSet); + assertTrue(resultSet.next()); + connection.close(); + } + + private int resultSetRowCount(ResultSet resultSet) throws SQLException { + int rowCount = 0; + while (resultSet.next()) { + rowCount++; + } + return rowCount; + } +} diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java new file mode 100644 index 000000000000..f36a0a29b848 --- /dev/null +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java @@ -0,0 +1,413 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bigquery.jdbc.statement; + +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.assertThrows; +import static org.junit.Assert.assertTrue; + +import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.ServiceOptions; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLDataException; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Statement; +import java.util.Properties; +import java.util.Random; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ITJdbcStatementTest { + private static final String DEFAULT_CATALOG = ServiceOptions.getDefaultProjectId(); + private static final String DATASET = "JDBC_STATEMENT_TEST_DATASET"; + private static String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=%s;OAuthType=3;Timeout=3600;"; + private static Random random = new Random(); + private static int randomNumber = random.nextInt(999); + private static final String TABLE_NAME = "JDBC_STATEMENT_TEST_TABLE" + randomNumber; + + @BeforeClass + public static void beforeClass() throws InterruptedException { + JdbcConnectionHelper.setUpDataset(DATASET); + JdbcConnectionHelper.setUpTable(DATASET, TABLE_NAME); + } + + @AfterClass + public static void afterClass() throws InterruptedException { + JdbcConnectionHelper.cleanUp(DATASET); + } + + @Test + public void testExecute() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME; + + Boolean selectQueryReturn = statement.execute(selectQuery); + assertEquals(true, selectQueryReturn); + + ResultSet resultSet = statement.getResultSet(); + while (resultSet.next()) { + if (resultSet.getInt("IntegerField") == 111) { + assertEquals("string1", resultSet.getString("StringField")); + assertEquals("737472696E6731", resultSet.getString("BytesField")); + } + } + + assertEquals(0, statement.getQueryTimeout()); + assertEquals(ResultSet.FETCH_FORWARD, statement.getFetchDirection()); + assertNotEquals(ResultSet.FETCH_REVERSE, statement.getFetchDirection()); + assertNotEquals(ResultSet.FETCH_UNKNOWN, statement.getFetchDirection()); + + assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, statement.getResultSetHoldability()); + assertNotEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, statement.getResultSetHoldability()); + + assertEquals(ResultSet.TYPE_FORWARD_ONLY, statement.getResultSetType()); + assertNotEquals(ResultSet.TYPE_SCROLL_SENSITIVE, statement.getResultSetType()); + assertNotEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, statement.getResultSetType()); + + assertEquals(ResultSet.CONCUR_READ_ONLY, statement.getResultSetConcurrency()); + assertNotEquals(ResultSet.CONCUR_UPDATABLE, statement.getResultSetConcurrency()); + + assertEquals(-1, statement.getUpdateCount()); + // assertEquals(-1L, statement.getLargeUpdateCount()); + + statement.close(); + connection.close(); + } + + @Test + public void testExecuteQuery() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + String selectQuery = + "SELECT * FROM bigquery-public-data.chicago_taxi_trips.taxi_trips LIMIT 1000;"; + + ResultSet selectQueryResult = statement.executeQuery(selectQuery); + ResultSet statementResult = statement.getResultSet(); + assertEquals(statementResult, selectQueryResult); + + assertEquals(0, statement.getFetchSize()); + + // setMaxRows Test + statement.setMaxRows(5); + ResultSet maxRowsResultSet = statement.executeQuery(selectQuery); + assertEquals(5, getSizeOfResultSet(maxRowsResultSet)); + + try { + statement.setMaxRows(0); + maxRowsResultSet = statement.executeQuery(selectQuery); + } catch (SQLDataException exception) { + assertTrue(true); + statement.close(); + } + + // TODO(note): setFetchSize not working + /*statement.setFetchSize(1); + ResultSet newResultSet = statement.executeQuery(selectQuery); + assertEquals(1, getSizeOfResultSet(newResultSet));*/ + + assertEquals(0, statement.getQueryTimeout()); + assertEquals(ResultSet.FETCH_FORWARD, statement.getFetchDirection()); + assertNotEquals(ResultSet.FETCH_REVERSE, statement.getFetchDirection()); + assertNotEquals(ResultSet.FETCH_UNKNOWN, statement.getFetchDirection()); + try { + statement.setFetchDirection(ResultSet.FETCH_REVERSE); + } catch (SQLFeatureNotSupportedException exception) { + assertTrue(true); + } + + assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, statement.getResultSetHoldability()); + assertNotEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, statement.getResultSetHoldability()); + + assertEquals(ResultSet.TYPE_FORWARD_ONLY, statement.getResultSetType()); + assertNotEquals(ResultSet.TYPE_SCROLL_SENSITIVE, statement.getResultSetType()); + assertNotEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, statement.getResultSetType()); + + assertEquals(ResultSet.CONCUR_READ_ONLY, statement.getResultSetConcurrency()); + assertNotEquals(ResultSet.CONCUR_UPDATABLE, statement.getResultSetConcurrency()); + + assertEquals(-1, statement.getUpdateCount()); + assertEquals(-1L, statement.getLargeUpdateCount()); + statement.close(); + connection.close(); + } + + @Test + public void testExecuteUpdate() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + String TEMP_TABLE_NAME = "TEMP_DDL_STATEMENT_TABLE"; + String createQuery = + "CREATE OR REPLACE TABLE " + + DATASET + + "." + + TEMP_TABLE_NAME + + " (\n" + + "`StringField` STRING,\n" + + "`BytesField` BYTES,\n" + + "`IntegerField` INTEGER);"; + String alterQuery = + "ALTER TABLE " + DATASET + "." + TEMP_TABLE_NAME + " ADD COLUMN `NewField` INTEGER;"; + String updateQuery = + "UPDATE " + + DATASET + + "." + + TEMP_TABLE_NAME + + " SET StringField = 'string71' " + + " WHERE IntegerField = 333 " + + " ;"; + String deleteQuery = "DROP TABLE " + DATASET + "." + TEMP_TABLE_NAME; + String multiInsertQuery = + "INSERT INTO " + + DATASET + + "." + + TEMP_TABLE_NAME + + " (\n" + + " StringField, BytesField,IntegerField)\n" + + " VALUES ('string3',CAST ('string3' AS BYTES),333), " + + " ('string4',CAST ('string4' AS BYTES),444), " + + " ('string5',CAST ('string5' AS BYTES),555) " + + " ;"; + String selectQuery = "select * from " + DATASET + "." + TEMP_TABLE_NAME; + + Statement statement = connection.createStatement(); + int createCount = statement.executeUpdate(createQuery); + assertEquals(0, createCount); + + int insertCount = statement.executeUpdate(multiInsertQuery); + assertEquals(3, insertCount); + + int alterCount = statement.executeUpdate(alterQuery); + assertEquals(0, alterCount); + ResultSet resultSet = statement.executeQuery(selectQuery); + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); + assertEquals(4, resultSetMetaData.getColumnCount()); + + int updateCount = statement.executeUpdate(updateQuery); + assertEquals(1, updateCount); + + int deleteCount = statement.executeUpdate(deleteQuery); + assertEquals(0, deleteCount); + + statement.close(); + connection.close(); + } + + @Test + public void testScript() throws SQLException { + String connection_uri = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID=" + + DEFAULT_CATALOG + + ";OAUTHTYPE=3"; + Properties withReadApi = new Properties(); + withReadApi.setProperty("EnableHighThroughputAPI", "1"); + Connection connection = DriverManager.getConnection(connection_uri, withReadApi); + Statement statement = connection.createStatement(); + String BASE_QUERY = + "SELECT * FROM bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2017 order by" + + " trip_distance asc LIMIT %s;"; + int expectedCnt = 500000; + String longQuery = String.format(BASE_QUERY, expectedCnt); + String longerQuery = String.format(BASE_QUERY, 700000); + String longerQuery2 = String.format(BASE_QUERY, 900000); + statement.execute(longQuery + longerQuery + longerQuery2); + ResultSet arrowResultSet = statement.getResultSet(); + assertEquals(500000, resultSetRowCount(arrowResultSet)); + arrowResultSet.close(); + connection.close(); + } + + private int resultSetRowCount(ResultSet resultSet) throws SQLException { + int rowCount = 0; + while (resultSet.next()) { + rowCount++; + } + return rowCount; + } + + @Test + public void testStringColumnLength() throws SQLException { + String projectId = DEFAULT_CATALOG; + String TABLE_NAME = "StringColumnLengthTable"; + String oauthType = "3"; // Google Application Credentials + int length = 10; + String connectionUrl = + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=" + + projectId + + ";OAuthType=" + + oauthType + + ";Timeout=3600;" + + "StringColumnLength=" + + length + + ";"; + // + "EnableSession=1"; + Connection connection1 = DriverManager.getConnection(connectionUrl); + Statement statement = connection1.createStatement(); + + String createQuery = + "CREATE OR REPLACE TABLE " + + DATASET + + "." + + TABLE_NAME + + " (\n" + + "`StringField1` STRING,\n" + + "`StringField2` STRING,\n" + + "`StringField3` STRING \n" + + ");"; + String insertQuery = + "INSERT INTO %s.%s (StringField1, StringField2, StringField3) VALUES ('%s', '%s', '%s') ;"; + String selectQuery = String.format("SELECT * FROM %s.%s; ", DATASET, TABLE_NAME); + statement.execute(createQuery); + + String s1 = generateString(1111); + String s2 = generateString(11111); + String s3 = generateString(111111); + statement.execute(String.format(insertQuery, DATASET, TABLE_NAME, s1, s2, s3)); + ResultSet rs = statement.executeQuery(selectQuery); + ResultSetMetaData metadata = rs.getMetaData(); + int i = 0; + while (rs.next()) { + assertNotNull(rs.getString(1)); + assertNotNull(rs.getString(2)); + assertNotNull(rs.getString(3)); + } + } + + private String generateString(int len) { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < len; i++) { + s = s.append("s"); + } + return s.toString(); + } + + @Test + public void testCloseStatement() throws SQLException { + String selectQuery = "select * from " + DATASET + "." + TABLE_NAME; + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + + assertFalse(statement.isClosed()); + assertFalse(statement.isCloseOnCompletion()); + statement.closeOnCompletion(); + assertTrue(statement.isCloseOnCompletion()); + ResultSet resultSet = statement.executeQuery(selectQuery); + resultSet.close(); + + assertTrue(statement.isClosed()); + statement = connection.createStatement(); + statement.close(); + assertTrue(statement.isClosed()); + connection.close(); + } + + @Test + public void testSetTimeout() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + + String selectQuery = + "SELECT views FROM bigquery-public-data.wikipedia.pageviews_2020 WHERE datehour >=" + + " '2020-01-01' LIMIT 9000000"; + + // statement.execute(selectQuery); + assertEquals(0, statement.getQueryTimeout()); + statement.setQueryTimeout(1); + assertEquals(1, statement.getQueryTimeout()); + try { + statement.executeQuery(selectQuery); + } catch (SQLException e) { + assertTrue(true); + assertEquals("SQL execution canceled", e.getMessage()); + } + statement.close(); + connection.close(); + } + + @Test + public void testSetTimeoutThrows() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + assertThrows(SQLException.class, () -> statement.setQueryTimeout(-1)); + } + + @Test + public void testDefaultValues() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + assertEquals(0, statement.getMaxFieldSize()); + // assertEquals(0, statement.getLargeMaxRows()); + assertNull(statement.getWarnings()); + assertFalse(statement.isPoolable()); + statement.close(); + connection.close(); + } + + @Test + public void testRangeSelectDataset() throws SQLException { + Connection connection = + DriverManager.getConnection(String.format(connectionUrl, DEFAULT_CATALOG)); + Statement statement = connection.createStatement(); + + // execute + try { + statement.execute( + "CREATE TABLE " + + DEFAULT_CATALOG + + "." + + DATASET + + ".RangeTable (x RANGE OPTIONS (description = 'An optional RANGE" + + " field'), y STRUCT > OPTIONS (description = 'An array of" + + " RANGE field')>);"); + ResultSet selectQueryResult = + statement.executeQuery( + "SELECT * FROM " + String.format(" `%s.%s.RangeTable`;", DEFAULT_CATALOG, DATASET)); + + assertEquals(selectQueryResult.getMetaData().getColumnTypeName(1), "RANGE"); + } finally { + // clean up + statement.execute( + String.format("DROP TABLE IF EXISTS %s.%s.RangeTable;", DEFAULT_CATALOG, DATASET)); + statement.close(); + } + connection.close(); + } + + int getSizeOfResultSet(ResultSet resultSet) throws SQLException { + int count = 0; + while (resultSet.next()) { + count++; + } + return count; + } +} From 2ccc61c9c54f2fe20b77e916ea043822f014cd00 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Wed, 1 Apr 2026 13:45:44 -0400 Subject: [PATCH 2/9] chore: update package names --- .../JdbcStarter.java | 0 .../bigquery/jdbc/testsuite}/BaseDatabaseMetadata.java | 2 +- .../bigquery/jdbc/testsuite}/JdbcConnectionHelper.java | 2 +- .../testsuite}/authentication/ITJdbcAuthenticationTest.java | 2 +- .../jdbc/testsuite}/connection/ITJdbcConnectionTest.java | 4 ++-- .../jdbc/testsuite}/connection/ITJdbcDriverTest.java | 4 ++-- .../testsuite}/metadata/ITJdbcDatabaseMetadataTest.java | 6 +++--- .../testsuite}/metadata/ITJdbcResultSetMetadataTest.java | 4 ++-- .../jdbc/testsuite}/statement/ITBigQueryJDBCTest.java | 4 ++-- .../jdbc/testsuite}/statement/ITJdbcStatementTest.java | 4 ++-- 10 files changed, 16 insertions(+), 16 deletions(-) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/{ => com.google.cloud.bigquery.jdbc.testsuite}/JdbcStarter.java (100%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/BaseDatabaseMetadata.java (99%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/JdbcConnectionHelper.java (99%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/authentication/ITJdbcAuthenticationTest.java (98%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/connection/ITJdbcConnectionTest.java (99%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/connection/ITJdbcDriverTest.java (97%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/metadata/ITJdbcDatabaseMetadataTest.java (97%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/metadata/ITJdbcResultSetMetadataTest.java (95%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/statement/ITBigQueryJDBCTest.java (99%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/{bigquery/jdbc => google/cloud/bigquery/jdbc/testsuite}/statement/ITJdbcStatementTest.java (99%) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/JdbcStarter.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.testsuite/JdbcStarter.java similarity index 100% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/JdbcStarter.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.testsuite/JdbcStarter.java diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/BaseDatabaseMetadata.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/BaseDatabaseMetadata.java index 2a7a9a2fcd09..df5a482454ca 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/BaseDatabaseMetadata.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/BaseDatabaseMetadata.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bigquery.jdbc; +package com.google.cloud.bigquery.jdbc.testsuite; import static java.sql.Types.TIME; import static java.sql.Types.TIMESTAMP; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/JdbcConnectionHelper.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/JdbcConnectionHelper.java index 4e2b63da99ed..342c277ef25f 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/JdbcConnectionHelper.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/JdbcConnectionHelper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bigquery.jdbc; +package com.google.cloud.bigquery.jdbc.testsuite; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.BigQuery; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java similarity index 98% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java index d0eedb2de980..5f73d2973913 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/authentication/ITJdbcAuthenticationTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bigquery.jdbc.authentication; +package com.google.cloud.bigquery.jdbc.testsuite.authentication; import com.google.gson.JsonObject; import com.google.gson.JsonParser; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcConnectionTest.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcConnectionTest.java index 6b2524dab96d..5f0e7116076d 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcConnectionTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcConnectionTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bigquery.jdbc.connection; +package com.google.cloud.bigquery.jdbc.testsuite.connection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -23,7 +23,7 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.sql.Array; import java.sql.CallableStatement; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcDriverTest.java similarity index 97% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcDriverTest.java index 92db3717f88b..0ba1bc6cf4f6 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/connection/ITJdbcDriverTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcDriverTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.bigquery.jdbc.connection; +package com.google.cloud.bigquery.jdbc.testsuite.connection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.BigQuery; import com.google.cloud.bigquery.BigQueryOptions; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcDatabaseMetadataTest.java similarity index 97% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcDatabaseMetadataTest.java index 436d1de0c030..3ec61a23e8fe 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcDatabaseMetadataTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcDatabaseMetadataTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.bigquery.jdbc.metadata; +package com.google.cloud.bigquery.jdbc.testsuite.metadata; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.bigquery.jdbc.BaseDatabaseMetadata; -import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.testsuite.BaseDatabaseMetadata; +import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.BigQuery; import java.sql.Connection; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcResultSetMetadataTest.java similarity index 95% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcResultSetMetadataTest.java index 02dc4eecacbc..765732ec3f86 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/metadata/ITJdbcResultSetMetadataTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcResultSetMetadataTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.bigquery.jdbc.metadata; +package com.google.cloud.bigquery.jdbc.testsuite.metadata; import static org.junit.Assert.assertEquals; -import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.sql.Connection; import java.sql.DriverManager; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITBigQueryJDBCTest.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITBigQueryJDBCTest.java index 227c210aab5c..fdc1c74370aa 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITBigQueryJDBCTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITBigQueryJDBCTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bigquery.jdbc.statement; +package com.google.cloud.bigquery.jdbc.testsuite.statement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -22,7 +22,7 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.nio.charset.StandardCharsets; import java.sql.Connection; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITJdbcStatementTest.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITJdbcStatementTest.java index f36a0a29b848..10f6a1e69999 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/bigquery/jdbc/statement/ITJdbcStatementTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITJdbcStatementTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.bigquery.jdbc.statement; +package com.google.cloud.bigquery.jdbc.testsuite.statement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -24,7 +24,7 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.bigquery.jdbc.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.sql.Connection; import java.sql.DriverManager; From 4562e9ecd2662b2ff9835cb045292d3bd22cbe6e Mon Sep 17 00:00:00 2001 From: Neenu Shaji Date: Wed, 1 Apr 2026 13:48:09 -0400 Subject: [PATCH 3/9] Update java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java index 5f73d2973913..9b5644692dda 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java @@ -118,7 +118,7 @@ public void testConnectOAuthPvtKeyAsJson() throws Exception { validateConnectionUri(connectionUri); } - @Disabled("Disabled until p12 file can be supplied") + @org.junit.Ignore("Disabled until p12 file can be supplied") @Test public void testConnectOAuthPvtKeyP12() throws Exception { final JsonObject authJson = getAuthJson(); From cb055dfc4a268cbf56025607c3140e89ef42c6b0 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Wed, 1 Apr 2026 13:58:12 -0400 Subject: [PATCH 4/9] make suggested changes --- java-bigquery/.cloudbuild/jdbc_external.yaml | 2 +- .../JdbcStarter.java | 7 ++++--- .../BaseDatabaseMetadata.java | 16 ++++++++-------- .../JdbcConnectionHelper.java | 2 +- .../authentication/ITJdbcAuthenticationTest.java | 2 +- .../connection/ITJdbcConnectionTest.java | 9 +++------ .../connection/ITJdbcDriverTest.java | 4 ++-- .../metadata/ITJdbcDatabaseMetadataTest.java | 6 +++--- .../metadata/ITJdbcResultSetMetadataTest.java | 4 ++-- .../statement/ITBigQueryJDBCTest.java | 4 ++-- .../statement/ITJdbcStatementTest.java | 4 ++-- 11 files changed, 29 insertions(+), 31 deletions(-) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/{com.google.cloud.bigquery.jdbc.testsuite => com.google.cloud.bigquery.jdbc.javatests}/JdbcStarter.java (87%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/BaseDatabaseMetadata.java (98%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/JdbcConnectionHelper.java (99%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/authentication/ITJdbcAuthenticationTest.java (98%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/connection/ITJdbcConnectionTest.java (97%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/connection/ITJdbcDriverTest.java (97%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/metadata/ITJdbcDatabaseMetadataTest.java (97%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/metadata/ITJdbcResultSetMetadataTest.java (95%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/statement/ITBigQueryJDBCTest.java (99%) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/{testsuite => javatests}/statement/ITJdbcStatementTest.java (99%) diff --git a/java-bigquery/.cloudbuild/jdbc_external.yaml b/java-bigquery/.cloudbuild/jdbc_external.yaml index b0aa3c1a13e9..8d10b637bc4a 100644 --- a/java-bigquery/.cloudbuild/jdbc_external.yaml +++ b/java-bigquery/.cloudbuild/jdbc_external.yaml @@ -17,7 +17,7 @@ steps: - name: 'gcr.io/cloud-devrel-public-resources/java11' entrypoint: 'bash' - args: ['java-bigquery/.cloudbuild/scripts/jdbc-external.sh'', "${_VERSION}"] + args: ['java-bigquery/.cloudbuild/scripts/jdbc-external.sh', "${_VERSION}"] secretEnv: ['SA_SECRET'] availableSecrets: secretManager: diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.testsuite/JdbcStarter.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.javatests/JdbcStarter.java similarity index 87% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.testsuite/JdbcStarter.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.javatests/JdbcStarter.java index c7bd59288a6b..3a0f7b90862b 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.testsuite/JdbcStarter.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.javatests/JdbcStarter.java @@ -32,8 +32,9 @@ public static void main(String[] args) throws SQLException { + ";OAuthType=" + oauthType + ";Timeout=3600;"; - Connection connection = DriverManager.getConnection(connectionUrl); - Statement statement = connection.createStatement(); - statement.execute("SELECT 1;"); + try(Connection connection = DriverManager.getConnection(connectionUrl); + Statement statement = connection.createStatement()) { + statement.execute("SELECT 1;"); + } } } diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/BaseDatabaseMetadata.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/BaseDatabaseMetadata.java similarity index 98% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/BaseDatabaseMetadata.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/BaseDatabaseMetadata.java index df5a482454ca..b3afe17d23fd 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/BaseDatabaseMetadata.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/BaseDatabaseMetadata.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite; +package com.google.cloud.bigquery.jdbc.javatests; import static java.sql.Types.TIME; import static java.sql.Types.TIMESTAMP; @@ -49,14 +49,14 @@ public static int getSizeOfResultSet(ResultSet rs) throws SQLException { public static List getInfoBySQL(Connection connection, String sqlCmd) throws SQLException { List result = new ArrayList<>(); - try { - Statement st = connection.createStatement(); - ResultSet rs = st.executeQuery(sqlCmd); - while (rs.next()) { - result.add(rs.getString(1)); + try {Statement st = connection.createStatement()) { + ResultSet rs = st.executeQuery(sqlCmd); + while (rs.next()) { + result.add(rs.getString(1)); + } + } catch (SQLException e) { + throw e; } - } catch (SQLException e) { - throw e; } return result; } diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/JdbcConnectionHelper.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/JdbcConnectionHelper.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/JdbcConnectionHelper.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/JdbcConnectionHelper.java index 342c277ef25f..ebcd3aef149c 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/JdbcConnectionHelper.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/JdbcConnectionHelper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite; +package com.google.cloud.bigquery.jdbc.javatests; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.BigQuery; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/authentication/ITJdbcAuthenticationTest.java similarity index 98% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/authentication/ITJdbcAuthenticationTest.java index 5f73d2973913..46512606f8a3 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/authentication/ITJdbcAuthenticationTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/authentication/ITJdbcAuthenticationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.authentication; +package com.google.cloud.bigquery.jdbc.javatests.authentication; import com.google.gson.JsonObject; import com.google.gson.JsonParser; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcConnectionTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/connection/ITJdbcConnectionTest.java similarity index 97% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcConnectionTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/connection/ITJdbcConnectionTest.java index 5f0e7116076d..b81623671c69 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcConnectionTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/connection/ITJdbcConnectionTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.connection; +package com.google.cloud.bigquery.jdbc.javatests.connection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -23,7 +23,7 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.javatests.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.sql.Array; import java.sql.CallableStatement; @@ -436,15 +436,12 @@ public void testAbort() throws SQLException, InterruptedException { // But we mainly want to test that calling abort doesn't cause a direct error assertFalse(connection.isClosed()); assertTrue(connection.isClosed()); - System.out.println(connection.isClosed()); connection.abort(java.util.concurrent.Executors.newSingleThreadExecutor()); - System.out.println(connection.isClosed()); - assertTrue(connection.isClosed()); + assertTrue(connection.isClosed()); } catch (SQLException e) { e.printStackTrace(); // It's expected that calling abort might cause an exception // depending on the state of the connection and driver. - System.out.println("Abort test threw an exception, which is expected in some cases."); } }); diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcDriverTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/connection/ITJdbcDriverTest.java similarity index 97% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcDriverTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/connection/ITJdbcDriverTest.java index 0ba1bc6cf4f6..efe9a5912d5c 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/connection/ITJdbcDriverTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/connection/ITJdbcDriverTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.connection; +package com.google.cloud.bigquery.jdbc.javatests.connection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.javatests.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.BigQuery; import com.google.cloud.bigquery.BigQueryOptions; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcDatabaseMetadataTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/metadata/ITJdbcDatabaseMetadataTest.java similarity index 97% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcDatabaseMetadataTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/metadata/ITJdbcDatabaseMetadataTest.java index 3ec61a23e8fe..094a9eefc236 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcDatabaseMetadataTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/metadata/ITJdbcDatabaseMetadataTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.metadata; +package com.google.cloud.bigquery.jdbc.javatests.metadata; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.cloud.bigquery.jdbc.testsuite.BaseDatabaseMetadata; -import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.javatests.BaseDatabaseMetadata; +import com.google.cloud.bigquery.jdbc.javatests.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.BigQuery; import java.sql.Connection; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcResultSetMetadataTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/metadata/ITJdbcResultSetMetadataTest.java similarity index 95% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcResultSetMetadataTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/metadata/ITJdbcResultSetMetadataTest.java index 765732ec3f86..1b43a8b7ac74 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/metadata/ITJdbcResultSetMetadataTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/metadata/ITJdbcResultSetMetadataTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.metadata; +package com.google.cloud.bigquery.jdbc.javatests.metadata; import static org.junit.Assert.assertEquals; -import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.javatests.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.sql.Connection; import java.sql.DriverManager; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITBigQueryJDBCTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/statement/ITBigQueryJDBCTest.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITBigQueryJDBCTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/statement/ITBigQueryJDBCTest.java index fdc1c74370aa..00407661060a 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITBigQueryJDBCTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/statement/ITBigQueryJDBCTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.statement; +package com.google.cloud.bigquery.jdbc.javatests.statement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -22,7 +22,7 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.javatests.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.nio.charset.StandardCharsets; import java.sql.Connection; diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITJdbcStatementTest.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/statement/ITJdbcStatementTest.java similarity index 99% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITJdbcStatementTest.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/statement/ITJdbcStatementTest.java index 10f6a1e69999..1d193cb12093 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/testsuite/statement/ITJdbcStatementTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/test/java/com/google/cloud/bigquery/jdbc/javatests/statement/ITJdbcStatementTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.cloud.bigquery.jdbc.testsuite.statement; +package com.google.cloud.bigquery.jdbc.javatests.statement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -24,7 +24,7 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.google.cloud.bigquery.jdbc.testsuite.JdbcConnectionHelper; +import com.google.cloud.bigquery.jdbc.javatests.JdbcConnectionHelper; import com.google.cloud.ServiceOptions; import java.sql.Connection; import java.sql.DriverManager; From bcae02e3f2af56b87d0df75d76a4784548c40b3a Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 2 Apr 2026 09:11:57 -0400 Subject: [PATCH 5/9] change package name --- .../google/cloud/bigquery/jdbc/javatests}/JdbcStarter.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/{com.google.cloud.bigquery.jdbc.javatests => com/google/cloud/bigquery/jdbc/javatests}/JdbcStarter.java (100%) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.javatests/JdbcStarter.java b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com/google/cloud/bigquery/jdbc/javatests/JdbcStarter.java similarity index 100% rename from java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com.google.cloud.bigquery.jdbc.javatests/JdbcStarter.java rename to java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/src/main/java/com/google/cloud/bigquery/jdbc/javatests/JdbcStarter.java From bb773b221a6021d2137af35645004fe9d6b6cade Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 2 Apr 2026 09:17:02 -0400 Subject: [PATCH 6/9] update license year --- .../bigquery-external-jdbc-tests/pom.xml | 2 +- .../com/google/cloud/bigquery/jdbc/javatests/JdbcStarter.java | 2 +- .../cloud/bigquery/jdbc/javatests/BaseDatabaseMetadata.java | 2 +- .../cloud/bigquery/jdbc/javatests/JdbcConnectionHelper.java | 2 +- .../jdbc/javatests/authentication/ITJdbcAuthenticationTest.java | 2 +- .../jdbc/javatests/connection/ITJdbcConnectionTest.java | 2 +- .../bigquery/jdbc/javatests/connection/ITJdbcDriverTest.java | 2 +- .../jdbc/javatests/metadata/ITJdbcDatabaseMetadataTest.java | 2 +- .../jdbc/javatests/metadata/ITJdbcResultSetMetadataTest.java | 2 +- .../bigquery/jdbc/javatests/statement/ITBigQueryJDBCTest.java | 2 +- .../bigquery/jdbc/javatests/statement/ITJdbcStatementTest.java | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml index 1d53b4484f6a..fbcb5d344352 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml @@ -1,6 +1,6 @@ 4.0.0 - org.example + com.google.cloud bigquery-external-jdbc-tests 1.0-SNAPSHOT @@ -27,8 +12,18 @@ 11 11 UTF-8 + ${env.JDBC_VERSION} + ${env.JDBC_JAR_PATH} - + + + com.google.cloud + google-cloud-bigquery-parent + 2.63.0-SNAPSHOT + ../../pom.xml + + + com.google.cloud @@ -48,9 +43,9 @@ com.google.cloud JDBC - ${env.JDBC_VERSION} + ${jdbc.version} system - ${env.JDBC_JAR_PATH} + ${jdbc.jarPath} From 7a998bc922e516fe7d19af1fe19efb7da932981c Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 2 Apr 2026 10:36:45 -0400 Subject: [PATCH 8/9] chore: skip lint check for jdbc ext test --- .kokoro/build.sh | 1 + .../bigquery-external-jdbc-tests/pom.xml | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.kokoro/build.sh b/.kokoro/build.sh index b8524fbb94d8..81755953c827 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -282,6 +282,7 @@ case ${JOB_TYPE} in [[ "$(basename "${dir}")" != "dependency-analyzer" ]] && \ [[ "$(basename "${dir}")" != "dependency-convergence-check" ]] && \ [[ "$(basename "${dir}")" != "unmanaged-dependency-check" ]] && \ + [[ "$(basename "${dir}")" != "bigquery-external-jdbc-tests" ]] && \ [[ "$(basename "${dir}")" != "google-cloud-jar-parent" ]]; then changed_modules+=("${dir}") diff --git a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml index 11f5abada18c..36f57cef8b2e 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml +++ b/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests/pom.xml @@ -16,14 +16,14 @@ ${env.JDBC_JAR_PATH} - + + 2.63.0-SNAPSHOT<!– {x-version-update:google-cloud-bigquery:current} –> ../../pom.xml - + --> - + com.google.cloud From 5025013947d7a3f702aa04656afb0cfd200725b7 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 2 Apr 2026 10:55:38 -0400 Subject: [PATCH 9/9] update script --- java-bigquery/.cloudbuild/scripts/jdbc-external.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/java-bigquery/.cloudbuild/scripts/jdbc-external.sh b/java-bigquery/.cloudbuild/scripts/jdbc-external.sh index 944106a3a851..df1c31bc04b4 100644 --- a/java-bigquery/.cloudbuild/scripts/jdbc-external.sh +++ b/java-bigquery/.cloudbuild/scripts/jdbc-external.sh @@ -5,4 +5,16 @@ source .kokoro/common.sh install_modules java-bigquery cd ${ROOT_FOLDER}/java-bigquery/google-cloud-bigquery-jdbc/bigquery-external-jdbc-tests -make integration-test \ No newline at end of file + +# This pom.xml is using export vars for install +export JDBC_VERSION=$1; +JDBC_FOLDER=jdbc-driver +JDBC_ZIP_NAME="SimbaJDBCDriverforGoogleBigQuery42_${JDBC_VERSION}.zip" +JDBC_JAR_NAME=GoogleBigQueryJDBC42.jar +export JDBC_JAR_PATH="$(pwd)/${JDBC_FOLDER}/${JDBC_JAR_NAME}" + +mkdir -p ${JDBC_FOLDER} +gsutil -m cp gs://bq-dev-tools-simba-drivers-testing/simba-jdbc/${JDBC_ZIP_NAME} ${JDBC_FOLDER} +unzip -p ./${JDBC_FOLDER}/${JDBC_ZIP_NAME} ${JDBC_JAR_NAME} > ${JDBC_JAR_PATH} + +mvn -B -V -fae -q install