Skip to content
This repository was archived by the owner on Feb 24, 2026. It is now read-only.

Commit c9371c9

Browse files
committed
test: Add picosecond test cases
1 parent 38837fc commit c9371c9

4 files changed

Lines changed: 241 additions & 101 deletions

File tree

google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/it/ITBigQueryStorageReadClientTest.java

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.google.cloud.bigquery.storage.v1.it;
1818

19+
import static com.google.cloud.bigquery.storage.v1.it.util.Helper.TIMESTAMP_COLUMN_NAME;
20+
import static com.google.cloud.bigquery.storage.v1.it.util.Helper.TIMESTAMP_HIGHER_PRECISION_COLUMN_NAME;
1921
import static com.google.common.truth.Truth.assertThat;
2022
import static com.google.common.truth.Truth.assertWithMessage;
2123
import static org.junit.Assert.assertArrayEquals;
@@ -53,6 +55,7 @@
5355
import com.google.cloud.bigquery.TableInfo;
5456
import com.google.cloud.bigquery.TimePartitioning;
5557
import com.google.cloud.bigquery.storage.v1.AppendRowsResponse;
58+
import com.google.cloud.bigquery.storage.v1.ArrowSerializationOptions;
5659
import com.google.cloud.bigquery.storage.v1.BigQueryReadClient;
5760
import com.google.cloud.bigquery.storage.v1.BigQueryReadSettings;
5861
import com.google.cloud.bigquery.storage.v1.CreateReadSessionRequest;
@@ -77,6 +80,7 @@
7780
import com.google.common.collect.ImmutableMap;
7881
import com.google.common.util.concurrent.MoreExecutors;
7982
import com.google.protobuf.Descriptors.DescriptorValidationException;
83+
import com.google.protobuf.Int64Value;
8084
import io.opentelemetry.api.OpenTelemetry;
8185
import io.opentelemetry.api.common.AttributeKey;
8286
import io.opentelemetry.sdk.OpenTelemetrySdk;
@@ -123,10 +127,8 @@ public class ITBigQueryStorageReadClientTest {
123127
private static final String DATASET = RemoteBigQueryHelper.generateDatasetName();
124128
private static final String DESCRIPTION = "BigQuery Storage Java client test dataset";
125129
private static final String BQSTORAGE_TIMESTAMP_READ_TABLE = "bqstorage_timestamp_read";
126-
127130
private static final int SHAKESPEARE_SAMPLE_ROW_COUNT = 164_656;
128131
private static final int SHAKESPEARE_SAMPELS_ROWS_MORE_THAN_100_WORDS = 1_333;
129-
130132
private static final int MAX_STREAM_COUNT = 1;
131133

132134
private static BigQueryReadClient readClient;
@@ -526,43 +528,48 @@ public static void beforeClass()
526528

527529
private static void setupTimestampTable()
528530
throws DescriptorValidationException, IOException, InterruptedException {
531+
// Schema to create a BQ table
529532
com.google.cloud.bigquery.Schema timestampSchema =
530533
com.google.cloud.bigquery.Schema.of(
531-
Field.newBuilder("timestamp", StandardSQLTypeName.TIMESTAMP)
534+
Field.newBuilder(TIMESTAMP_COLUMN_NAME, StandardSQLTypeName.TIMESTAMP)
535+
.setMode(Mode.NULLABLE)
536+
.build(),
537+
Field.newBuilder(TIMESTAMP_HIGHER_PRECISION_COLUMN_NAME, StandardSQLTypeName.TIMESTAMP)
538+
.setTimestampPrecision(12L)
532539
.setMode(Mode.NULLABLE)
533540
.build());
534541

542+
// Create BQ table with timestamps
543+
TableId tableId = TableId.of(DATASET, BQSTORAGE_TIMESTAMP_READ_TABLE);
544+
bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(timestampSchema)));
545+
546+
TableName parentTable = TableName.of(projectName, DATASET, BQSTORAGE_TIMESTAMP_READ_TABLE);
547+
548+
// Define the BQStorage schema to write to
535549
TableSchema timestampTableSchema =
536550
TableSchema.newBuilder()
537551
.addFields(
538552
TableFieldSchema.newBuilder()
539-
.setName("timestamp")
553+
.setName(TIMESTAMP_COLUMN_NAME)
554+
.setType(TableFieldSchema.Type.TIMESTAMP)
555+
.setMode(TableFieldSchema.Mode.NULLABLE)
556+
.build())
557+
.addFields(
558+
TableFieldSchema.newBuilder()
559+
.setName(TIMESTAMP_HIGHER_PRECISION_COLUMN_NAME)
560+
.setTimestampPrecision(Int64Value.newBuilder().setValue(12).build())
540561
.setType(TableFieldSchema.Type.TIMESTAMP)
541562
.setMode(TableFieldSchema.Mode.NULLABLE)
542563
.build())
543-
.build();
544-
545-
// Create table with Range fields.
546-
TableId tableId = TableId.of(DATASET, BQSTORAGE_TIMESTAMP_READ_TABLE);
547-
bigquery.create(TableInfo.of(tableId, StandardTableDefinition.of(timestampSchema)));
548-
549-
TableName parentTable = TableName.of(projectName, DATASET, BQSTORAGE_TIMESTAMP_READ_TABLE);
550-
RetrySettings retrySettings =
551-
RetrySettings.newBuilder()
552-
.setInitialRetryDelayDuration(Duration.ofMillis(500))
553-
.setRetryDelayMultiplier(1.1)
554-
.setMaxAttempts(5)
555-
.setMaxRetryDelayDuration(Duration.ofSeconds(10))
556564
.build();
557565

