From 58f80926f743eb2fd7258c19acb060b870f8841c Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 30 Jan 2025 16:19:37 +0100 Subject: [PATCH 01/14] chore(deps): update dependency com.google.cloud:google-cloud-bigquery to v2.47.0 (#3658) --- samples/install-without-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 9f33fb2e6..2b580c6d4 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -45,7 +45,7 @@ com.google.cloud google-cloud-bigquery - 2.46.0 + 2.47.0 From 728e312887856b3cfb243f650a4392d354c7a4d5 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 30 Jan 2025 16:20:56 +0100 Subject: [PATCH 02/14] chore(deps): update dependency com.google.cloud:google-cloud-bigqueryconnection to v2.59.0 (#3659) --- pom.xml | 2 +- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d6826d566..a3ee30d41 100644 --- a/pom.xml +++ b/pom.xml @@ -143,7 +143,7 @@ com.google.cloud google-cloud-bigqueryconnection - 2.58.0 + 2.59.0 test diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 2b580c6d4..b5f6b66f5 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -69,7 +69,7 @@ com.google.cloud google-cloud-bigqueryconnection - 2.58.0 + 2.59.0 test diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index bb0ca36c1..600522b26 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -67,7 +67,7 @@ com.google.cloud google-cloud-bigqueryconnection - 2.58.0 + 2.59.0 test diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 635d02a71..69ea0c9e1 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -85,7 +85,7 @@ com.google.cloud google-cloud-bigqueryconnection - 2.58.0 + 2.59.0 test From 3a6228b4adc638759d3b2725c612e97e1a3b9cec Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 30 Jan 2025 16:21:19 +0100 Subject: [PATCH 03/14] deps: update dependency com.google.api.grpc:proto-google-cloud-bigqueryconnection-v1 to v2.59.0 (#3660) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a3ee30d41..497654fc9 100644 --- a/pom.xml +++ b/pom.xml @@ -149,7 +149,7 @@ com.google.api.grpc proto-google-cloud-bigqueryconnection-v1 - 2.58.0 + 2.59.0 test From 9bc8c0115dc16fb950567cd85cc7dfaa9df50d7d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 30 Jan 2025 19:51:08 +0100 Subject: [PATCH 04/14] deps: update dependency com.google.cloud:google-cloud-datacatalog-bom to v1.63.0 (#3661) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 497654fc9..5b1d3a0d7 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ com.google.cloud google-cloud-datacatalog-bom - 1.62.0 + 1.63.0 pom import From c7ef94be115cd572df589385f9be801033d72d6d Mon Sep 17 00:00:00 2001 From: Phong Chuong <147636638+PhongChuong@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:56:57 -0500 Subject: [PATCH 05/14] feat: implement wasNull for BigQueryResultSet (#3650) * feat: implement wasNull for BigQueryResultSet * feat: implement wasNull for BigQueryResultSet * feat: implement wasNull for BigQueryResultSet * feat: implement wasNull for BigQueryResultSet * feat: implement wasNull for BigQueryResultSet * feat: implement wasNull for BigQueryResultSet * feat: implement wasNull for BigQueryResultSet --- .../cloud/bigquery/BigQueryResultImpl.java | 407 +++++++++++------- .../bigquery/BigQueryResultImplTest.java | 257 +++++++++++ 2 files changed, 505 insertions(+), 159 deletions(-) create mode 100644 google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryResultImplTest.java diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java index a1bb4d406..e1e129eae 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryResultImpl.java @@ -24,14 +24,17 @@ import java.sql.Timestamp; import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.ZoneId; import java.util.Map; -import java.util.TimeZone; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import org.apache.arrow.vector.util.JsonStringArrayList; import org.apache.arrow.vector.util.Text; +/** + * An implementation of BigQueryResult. + * + *

This class and the ResultSet it returns is not thread-safe. + */ public class BigQueryResultImpl implements BigQueryResult { private static final String NULL_CURSOR_MSG = @@ -109,6 +112,7 @@ private class BigQueryResultSet extends AbstractJdbcResultSet { private boolean hasReachedEnd = false; // flag which will be set to true when we have encountered a EndOfStream or when // curTup.isLast(). Ref: https://github.com/googleapis/java-bigquery/issues/2033 + private boolean wasNull = false; @Override /*Advances the result set to the next row, returning false if no such row exists. Potentially blocking operation*/ @@ -148,6 +152,14 @@ private boolean isEndOfStream(T cursor) { return cursor instanceof ConnectionImpl.EndOfFieldValueList; } + private Object getCurrentValueForReadApiData(String fieldName) throws SQLException { + Row curRow = (Row) cursor; + if (!curRow.hasField(fieldName)) { + throw new SQLException(String.format("Field %s not found", fieldName)); + } + return curRow.get(fieldName); + } + @Override public Object getObject(String fieldName) throws SQLException { if (fieldName == null) { @@ -157,13 +169,20 @@ public Object getObject(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) ? null : fieldValue.getValue(); + if (fieldValue == null || fieldValue.getValue() == null) { + wasNull = true; + return null; + } + wasNull = false; + return fieldValue.getValue(); } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return null; } - return curRow.get(fieldName); + wasNull = false; + return curVal; } } @@ -173,7 +192,12 @@ public Object getObject(int columnIndex) throws SQLException { return null; } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) ? null : fieldValue.getValue(); + if (fieldValue == null || fieldValue.getValue() == null) { + wasNull = true; + return null; + } + wasNull = false; + return fieldValue.getValue(); } else { // Data received from Read API (Arrow) return getObject(schemaFieldList.get(columnIndex).getName()); } @@ -189,23 +213,23 @@ public String getString(String fieldName) throws SQLException { } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; return null; - } else if (fieldValue - .getAttribute() - .equals(FieldValue.Attribute.REPEATED)) { // Case for Arrays + } + wasNull = false; + if (fieldValue.getAttribute().equals(FieldValue.Attribute.REPEATED)) { // Case for Arrays return fieldValue.getValue().toString(); } else { return fieldValue.getStringValue(); } } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); - } - Object currentVal = curRow.get(fieldName); + Object currentVal = getCurrentValueForReadApiData(fieldName); if (currentVal == null) { + wasNull = true; return null; - } else if (currentVal instanceof JsonStringArrayList) { // arrays + } + wasNull = false; + if (currentVal instanceof JsonStringArrayList) { // arrays JsonStringArrayList jsnAry = (JsonStringArrayList) currentVal; return jsnAry.toString(); } else if (currentVal instanceof LocalDateTime) { @@ -224,9 +248,12 @@ public String getString(int columnIndex) throws SQLException { return null; } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : fieldValue.getStringValue(); + if (fieldValue == null || fieldValue.getValue() == null) { + wasNull = true; + return null; + } + wasNull = false; + return fieldValue.getStringValue(); } else { // Data received from Read API (Arrow) return getString(schemaFieldList.get(columnIndex).getName()); } @@ -242,27 +269,27 @@ public int getInt(String fieldName) throws SQLException { // java.sql.ResultSet definition } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? 0 - : fieldValue.getNumericValue().intValue(); - } else { // Data received from Read API (Arrow) - - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return 0; } - Object curVal = curRow.get(fieldName); - if (curVal == null) { + wasNull = false; + return fieldValue.getNumericValue().intValue(); + } else { // Data received from Read API (Arrow) + Object currentVal = getCurrentValueForReadApiData(fieldName); + if (currentVal == null) { + wasNull = true; return 0; } - if (curVal instanceof Text) { // parse from text to int - return Integer.parseInt(((Text) curVal).toString()); - } else if (curVal + wasNull = false; + if (currentVal instanceof Text) { // parse from text to int + return Integer.parseInt((currentVal).toString()); + } else if (currentVal instanceof Long) { // incase getInt is called for a Long value. Loss of precision might occur - return ((Long) curVal).intValue(); + return ((Long) currentVal).intValue(); } - return ((BigDecimal) curVal).intValue(); + return ((BigDecimal) currentVal).intValue(); } } @@ -273,9 +300,11 @@ public int getInt(int columnIndex) throws SQLException { // java.sql.ResultSet definition } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? 0 - : fieldValue.getNumericValue().intValue(); + if (fieldValue == null || fieldValue.getValue() == null) { + wasNull = true; + return 0; + } + return fieldValue.getNumericValue().intValue(); } else { // Data received from Read API (Arrow) return getInt(schemaFieldList.get(columnIndex).getName()); } @@ -290,20 +319,21 @@ public long getLong(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? 0L - : fieldValue.getNumericValue().longValue(); - } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return 0L; } - Object curVal = curRow.get(fieldName); + wasNull = false; + return fieldValue.getNumericValue().longValue(); + } else { // Data received from Read API (Arrow) + Object curVal = getCurrentValueForReadApiData(fieldName); if (curVal == null) { + wasNull = true; return 0L; - } else { // value will be Long or BigDecimal, but are Number - return ((Number) curVal).longValue(); } + wasNull = false; + // value will be Long or BigDecimal, but are Number + return ((Number) curVal).longValue(); } } @@ -314,9 +344,12 @@ public long getLong(int columnIndex) throws SQLException { // java.sql.ResultSet definition } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? 0L - : fieldValue.getNumericValue().longValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return 0L; + } + wasNull = false; + return fieldValue.getNumericValue().longValue(); } else { // Data received from Read API (Arrow) return getInt(schemaFieldList.get(columnIndex).getName()); } @@ -331,16 +364,20 @@ public double getDouble(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? 0d - : fieldValue.getNumericValue().doubleValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return 0.0d; + } + wasNull = false; + return fieldValue.getNumericValue().doubleValue(); } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return 0.0d; } - Object curVal = curRow.get(fieldName); - return curVal == null ? 0.0d : new BigDecimal(curVal.toString()).doubleValue(); + wasNull = false; + return new BigDecimal(curVal.toString()).doubleValue(); } } @@ -351,9 +388,12 @@ public double getDouble(int columnIndex) throws SQLException { // java.sql.ResultSet definition } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? 0d - : fieldValue.getNumericValue().doubleValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return 0.0d; + } + wasNull = false; + return fieldValue.getNumericValue().doubleValue(); } else { // Data received from Read API (Arrow) return getDouble(schemaFieldList.get(columnIndex).getName()); } @@ -368,10 +408,19 @@ public BigDecimal getBigDecimal(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : BigDecimal.valueOf(fieldValue.getNumericValue().doubleValue()); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return BigDecimal.valueOf(fieldValue.getNumericValue().doubleValue()); } else { // Data received from Read API (Arrow) + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return null; + } + wasNull = false; return BigDecimal.valueOf(getDouble(fieldName)); } } @@ -382,9 +431,12 @@ public BigDecimal getBigDecimal(int columnIndex) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : BigDecimal.valueOf(fieldValue.getNumericValue().doubleValue()); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return BigDecimal.valueOf(fieldValue.getNumericValue().doubleValue()); } else { // Data received from Read API (Arrow) return getBigDecimal(schemaFieldList.get(columnIndex).getName()); } @@ -399,14 +451,20 @@ public boolean getBoolean(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return fieldValue.getValue() != null && fieldValue.getBooleanValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return false; + } + wasNull = false; + return fieldValue.getBooleanValue(); } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return false; } - Object curVal = curRow.get(fieldName); - return curVal != null && (Boolean) curVal; + wasNull = false; + return (Boolean) curVal; } } @@ -416,7 +474,12 @@ public boolean getBoolean(int columnIndex) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return fieldValue.getValue() != null && fieldValue.getBooleanValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return false; + } + wasNull = false; + return fieldValue.getBooleanValue(); } else { // Data received from Read API (Arrow) return getBoolean(schemaFieldList.get(columnIndex).getName()); } @@ -431,16 +494,20 @@ public byte[] getBytes(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : fieldValue.getBytesValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return fieldValue.getBytesValue(); } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return null; } - Object curVal = curRow.get(fieldName); - return curVal == null ? null : (byte[]) curVal; + wasNull = false; + return (byte[]) curVal; } } @@ -450,9 +517,12 @@ public byte[] getBytes(int columnIndex) throws SQLException { return null; // if the value is SQL NULL, the value returned is null } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : fieldValue.getBytesValue(); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return fieldValue.getBytesValue(); } else { // Data received from Read API (Arrow) return getBytes(schemaFieldList.get(columnIndex).getName()); } @@ -467,21 +537,23 @@ public Timestamp getTimestamp(String fieldName) throws SQLException { return null; // if the value is SQL NULL, the value returned is null } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : new Timestamp( - fieldValue.getTimestampValue() - / 1000); // getTimestampValue returns time in microseconds, and TimeStamp - // expects it in millis + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return new Timestamp( + fieldValue.getTimestampValue() + / 1000); // getTimestampValue returns time in microseconds, and TimeStamp expects it + // in millis } else { - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return null; } - Object timeStampVal = curRow.get(fieldName); - return timeStampVal == null - ? null - : new Timestamp((Long) timeStampVal / 1000); // Timestamp is represented as a Long + wasNull = false; + return new Timestamp((Long) curVal / 1000); // Timestamp is represented as a Long } } @@ -491,12 +563,15 @@ public Timestamp getTimestamp(int columnIndex) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : new Timestamp( - fieldValue.getTimestampValue() - / 1000); // getTimestampValue returns time in microseconds, and TimeStamp - // expects it in millis + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return new Timestamp( + fieldValue.getTimestampValue() + / 1000); // getTimestampValue returns time in microseconds, and TimeStamp expects it + // in millis } else { // Data received from Read API (Arrow) return getTimestamp(schemaFieldList.get(columnIndex).getName()); } @@ -511,61 +586,62 @@ public Time getTime(String fieldName) throws SQLException { return null; // if the value is SQL NULL, the value returned is null } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; return getTimeFromFieldVal(fieldValue); } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; + return null; } - Object timeStampObj = curRow.get(fieldName); - return timeStampObj == null - ? null - : new Time( - ((Long) timeStampObj) - / 1000); // Time.toString() will return 12:11:35 in GMT as 17:41:35 in - // (GMT+5:30). This can be offset using getTimeZoneOffset + wasNull = false; + return new Time( + ((Long) curVal) + / 1000); // Time.toString() will return 12:11:35 in GMT as 17:41:35 in (GMT+5:30). + // This can be offset using getTimeZoneOffset } } - private int getTimeZoneOffset() { - TimeZone timeZone = TimeZone.getTimeZone(ZoneId.systemDefault()); - return timeZone.getOffset(new java.util.Date().getTime()); // offset in seconds - } - @Override public Time getTime(int columnIndex) throws SQLException { if (cursor == null) { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; return getTimeFromFieldVal(fieldValue); } else { // Data received from Read API (Arrow) return getTime(schemaFieldList.get(columnIndex).getName()); } } + // Expects fieldValue.getValue() != null. private Time getTimeFromFieldVal(FieldValue fieldValue) throws SQLException { - if (fieldValue.getValue() != null) { - // Time ranges from 00:00:00 to 23:59:59.99999. in BigQuery. Parsing it to java.sql.Time - String strTime = fieldValue.getStringValue(); - String[] timeSplt = strTime.split(":"); - if (timeSplt.length != 3) { - throw new SQLException("Can not parse the value " + strTime + " to java.sql.Time"); - } - int hr = Integer.parseInt(timeSplt[0]); - int min = Integer.parseInt(timeSplt[1]); - int sec = 0, nanoSec = 0; - if (timeSplt[2].contains(".")) { - String[] secSplt = timeSplt[2].split("\\."); - sec = Integer.parseInt(secSplt[0]); - nanoSec = Integer.parseInt(secSplt[1]); - } else { - sec = Integer.parseInt(timeSplt[2]); - } - return Time.valueOf(LocalTime.of(hr, min, sec, nanoSec)); + // Time ranges from 00:00:00 to 23:59:59.99999. in BigQuery. Parsing it to java.sql.Time + String strTime = fieldValue.getStringValue(); + String[] timeSplt = strTime.split(":"); + if (timeSplt.length != 3) { + throw new SQLException("Can not parse the value " + strTime + " to java.sql.Time"); + } + int hr = Integer.parseInt(timeSplt[0]); + int min = Integer.parseInt(timeSplt[1]); + int sec, nanoSec = 0; + if (timeSplt[2].contains(".")) { + String[] secSplt = timeSplt[2].split("\\."); + sec = Integer.parseInt(secSplt[0]); + nanoSec = Integer.parseInt(secSplt[1]); } else { - return null; + sec = Integer.parseInt(timeSplt[2]); } + return Time.valueOf(LocalTime.of(hr, min, sec, nanoSec)); } @Override @@ -577,26 +653,26 @@ public Date getDate(String fieldName) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : Date.valueOf(fieldValue.getStringValue()); - } else { // Data received from Read API (Arrow) - Row curRow = (Row) cursor; - if (!curRow.hasField(fieldName)) { - throw new SQLException(String.format("Field %s not found", fieldName)); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; } - Object dateObj = curRow.get(fieldName); - if (dateObj == null) { + wasNull = false; + return Date.valueOf(fieldValue.getStringValue()); + } else { // Data received from Read API (Arrow) + Object curVal = getCurrentValueForReadApiData(fieldName); + if (curVal == null) { + wasNull = true; return null; - } else { - Integer dateInt = (Integer) dateObj; - long dateInMillis = - TimeUnit.DAYS.toMillis( - Long.valueOf( - dateInt)); // For example int 18993 represents 2022-01-01, converting time to - // milli seconds - return new Date(dateInMillis); } + wasNull = false; + Integer dateInt = (Integer) curVal; + long dateInMillis = + TimeUnit.DAYS.toMillis( + Long.valueOf( + dateInt)); // For example int 18993 represents 2022-01-01, converting time to + // milli seconds + return new Date(dateInMillis); } } @@ -606,13 +682,26 @@ public Date getDate(int columnIndex) throws SQLException { throw new BigQuerySQLException(NULL_CURSOR_MSG); } else if (cursor instanceof FieldValueList) { FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); - return (fieldValue == null || fieldValue.getValue() == null) - ? null - : Date.valueOf(fieldValue.getStringValue()); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + return Date.valueOf(fieldValue.getStringValue()); } else { // Data received from Read API (Arrow) return getDate(schemaFieldList.get(columnIndex).getName()); } } + + /** + * Returns whether the last column read had a value of SQL NULL. Note that you must first call + * one of the getter methods on a column to try to read its value and then call the method + * wasNull to see if the value read was SQL NULL. * + */ + @Override + public boolean wasNull() { + return wasNull; + } } @Override diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryResultImplTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryResultImplTest.java new file mode 100644 index 000000000..6431673e3 --- /dev/null +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryResultImplTest.java @@ -0,0 +1,257 @@ +/* + * 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.google.cloud.bigquery; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.cloud.bigquery.ConnectionImpl.EndOfFieldValueList; +import com.google.cloud.bigquery.FieldValue.Attribute; +import com.google.common.collect.ImmutableList; +import com.google.common.io.BaseEncoding; +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Time; +import java.sql.Timestamp; +import java.time.LocalTime; +import java.util.AbstractList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import org.apache.arrow.vector.util.Text; +import org.junit.Test; + +public class BigQueryResultImplTest { + + private static final Schema SCHEMA = + Schema.of( + Field.newBuilder("boolean", StandardSQLTypeName.BOOL) + .setMode(Field.Mode.NULLABLE) + .build(), + Field.newBuilder("long", StandardSQLTypeName.NUMERIC) + .setMode(Field.Mode.NULLABLE) + .build(), + Field.newBuilder("double", StandardSQLTypeName.NUMERIC) + .setMode(Field.Mode.NULLABLE) + .build(), + Field.newBuilder("string", StandardSQLTypeName.STRING) + .setMode(Field.Mode.NULLABLE) + .build(), + Field.newBuilder("bytes", StandardSQLTypeName.BYTES).setMode(Field.Mode.NULLABLE).build(), + Field.newBuilder("timestamp", StandardSQLTypeName.TIMESTAMP) + .setMode(Field.Mode.NULLABLE) + .build(), + Field.newBuilder("time", StandardSQLTypeName.TIME).setMode(Field.Mode.NULLABLE).build(), + Field.newBuilder("date", StandardSQLTypeName.DATE).setMode(Field.Mode.NULLABLE).build()); + + private static final FieldList FIELD_LIST_SCHEMA = + FieldList.of( + Field.of("boolean", LegacySQLTypeName.BOOLEAN), + Field.of("long", LegacySQLTypeName.INTEGER), + Field.of("double", LegacySQLTypeName.FLOAT), + Field.of("string", LegacySQLTypeName.STRING), + Field.of("bytes", LegacySQLTypeName.BYTES), + Field.of("timestamp", LegacySQLTypeName.TIMESTAMP), + Field.of("time", LegacySQLTypeName.TIME), + Field.of("date", LegacySQLTypeName.DATE)); + + private static final byte[] BYTES = {0xD, 0xE, 0xA, 0xD}; + private static final String BYTES_BASE64 = BaseEncoding.base64().encode(BYTES); + private static final Timestamp EXPECTED_TIMESTAMP = Timestamp.valueOf("2025-01-02 03:04:05.0"); + private static final String TIME = "20:21:22"; + private static final Time EXPECTED_TIME = Time.valueOf(LocalTime.of(20, 21, 22)); + private static final String DATE = "2020-01-21"; + private static final int DATE_INT = 0; + private static final Date EXPECTED_DATE = java.sql.Date.valueOf(DATE); + private static final int BUFFER_SIZE = 10; + + @Test + public void testResultSetFieldValueList() throws InterruptedException, SQLException { + BlockingQueue> buffer = new LinkedBlockingDeque<>(BUFFER_SIZE); + FieldValueList fieldValues = + FieldValueList.of( + ImmutableList.of( + FieldValue.of(Attribute.PRIMITIVE, "false"), + FieldValue.of(Attribute.PRIMITIVE, "1"), + FieldValue.of(Attribute.PRIMITIVE, "1.5"), + FieldValue.of(Attribute.PRIMITIVE, "string_value"), + FieldValue.of(Attribute.PRIMITIVE, BYTES_BASE64), + FieldValue.of( + Attribute.PRIMITIVE, + Long.toString(EXPECTED_TIMESTAMP.getTime() / 1000), + false), // getTime is in milliseconds. + FieldValue.of(Attribute.PRIMITIVE, TIME), + FieldValue.of(Attribute.PRIMITIVE, DATE)), + FIELD_LIST_SCHEMA); + buffer.put(fieldValues); + + FieldValueList nullValues = + FieldValueList.of( + ImmutableList.of( + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null), + FieldValue.of(Attribute.PRIMITIVE, null)), + FIELD_LIST_SCHEMA); + buffer.put(nullValues); + + buffer.put(new EndOfFieldValueList()); // End of buffer marker. + + BigQueryResultImpl> bigQueryResult = + new BigQueryResultImpl<>(SCHEMA, 1, buffer, null); + ResultSet resultSet = bigQueryResult.getResultSet(); + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.getObject("string")).isEqualTo("string_value"); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getString("string")).isEqualTo("string_value"); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getInt("long")).isEqualTo(1); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getLong("long")).isEqualTo(1); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getDouble("double")).isEqualTo(1.5); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getBigDecimal("double")).isEqualTo(BigDecimal.valueOf(1.5)); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getBoolean("boolean")).isFalse(); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getBytes("bytes")).isEqualTo(BYTES); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getTimestamp("timestamp")).isEqualTo(EXPECTED_TIMESTAMP); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getTime("time").getTime()).isEqualTo(EXPECTED_TIME.getTime()); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getDate("date").getTime()).isEqualTo(EXPECTED_DATE.getTime()); + assertThat(resultSet.wasNull()).isFalse(); + + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.getObject("string")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getString("string")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getInt("long")).isEqualTo(0); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getLong("long")).isEqualTo(0); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getDouble("double")).isEqualTo(0.0); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getBigDecimal("double")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getBoolean("boolean")).isFalse(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getBytes("bytes")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getTimestamp("timestamp")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getTime("time")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getDate("date")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + + assertThat(resultSet.next()).isFalse(); + } + + @Test + public void testResultSetReadApi() throws InterruptedException, SQLException { + BlockingQueue buffer = new LinkedBlockingDeque<>(BUFFER_SIZE); + + Map rowValues = new HashMap<>(); + rowValues.put("boolean", false); + rowValues.put("long", 1L); + rowValues.put("double", 1.5); + rowValues.put("string", new Text("string_value")); + rowValues.put("bytes", BYTES); + rowValues.put("timestamp", EXPECTED_TIMESTAMP.getTime() * 1000); + rowValues.put("time", EXPECTED_TIME.getTime() * 1000); + rowValues.put("date", DATE_INT); + buffer.put(new BigQueryResultImpl.Row(rowValues)); + + Map nullValues = new HashMap<>(); + nullValues.put("boolean", null); + nullValues.put("long", null); + nullValues.put("double", null); + nullValues.put("string", null); + nullValues.put("bytes", null); + nullValues.put("timestamp", null); + nullValues.put("time", null); + nullValues.put("date", null); + buffer.put(new BigQueryResultImpl.Row(nullValues)); + + buffer.put(new BigQueryResultImpl.Row(null, true)); // End of buffer marker. + + BigQueryResultImpl bigQueryResult = + new BigQueryResultImpl<>(SCHEMA, 1, buffer, null); + ResultSet resultSet = bigQueryResult.getResultSet(); + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.getObject("string")).isEqualTo(new Text("string_value")); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getString("string")).isEqualTo("string_value"); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getInt("long")).isEqualTo(1); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getLong("long")).isEqualTo(1); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getDouble("double")).isEqualTo(1.5); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getBigDecimal("double")).isEqualTo(BigDecimal.valueOf(1.5)); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getBoolean("boolean")).isFalse(); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getBytes("bytes")).isEqualTo(BYTES); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getTimestamp("timestamp")).isEqualTo(EXPECTED_TIMESTAMP); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getTime("time").getTime()).isEqualTo(EXPECTED_TIME.getTime()); + assertThat(resultSet.wasNull()).isFalse(); + // Do not check date value as Date object do not have timezone but its toString() applies the + // JVM default timezone which causes flakes in non-UTC zones. + assertThat(resultSet.getDate("date")).isNotNull(); + assertThat(resultSet.wasNull()).isFalse(); + + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.getObject("string")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getString("string")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getInt("long")).isEqualTo(0); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getLong("long")).isEqualTo(0); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getDouble("double")).isEqualTo(0.0); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getBigDecimal("double")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getBoolean("boolean")).isFalse(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getBytes("bytes")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getTimestamp("timestamp")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getTime("time")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getDate("date")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + + assertThat(resultSet.next()).isFalse(); + } +} From c91d2a6c6aae5904eab6fc4fe43dc1c68ca879b7 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:52:45 -0500 Subject: [PATCH 06/14] chore(main): release 2.47.1-SNAPSHOT (#3657) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- benchmark/pom.xml | 2 +- google-cloud-bigquery-bom/pom.xml | 4 ++-- google-cloud-bigquery/pom.xml | 4 ++-- pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 602d04857..cf8e30800 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -6,7 +6,7 @@ google-cloud-bigquery-parent com.google.cloud - 2.47.0 + 2.47.1-SNAPSHOT diff --git a/google-cloud-bigquery-bom/pom.xml b/google-cloud-bigquery-bom/pom.xml index 3a5c6f3e1..7980f17e4 100644 --- a/google-cloud-bigquery-bom/pom.xml +++ b/google-cloud-bigquery-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigquery-bom - 2.47.0 + 2.47.1-SNAPSHOT pom com.google.cloud @@ -54,7 +54,7 @@ com.google.cloud google-cloud-bigquery - 2.47.0 + 2.47.1-SNAPSHOT diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 13651acac..10e5fbb27 100644 --- a/google-cloud-bigquery/pom.xml +++ b/google-cloud-bigquery/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigquery - 2.47.0 + 2.47.1-SNAPSHOT jar BigQuery https://github.com/googleapis/java-bigquery @@ -11,7 +11,7 @@ com.google.cloud google-cloud-bigquery-parent - 2.47.0 + 2.47.1-SNAPSHOT google-cloud-bigquery diff --git a/pom.xml b/pom.xml index 5b1d3a0d7..8b5acdfa0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-bigquery-parent pom - 2.47.0 + 2.47.1-SNAPSHOT BigQuery Parent https://github.com/googleapis/java-bigquery @@ -93,7 +93,7 @@ com.google.cloud google-cloud-bigquery - 2.47.0 + 2.47.1-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 600522b26..8b26b3f5a 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -44,7 +44,7 @@ com.google.cloud google-cloud-bigquery - 2.47.0 + 2.47.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index d6010fec4..8ab96d478 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-bigquery:2.47.0:2.47.0 \ No newline at end of file +google-cloud-bigquery:2.47.0:2.47.1-SNAPSHOT \ No newline at end of file From 0fc7179d906c2d65ef5d92a644aea9192a4e3cff Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 3 Feb 2025 19:50:16 +0100 Subject: [PATCH 07/14] chore(deps): update dependency com.google.cloud:google-cloud-bigtable to v2.51.2 (#3665) --- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index b5f6b66f5..f92ed0e2c 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -63,7 +63,7 @@ com.google.cloud google-cloud-bigtable - 2.51.1 + 2.51.2 test diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 8b26b3f5a..42c8707f4 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -61,7 +61,7 @@ com.google.cloud google-cloud-bigtable - 2.51.1 + 2.51.2 test diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 69ea0c9e1..275dc8a8e 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -79,7 +79,7 @@ com.google.cloud google-cloud-bigtable - 2.51.1 + 2.51.2 test From 21910c7c4450ab4a1c85434745a7059220c3ba8d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 4 Feb 2025 15:41:23 +0100 Subject: [PATCH 08/14] test(deps): update dependency com.google.cloud:google-cloud-storage to v2.48.1 (#3666) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b5acdfa0..8592d12ce 100644 --- a/pom.xml +++ b/pom.xml @@ -137,7 +137,7 @@ com.google.cloud google-cloud-storage - 2.48.0 + 2.48.1 test From 0b92af6eba4a633bb514089c24b7dd19cf286789 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 10 Feb 2025 16:21:30 +0100 Subject: [PATCH 09/14] deps: update dependency com.google.apis:google-api-services-bigquery to v2-rev20250128-2.0.0 (#3667) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8592d12ce..cf7498430 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ UTF-8 github google-cloud-bigquery-parent - v2-rev20250112-2.0.0 + v2-rev20250128-2.0.0 From 4d9e0ff30269127f47484910e71fa7a21a735492 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 11 Feb 2025 18:29:05 +0100 Subject: [PATCH 10/14] deps: update dependency com.google.cloud:sdk-platform-java-config to v3.43.0 (#3669) --- .github/workflows/unmanaged_dependency_check.yaml | 2 +- .kokoro/continuous/graalvm-native-17.cfg | 2 +- .kokoro/continuous/graalvm-native.cfg | 2 +- .kokoro/presubmit/graalvm-native-17.cfg | 2 +- .kokoro/presubmit/graalvm-native.cfg | 2 +- google-cloud-bigquery-bom/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index 813d09f1b..2df44688d 100644 --- a/.github/workflows/unmanaged_dependency_check.yaml +++ b/.github/workflows/unmanaged_dependency_check.yaml @@ -17,7 +17,7 @@ jobs: # repository .kokoro/build.sh - name: Unmanaged dependency check - uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.42.0 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.43.0 with: # java-bigquery does not produce a BOM. Fortunately the root pom.xml # defines google-cloud-bigquery in dependencyManagement section. So diff --git a/.kokoro/continuous/graalvm-native-17.cfg b/.kokoro/continuous/graalvm-native-17.cfg index ce5394753..b9d88e776 100644 --- a/.kokoro/continuous/graalvm-native-17.cfg +++ b/.kokoro/continuous/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.42.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.43.0" } env_vars: { diff --git a/.kokoro/continuous/graalvm-native.cfg b/.kokoro/continuous/graalvm-native.cfg index ffdac2378..12e3b21ad 100644 --- a/.kokoro/continuous/graalvm-native.cfg +++ b/.kokoro/continuous/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.42.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.43.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg index 6331bd586..5b6a943cd 100644 --- a/.kokoro/presubmit/graalvm-native-17.cfg +++ b/.kokoro/presubmit/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.42.0"" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.43.0"" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg index f08c4be3e..f78bafd26 100644 --- a/.kokoro/presubmit/graalvm-native.cfg +++ b/.kokoro/presubmit/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.42.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.43.0" } env_vars: { diff --git a/google-cloud-bigquery-bom/pom.xml b/google-cloud-bigquery-bom/pom.xml index 7980f17e4..c81b3c8a8 100644 --- a/google-cloud-bigquery-bom/pom.xml +++ b/google-cloud-bigquery-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud sdk-platform-java-config - 3.42.0 + 3.43.0 diff --git a/pom.xml b/pom.xml index cf7498430..dbf083b4c 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.42.0 + 3.43.0 From 009b9a2b3940ab66220e68ddd565710b8552cc45 Mon Sep 17 00:00:00 2001 From: Phong Chuong <147636638+PhongChuong@users.noreply.github.com> Date: Tue, 11 Feb 2025 13:41:49 -0500 Subject: [PATCH 11/14] docs: update CONTRIBUTING.md for users without branch permissions (#3670) --- CONTRIBUTING.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b65dd279c..0599033d7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,9 +18,13 @@ again. ## Code reviews All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. +use GitHub pull requests for this purpose. Consult the +[GitHub Help: about pull requests](https://help.github.com/articles/about-pull-requests/) +article for more information on using pull requests. If you do not have +permission to create a branch, then fork the repository and submit a pull +request from the forked repository. Consult +[Github Help: about forks](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo#about-forks) +article for more information. ## Community Guidelines From 367dd4da0c1f4c824a2f4e1c4151f018d202e41d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 12 Feb 2025 23:44:44 +0100 Subject: [PATCH 12/14] test(deps): update dependency com.google.cloud:google-cloud-storage to v2.48.2 (#3674) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dbf083b4c..10600c05f 100644 --- a/pom.xml +++ b/pom.xml @@ -137,7 +137,7 @@ com.google.cloud google-cloud-storage - 2.48.1 + 2.48.2 test From abbdde0e7797712d98183ea2d5390671f92d5407 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 13 Feb 2025 01:32:07 +0100 Subject: [PATCH 13/14] chore(deps): update dependency com.google.cloud:google-cloud-bigquerystorage-bom to v3.11.3 (#3675) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 10600c05f..2b73fe2a7 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ com.google.cloud google-cloud-bigquerystorage-bom - 3.11.2 + 3.11.3 pom import From 759cb0a6706e91043c39b9dfc71fbaf7b7ffbc20 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 20:23:44 -0500 Subject: [PATCH 14/14] chore(main): release 2.48.0 (#3663) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 20 ++++++++++++++++++++ benchmark/pom.xml | 2 +- google-cloud-bigquery-bom/pom.xml | 4 ++-- google-cloud-bigquery/pom.xml | 4 ++-- pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 2 +- 7 files changed, 29 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index addb3d723..c91011f88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [2.48.0](https://github.com/googleapis/java-bigquery/compare/v2.47.0...v2.48.0) (2025-02-13) + + +### Features + +* Implement wasNull for BigQueryResultSet ([#3650](https://github.com/googleapis/java-bigquery/issues/3650)) ([c7ef94b](https://github.com/googleapis/java-bigquery/commit/c7ef94be115cd572df589385f9be801033d72d6d)) + + +### Dependencies + +* Update dependency com.google.api.grpc:proto-google-cloud-bigqueryconnection-v1 to v2.59.0 ([#3660](https://github.com/googleapis/java-bigquery/issues/3660)) ([3a6228b](https://github.com/googleapis/java-bigquery/commit/3a6228b4adc638759d3b2725c612e97e1a3b9cec)) +* Update dependency com.google.apis:google-api-services-bigquery to v2-rev20250128-2.0.0 ([#3667](https://github.com/googleapis/java-bigquery/issues/3667)) ([0b92af6](https://github.com/googleapis/java-bigquery/commit/0b92af6eba4a633bb514089c24b7dd19cf286789)) +* Update dependency com.google.cloud:google-cloud-datacatalog-bom to v1.63.0 ([#3661](https://github.com/googleapis/java-bigquery/issues/3661)) ([9bc8c01](https://github.com/googleapis/java-bigquery/commit/9bc8c0115dc16fb950567cd85cc7dfaa9df50d7d)) +* Update dependency com.google.cloud:sdk-platform-java-config to v3.43.0 ([#3669](https://github.com/googleapis/java-bigquery/issues/3669)) ([4d9e0ff](https://github.com/googleapis/java-bigquery/commit/4d9e0ff30269127f47484910e71fa7a21a735492)) + + +### Documentation + +* Update CONTRIBUTING.md for users without branch permissions ([#3670](https://github.com/googleapis/java-bigquery/issues/3670)) ([009b9a2](https://github.com/googleapis/java-bigquery/commit/009b9a2b3940ab66220e68ddd565710b8552cc45)) + ## [2.47.0](https://github.com/googleapis/java-bigquery/compare/v2.46.0...v2.47.0) (2025-01-29) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index cf8e30800..120d16ced 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -6,7 +6,7 @@ google-cloud-bigquery-parent com.google.cloud - 2.47.1-SNAPSHOT + 2.48.0 diff --git a/google-cloud-bigquery-bom/pom.xml b/google-cloud-bigquery-bom/pom.xml index c81b3c8a8..e1a74b5e9 100644 --- a/google-cloud-bigquery-bom/pom.xml +++ b/google-cloud-bigquery-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigquery-bom - 2.47.1-SNAPSHOT + 2.48.0 pom com.google.cloud @@ -54,7 +54,7 @@ com.google.cloud google-cloud-bigquery - 2.47.1-SNAPSHOT + 2.48.0 diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 10e5fbb27..bec0e10d3 100644 --- a/google-cloud-bigquery/pom.xml +++ b/google-cloud-bigquery/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigquery - 2.47.1-SNAPSHOT + 2.48.0 jar BigQuery https://github.com/googleapis/java-bigquery @@ -11,7 +11,7 @@ com.google.cloud google-cloud-bigquery-parent - 2.47.1-SNAPSHOT + 2.48.0 google-cloud-bigquery diff --git a/pom.xml b/pom.xml index 2b73fe2a7..12b44c359 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-bigquery-parent pom - 2.47.1-SNAPSHOT + 2.48.0 BigQuery Parent https://github.com/googleapis/java-bigquery @@ -93,7 +93,7 @@ com.google.cloud google-cloud-bigquery - 2.47.1-SNAPSHOT + 2.48.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 42c8707f4..f274559a2 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -44,7 +44,7 @@ com.google.cloud google-cloud-bigquery - 2.47.1-SNAPSHOT + 2.48.0 diff --git a/versions.txt b/versions.txt index 8ab96d478..a184e92b9 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-bigquery:2.47.0:2.47.1-SNAPSHOT \ No newline at end of file +google-cloud-bigquery:2.48.0:2.48.0 \ No newline at end of file