2828import com .google .cloud .spanner .Struct ;
2929import com .google .cloud .spanner .Type ;
3030import java .math .BigDecimal ;
31+ import java .time .Instant ;
3132import java .util .List ;
3233import org .apache .beam .sdk .schemas .Schema ;
34+ import org .apache .beam .sdk .schemas .logicaltypes .MicrosInstant ;
3335import org .apache .beam .sdk .values .Row ;
3436import org .apache .beam .vendor .guava .v32_1_2_jre .com .google .common .collect .ImmutableList ;
3537import org .joda .time .DateTime ;
@@ -44,6 +46,7 @@ public class MutationUtilsTest {
4446 private static final Struct EMPTY_STRUCT = Struct .newBuilder ().build ();
4547 private static final Struct INT64_STRUCT = Struct .newBuilder ().set ("int64" ).to (3L ).build ();
4648 private static final String TABLE = "some_table" ;
49+ private static final Instant TEST_INSTANT = Instant .parse ("2024-01-15T10:30:00.123456Z" );
4750
4851 private static final Schema WRITE_ROW_SCHEMA =
4952 Schema .builder ()
@@ -71,6 +74,10 @@ public class MutationUtilsTest {
7174 .addNullableField ("f_decimal" , Schema .FieldType .DECIMAL )
7275 .addNullableField ("f_byte" , Schema .FieldType .BYTE )
7376 .addNullableField ("f_iterable" , Schema .FieldType .iterable (Schema .FieldType .INT64 ))
77+ .addNullableField ("f_micros_instant" , Schema .FieldType .logicalType (new MicrosInstant ()))
78+ .addNullableField (
79+ "f_micros_instant_array" ,
80+ Schema .FieldType .array (Schema .FieldType .logicalType (new MicrosInstant ())))
7481 .build ();
7582
7683 private static final Row WRITE_ROW =
@@ -107,6 +114,8 @@ public class MutationUtilsTest {
107114 .withFieldValue ("f_decimal" , BigDecimal .valueOf (Long .MIN_VALUE ))
108115 .withFieldValue ("f_byte" , Byte .parseByte ("127" ))
109116 .withFieldValue ("f_iterable" , ImmutableList .of (2L , 3L ))
117+ .withFieldValue ("f_micros_instant" , TEST_INSTANT )
118+ .withFieldValue ("f_micros_instant_array" , ImmutableList .of (TEST_INSTANT , TEST_INSTANT ))
110119 .build ();
111120
112121 private static final Schema WRITE_ROW_SCHEMA_NULLS =
@@ -123,6 +132,10 @@ public class MutationUtilsTest {
123132 .addNullableField ("f_array" , Schema .FieldType .array (Schema .FieldType .INT64 ))
124133 .addNullableField (
125134 "f_struct_array" , Schema .FieldType .array (Schema .FieldType .row (INT64_SCHEMA )))
135+ .addNullableField ("f_micros_instant" , Schema .FieldType .logicalType (new MicrosInstant ()))
136+ .addNullableField (
137+ "f_micros_instant_array" ,
138+ Schema .FieldType .array (Schema .FieldType .logicalType (new MicrosInstant ())))
126139 .build ();
127140
128141 private static final Row WRITE_ROW_NULLS =
@@ -138,6 +151,8 @@ public class MutationUtilsTest {
138151 .addValue (null )
139152 .addValue (null )
140153 .addValue (null )
154+ .addValue (null )
155+ .addValue (null )
141156 .build ();
142157
143158 private static final Schema KEY_SCHEMA =
@@ -153,6 +168,7 @@ public class MutationUtilsTest {
153168 .addNullableField ("f_int32" , Schema .FieldType .INT32 )
154169 .addNullableField ("f_decimal" , Schema .FieldType .DECIMAL )
155170 .addNullableField ("f_byte" , Schema .FieldType .BYTE )
171+ .addNullableField ("f_micros_instant" , Schema .FieldType .logicalType (new MicrosInstant ()))
156172 .build ();
157173
158174 private static final Row KEY_ROW =
@@ -168,6 +184,7 @@ public class MutationUtilsTest {
168184 .withFieldValue ("f_int32" , 0x7fffffff )
169185 .withFieldValue ("f_decimal" , BigDecimal .valueOf (Long .MIN_VALUE ))
170186 .withFieldValue ("f_byte" , Byte .parseByte ("127" ))
187+ .withFieldValue ("f_micros_instant" , TEST_INSTANT )
171188 .build ();
172189
173190 private static final Schema KEY_SCHEMA_NULLS =
@@ -178,6 +195,7 @@ public class MutationUtilsTest {
178195 .addNullableField ("f_bytes" , Schema .FieldType .BYTES )
179196 .addNullableField ("f_date_time" , Schema .FieldType .DATETIME )
180197 .addNullableField ("f_bool" , Schema .FieldType .BOOLEAN )
198+ .addNullableField ("f_micros_instant" , Schema .FieldType .logicalType (new MicrosInstant ()))
181199 .build ();
182200
183201 private static final Row KEY_ROW_NULLS =
@@ -188,6 +206,7 @@ public class MutationUtilsTest {
188206 .addValue (null )
189207 .addValue (null )
190208 .addValue (null )
209+ .addValue (null )
191210 .build ();
192211
193212 @ Test
@@ -264,6 +283,7 @@ public void testCreateDeleteMutationFromRowWithNulls() {
264283 }
265284
266285 private static Mutation createDeleteMutation () {
286+ long micros = TEST_INSTANT .getEpochSecond () * 1_000_000L + TEST_INSTANT .getNano () / 1_000L ;
267287 Key key =
268288 Key .newBuilder ()
269289 .append (1L )
@@ -277,6 +297,7 @@ private static Mutation createDeleteMutation() {
277297 .append (0x7fffffff )
278298 .append (BigDecimal .valueOf (Long .MIN_VALUE ))
279299 .append (Byte .parseByte ("127" ))
300+ .append (Timestamp .ofTimeMicroseconds (micros ))
280301 .build ();
281302 return Mutation .delete (TABLE , key );
282303 }
@@ -290,12 +311,14 @@ private static Mutation createDeleteMutationNulls() {
290311 .append ((ByteArray ) null )
291312 .append ((Timestamp ) null )
292313 .append ((Boolean ) null )
314+ .append ((Timestamp ) null )
293315 .build ();
294316 return Mutation .delete (TABLE , key );
295317 }
296318
297319 private static Mutation createMutation (Mutation .Op operation ) {
298320 Mutation .WriteBuilder builder = chooseBuilder (operation );
321+ long micros = TEST_INSTANT .getEpochSecond () * 1_000_000L + TEST_INSTANT .getNano () / 1_000L ;
299322 return builder
300323 .set ("f_int64" )
301324 .to (1L )
@@ -353,6 +376,12 @@ private static Mutation createMutation(Mutation.Op operation) {
353376 .to (Byte .parseByte ("127" ))
354377 .set ("f_iterable" )
355378 .toInt64Array (ImmutableList .of (2L , 3L ))
379+ .set ("f_micros_instant" )
380+ .to (Timestamp .ofTimeMicroseconds (micros ))
381+ .set ("f_micros_instant_array" )
382+ .toTimestampArray (
383+ ImmutableList .of (
384+ Timestamp .ofTimeMicroseconds (micros ), Timestamp .ofTimeMicroseconds (micros )))
356385 .build ();
357386 }
358387
@@ -381,6 +410,10 @@ private static Mutation createMutationNulls(Mutation.Op operation) {
381410 .toInt64Array ((List <Long >) null )
382411 .set ("f_struct_array" )
383412 .toStructArray (Type .struct (Type .StructField .of ("int64" , Type .int64 ())), null )
413+ .set ("f_micros_instant" )
414+ .to ((Timestamp ) null )
415+ .set ("f_micros_instant_array" )
416+ .toTimestampArray (null )
384417 .build ();
385418 }
386419
0 commit comments