Skip to content

Commit e60bdff

Browse files
fix: fix timestamp rounding issue (#1645)
* fix: fix timestamp ronuding issue Fixes #1644 remove unrelated test case update test case * add comment
1 parent 96bba38 commit e60bdff

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

‎google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.common.io.BaseEncoding;
2626
import java.io.Serializable;
2727
import java.math.BigDecimal;
28+
import java.math.RoundingMode;
2829
import java.util.List;
2930
import java.util.Map;
3031
import java.util.Objects;
@@ -183,7 +184,10 @@ public long getTimestampValue() {
183184
// timestamps are encoded in the format 1408452095.22 where the integer part is seconds since
184185
// epoch (e.g. 1408452095.22 == 2014-08-19 07:41:35.220 -05:00)
185186
BigDecimal secondsWithMicro = new BigDecimal(getStringValue());
186-
BigDecimal scaled = secondsWithMicro.scaleByPowerOfTen(6);
187+
// Rounding the BigDecimal to the nearest whole number before setting the longValue in order to
188+
// address TimeStamp rounding issue described in
189+
// https://github.com/googleapis/java-bigquery/issues/1644
190+
BigDecimal scaled = secondsWithMicro.scaleByPowerOfTen(6).setScale(0, RoundingMode.HALF_UP);
187191
return scaled.longValue();
188192
}
189193

‎google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
import java.nio.ByteBuffer;
128128
import java.nio.charset.StandardCharsets;
129129
import java.nio.file.FileSystems;
130+
import java.time.Instant;
130131
import java.util.ArrayList;
131132
import java.util.Collection;
132133
import java.util.Collections;
@@ -1854,6 +1855,40 @@ public void testQuery() throws InterruptedException {
18541855
assertNotNull(statistics.getQueryPlan());
18551856
}
18561857

1858+
@Test
1859+
public void testQueryTimeStamp() throws InterruptedException {
1860+
String query = "SELECT TIMESTAMP '2022-01-24T23:54:25.095574Z'";
1861+
Instant beforeQueryInstant = Instant.parse("2022-01-24T23:54:25.095574Z");
1862+
long microsBeforeQuery =
1863+
TimeUnit.SECONDS.toMicros(beforeQueryInstant.getEpochSecond())
1864+
+ TimeUnit.NANOSECONDS.toMicros(beforeQueryInstant.getNano());
1865+
1866+
// Verify that timestamp remains the same when priority is set to INTERACTIVE
1867+
TableResult result =
1868+
bigquery.query(
1869+
QueryJobConfiguration.newBuilder(query)
1870+
.setDefaultDataset(DatasetId.of(DATASET))
1871+
.setPriority(QueryJobConfiguration.Priority.INTERACTIVE)
1872+
.build());
1873+
for (FieldValueList row : result.getValues()) {
1874+
FieldValue timeStampCell = row.get(0);
1875+
long microsAfterQuery = timeStampCell.getTimestampValue();
1876+
assertEquals(microsBeforeQuery, microsAfterQuery);
1877+
}
1878+
1879+
// Verify that timestamp remains the same without priority set to INTERACTIVE
1880+
TableResult resultInteractive =
1881+
bigquery.query(
1882+
QueryJobConfiguration.newBuilder(query)
1883+
.setDefaultDataset(DatasetId.of(DATASET))
1884+
.build());
1885+
for (FieldValueList row : resultInteractive.getValues()) {
1886+
FieldValue timeStampCell = row.get(0);
1887+
long microsAfterQuery = timeStampCell.getTimestampValue();
1888+
assertEquals(microsBeforeQuery, microsAfterQuery);
1889+
}
1890+
}
1891+
18571892
@Test
18581893
public void testQueryCaseInsensitiveSchemaFieldByGetName() throws InterruptedException {
18591894
String query = "SELECT TimestampField, StringField, BooleanField FROM " + TABLE_ID.getTable();

0 commit comments

Comments
 (0)