-
Notifications
You must be signed in to change notification settings - Fork 129
Description
Component: google-cloud-bigquery
Java Client Library
Version(s) Affected: 2.45.0
Description:
An ArrayIndexOutOfBoundsException
occurs in com.google.cloud.bigquery.ConnectionImpl.createQueryRequest
when attempting to execute a BigQuery SELECT query via Connection.executeSelect()
with an empty list of Parameter
objects, provided that ConnectionImpl.isFastQuerySupported()
evaluates to true
.
Steps to Reproduce:
- Initialize
BigQueryOptions
andConnectionSettings
. - Create a
Connection
instance usingBigQuery.createConnection()
. - Prepare an SQL
SELECT
statement that does not require or contain any query parameter placeholders. For example:SELECT updatedat AS updated_at FROM `my_project.my_dataset.my_table` ORDER BY updatedAt DESC LIMIT 1;
- Call
Connection.executeSelect(sql, parameters, labels)
where:sql
is the non-parameterized SQL query string.parameters
is an emptyList<Parameter>
, specificallyImmutableList.of()
.labels
isnull
or an empty array of maps.
- Ensure that the internal conditions for
ConnectionImpl.isFastQuerySupported()
evaluate totrue
(e.g., no specialConnectionSettings
are used that would force thejobs.insert
path).
Expected Behavior:
The query should execute successfully, returning a BigQueryResult
object, or an appropriate BigQuerySQLException
if there's a problem with the SQL itself (e.g., table not found). The client library should gracefully handle an empty queryParameters
list for a non-parameterized query without throwing an internal exception.
Actual Behavior:
The execution throws an ArrayIndexOutOfBoundsException
with the following or similar stack trace:
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at com.google.common.collect.RegularImmutableList.get(RegularImmutableList.java:79)
at com.google.cloud.bigquery.ConnectionImpl.createQueryRequest(ConnectionImpl.java:1283)
at com.google.cloud.bigquery.ConnectionImpl.getExecuteSelectResponse(ConnectionImpl.java:241)
at com.google.cloud.bigquery.ConnectionImpl.executeSelect(ConnectionImpl.java:224)
at com.solvimon.bigquery.BigQuerySelect.selectFromBigQuery(BigQuerySelect.kt:10)
... (rest of application stack trace)
Root Cause Analysis:
Upon inspection of the ConnectionImpl.java
source code from version 2.45.0, the createQueryRequest
method contains the following problematic logic:
if (queryParameters != null) {
// content.setQueryParameters(queryParameters);
if (queryParameters.get(0).getName() == null) { // <<< Problematic line
// ... (rest of positional parameter handling)
} else {
// ... (named parameter handling)
}
}
The if (queryParameters != null)
check allows the code to proceed even when queryParameters
is an empty list (as ImmutableList.of()
returns a non-null empty list). However, the subsequent line queryParameters.get(0).getName()
attempts to access the first element of this empty list, resulting in the ArrayIndexOutOfBoundsException
.
Proposed Fix (Conceptual):
The if
condition should also check if the queryParameters
list is not empty before attempting to access its elements.
if (queryParameters != null && !queryParameters.isEmpty()) { // Add !queryParameters.isEmpty()
// ... (existing logic)
}