558566
try (JsonStreamWriter writer =
559-
JsonStreamWriter.newBuilder(parentTable.toString(), timestampTableSchema)
560-
.setRetrySettings(retrySettings)
561-
.build()) {
567+
JsonStreamWriter.newBuilder(parentTable.toString(), timestampTableSchema).build()) {
562568
JSONArray data = new JSONArray();
563-
for (long timestampMicro : Helper.INPUT_TIMESTAMPS_MICROS) {
569+
for (Object[] timestampData : Helper.INPUT_TIMESTAMPS) {
564570
JSONObject row = new JSONObject();
565-
row.put("timestamp", timestampMicro);
571+
row.put(TIMESTAMP_COLUMN_NAME, timestampData[0]);
572+
row.put(TIMESTAMP_HIGHER_PRECISION_COLUMN_NAME, timestampData[1]);
566573
data.put(row);
567574
}
568575

@@ -858,14 +865,29 @@ public void testRangeTypeWrite()
858865
}
859866
}
860867

868+
// Tests that inputs for micros and picos can be read properly via Arrow
861869
@Test
862870
public void timestamp_readArrow() throws IOException {
863871
String table =
864872
BigQueryResource.formatTableResource(projectName, DATASET, BQSTORAGE_TIMESTAMP_READ_TABLE);
865873
ReadSession session =
866874
readClient.createReadSession(
867875
parentProjectId,
868-
ReadSession.newBuilder().setTable(table).setDataFormat(DataFormat.ARROW).build(),
876+
ReadSession.newBuilder()
877+
.setTable(table)
878+
.setDataFormat(DataFormat.ARROW)
879+
.setReadOptions(
880+
TableReadOptions.newBuilder()
881+
.setArrowSerializationOptions(
882+
ArrowSerializationOptions.newBuilder()
883+
// This serialization option only impacts columns that are type
884+
// `TIMESTAMP_PICOS` and has no impact on other columns types
885+
.setPicosTimestampPrecision(
886+
ArrowSerializationOptions.PicosTimestampPrecision
887+
.TIMESTAMP_PRECISION_PICOS)
888+
.build())
889+
.build())
890+
.build(),
869891
MAX_STREAM_COUNT);
870892
assertEquals(
871893
String.format(
@@ -896,22 +918,32 @@ public void timestamp_readArrow() throws IOException {
896918
reader.processRows(
897919
response.getArrowRecordBatch(),
898920
new SimpleRowReaderArrow.ArrowTimestampBatchConsumer(
899-
Arrays.asList(Helper.INPUT_TIMESTAMPS_MICROS)));
921+
Helper.EXPECTED_TIMESTAMPS_HIGHER_PRECISION_ISO_OUTPUT));
900922
rowCount += response.getRowCount();
901923
}
902-
assertEquals(Helper.EXPECTED_TIMESTAMPS_MICROS.length, rowCount);
924+
assertEquals(Helper.EXPECTED_TIMESTAMPS_HIGHER_PRECISION_ISO_OUTPUT.length, rowCount);
903925
}
904926
}
905927

928+
// Tests that inputs for micros and picos can be read properly via Avro
906929
@Test
907930
public void timestamp_readAvro() throws IOException {
908931
String table =
909932
BigQueryResource.formatTableResource(projectName, DATASET, BQSTORAGE_TIMESTAMP_READ_TABLE);
910933
List<GenericData.Record> rows = Helper.readAllRows(readClient, parentProjectId, table, null);
911934
List<Long> timestamps =
912-
rows.stream().map(x -> (Long) x.get("timestamp")).collect(Collectors.toList());
935+
rows.stream().map(x -> (Long) x.get(TIMESTAMP_COLUMN_NAME)).collect(Collectors.toList());
936+
List<String> timestampHigherPrecision =
937+
rows.stream()
938+
.map(x -> x.get(TIMESTAMP_HIGHER_PRECISION_COLUMN_NAME).toString())
939+
.collect(Collectors.toList());
913940
for (int i = 0; i < timestamps.size(); i++) {
914-
assertEquals(Helper.EXPECTED_TIMESTAMPS_MICROS[i], timestamps.get(i));
941+
assertEquals(Helper.EXPECTED_TIMESTAMPS_HIGHER_PRECISION_ISO_OUTPUT[i][0], timestamps.get(i));
942+
}
943+
for (int i = 0; i < timestampHigherPrecision.size(); i++) {
944+
assertEquals(
945+
Helper.EXPECTED_TIMESTAMPS_HIGHER_PRECISION_ISO_OUTPUT[i][1],
946+
timestampHigherPrecision.get(i));
915947
}
916948
}
917949

0 commit comments

Comments
 (0)