Skip to content

BigQuery: ArrayIndexOutOfBoundsException in ConnectionImpl.createQueryRequest when queryParameters is an empty list (Version 2.45.0) #3945

@thjnmcdonald

Description

@thjnmcdonald

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:

  1. Initialize BigQueryOptions and ConnectionSettings.
  2. Create a Connection instance using BigQuery.createConnection().
  3. 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;
  4. Call Connection.executeSelect(sql, parameters, labels) where:
    • sql is the non-parameterized SQL query string.
    • parameters is an empty List<Parameter>, specifically ImmutableList.of().
    • labels is null or an empty array of maps.
  5. Ensure that the internal conditions for ConnectionImpl.isFastQuerySupported() evaluate to true (e.g., no special ConnectionSettings are used that would force the jobs.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)
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    api: bigqueryIssues related to the googleapis/java-bigquery API.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions