2121import static org .hamcrest .MatcherAssert .assertThat ;
2222import static org .hamcrest .Matchers .equalTo ;
2323
24+ import java .time .Instant ;
2425import java .util .ArrayList ;
2526import org .apache .arrow .memory .BufferAllocator ;
2627import org .apache .arrow .memory .RootAllocator ;
3031import org .apache .arrow .vector .IntVector ;
3132import org .apache .arrow .vector .TimeStampMicroTZVector ;
3233import org .apache .arrow .vector .TimeStampMilliTZVector ;
34+ import org .apache .arrow .vector .TimeStampNanoTZVector ;
3335import org .apache .arrow .vector .VarCharVector ;
3436import org .apache .arrow .vector .VectorSchemaRoot ;
3537import org .apache .arrow .vector .complex .ListVector ;
4042import org .apache .beam .sdk .schemas .Schema ;
4143import org .apache .beam .sdk .schemas .Schema .Field ;
4244import org .apache .beam .sdk .schemas .Schema .FieldType ;
45+ import org .apache .beam .sdk .schemas .logicaltypes .Timestamp ;
4346import org .apache .beam .sdk .values .Row ;
4447import org .apache .beam .vendor .guava .v32_1_2_jre .com .google .common .collect .ImmutableList ;
4548import org .hamcrest .collection .IsIterableContainingInOrder ;
@@ -95,7 +98,8 @@ public void rowIterator() {
9598 new ArrowType .List (),
9699 field ("int32s" , new ArrowType .Int (32 , true ))),
97100 field ("boolean" , new ArrowType .Bool ()),
98- field ("fixed_size_binary" , new ArrowType .FixedSizeBinary (3 ))));
101+ field ("fixed_size_binary" , new ArrowType .FixedSizeBinary (3 )),
102+ field ("timestampNanoUTC" , new ArrowType .Timestamp (TimeUnit .NANOSECOND , "UTC" ))));
99103
100104 Schema beamSchema = ArrowConversion .ArrowSchemaTranslator .toBeamSchema (schema );
101105
@@ -109,6 +113,9 @@ public void rowIterator() {
109113 (TimeStampMicroTZVector ) expectedSchemaRoot .getFieldVectors ().get (3 );
110114 TimeStampMilliTZVector timeStampMilliTZVector =
111115 (TimeStampMilliTZVector ) expectedSchemaRoot .getFieldVectors ().get (4 );
116+ TimeStampNanoTZVector timestampNanoUtcVector =
117+ (TimeStampNanoTZVector ) expectedSchemaRoot .getFieldVectors ().get (8 );
118+
112119 ListVector int32ListVector = (ListVector ) expectedSchemaRoot .getFieldVectors ().get (5 );
113120 IntVector int32ListElementVector =
114121 int32ListVector
@@ -123,6 +130,10 @@ public void rowIterator() {
123130 ArrayList <Row > expectedRows = new ArrayList <>();
124131 for (int i = 0 ; i < 16 ; i ++) {
125132 DateTime dt = new DateTime (2019 , 1 , i + 1 , i , i , i , DateTimeZone .UTC );
133+ Instant instantNano =
134+ Instant .ofEpochSecond (
135+ dt .getMillis () / 1000 ,
136+ (dt .getMillis () % 1000 ) * 1_000_000L + (1_000_000000L - 1 - i ));
126137 expectedRows .add (
127138 Row .withSchema (beamSchema )
128139 .addValues (
@@ -133,14 +144,16 @@ public void rowIterator() {
133144 dt ,
134145 ImmutableList .of (i ),
135146 (i % 2 ) != 0 ,
136- new byte [] {(byte ) i , (byte ) (i + 1 ), (byte ) (i + 2 )})
147+ new byte [] {(byte ) i , (byte ) (i + 1 ), (byte ) (i + 2 )},
148+ instantNano )
137149 .build ());
138150
139151 intVector .set (i , i );
140152 floatVector .set (i , i + .1 * i );
141153 strVector .set (i , new Text ("" + i ));
142154 timestampMicroUtcVector .set (i , dt .getMillis () * 1000 );
143155 timeStampMilliTZVector .set (i , dt .getMillis ());
156+ timestampNanoUtcVector .set (i , dt .getMillis () * 1_000_000L + (1_000_000000L - 1 - i ));
144157 int32ListVector .startNewValue (i );
145158 int32ListElementVector .set (i , i );
146159 int32ListVector .endValue (i , 1 );
@@ -158,6 +171,23 @@ public void rowIterator() {
158171 expectedSchemaRoot .close ();
159172 }
160173
174+ @ Test
175+ public void toBeamSchema_convertsTimestampTypes () {
176+ org .apache .arrow .vector .types .pojo .Schema arrowSchema =
177+ new org .apache .arrow .vector .types .pojo .Schema (
178+ ImmutableList .of (
179+ field ("ts_milli" , new ArrowType .Timestamp (TimeUnit .MILLISECOND , "UTC" )),
180+ field ("ts_micro" , new ArrowType .Timestamp (TimeUnit .MICROSECOND , "UTC" )),
181+ field ("ts_nano" , new ArrowType .Timestamp (TimeUnit .NANOSECOND , "UTC" ))));
182+
183+ Schema beamSchema = ArrowConversion .ArrowSchemaTranslator .toBeamSchema (arrowSchema );
184+
185+ assertThat (beamSchema .getField ("ts_milli" ).getType (), equalTo (FieldType .DATETIME ));
186+ assertThat (beamSchema .getField ("ts_micro" ).getType (), equalTo (FieldType .DATETIME ));
187+ assertThat (
188+ beamSchema .getField ("ts_nano" ).getType (), equalTo (FieldType .logicalType (Timestamp .NANOS )));
189+ }
190+
161191 private static org .apache .arrow .vector .types .pojo .Field field (
162192 String name ,
163193 boolean nullable ,
0 commit comments