Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion java-bigquery-jdbc/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ target-it/**
tools/**/*.class
tools/**/drivers/**
tools/**/logs/**
tools/**/*.jfr
tools/**/*.jfr

# Gemini/Jetski agent custom skills
.agents/
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.exception.BigQueryJdbcException;
Expand Down Expand Up @@ -93,9 +94,10 @@ private BigQueryArrowResultSet(
int fromIndex,
int toIndexExclusive,
Thread ownedThread,
BigQuery bigQuery)
BigQuery bigQuery,
Job job)
throws SQLException {
super(bigQuery, statement, schema, isNested);
super(bigQuery, statement, schema, isNested, job);
LOG.finestTrace("<init>");
this.totalRows = totalRows;
this.buffer = buffer;
Expand Down Expand Up @@ -128,6 +130,19 @@ static BigQueryArrowResultSet of(
Thread ownedThread,
BigQuery bigQuery)
throws SQLException {
return of(schema, arrowSchema, totalRows, statement, buffer, ownedThread, bigQuery, null);
}

static BigQueryArrowResultSet of(
Schema schema,
ArrowSchema arrowSchema,
long totalRows,
BigQueryStatement statement,
BlockingQueue<BigQueryArrowBatchWrapper> buffer,
Thread ownedThread,
BigQuery bigQuery,
Job job)
throws SQLException {
return new BigQueryArrowResultSet(
schema,
arrowSchema,
Expand All @@ -139,7 +154,8 @@ static BigQueryArrowResultSet of(
-1,
-1,
ownedThread,
bigQuery);
bigQuery,
job);
}

BigQueryArrowResultSet() throws SQLException {
Expand All @@ -159,7 +175,18 @@ static BigQueryArrowResultSet getNestedResultSet(
Schema schema, BigQueryArrowBatchWrapper nestedBatch, int fromIndex, int toIndexExclusive)
throws SQLException {
return new BigQueryArrowResultSet(
schema, null, -1, null, null, nestedBatch, true, fromIndex, toIndexExclusive, null, null);
schema,
null,
-1,
null,
null,
nestedBatch,
true,
fromIndex,
toIndexExclusive,
null,
null,
null);
}

private class ArrowDeserializer implements AutoCloseable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package com.google.cloud.bigquery.jdbc;

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryError;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.FieldList;
import com.google.cloud.bigquery.Job;
Expand All @@ -40,10 +42,12 @@
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;

public abstract class BigQueryBaseResultSet extends BigQueryNoOpsResultSet
implements BigQueryResultSet {
Expand All @@ -58,15 +62,28 @@ public abstract class BigQueryBaseResultSet extends BigQueryNoOpsResultSet
protected final boolean isNested;
protected boolean isClosed = false;
protected boolean wasNull = false;
private int fetchSize = -1;
private Job job;
private SQLWarning warnings;
private boolean warningsLoaded = false;
protected final BigQueryTypeCoercer bigQueryTypeCoercer = BigQueryTypeCoercionUtility.INSTANCE;

protected BigQueryBaseResultSet(
BigQuery bigQuery, BigQueryStatement statement, Schema schema, boolean isNested) {
this(bigQuery, statement, schema, isNested, null);
}

protected BigQueryBaseResultSet(
BigQuery bigQuery, BigQueryStatement statement, Schema schema, boolean isNested, Job job) {
this.bigQuery = bigQuery;
this.statement = statement;
this.schema = schema;
this.schemaFieldList = schema != null ? schema.getFields() : null;
this.isNested = isNested;
this.job = job;
if (job != null) {
this.jobId = job.getJobId();
}
this.LOG =
BigQueryJdbcResultSetLogger.getLogger(
this.getClass(), statement != null ? statement.connectionId : null);
Expand All @@ -76,11 +93,12 @@ public QueryStatistics getQueryStatistics() {
if (queryStatistics != null) {
return queryStatistics;
}
if (jobId == null || bigQuery == null) {
return null;
Job activeJob = this.job;
if (activeJob == null && jobId != null && bigQuery != null) {
this.job = bigQuery.getJob(jobId);
activeJob = this.job;
}
Job job = bigQuery.getJob(jobId);
queryStatistics = job != null ? job.getStatistics() : null;
queryStatistics = activeJob != null ? activeJob.getStatistics() : null;
return queryStatistics;
}

Expand All @@ -92,6 +110,20 @@ public JobId getJobId() {
return jobId;
}

public void setJob(Job job) {
this.job = job;
if (job != null) {
this.jobId = job.getJobId();
}
this.queryStatistics = null;
this.warnings = null;
this.warningsLoaded = false;
}
Comment thread
Neenu1995 marked this conversation as resolved.
Comment thread
Neenu1995 marked this conversation as resolved.

public Job getJob() {
return job;
}

public void setQueryId(String queryId) {
this.queryId = queryId;
}
Expand Down Expand Up @@ -688,4 +720,97 @@ public <T> T unwrap(Class<T> iface) throws SQLException {
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return iface != null && iface.isInstance(this);
}

@Override
public int getFetchDirection() throws SQLException {
checkClosed();
// Fetch direction is restricted to forward-only.
return ResultSet.FETCH_FORWARD;
}

@Override
public void setFetchDirection(int direction) throws SQLException {
checkClosed();
// Restricts the fetch direction to FETCH_FORWARD. Other directions are not supported.
if (direction != ResultSet.FETCH_FORWARD) {
throw new SQLException("Only FETCH_FORWARD is supported");
}
}

@Override
public void setFetchSize(int rows) throws SQLException {
checkClosed();
if (rows < 0) {
throw new SQLException("Fetch size must be >= 0");
}
// This is a no-op placeholder for JDBC API compliance to prevent crashes in
// third-party client tools that call this automatically.
// The driver manages pagination internally under the hood.
this.fetchSize = rows;
}

@Override
public int getFetchSize() throws SQLException {
checkClosed();
// Returns the fetch size set on this ResultSet, or falls back to the statement's
// fetch size, defaulting to the internal row buffer size of
// BigQueryStatement.DEFAULT_BUFFER_SIZE.
if (this.fetchSize > 0) {
return this.fetchSize;
}
if (statement != null) {
int statementFetchSize = statement.getFetchSize();
if (statementFetchSize > 0) {
return statementFetchSize;
}
}
return BigQueryStatement.DEFAULT_BUFFER_SIZE;
}

@Override
public SQLWarning getWarnings() throws SQLException {
checkClosed();
// Dynamically fetches and chains non-fatal execution errors from the BigQuery Job
// as SQLWarning objects, using lazy-loading and local caching for performance.
if (warningsLoaded) {
return warnings;
}
Job activeJob = this.job;
if (activeJob == null && jobId != null && bigQuery != null) {
try {
this.job = bigQuery.getJob(jobId);
activeJob = this.job;
} catch (BigQueryException e) {
throw new BigQueryJdbcException("Failed to retrieve job for warnings", e);
}
}
if (activeJob != null
&& activeJob.getStatus() != null
&& activeJob.getStatus().getExecutionErrors() != null) {
List<BigQueryError> errors = activeJob.getStatus().getExecutionErrors();
SQLWarning head = null;
SQLWarning tail = null;
for (BigQueryError error : errors) {
SQLWarning warning = new SQLWarning(error.getMessage(), error.getReason());
if (head == null) {
head = warning;
tail = warning;
} else {
tail.setNextWarning(warning);
tail = warning;
}
}
this.warnings = head;
}
this.warningsLoaded = true;
return warnings;
}
Comment thread
Neenu1995 marked this conversation as resolved.

@Override
public void clearWarnings() throws SQLException {
checkClosed();
// Clears the cached warnings chain.
this.warnings = null;
this.warningsLoaded = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.FieldValue;
import com.google.cloud.bigquery.FieldValue.Attribute;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.exception.BigQueryJdbcRuntimeException;
import java.sql.ResultSet;
Expand Down Expand Up @@ -54,8 +55,9 @@ private BigQueryJsonResultSet(
int fromIndex,
int toIndexExclusive,
Thread[] ownedThreads,
BigQuery bigQuery) {
super(bigQuery, statement, schema, isNested);
BigQuery bigQuery,
Job job) {
super(bigQuery, statement, schema, isNested, job);
this.totalRows = totalRows;
this.buffer = buffer;
this.cursor = cursor;
Expand All @@ -79,8 +81,20 @@ static BigQueryJsonResultSet of(
Thread[] ownedThreads,
BigQuery bigQuery) {

return of(schema, totalRows, buffer, statement, ownedThreads, bigQuery, null);
}

static BigQueryJsonResultSet of(
Schema schema,
long totalRows,
BlockingQueue<BigQueryFieldValueListWrapper> buffer,
BigQueryStatement statement,
Thread[] ownedThreads,
BigQuery bigQuery,
Job job) {

return new BigQueryJsonResultSet(
schema, totalRows, buffer, statement, false, null, -1, -1, ownedThreads, bigQuery);
schema, totalRows, buffer, statement, false, null, -1, -1, ownedThreads, bigQuery, job);
}

static BigQueryJsonResultSet of(
Expand All @@ -91,7 +105,7 @@ static BigQueryJsonResultSet of(
Thread[] ownedThreads) {

return new BigQueryJsonResultSet(
schema, totalRows, buffer, statement, false, null, -1, -1, ownedThreads, null);
schema, totalRows, buffer, statement, false, null, -1, -1, ownedThreads, null, null);
}

BigQueryJsonResultSet() {
Expand Down Expand Up @@ -127,6 +141,7 @@ static BigQueryJsonResultSet getNestedResultSet(
fromIndex,
toIndexExclusive,
null,
null,
null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.sql.ResultSet;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
Expand All @@ -42,21 +41,6 @@
/** NoOps Abstract base class for BigQuery JDBC ResultSet(s). */
abstract class BigQueryNoOpsResultSet implements ResultSet {

@Override
public int getFetchDirection() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public void setFetchSize(int rows) throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public int getFetchSize() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public String getCursorName() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
Expand Down Expand Up @@ -102,11 +86,6 @@ public boolean previous() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public void setFetchDirection(int direction) throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public boolean rowUpdated() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
Expand Down Expand Up @@ -655,16 +634,6 @@ public void updateNClob(String columnLabel, Reader reader) throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public SQLWarning getWarnings() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

@Override
public void clearWarnings() throws SQLException {
throw new BigQueryJdbcSqlFeatureNotSupportedException(METHOD_NOT_IMPLEMENTED);
}

void checkClosed() throws SQLException {
if (isClosed()) {
throw new BigQueryJdbcException("This " + getClass().getName() + " has been closed");
Expand Down
Loading
Loading