From 81bd13662ee6dc7fdffc51d3ba6ea4bc42bf9b5e Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Tue, 25 Feb 2025 15:54:23 -0800 Subject: [PATCH 01/11] Implement getArray in BigQueryResultImpl --- .../cloud/bigquery/BigQueryResultImpl.java | 126 +++++++++++++++++- .../bigquery/BigQueryResultImplTest.java | 41 +++++- .../cloud/bigquery/it/ITBigQueryTest.java | 19 +++ 3 files changed, 181 insertions(+), 5 deletions(-) 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 e1e129eae..54e16a26d 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 @@ -16,14 +16,19 @@ package com.google.cloud.bigquery; +import com.google.cloud.bigquery.FieldValue.Attribute; import java.math.BigDecimal; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import java.sql.Time; import java.sql.Timestamp; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; @@ -108,12 +113,83 @@ public ResultSet getResultSet() { return underlyingResultSet; } - private class BigQueryResultSet extends AbstractJdbcResultSet { + public 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; + private class BigQueryArrayResult implements java.sql.Array { + List array; + + public BigQueryArrayResult(Object array) { + if (array instanceof Object[]) { + this.array = new ArrayList<>(Arrays.asList((Object[]) array)); + } else if (array instanceof FieldValueList) { + this.array = new ArrayList<>((FieldValueList) array); + } else { + this.array = (List) array; + } + } + + @Override + public String getBaseTypeName() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getBaseType() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getArray() throws SQLException { + return array; + } + + @Override + public Object getArray(java.util.Map> map) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getArray(long index, int count) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getArray(long index, int count, java.util.Map> map) + throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSet getResultSet() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSet getResultSet(java.util.Map> map) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSet getResultSet(long index, int count) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSet getResultSet(long index, int count, java.util.Map> map) + throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void free() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + } + @Override /*Advances the result set to the next row, returning false if no such row exists. Potentially blocking operation*/ public boolean next() throws SQLException { @@ -160,6 +236,54 @@ private Object getCurrentValueForReadApiData(String fieldName) throws SQLExcepti return curRow.get(fieldName); } + @Override + public java.sql.Array getArray(String fieldName) throws SQLException { + if (fieldName == null) { + throw new SQLException("fieldName can't be null"); + } + if (cursor == null) { + throw new BigQuerySQLException(NULL_CURSOR_MSG); + } else if (cursor instanceof FieldValueList) { + FieldValue fieldValue = ((FieldValueList) cursor).get(fieldName); + if ((fieldValue == null || fieldValue.getValue() == null)) { + wasNull = true; + return null; + } + wasNull = false; + if (fieldValue.getAttribute().equals(Attribute.REPEATED)) { + return new BigQueryArrayResult(fieldValue.getValue()); + } else { + wasNull = true; + return null; + } + } else { // Data received from Read API (Arrow) + Object currentVal = getCurrentValueForReadApiData(fieldName); + if (currentVal == null) { + wasNull = true; + return null; + } + wasNull = false; + return new BigQueryArrayResult(currentVal); + } + } + + @Override + public java.sql.Array getArray(int columnIndex) throws SQLException { + if (cursor == null) { + return null; + } else if (cursor instanceof FieldValueList) { + FieldValue fieldValue = ((FieldValueList) cursor).get(columnIndex); + if (fieldValue == null || fieldValue.getValue() == null) { + wasNull = true; + return null; + } + wasNull = false; + return new BigQueryArrayResult(fieldValue.getValue()); + } else { + return getArray(schemaFieldList.get(columnIndex).getName()); + } + } + @Override public Object getObject(String fieldName) throws SQLException { if (fieldName == null) { 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 index 6431673e3..fe7b4f025 100644 --- 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 @@ -30,6 +30,8 @@ import java.sql.Timestamp; import java.time.LocalTime; import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.BlockingQueue; @@ -58,7 +60,13 @@ public class BigQueryResultImplTest { .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()); + Field.newBuilder("date", StandardSQLTypeName.DATE).setMode(Field.Mode.NULLABLE).build(), + Field.newBuilder("intArray", StandardSQLTypeName.INT64) + .setMode(Field.Mode.REPEATED) + .build(), + Field.newBuilder("stringArray", StandardSQLTypeName.STRING) + .setMode(Field.Mode.REPEATED) + .build()); private static final FieldList FIELD_LIST_SCHEMA = FieldList.of( @@ -69,7 +77,9 @@ public class BigQueryResultImplTest { Field.of("bytes", LegacySQLTypeName.BYTES), Field.of("timestamp", LegacySQLTypeName.TIMESTAMP), Field.of("time", LegacySQLTypeName.TIME), - Field.of("date", LegacySQLTypeName.DATE)); + Field.of("date", LegacySQLTypeName.DATE), + Field.of("intArray", LegacySQLTypeName.INTEGER), + Field.of("stringArray", LegacySQLTypeName.STRING)); private static final byte[] BYTES = {0xD, 0xE, 0xA, 0xD}; private static final String BYTES_BASE64 = BaseEncoding.base64().encode(BYTES); @@ -79,6 +89,11 @@ public class BigQueryResultImplTest { 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 ArrayList EXPECTED_INT_ARRAY = + new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4)); + private static final String[] STRING_ARRAY = {"str1", "str2", "str3"}; + private static final ArrayList EXPECTED_STRING_ARRAY = + new ArrayList<>(Arrays.asList(STRING_ARRAY)); private static final int BUFFER_SIZE = 10; @Test @@ -97,7 +112,9 @@ public void testResultSetFieldValueList() throws InterruptedException, SQLExcept Long.toString(EXPECTED_TIMESTAMP.getTime() / 1000), false), // getTime is in milliseconds. FieldValue.of(Attribute.PRIMITIVE, TIME), - FieldValue.of(Attribute.PRIMITIVE, DATE)), + FieldValue.of(Attribute.PRIMITIVE, DATE), + FieldValue.of(Attribute.REPEATED, EXPECTED_INT_ARRAY), + FieldValue.of(Attribute.REPEATED, STRING_ARRAY)), FIELD_LIST_SCHEMA); buffer.put(fieldValues); @@ -111,7 +128,9 @@ public void testResultSetFieldValueList() throws InterruptedException, SQLExcept 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.REPEATED, null), + FieldValue.of(Attribute.REPEATED, null)), FIELD_LIST_SCHEMA); buffer.put(nullValues); @@ -143,6 +162,10 @@ public void testResultSetFieldValueList() throws InterruptedException, SQLExcept assertThat(resultSet.wasNull()).isFalse(); assertThat(resultSet.getDate("date").getTime()).isEqualTo(EXPECTED_DATE.getTime()); assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getArray("intArray").getArray()).isEqualTo(EXPECTED_INT_ARRAY); + assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getArray("stringArray").getArray()).isEqualTo(EXPECTED_STRING_ARRAY); + assertThat(resultSet.wasNull()).isFalse(); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getObject("string")).isNull(); @@ -167,6 +190,10 @@ public void testResultSetFieldValueList() throws InterruptedException, SQLExcept assertThat(resultSet.wasNull()).isTrue(); assertThat(resultSet.getDate("date")).isNull(); assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getArray("intArray")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getArray("stringArray")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); assertThat(resultSet.next()).isFalse(); } @@ -184,6 +211,7 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { rowValues.put("timestamp", EXPECTED_TIMESTAMP.getTime() * 1000); rowValues.put("time", EXPECTED_TIME.getTime() * 1000); rowValues.put("date", DATE_INT); + rowValues.put("intArray", EXPECTED_INT_ARRAY); buffer.put(new BigQueryResultImpl.Row(rowValues)); Map nullValues = new HashMap<>(); @@ -195,6 +223,7 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { nullValues.put("timestamp", null); nullValues.put("time", null); nullValues.put("date", null); + nullValues.put("intArray", null); buffer.put(new BigQueryResultImpl.Row(nullValues)); buffer.put(new BigQueryResultImpl.Row(null, true)); // End of buffer marker. @@ -227,6 +256,8 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { // JVM default timezone which causes flakes in non-UTC zones. assertThat(resultSet.getDate("date")).isNotNull(); assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getArray("intArray")).isNotNull(); + assertThat(resultSet.wasNull()).isFalse(); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getObject("string")).isNull(); @@ -251,6 +282,8 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { assertThat(resultSet.wasNull()).isTrue(); assertThat(resultSet.getDate("date")).isNull(); assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getArray("intArray")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); assertThat(resultSet.next()).isFalse(); } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 0178ac10a..c054d0c70 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -223,6 +223,8 @@ public class ITBigQueryTest { ImmutableMap.of( "example-label1", "example-value1", "example-label2", "example-value2"); + private static final List INTEGER_ARRAY_FIELD_LIST = + new ArrayList<>(Arrays.asList(1, 2, 3, 4)); private static final Field TIMESTAMP_FIELD_SCHEMA = Field.newBuilder("TimestampField", LegacySQLTypeName.TIMESTAMP) .setMode(Field.Mode.NULLABLE) @@ -3925,6 +3927,10 @@ public void testExecuteSelectSinglePageTableRow() throws SQLException { (com.google.cloud.bigquery.FieldValueList) rs.getObject("IntegerArrayField"); assertEquals(4, integerArrayFieldValue.size()); // Array has 4 elements assertEquals(3, (integerArrayFieldValue.get(2).getNumericValue()).intValue()); + List integerArrayFieldValueList = + (List) rs.getArray("IntegerArrayField").getArray(); + assertEquals(4, integerArrayFieldValueList.size()); + assertEquals(3, integerArrayFieldValueList.get(2).getNumericValue().intValue()); assertFalse(rs.next()); // no 3rd row in the table } @@ -4278,6 +4284,19 @@ public void testExecuteSelectSinglePageTableRowColInd() throws SQLException { (integerArrayFieldValue.get(2).getNumericValue()).intValue(), (integerArrayFieldValueColInd.get(2).getNumericValue()).intValue()); } + + List integerArrayFieldValueList = + (List) rs.getArray("IntegerArrayField").getArray(); + List integerArrayFieldValueListColInd = + (List) rs.getArray(14).getArray(); + assertEquals( + integerArrayFieldValueList.size(), + integerArrayFieldValueListColInd.size()); // Array has 4 elements + if (integerArrayFieldValueList.size() == 4) { // as we are picking the third index + assertEquals( + (integerArrayFieldValueList.get(2).getNumericValue()).intValue(), + (integerArrayFieldValueListColInd.get(2).getNumericValue()).intValue()); + } } } From 4e28b422e308adc5d8003a63e8d8119bdccb2a55 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Feb 2025 16:16:31 +0100 Subject: [PATCH 02/11] deps: update dependency com.google.apis:google-api-services-bigquery to v2-rev20250216-2.0.0 (#3688) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0186bfff7..7ea819901 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ UTF-8 github google-cloud-bigquery-parent - v2-rev20250128-2.0.0 + v2-rev20250216-2.0.0 From dc3c0fb18b2917e8c0515a7947b21faf6e996f24 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Feb 2025 16:16:42 +0100 Subject: [PATCH 03/11] build(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.0 (#3689) --- benchmark/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index b0d222a13..a49d95a56 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -37,7 +37,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 From 8011eaf2696fbe6aa8f34bb27b3bc08c83eef147 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 24 Feb 2025 16:08:15 +0100 Subject: [PATCH 04/11] deps: update ossf/scorecard-action action to v2.4.1 (#3690) --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index b04c8ba87..ecdc2758d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -37,7 +37,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif From fac2ae1f4e624eda9ba4b2a3c8d0424f45550f9c Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 24 Feb 2025 16:54:38 +0100 Subject: [PATCH 05/11] deps: update actions/upload-artifact action to v4.6.1 (#3691) --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ecdc2758d..1831a7d08 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: SARIF file path: results.sarif From aa73bfd636a72f7def35c0acaa13f89d669c88a2 Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Tue, 25 Feb 2025 16:26:03 -0800 Subject: [PATCH 06/11] Remove public from BigQueryResultSet class def --- .../main/java/com/google/cloud/bigquery/BigQueryResultImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 54e16a26d..b705e77c1 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 @@ -113,7 +113,7 @@ public ResultSet getResultSet() { return underlyingResultSet; } - public class BigQueryResultSet extends AbstractJdbcResultSet { + 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 From 3b4791dc68584f8d99d424a42e7709b712497654 Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Tue, 25 Feb 2025 16:31:36 -0800 Subject: [PATCH 07/11] Remove INTEGER_ARRAY_FIELD_LIST from IT test file --- .../test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index c054d0c70..75ef5dd27 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -223,8 +223,6 @@ public class ITBigQueryTest { ImmutableMap.of( "example-label1", "example-value1", "example-label2", "example-value2"); - private static final List INTEGER_ARRAY_FIELD_LIST = - new ArrayList<>(Arrays.asList(1, 2, 3, 4)); private static final Field TIMESTAMP_FIELD_SCHEMA = Field.newBuilder("TimestampField", LegacySQLTypeName.TIMESTAMP) .setMode(Field.Mode.NULLABLE) From a32c1231f4ae948bf5895df00c18edfda7cac10c Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Mon, 3 Mar 2025 15:56:17 -0800 Subject: [PATCH 08/11] Add ReadApi IT test --- .../bigquery/BigQueryResultImplTest.java | 6 ++ .../cloud/bigquery/it/ITBigQueryTest.java | 66 +++++++++++++++++++ 2 files changed, 72 insertions(+) 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 index fe7b4f025..ca150eb1b 100644 --- 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 @@ -212,6 +212,7 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { rowValues.put("time", EXPECTED_TIME.getTime() * 1000); rowValues.put("date", DATE_INT); rowValues.put("intArray", EXPECTED_INT_ARRAY); + rowValues.put("stringArray", STRING_ARRAY); buffer.put(new BigQueryResultImpl.Row(rowValues)); Map nullValues = new HashMap<>(); @@ -224,6 +225,7 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { nullValues.put("time", null); nullValues.put("date", null); nullValues.put("intArray", null); + nullValues.put("stringArray", null); buffer.put(new BigQueryResultImpl.Row(nullValues)); buffer.put(new BigQueryResultImpl.Row(null, true)); // End of buffer marker. @@ -258,6 +260,8 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { assertThat(resultSet.wasNull()).isFalse(); assertThat(resultSet.getArray("intArray")).isNotNull(); assertThat(resultSet.wasNull()).isFalse(); + assertThat(resultSet.getArray("stringArray")).isNotNull(); + assertThat(resultSet.wasNull()).isFalse(); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getObject("string")).isNull(); @@ -284,6 +288,8 @@ public void testResultSetReadApi() throws InterruptedException, SQLException { assertThat(resultSet.wasNull()).isTrue(); assertThat(resultSet.getArray("intArray")).isNull(); assertThat(resultSet.wasNull()).isTrue(); + assertThat(resultSet.getArray("stringArray")).isNull(); + assertThat(resultSet.wasNull()).isTrue(); assertThat(resultSet.next()).isFalse(); } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 75ef5dd27..e429ae9e0 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -3933,6 +3933,72 @@ public void testExecuteSelectSinglePageTableRow() throws SQLException { assertFalse(rs.next()); // no 3rd row in the table } + @Test + public void testExecuteSelectSinglePageTableRowWithReadAPI() throws SQLException { + String query = + "select StringField, BigNumericField, BooleanField, BytesField, IntegerField, TimestampField, FloatField, " + + "NumericField, TimeField, DateField, DateTimeField , GeographyField, RecordField.BytesField, RecordField.BooleanField, IntegerArrayField from " + + TABLE_ID_FASTQUERY_BQ_RESULTSET.getTable() + + " order by TimestampField"; + ConnectionSettings connectionSettings = + ConnectionSettings.newBuilder() + .setDefaultDataset(DatasetId.of(DATASET)) + .setUseReadAPI(true) + .setMinResultSize(1) + .setTotalToPageRowCountRatio(1) + .build(); + Connection connection = bigquery.createConnection(connectionSettings); + BigQueryResult bigQueryResult = connection.executeSelect(query); + assertTrue(bigQueryResult.getBigQueryResultStats().getQueryStatistics().getUseReadApi()); + ResultSet rs = bigQueryResult.getResultSet(); + Schema sc = bigQueryResult.getSchema(); + + assertEquals(BQ_RESULTSET_EXPECTED_SCHEMA, sc); // match the schema + assertEquals(2, bigQueryResult.getTotalRows()); // Expecting 2 rows + + assertTrue(rs.next()); // first row + // checking for the null or 0 column values + assertNull(rs.getString("StringField")); + assertTrue(rs.getDouble("BigNumericField") == 0.0d); + assertFalse(rs.getBoolean("BooleanField")); + assertNull(rs.getBytes("BytesField")); + assertEquals(rs.getInt("IntegerField"), 0); + assertNull(rs.getTimestamp("TimestampField")); + assertNull(rs.getDate("DateField")); + assertTrue(rs.getDouble("FloatField") == 0.0d); + assertTrue(rs.getDouble("NumericField") == 0.0d); + assertNull(rs.getTime("TimeField")); + assertNull(rs.getString("DateTimeField")); + assertNull(rs.getString("GeographyField")); + assertNull(rs.getBytes("BytesField_1")); + assertFalse(rs.getBoolean("BooleanField_1")); + + assertTrue(rs.next()); // second row + // second row is non null, comparing the values + assertEquals("StringValue1", rs.getString("StringField")); + assertTrue(rs.getDouble("BigNumericField") == 0.3333333333333333d); + assertFalse(rs.getBoolean("BooleanField")); + assertNotNull(rs.getBytes("BytesField")); + assertEquals(1, rs.getInt("IntegerField")); + assertEquals(1534680695123L, rs.getTimestamp("TimestampField").getTime()); + assertEquals( + java.sql.Date.valueOf("2018-08-18").toLocalDate(), rs.getDate("DateField").toLocalDate()); + assertTrue(rs.getDouble("FloatField") == 10.1d); + assertTrue(rs.getDouble("NumericField") == 100.0d); + assertEquals( + Time.valueOf(LocalTime.of(4, 11, 35, 123456)).toLocalTime(), + rs.getTime("TimeField").toLocalTime()); + assertEquals("2018-08-19T12:11:35.123456", rs.getString("DateTimeField")); + assertEquals("POINT(-122.35022 47.649154)", rs.getString("GeographyField")); + assertNotNull(rs.getBytes("BytesField_1")); + assertTrue(rs.getBoolean("BooleanField_1")); + List integerArray = (List) rs.getArray("IntegerArrayField").getArray(); + assertEquals(4, integerArray.size()); + assertEquals(3, integerArray.get(2).intValue()); + + assertFalse(rs.next()); // no 3rd row in the table + } + @Test public void testConnectionClose() throws SQLException { String query = From 34c59dfb5416a2acf1f31c90f43aff6a8844464f Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Mon, 3 Mar 2025 22:43:52 -0800 Subject: [PATCH 09/11] Try old IT test values --- .../java/com/google/cloud/bigquery/it/ITBigQueryTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index e429ae9e0..7f6fa05f4 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -3981,13 +3981,10 @@ public void testExecuteSelectSinglePageTableRowWithReadAPI() throws SQLException assertNotNull(rs.getBytes("BytesField")); assertEquals(1, rs.getInt("IntegerField")); assertEquals(1534680695123L, rs.getTimestamp("TimestampField").getTime()); - assertEquals( - java.sql.Date.valueOf("2018-08-18").toLocalDate(), rs.getDate("DateField").toLocalDate()); + assertEquals(java.sql.Date.valueOf("2018-08-19"), rs.getDate("DateField")); assertTrue(rs.getDouble("FloatField") == 10.1d); assertTrue(rs.getDouble("NumericField") == 100.0d); - assertEquals( - Time.valueOf(LocalTime.of(4, 11, 35, 123456)).toLocalTime(), - rs.getTime("TimeField").toLocalTime()); + assertEquals(Time.valueOf(LocalTime.of(12, 11, 35, 123456)), rs.getTime("TimeField")); assertEquals("2018-08-19T12:11:35.123456", rs.getString("DateTimeField")); assertEquals("POINT(-122.35022 47.649154)", rs.getString("GeographyField")); assertNotNull(rs.getBytes("BytesField_1")); From 2fc76c826ded12d1da2ed86d00ea9956d2eb6904 Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Tue, 4 Mar 2025 00:47:17 -0800 Subject: [PATCH 10/11] Convert Time objects to strings for comparison --- .../java/com/google/cloud/bigquery/it/ITBigQueryTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 7f6fa05f4..8518c55db 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -3938,7 +3938,7 @@ public void testExecuteSelectSinglePageTableRowWithReadAPI() throws SQLException String query = "select StringField, BigNumericField, BooleanField, BytesField, IntegerField, TimestampField, FloatField, " + "NumericField, TimeField, DateField, DateTimeField , GeographyField, RecordField.BytesField, RecordField.BooleanField, IntegerArrayField from " - + TABLE_ID_FASTQUERY_BQ_RESULTSET.getTable() + + TABLE_ID_FASTQUERY_BQ_RESULTSET.getTable( + " order by TimestampField"; ConnectionSettings connectionSettings = ConnectionSettings.newBuilder() @@ -3984,7 +3984,7 @@ public void testExecuteSelectSinglePageTableRowWithReadAPI() throws SQLException assertEquals(java.sql.Date.valueOf("2018-08-19"), rs.getDate("DateField")); assertTrue(rs.getDouble("FloatField") == 10.1d); assertTrue(rs.getDouble("NumericField") == 100.0d); - assertEquals(Time.valueOf(LocalTime.of(12, 11, 35, 123456)), rs.getTime("TimeField")); + assertEquals(Time.valueOf(LocalTime.of(12, 11, 35, 123456)).toString(), rs.getTime("TimeField").toString()); assertEquals("2018-08-19T12:11:35.123456", rs.getString("DateTimeField")); assertEquals("POINT(-122.35022 47.649154)", rs.getString("GeographyField")); assertNotNull(rs.getBytes("BytesField_1")); From 5416a1aece3d8905e61d13f846cf761e69413f1c Mon Sep 17 00:00:00 2001 From: Liam Huffman Date: Tue, 4 Mar 2025 00:52:03 -0800 Subject: [PATCH 11/11] Fix Formatting --- .../java/com/google/cloud/bigquery/it/ITBigQueryTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 8518c55db..a7bf5fa3e 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -3938,7 +3938,7 @@ public void testExecuteSelectSinglePageTableRowWithReadAPI() throws SQLException String query = "select StringField, BigNumericField, BooleanField, BytesField, IntegerField, TimestampField, FloatField, " + "NumericField, TimeField, DateField, DateTimeField , GeographyField, RecordField.BytesField, RecordField.BooleanField, IntegerArrayField from " - + TABLE_ID_FASTQUERY_BQ_RESULTSET.getTable( + + TABLE_ID_FASTQUERY_BQ_RESULTSET.getTable() + " order by TimestampField"; ConnectionSettings connectionSettings = ConnectionSettings.newBuilder() @@ -3984,7 +3984,9 @@ public void testExecuteSelectSinglePageTableRowWithReadAPI() throws SQLException assertEquals(java.sql.Date.valueOf("2018-08-19"), rs.getDate("DateField")); assertTrue(rs.getDouble("FloatField") == 10.1d); assertTrue(rs.getDouble("NumericField") == 100.0d); - assertEquals(Time.valueOf(LocalTime.of(12, 11, 35, 123456)).toString(), rs.getTime("TimeField").toString()); + assertEquals( + Time.valueOf(LocalTime.of(12, 11, 35, 123456)).toString(), + rs.getTime("TimeField").toString()); assertEquals("2018-08-19T12:11:35.123456", rs.getString("DateTimeField")); assertEquals("POINT(-122.35022 47.649154)", rs.getString("GeographyField")); assertNotNull(rs.getBytes("BytesField_1"));