Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2213,18 +2213,19 @@ public TableDataList call() throws IOException {
new PageImpl<>(
new TableDataPageFetcher(tableId, schema, serviceOptions, cursor, pageOptionMap),
cursor,
transformTableData(
result.getRows(),
schema,
serviceOptions.getDataFormatOptions().useInt64Timestamp())),
transformTableData(result.getRows(), schema, serviceOptions.getDataFormatOptions())),
result.getTotalRows());
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
}
}

private static Iterable<FieldValueList> transformTableData(
Iterable<TableRow> tableDataPb, final Schema schema, boolean useInt64Timestamps) {
Iterable<TableRow> tableDataPb, final Schema schema, DataFormatOptions dataFormatOptions) {
final boolean useInt64Timestamps =
dataFormatOptions.useInt64Timestamp()
|| dataFormatOptions.timestampFormatOptions()
== DataFormatOptions.TimestampFormatOptions.INT64;
return ImmutableList.copyOf(
Iterables.transform(
tableDataPb != null ? tableDataPb : ImmutableList.<TableRow>of(),
Expand Down Expand Up @@ -2490,9 +2491,7 @@ public com.google.api.services.bigquery.model.QueryResponse call()
new QueryPageFetcher(jobId, schema, getOptions(), cursor, optionMap(options)),
cursor,
transformTableData(
results.getRows(),
schema,
getOptions().getDataFormatOptions().useInt64Timestamp())))
results.getRows(), schema, getOptions().getDataFormatOptions())))
.setJobId(jobId)
.setRowsInPage(results.getRows() != null ? (long) results.getRows().size() : 0L)
.build();
Expand All @@ -2504,10 +2503,7 @@ public com.google.api.services.bigquery.model.QueryResponse call()
new PageImpl<>(
new TableDataPageFetcher(null, schema, getOptions(), null, optionMap(options)),
null,
transformTableData(
results.getRows(),
schema,
getOptions().getDataFormatOptions().useInt64Timestamp())))
transformTableData(results.getRows(), schema, getOptions().getDataFormatOptions())))
// Return the JobID of the successful job
.setJobId(
results.getJobReference() != null ? JobId.fromPb(results.getJobReference()) : null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
import com.google.cloud.Tuple;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.DataFormatOptions;
import com.google.cloud.bigquery.DataFormatOptions.TimestampFormatOptions;
import com.google.cloud.bigquery.telemetry.BigQueryTelemetryTracer;
import com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer;
import com.google.cloud.http.HttpTransportOptions;
Expand Down Expand Up @@ -1419,6 +1421,8 @@ public TableDataList listTableDataSkipExceptionTranslation(
String projectId, String datasetId, String tableId, Map<Option, ?> options)
throws IOException {
validateRPC();
DataFormatOptions formatOptions = this.options.getDataFormatOptions();
TimestampFormatOptions timestampFormat = formatOptions.timestampFormatOptions();
Bigquery.Tabledata.List bqListRequest =
bigquery
.tabledata()
Expand All @@ -1429,6 +1433,11 @@ public TableDataList listTableDataSkipExceptionTranslation(
.setStartIndex(
Option.START_INDEX.getLong(options) != null
? BigInteger.valueOf(Option.START_INDEX.getLong(options))
: null)
.setFormatOptionsUseInt64Timestamp(formatOptions.useInt64Timestamp() ? true : null)
.setFormatOptionsTimestampOutputFormat(
timestampFormat != TimestampFormatOptions.TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED
? timestampFormat.toString()
: null);
Comment thread
keshavdandeva marked this conversation as resolved.
Resolved

bqListRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,34 @@ void testListTableData() throws IOException {
.listTableDataSkipExceptionTranslation(PROJECT, DATASET, TABLE, EMPTY_RPC_OPTIONS);
}

@Test
void testListTableDataWithInt64TimestampFormat() throws IOException {
TableDataList tableDataPb =
new TableDataList()
.setTotalRows(1L)
.setRows(
ImmutableList.of(
new TableRow()
.setF(ImmutableList.of(new TableCell().setV("253402300799999999")))));
when(bigqueryRpcMock.listTableDataSkipExceptionTranslation(
PROJECT, DATASET, TABLE, EMPTY_RPC_OPTIONS))
.thenReturn(tableDataPb);
bigquery =
options.toBuilder()
.setDataFormatOptions(
DataFormatOptions.newBuilder()
.timestampFormatOptions(DataFormatOptions.TimestampFormatOptions.INT64)
.build())
.build()
.getService();

Page<FieldValueList> page = bigquery.listTableData(DATASET, TABLE);
assertEquals(
253402300799999999L, page.getValues().iterator().next().get(0).getTimestampValue());
verify(bigqueryRpcMock)
.listTableDataSkipExceptionTranslation(PROJECT, DATASET, TABLE, EMPTY_RPC_OPTIONS);
}

@Test
void testListTableDataFromTableId() throws IOException {
when(bigqueryRpcMock.listTableDataSkipExceptionTranslation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1236,8 +1236,12 @@ static GoogleCredentials loadCredentials(String credentialFile) {

@Test
void testLosslessMaxTimestampIntegration() throws InterruptedException {
String query = "SELECT TIMESTAMP '9999-12-31 23:59:59.999999 UTC' as max_ts";
QueryJobConfiguration config = QueryJobConfiguration.newBuilder(query).build();
// Two rows, one per page, so the second page is read through tabledata.list.
String query =
"SELECT max_ts FROM UNNEST([TIMESTAMP '9999-12-31 23:59:59.999999 UTC',"
+ " TIMESTAMP '9999-12-31 23:59:59.999999 UTC']) AS max_ts";
QueryJobConfiguration config =
QueryJobConfiguration.newBuilder(query).setMaxResults(1L).build();

// 1. Test lossless 64-bit integer parsing (useInt64Timestamps = true)
DataFormatOptions losslessOptions =
Expand All @@ -1249,7 +1253,7 @@ void testLosslessMaxTimestampIntegration() throws InterruptedException {
.getService();

TableResult losslessResult = losslessBigQuery.query(config);
assertEquals(1L, losslessResult.getTotalRows());
assertEquals(2L, losslessResult.getTotalRows());
for (FieldValueList row : losslessResult.iterateAll()) {
long exactMicros = row.get("max_ts").getTimestampValue();
assertEquals(253402300799999999L, exactMicros);
Expand All @@ -1262,7 +1266,7 @@ void testLosslessMaxTimestampIntegration() throws InterruptedException {
bigquery.getOptions().toBuilder().setDataFormatOptions(floatOptions).build().getService();

TableResult floatResult = floatBigQuery.query(config);
assertEquals(1L, floatResult.getTotalRows());
assertEquals(2L, floatResult.getTotalRows());
for (FieldValueList row : floatResult.iterateAll()) {
long roundedMicros = row.get("max_ts").getTimestampValue();
assertEquals(253402300800000000L, roundedMicros);
Expand All @@ -1277,11 +1281,26 @@ void testLosslessMaxTimestampIntegration() throws InterruptedException {
bigquery.getOptions().toBuilder().setDataFormatOptions(isoOptions).build().getService();

TableResult isoResult = isoBigQuery.query(config);
assertEquals(1L, isoResult.getTotalRows());
assertEquals(2L, isoResult.getTotalRows());
for (FieldValueList row : isoResult.iterateAll()) {
String isoValue = row.get("max_ts").getStringValue();
assertEquals("9999-12-31T23:59:59.999999Z", isoValue);
}

// 4. Test INT64 timestamp output format
DataFormatOptions int64Options =
DataFormatOptions.newBuilder()
.timestampFormatOptions(DataFormatOptions.TimestampFormatOptions.INT64)
.build();
BigQuery int64BigQuery =
bigquery.getOptions().toBuilder().setDataFormatOptions(int64Options).build().getService();

TableResult int64Result = int64BigQuery.query(config);
assertEquals(2L, int64Result.getTotalRows());
for (FieldValueList row : int64Result.iterateAll()) {
long exactMicros = row.get("max_ts").getTimestampValue();
assertEquals(253402300799999999L, exactMicros);
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
import com.google.api.services.bigquery.model.TableReference;
import com.google.cloud.NoCredentials;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.DataFormatOptions;
import com.google.cloud.bigquery.DataFormatOptions.TimestampFormatOptions;
import com.google.cloud.bigquery.telemetry.BigQueryTelemetryTracer;
import com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer;
import io.opentelemetry.api.common.AttributeKey;
Expand Down Expand Up @@ -1565,9 +1567,37 @@ public void testListTableDataNoTelemetry() throws Exception {
verifyRequest(
"GET",
"/projects/" + PROJECT_ID + "/datasets/" + DATASET_ID + "/tables/" + TABLE_ID + "/data");
assertThat(lastRequestUrl).doesNotContain("formatOptions");
verifyNoSpans();
}

@Test
public void testListTableDataWithDataFormatOptions() throws Exception {
setMockResponse("{\"kind\":\"bigquery#tableDataList\",\"rows\":[]}");

BigQueryOptions customOptions =
BigQueryOptions.newBuilder()
.setProjectId(PROJECT_ID)
.setCredentials(NoCredentials.getInstance())
.setTransportOptions(
BigQueryOptions.getDefaultHttpTransportOptions().toBuilder()
.setHttpTransportFactory(() -> mockTransport)
.build())
.setDataFormatOptions(
DataFormatOptions.newBuilder()
.useInt64Timestamp(true)
.timestampFormatOptions(TimestampFormatOptions.ISO8601_STRING)
.build())
.build();
HttpBigQueryRpc customRpc = new HttpBigQueryRpc(customOptions);

customRpc.listTableDataSkipExceptionTranslation(
PROJECT_ID, DATASET_ID, TABLE_ID, new HashMap<>());

assertThat(lastRequestUrl).contains("formatOptions.useInt64Timestamp=true");
assertThat(lastRequestUrl).contains("formatOptions.timestampOutputFormat=ISO8601_STRING");
}

@Test
public void testListTableDataWithRowLimitNoTelemetry() throws Exception {
setMockResponse("{\"kind\":\"bigquery#tableDataList\",\"rows\":[]}");
Expand Down
Loading