From 62ec3e939e1ec29d7ba10be6d54ab613fcc89f08 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 21 Jan 2026 14:34:24 -0500 Subject: [PATCH 1/3] chore: Add IT for positional parameter on higher precision timestamp field --- .../bigquery/it/ITHighPrecisionTimestamp.java | 68 +++++++++++++------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java index 4942c3008..2a68bf073 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java @@ -51,14 +51,14 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -public class ITHighPrecisionTimestamp { +class ITHighPrecisionTimestamp { - public static final String TEST_HIGH_PRECISION_TIMESTAMP_TABLE_NAME = - "test_high_precision_timestamp"; + private static final String TEST_HIGH_PRECISION_TIMESTAMP_TABLE_NAME = + generateTempTableName("test_high_precision_timestamp"); private static BigQuery bigquery; private static final String DATASET = RemoteBigQueryHelper.generateDatasetName(); private static TableId defaultTableId; - public static final long TIMESTAMP_PICOSECOND_PRECISION = 12L; + private static final long TIMESTAMP_PICOSECOND_PRECISION = 12L; private static final Field TIMESTAMP_HIGH_PRECISION_FIELD_SCHEMA = Field.newBuilder("timestampHighPrecisionField", StandardSQLTypeName.TIMESTAMP) .setTimestampPrecision(TIMESTAMP_PICOSECOND_PRECISION) @@ -69,8 +69,12 @@ public class ITHighPrecisionTimestamp { private static final String TIMESTAMP2 = "1970-01-01T12:34:56.123456789123Z"; private static final String TIMESTAMP3 = "2000-01-01T12:34:56.123456789123Z"; + private static String generateTempTableName(String prefix) { + return String.format("%s_%s", prefix, UUID.randomUUID().toString().substring(0, 8)); + } + @BeforeAll - public static void beforeClass() { + static void beforeClass() { BigQueryOptions.Builder builder = BigQueryOptions.newBuilder() .setDataFormatOptions( @@ -111,21 +115,15 @@ public static void beforeClass() { } @AfterAll - public static void afterClass() { + static void afterClass() { if (bigquery != null) { bigquery.delete(defaultTableId); RemoteBigQueryHelper.forceDelete(bigquery, DATASET); } } - private static String generateTempTableName() { - return String.format( - "insert_temp_%s%s", - UUID.randomUUID().toString().substring(0, 6), TEST_HIGH_PRECISION_TIMESTAMP_TABLE_NAME); - } - @Test - public void query_highPrecisionTimestamp() throws InterruptedException { + void query_highPrecisionTimestamp() throws InterruptedException { String sql = String.format("SELECT timestampHighPrecisionField FROM %s;", defaultTableId.getTable()); QueryJobConfiguration queryJobConfiguration = @@ -147,10 +145,10 @@ public void query_highPrecisionTimestamp() throws InterruptedException { } @Test - public void insert_highPrecisionTimestamp_ISOValidFormat() { + void insert_highPrecisionTimestamp_ISOValidFormat() { StandardTableDefinition tableDefinition = StandardTableDefinition.newBuilder().setSchema(TABLE_SCHEMA).build(); - String tempTableName = generateTempTableName(); + String tempTableName = generateTempTableName("insert_temp"); TableId tableId = TableId.of(DATASET, tempTableName); Table createdTable = bigquery.create(TableInfo.of(tableId, tableDefinition)); assertNotNull(createdTable); @@ -166,10 +164,10 @@ public void insert_highPrecisionTimestamp_ISOValidFormat() { } @Test - public void insert_highPrecisionTimestamp_invalidFormats() { + void insert_highPrecisionTimestamp_invalidFormats() { StandardTableDefinition tableDefinition = StandardTableDefinition.newBuilder().setSchema(TABLE_SCHEMA).build(); - String tempTable = generateTempTableName(); + String tempTable = generateTempTableName("insert_temp"); TableId tableId = TableId.of(DATASET, tempTable); Table createdTable = bigquery.create(TableInfo.of(tableId, tableDefinition)); assertNotNull(createdTable); @@ -207,7 +205,7 @@ public void insert_highPrecisionTimestamp_invalidFormats() { } @Test - public void queryNamedParameter_highPrecisionTimestamp() throws InterruptedException { + void queryNamedParameter_highPrecisionTimestamp() throws InterruptedException { String query = String.format( "SELECT * FROM %s.%s WHERE timestampHighPrecisionField >= CAST(@timestampParam AS TIMESTAMP(12))", @@ -236,7 +234,34 @@ public void queryNamedParameter_highPrecisionTimestamp() throws InterruptedExcep } @Test - public void queryNamedParameter_highPrecisionTimestamp_microsLong() throws InterruptedException { + void queryPositionalParameter_highPrecisionTimestamp() throws InterruptedException { + String query = + String.format( + "SELECT * FROM %s.%s WHERE timestampHighPrecisionField >= CAST(? AS TIMESTAMP(12))", + DATASET, defaultTableId.getTable()); + + QueryJobConfiguration queryConfig = + QueryJobConfiguration.newBuilder(query) + .setDefaultDataset(DATASET) + .setUseLegacySql(false) + .addPositionalParameter(QueryParameterValue.timestamp("2000-01-01 12:34:56.123456789123Z")) + .build(); + + TableResult result = bigquery.query(queryConfig); + assertNotNull(result); + String[] expected = new String[] {TIMESTAMP1, TIMESTAMP3}; + List timestamps = + StreamSupport.stream(result.getValues().spliterator(), false) + .map(x -> (String) x.get(0).getValue()) + .collect(Collectors.toList()); + assertEquals(expected.length, timestamps.size()); + for (int i = 0; i < timestamps.size(); i++) { + assertEquals(expected[i], timestamps.get(i)); + } + } + + @Test + void queryNamedParameter_highPrecisionTimestamp_microsLong() throws InterruptedException { String query = String.format( "SELECT * FROM %s.%s WHERE timestampHighPrecisionField >= CAST(@timestampParam AS TIMESTAMP(12))", @@ -269,8 +294,7 @@ public void queryNamedParameter_highPrecisionTimestamp_microsLong() throws Inter } @Test - public void queryNamedParameter_highPrecisionTimestamp_microsISOString() - throws InterruptedException { + void queryNamedParameter_highPrecisionTimestamp_microsISOString() throws InterruptedException { String query = String.format( "SELECT * FROM %s.%s WHERE timestampHighPrecisionField >= CAST(@timestampParam AS TIMESTAMP(12))", @@ -298,7 +322,7 @@ public void queryNamedParameter_highPrecisionTimestamp_microsISOString() } @Test - public void queryNamedParameter_highPrecisionTimestamp_noExplicitCastInQuery_fails() { + void queryNamedParameter_highPrecisionTimestamp_noExplicitCastInQuery_fails() { String query = String.format( "SELECT * FROM %s.%s WHERE timestampHighPrecisionField >= @timestampParam", From 2df7a0ac62f3ce511d9ba530a15e27cb1c3a4709 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 21 Jan 2026 14:53:33 -0500 Subject: [PATCH 2/3] chore: Fix gemini comments --- .../bigquery/it/ITHighPrecisionTimestamp.java | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java index 2a68bf073..e64fe5988 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java @@ -15,6 +15,7 @@ */ package com.google.cloud.bigquery.it; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -139,9 +140,7 @@ void query_highPrecisionTimestamp() throws InterruptedException { .map(x -> (String) x.get(0).getValue()) .collect(Collectors.toList()); assertEquals(expected.length, timestamps.size()); - for (int i = 0; i < timestamps.size(); i++) { - assertEquals(expected[i], timestamps.get(i)); - } + assertThat(timestamps).containsAtLeastElementsIn(expected); } @Test @@ -217,6 +216,7 @@ void queryNamedParameter_highPrecisionTimestamp() throws InterruptedException { .setUseLegacySql(false) .addNamedParameter( "timestampParam", + // For named parameters, java-bigquery does not expect the 'T' QueryParameterValue.timestamp("2000-01-01 12:34:56.123456789123Z")) .build(); @@ -228,9 +228,7 @@ void queryNamedParameter_highPrecisionTimestamp() throws InterruptedException { .map(x -> (String) x.get(0).getValue()) .collect(Collectors.toList()); assertEquals(expected.length, timestamps.size()); - for (int i = 0; i < timestamps.size(); i++) { - assertEquals(expected[i], timestamps.get(i)); - } + assertThat(timestamps).containsAtLeastElementsIn(expected); } @Test @@ -244,7 +242,9 @@ void queryPositionalParameter_highPrecisionTimestamp() throws InterruptedExcepti QueryJobConfiguration.newBuilder(query) .setDefaultDataset(DATASET) .setUseLegacySql(false) - .addPositionalParameter(QueryParameterValue.timestamp("2000-01-01 12:34:56.123456789123Z")) + .addPositionalParameter( + // For named parameters, java-bigquery does not expect the 'T' + QueryParameterValue.timestamp("2000-01-01 12:34:56.123456789123Z")) .build(); TableResult result = bigquery.query(queryConfig); @@ -255,9 +255,7 @@ void queryPositionalParameter_highPrecisionTimestamp() throws InterruptedExcepti .map(x -> (String) x.get(0).getValue()) .collect(Collectors.toList()); assertEquals(expected.length, timestamps.size()); - for (int i = 0; i < timestamps.size(); i++) { - assertEquals(expected[i], timestamps.get(i)); - } + assertThat(timestamps).containsAtLeastElementsIn(expected); } @Test @@ -288,9 +286,7 @@ void queryNamedParameter_highPrecisionTimestamp_microsLong() throws InterruptedE .map(x -> (String) x.get(0).getValue()) .collect(Collectors.toList()); assertEquals(expected.length, timestamps.size()); - for (int i = 0; i < timestamps.size(); i++) { - assertEquals(expected[i], timestamps.get(i)); - } + assertThat(timestamps).containsAtLeastElementsIn(expected); } @Test @@ -305,6 +301,7 @@ void queryNamedParameter_highPrecisionTimestamp_microsISOString() throws Interru .setDefaultDataset(DATASET) .setUseLegacySql(false) .addNamedParameter( + // For named parameters, java-bigquery does not expect the 'T' "timestampParam", QueryParameterValue.timestamp("2000-01-01 12:34:56.123456Z")) .build(); @@ -316,9 +313,7 @@ void queryNamedParameter_highPrecisionTimestamp_microsISOString() throws Interru .collect(Collectors.toList()); String[] expected = new String[] {TIMESTAMP1, TIMESTAMP3}; assertEquals(expected.length, timestamps.size()); - for (int i = 0; i < timestamps.size(); i++) { - assertEquals(expected[i], timestamps.get(i)); - } + assertThat(timestamps).containsAtLeastElementsIn(expected); } @Test @@ -333,6 +328,7 @@ void queryNamedParameter_highPrecisionTimestamp_noExplicitCastInQuery_fails() { .setDefaultDataset(DATASET) .setUseLegacySql(false) .addNamedParameter( + // For named parameters, java-bigquery does not expect the 'T' "timestampParam", QueryParameterValue.timestamp("2000-01-01 12:34:56.123456789123")) .build(); From c70f1f0588029bc2eb13fe08c2e9a75ee19c4dbb Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Wed, 21 Jan 2026 14:54:49 -0500 Subject: [PATCH 3/3] chore: Fix typo --- .../com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java index e64fe5988..e4dc534f9 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITHighPrecisionTimestamp.java @@ -243,7 +243,7 @@ void queryPositionalParameter_highPrecisionTimestamp() throws InterruptedExcepti .setDefaultDataset(DATASET) .setUseLegacySql(false) .addPositionalParameter( - // For named parameters, java-bigquery does not expect the 'T' + // For positional parameters, java-bigquery does not expect the 'T' QueryParameterValue.timestamp("2000-01-01 12:34:56.123456789123Z")) .build();