Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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