Skip to content

Commit f520e91

Browse files
committed
GH-551: [Java] Add TimeStamp*TZ support to ComplexCopier
ComplexCopier skipped types with typeParams except Decimal. Generate TimeStamp*TZ cases and pass timezone to the struct writer.
1 parent 6a9bcf6 commit f520e91

2 files changed

Lines changed: 79 additions & 3 deletions

File tree

vector/src/main/codegen/templates/ComplexCopier.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030

3131
<#include "/@includes/vv_imports.ftl" />
3232

33+
<#function is_timestamp_tz type>
34+
<#return type?starts_with("TimeStamp") && type?ends_with("TZ")>
35+
</#function>
36+
3337
/*
3438
* This class is generated using freemarker and the ${.template_name} template.
3539
*/
@@ -121,7 +125,7 @@ public static void copy(FieldReader reader, FieldWriter writer) {
121125
<#assign fields = minor.fields!type.fields />
122126
<#assign uncappedName = name?uncap_first/>
123127

124-
<#if !minor.typeParams?? || minor.class?starts_with("Decimal") >
128+
<#if !minor.typeParams?? || minor.class?starts_with("Decimal") || is_timestamp_tz(minor.class) >
125129

126130
case ${name?upper_case}:
127131
if (reader.isSet()) {
@@ -158,6 +162,15 @@ private static FieldWriter getStructWriterForReader(FieldReader reader, StructWr
158162
return (FieldWriter) writer.${uncappedName}(name);
159163
}
160164
</#if>
165+
<#if is_timestamp_tz(minor.class)>
166+
case ${name?upper_case}:
167+
if (reader.getField().getType() instanceof ArrowType.Timestamp) {
168+
ArrowType.Timestamp type = (ArrowType.Timestamp) reader.getField().getType();
169+
return (FieldWriter) writer.${uncappedName}(name, type.getTimezone());
170+
} else {
171+
return (FieldWriter) writer.${uncappedName}(name);
172+
}
173+
</#if>
161174
162175
</#list></#list>
163176
case STRUCT:
@@ -182,7 +195,7 @@ private static FieldWriter getListWriterForReader(FieldReader reader, ListWriter
182195
<#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
183196
<#assign fields = minor.fields!type.fields />
184197
<#assign uncappedName = name?uncap_first/>
185-
<#if !minor.typeParams?? || minor.class?starts_with("Decimal") >
198+
<#if !minor.typeParams?? || minor.class?starts_with("Decimal") || is_timestamp_tz(minor.class) >
186199
case ${name?upper_case}:
187200
return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}</#if>();
188201
</#if>
@@ -209,7 +222,7 @@ private static FieldWriter getMapWriterForReader(FieldReader reader, MapWriter w
209222
<#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
210223
<#assign fields = minor.fields!type.fields />
211224
<#assign uncappedName = name?uncap_first/>
212-
<#if !minor.typeParams?? || minor.class?starts_with("Decimal") >
225+
<#if !minor.typeParams?? || minor.class?starts_with("Decimal") || is_timestamp_tz(minor.class) >
213226
case ${name?upper_case}:
214227
return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}</#if>();
215228
</#if>

vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.arrow.vector.complex.writer.FieldWriter;
3737
import org.apache.arrow.vector.extension.UuidType;
3838
import org.apache.arrow.vector.holders.DecimalHolder;
39+
import org.apache.arrow.vector.types.TimeUnit;
3940
import org.apache.arrow.vector.types.Types;
4041
import org.apache.arrow.vector.types.pojo.ArrowType;
4142
import org.apache.arrow.vector.types.pojo.FieldType;
@@ -954,4 +955,66 @@ public void testCopyStructVectorWithExtensionType() {
954955
assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
955956
}
956957
}
958+
959+
@Test
960+
public void testCopyListOfTimeStampNanoTZ() {
961+
try (ListVector from = ListVector.empty("v", allocator);
962+
ListVector to = ListVector.empty("v", allocator)) {
963+
from.addOrGetVector(
964+
FieldType.nullable(new ArrowType.Timestamp(TimeUnit.NANOSECOND, "UTC")));
965+
to.addOrGetVector(
966+
FieldType.nullable(new ArrowType.Timestamp(TimeUnit.NANOSECOND, "UTC")));
967+
968+
UnionListWriter listWriter = from.getWriter();
969+
listWriter.allocate();
970+
971+
for (int i = 0; i < COUNT; i++) {
972+
listWriter.setPosition(i);
973+
listWriter.startList();
974+
listWriter.timeStampNanoTZ().writeTimeStampNanoTZ(i * 1_000_000L);
975+
listWriter.timeStampNanoTZ().writeTimeStampNanoTZ(i * 2_000_000L);
976+
listWriter.endList();
977+
}
978+
from.setValueCount(COUNT);
979+
980+
FieldReader in = from.getReader();
981+
FieldWriter out = to.getWriter();
982+
for (int i = 0; i < COUNT; i++) {
983+
in.setPosition(i);
984+
out.setPosition(i);
985+
ComplexCopier.copy(in, out);
986+
}
987+
to.setValueCount(COUNT);
988+
989+
assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
990+
}
991+
}
992+
993+
@Test
994+
public void testCopyStructOfTimeStampNanoTZ() {
995+
try (final StructVector from = StructVector.empty("v", allocator);
996+
final StructVector to = StructVector.empty("v", allocator)) {
997+
from.allocateNewSafe();
998+
NullableStructWriter structWriter = from.getWriter();
999+
1000+
for (int i = 0; i < COUNT; i++) {
1001+
structWriter.setPosition(i);
1002+
structWriter.start();
1003+
structWriter.timeStampNanoTZ("ts", "UTC").writeTimeStampNanoTZ(i * 1_000_000L);
1004+
structWriter.end();
1005+
}
1006+
from.setValueCount(COUNT);
1007+
1008+
FieldReader in = from.getReader();
1009+
FieldWriter out = to.getWriter();
1010+
for (int i = 0; i < COUNT; i++) {
1011+
in.setPosition(i);
1012+
out.setPosition(i);
1013+
ComplexCopier.copy(in, out);
1014+
}
1015+
to.setValueCount(COUNT);
1016+
1017+
assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
1018+
}
1019+
}
9571020
}

0 commit comments

Comments
 (0)