@@ -59,8 +59,11 @@ public class BigQueryTimestampPicosIT {
5959 /**
6060 * Input rows with timestamp columns at different precisions. Each row contains: - ts_picos: full
6161 * picosecond precision (12 digits) in ISO format - ts_nanos: nanosecond precision (9 digits) in
62- * UTC format - ts_micros: microsecond precision (6 digits) in UTC format - ts_millis: millisecond
63- * precision (3 digits) in UTC format
62+ * UTC format (limited to int64 nanos range) - ts_micros: microsecond precision (6 digits) in UTC
63+ * format - ts_millis: millisecond precision (3 digits) in UTC format
64+ *
65+ * <p>Note: ts_nanos uses dates within int64 nanoseconds-since-epoch bounds (~1677-09-21 to
66+ * ~2262-04-11) since Avro/Arrow use int64 for nanos timestamps.
6467 */
6568 private static final List <TableRow > INPUT_ROWS =
6669 ImmutableList .of (
@@ -76,7 +79,7 @@ public class BigQueryTimestampPicosIT {
7679 .set ("ts_millis" , "2024-01-15 10:30:45.001 UTC" ),
7780 new TableRow ()
7881 .set ("ts_picos" , "0001-01-01T10:30:45.999999999999Z" )
79- .set ("ts_nanos" , "0001-01-01 10:30:45.999999999 UTC" )
82+ .set ("ts_nanos" , "1677-09-21 00:12:43.145224192 UTC" )
8083 .set ("ts_micros" , "0001-01-01 10:30:45.999999 UTC" )
8184 .set ("ts_millis" , "0001-01-01 10:30:45.999 UTC" ),
8285 new TableRow ()
@@ -86,7 +89,7 @@ public class BigQueryTimestampPicosIT {
8689 .set ("ts_millis" , "1970-01-01 00:00:00.001 UTC" ),
8790 new TableRow ()
8891 .set ("ts_picos" , "9999-12-31T23:59:59.999999999999Z" )
89- .set ("ts_nanos" , "9999-12-31 23:59:59.999999999 UTC" )
92+ .set ("ts_nanos" , "2262-04-11 23:47:16.854775807 UTC" )
9093 .set ("ts_micros" , "9999-12-31 23:59:59.999999 UTC" )
9194 .set ("ts_millis" , "9999-12-31 23:59:59.999 UTC" ));
9295
@@ -103,9 +106,9 @@ public class BigQueryTimestampPicosIT {
103106 ImmutableList .of (
104107 "2024-01-15T10:30:45.123456789000Z" ,
105108 "2024-01-15T10:30:45.000000001000Z" ,
106- "0001-01-01T10:30:45.999999999000Z " ,
109+ "1677-09-21T00:12:43.145224192000Z " ,
107110 "1970-01-01T00:00:00.000000001000Z" ,
108- "9999-12-31T23:59:59.999999999000Z " );
111+ "2262-04-11T23:47:16.854775807000Z " );
109112
110113 private static final List <String > EXPECTED_TS_MICROS_AT_PICOS =
111114 ImmutableList .of (
@@ -136,9 +139,9 @@ public class BigQueryTimestampPicosIT {
136139 ImmutableList .of (
137140 "2024-01-15 10:30:45.123456789 UTC" ,
138141 "2024-01-15 10:30:45.000000001 UTC" ,
139- "0001-01-01 10:30:45.999999999 UTC" ,
142+ "1677-09-21 00:12:43.145224192 UTC" ,
140143 "1970-01-01 00:00:00.000000001 UTC" ,
141- "9999-12-31 23:59:59.999999999 UTC" );
144+ "2262-04-11 23:47:16.854775807 UTC" );
142145
143146 private static final List <String > EXPECTED_TS_MICROS_AT_NANOS =
144147 ImmutableList .of (
@@ -169,9 +172,9 @@ public class BigQueryTimestampPicosIT {
169172 ImmutableList .of (
170173 "2024-01-15 10:30:45.123456 UTC" ,
171174 "2024-01-15 10:30:45.000000 UTC" ,
172- "0001-01-01 10:30:45.999999 UTC" ,
175+ "1677-09-21 00:12:43.145224 UTC" ,
173176 "1970-01-01 00:00:00.000000 UTC" ,
174- "9999-12-31 23:59:59.999999 UTC" );
177+ "2262-04-11 23:47:16.854775 UTC" );
175178
176179 private static final List <String > EXPECTED_TS_MICROS_AT_MICROS =
177180 ImmutableList .of (
@@ -189,6 +192,40 @@ public class BigQueryTimestampPicosIT {
189192 "1970-01-01 00:00:00.001000 UTC" ,
190193 "9999-12-31 23:59:59.999000 UTC" );
191194
195+ // Expected values when read at MICROS precision with ARROW format (truncated to millis due to
196+ // known issue)
197+ private static final List <String > EXPECTED_TS_PICOS_AT_MICROS_ARROW =
198+ ImmutableList .of (
199+ "2024-01-15 10:30:45.123000 UTC" ,
200+ "2024-01-15 10:30:45.000000 UTC" ,
201+ "0001-01-01 10:30:45.999000 UTC" ,
202+ "1970-01-01 00:00:00.000000 UTC" ,
203+ "9999-12-31 23:59:59.999000 UTC" );
204+
205+ private static final List <String > EXPECTED_TS_NANOS_AT_MICROS_ARROW =
206+ ImmutableList .of (
207+ "2024-01-15 10:30:45.123000 UTC" ,
208+ "2024-01-15 10:30:45.000000 UTC" ,
209+ "1677-09-21 00:12:43.145000 UTC" ,
210+ "1970-01-01 00:00:00.000000 UTC" ,
211+ "2262-04-11 23:47:16.854000 UTC" );
212+
213+ private static final List <String > EXPECTED_TS_MICROS_AT_MICROS_ARROW =
214+ ImmutableList .of (
215+ "2024-01-15 10:30:45.123000 UTC" ,
216+ "2024-01-15 10:30:45.000000 UTC" ,
217+ "0001-01-01 10:30:45.999000 UTC" ,
218+ "1970-01-01 00:00:00.000000 UTC" ,
219+ "9999-12-31 23:59:59.999000 UTC" );
220+
221+ private static final List <String > EXPECTED_TS_MILLIS_AT_MICROS_ARROW =
222+ ImmutableList .of (
223+ "2024-01-15 10:30:45.123000 UTC" ,
224+ "2024-01-15 10:30:45.001000 UTC" ,
225+ "0001-01-01 10:30:45.999000 UTC" ,
226+ "1970-01-01 00:00:00.001000 UTC" ,
227+ "9999-12-31 23:59:59.999000 UTC" );
228+
192229 @ BeforeClass
193230 public static void setup () throws Exception {
194231 bqOptions = TestPipeline .testingPipelineOptions ().as (TestBigQueryOptions .class );
@@ -235,15 +272,15 @@ private static TableSchema multiPrecisionSchema() {
235272 new TableFieldSchema ()
236273 .setName ("ts_nanos" )
237274 .setType ("TIMESTAMP" )
238- .setTimestampPrecision (12L ),
275+ .setTimestampPrecision (9L ),
239276 new TableFieldSchema ()
240277 .setName ("ts_micros" )
241278 .setType ("TIMESTAMP" )
242- .setTimestampPrecision (12L ),
279+ .setTimestampPrecision (6L ),
243280 new TableFieldSchema ()
244281 .setName ("ts_millis" )
245282 .setType ("TIMESTAMP" )
246- .setTimestampPrecision (12L )));
283+ .setTimestampPrecision (3L )));
247284 }
248285
249286 /** Builds expected TableRows from expected values for each column. */
@@ -290,8 +327,6 @@ private void runReadTest(
290327 readPipeline .run ().waitUntilFinish ();
291328 }
292329
293- // ==================== PICOS precision read tests ====================
294-
295330 @ Test
296331 public void testRead_Picos_Avro () {
297332 List <TableRow > expected =
@@ -314,8 +349,6 @@ public void testRead_Picos_Arrow() {
314349 runReadTest (TimestampPrecision .PICOS , DataFormat .ARROW , expected );
315350 }
316351
317- // ==================== NANOS precision read tests ====================
318-
319352 @ Test
320353 public void testRead_Nanos_Avro () {
321354 List <TableRow > expected =
@@ -338,8 +371,6 @@ public void testRead_Nanos_Arrow() {
338371 runReadTest (TimestampPrecision .NANOS , DataFormat .ARROW , expected );
339372 }
340373
341- // ==================== MICROS precision read tests ====================
342-
343374 @ Test
344375 public void testRead_Micros_Avro () {
345376 List <TableRow > expected =
@@ -353,12 +384,13 @@ public void testRead_Micros_Avro() {
353384
354385 @ Test
355386 public void testRead_Micros_Arrow () {
387+ // Arrow micros has a known issue where values are truncated to milliseconds
356388 List <TableRow > expected =
357389 buildExpectedRows (
358- EXPECTED_TS_PICOS_AT_MICROS ,
359- EXPECTED_TS_NANOS_AT_MICROS ,
360- EXPECTED_TS_MICROS_AT_MICROS ,
361- EXPECTED_TS_MILLIS_AT_MICROS );
390+ EXPECTED_TS_PICOS_AT_MICROS_ARROW ,
391+ EXPECTED_TS_NANOS_AT_MICROS_ARROW ,
392+ EXPECTED_TS_MICROS_AT_MICROS_ARROW ,
393+ EXPECTED_TS_MILLIS_AT_MICROS_ARROW );
362394 runReadTest (TimestampPrecision .MICROS , DataFormat .ARROW , expected );
363395 }
364396}
0 commit comments