You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by we...@apache.org on 2017/01/20 17:45:05 UTC
arrow git commit: ARROW-386: [Java] Respect case of struct / map
field names
Repository: arrow
Updated Branches:
refs/heads/master 6811d3fcf -> 512bc160e
ARROW-386: [Java] Respect case of struct / map field names
Changes include:
- Remove all toLowerCase() calls on field names in MapWriters.java template file, so that the writers can respect case of the field names.
- Use lower-case keys for internalMap in UnionVector instead of camel-case (e.g. bigInt -> bigint). p.s. I don't know what is the original purpose of using camel case here. It did not conflict because all field names are converted to lower cases in the past.
- Add a simple test case of MapWriter with mixed-case field names.
Author: Jingyuan Wang <ji...@live.com>
Closes #261 from alphalfalfa/arrow-386 and squashes the following commits:
cd08145 [Jingyuan Wang] Remove unnecessary handleCase() call
7b28bfc [Jingyuan Wang] Pass caseSensitive Attribute down to nested MapWriters
2fe7bcf [Jingyuan Wang] Separate MapWriters with CaseSensitiveMapWriters
d269e21 [Jingyuan Wang] Configure case sensitivity when constructing ComplexWriterImpl
cba60d1 [Jingyuan Wang] Add option to MapWriters to configure the case sensitivity (defaulted as case-insensitive)
51da2a1 [Jingyuan Wang] Arrow-386: [Java] Respect case of struct / map field names
Project: http://git-wip-us.apache.org/repos/asf/arrow/repo
Commit: http://git-wip-us.apache.org/repos/asf/arrow/commit/512bc160
Tree: http://git-wip-us.apache.org/repos/asf/arrow/tree/512bc160
Diff: http://git-wip-us.apache.org/repos/asf/arrow/diff/512bc160
Branch: refs/heads/master
Commit: 512bc160ebaf8d6775ea67994262709e10a72795
Parents: 6811d3f
Author: Jingyuan Wang <ji...@live.com>
Authored: Fri Jan 20 12:43:20 2017 -0500
Committer: Wes McKinney <we...@twosigma.com>
Committed: Fri Jan 20 12:43:20 2017 -0500
----------------------------------------------------------------------
.../templates/CaseSensitiveMapWriters.java | 54 ++++++++++++++
.../src/main/codegen/templates/MapWriters.java | 35 +++++----
.../main/codegen/templates/UnionListWriter.java | 6 +-
.../src/main/codegen/templates/UnionVector.java | 3 +-
.../src/main/codegen/templates/UnionWriter.java | 12 +++-
.../arrow/vector/complex/AbstractMapVector.java | 6 +-
.../vector/complex/impl/ComplexWriterImpl.java | 17 +++--
.../complex/impl/NullableMapWriterFactory.java | 42 +++++++++++
.../vector/complex/impl/PromotableWriter.java | 31 +++++++-
.../complex/writer/TestComplexWriter.java | 76 ++++++++++++++++++++
10 files changed, 253 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/codegen/templates/CaseSensitiveMapWriters.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/codegen/templates/CaseSensitiveMapWriters.java b/java/vector/src/main/codegen/templates/CaseSensitiveMapWriters.java
new file mode 100644
index 0000000..5357f9b
--- /dev/null
+++ b/java/vector/src/main/codegen/templates/CaseSensitiveMapWriters.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+<@pp.dropOutputFile />
+<#list ["Nullable", "Single"] as mode>
+<@pp.changeOutputFile name="/org/apache/arrow/vector/complex/impl/${mode}CaseSensitiveMapWriter.java" />
+<#assign index = "idx()">
+<#if mode == "Single">
+<#assign containerClass = "MapVector" />
+<#else>
+<#assign containerClass = "NullableMapVector" />
+</#if>
+
+<#include "/@includes/license.ftl" />
+
+package org.apache.arrow.vector.complex.impl;
+
+<#include "/@includes/vv_imports.ftl" />
+/*
+ * This class is generated using FreeMarker and the ${.template_name} template.
+ */
+@SuppressWarnings("unused")
+public class ${mode}CaseSensitiveMapWriter extends ${mode}MapWriter {
+ public ${mode}CaseSensitiveMapWriter(${containerClass} container) {
+ super(container);
+ }
+
+ @Override
+ protected String handleCase(final String input){
+ return input;
+ }
+
+ @Override
+ protected NullableMapWriterFactory getNullableMapWriterFactory() {
+ return NullableMapWriterFactory.getNullableCaseSensitiveMapWriterFactoryInstance();
+ }
+
+}
+</#list>
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/codegen/templates/MapWriters.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/codegen/templates/MapWriters.java b/java/vector/src/main/codegen/templates/MapWriters.java
index f41b600..4af6eee 100644
--- a/java/vector/src/main/codegen/templates/MapWriters.java
+++ b/java/vector/src/main/codegen/templates/MapWriters.java
@@ -48,7 +48,6 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
protected final ${containerClass} container;
private final Map<String, FieldWriter> fields = Maps.newHashMap();
-
public ${mode}MapWriter(${containerClass} container) {
<#if mode == "Single">
if (container instanceof NullableMapVector) {
@@ -65,8 +64,8 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
list(child.getName());
break;
case UNION:
- UnionWriter writer = new UnionWriter(container.addOrGet(child.getName(), MinorType.UNION, UnionVector.class));
- fields.put(child.getName().toLowerCase(), writer);
+ UnionWriter writer = new UnionWriter(container.addOrGet(child.getName(), MinorType.UNION, UnionVector.class), getNullableMapWriterFactory());
+ fields.put(handleCase(child.getName()), writer);
break;
<#list vv.types as type><#list type.minor as minor>
<#assign lowerName = minor.class?uncap_first />
@@ -85,6 +84,14 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
}
}
+ protected String handleCase(final String input) {
+ return input.toLowerCase();
+ }
+
+ protected NullableMapWriterFactory getNullableMapWriterFactory() {
+ return NullableMapWriterFactory.getNullableMapWriterFactoryInstance();
+ }
+
@Override
public int getValueCapacity() {
return container.getValueCapacity();
@@ -102,16 +109,17 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
@Override
public MapWriter map(String name) {
- FieldWriter writer = fields.get(name.toLowerCase());
+ String finalName = handleCase(name);
+ FieldWriter writer = fields.get(finalName);
if(writer == null){
int vectorCount=container.size();
NullableMapVector vector = container.addOrGet(name, MinorType.MAP, NullableMapVector.class);
- writer = new PromotableWriter(vector, container);
+ writer = new PromotableWriter(vector, container, getNullableMapWriterFactory());
if(vectorCount != container.size()) {
writer.allocate();
}
writer.setPosition(idx());
- fields.put(name.toLowerCase(), writer);
+ fields.put(finalName, writer);
} else {
if (writer instanceof PromotableWriter) {
// ensure writers are initialized
@@ -145,15 +153,16 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
@Override
public ListWriter list(String name) {
- FieldWriter writer = fields.get(name.toLowerCase());
+ String finalName = handleCase(name);
+ FieldWriter writer = fields.get(finalName);
int vectorCount = container.size();
if(writer == null) {
- writer = new PromotableWriter(container.addOrGet(name, MinorType.LIST, ListVector.class), container);
+ writer = new PromotableWriter(container.addOrGet(name, MinorType.LIST, ListVector.class), container, getNullableMapWriterFactory());
if (container.size() > vectorCount) {
writer.allocate();
}
writer.setPosition(idx());
- fields.put(name.toLowerCase(), writer);
+ fields.put(finalName, writer);
} else {
if (writer instanceof PromotableWriter) {
// ensure writers are initialized
@@ -199,7 +208,7 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
<#if minor.class?starts_with("Decimal") >
public ${minor.class}Writer ${lowerName}(String name) {
// returns existing writer
- final FieldWriter writer = fields.get(name.toLowerCase());
+ final FieldWriter writer = fields.get(handleCase(name));
assert writer != null;
return writer;
}
@@ -209,18 +218,18 @@ public class ${mode}MapWriter extends AbstractFieldWriter {
@Override
public ${minor.class}Writer ${lowerName}(String name) {
</#if>
- FieldWriter writer = fields.get(name.toLowerCase());
+ FieldWriter writer = fields.get(handleCase(name));
if(writer == null) {
ValueVector vector;
ValueVector currentVector = container.getChild(name);
${vectName}Vector v = container.addOrGet(name, MinorType.${upperName}, ${vectName}Vector.class<#if minor.class == "Decimal"> , new int[] {precision, scale}</#if>);
- writer = new PromotableWriter(v, container);
+ writer = new PromotableWriter(v, container, getNullableMapWriterFactory());
vector = v;
if (currentVector == null || currentVector != vector) {
vector.allocateNewSafe();
}
writer.setPosition(idx());
- fields.put(name.toLowerCase(), writer);
+ fields.put(handleCase(name), writer);
} else {
if (writer instanceof PromotableWriter) {
// ensure writers are initialized
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/codegen/templates/UnionListWriter.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/codegen/templates/UnionListWriter.java b/java/vector/src/main/codegen/templates/UnionListWriter.java
index bb39fe8..d980830 100644
--- a/java/vector/src/main/codegen/templates/UnionListWriter.java
+++ b/java/vector/src/main/codegen/templates/UnionListWriter.java
@@ -43,8 +43,12 @@ public class UnionListWriter extends AbstractFieldWriter {
private int lastIndex = 0;
public UnionListWriter(ListVector vector) {
+ this(vector, NullableMapWriterFactory.getNullableMapWriterFactoryInstance());
+ }
+
+ public UnionListWriter(ListVector vector, NullableMapWriterFactory nullableMapWriterFactory) {
this.vector = vector;
- this.writer = new PromotableWriter(vector.getDataVector(), vector);
+ this.writer = new PromotableWriter(vector.getDataVector(), vector, nullableMapWriterFactory);
this.offsets = vector.getOffsetVector();
}
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/codegen/templates/UnionVector.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/codegen/templates/UnionVector.java b/java/vector/src/main/codegen/templates/UnionVector.java
index 18acdf4..1a6908d 100644
--- a/java/vector/src/main/codegen/templates/UnionVector.java
+++ b/java/vector/src/main/codegen/templates/UnionVector.java
@@ -136,6 +136,7 @@ public class UnionVector implements FieldVector {
<#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
<#assign fields = minor.fields!type.fields />
<#assign uncappedName = name?uncap_first/>
+ <#assign lowerCaseName = name?lower_case/>
<#if !minor.class?starts_with("Decimal")>
private Nullable${name}Vector ${uncappedName}Vector;
@@ -143,7 +144,7 @@ public class UnionVector implements FieldVector {
public Nullable${name}Vector get${name}Vector() {
if (${uncappedName}Vector == null) {
int vectorCount = internalMap.size();
- ${uncappedName}Vector = internalMap.addOrGet("${uncappedName}", MinorType.${name?upper_case}, Nullable${name}Vector.class);
+ ${uncappedName}Vector = internalMap.addOrGet("${lowerCaseName}", MinorType.${name?upper_case}, Nullable${name}Vector.class);
if (internalMap.size() > vectorCount) {
${uncappedName}Vector.allocateNew();
if (callBack != null) {
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/codegen/templates/UnionWriter.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/codegen/templates/UnionWriter.java b/java/vector/src/main/codegen/templates/UnionWriter.java
index efb66f1..880f537 100644
--- a/java/vector/src/main/codegen/templates/UnionWriter.java
+++ b/java/vector/src/main/codegen/templates/UnionWriter.java
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+import org.apache.arrow.vector.complex.impl.NullableMapWriterFactory;
+
<@pp.dropOutputFile />
<@pp.changeOutputFile name="/org/apache/arrow/vector/complex/impl/UnionWriter.java" />
@@ -38,9 +40,15 @@ public class UnionWriter extends AbstractFieldWriter implements FieldWriter {
private MapWriter mapWriter;
private UnionListWriter listWriter;
private List<BaseWriter> writers = Lists.newArrayList();
+ private final NullableMapWriterFactory nullableMapWriterFactory;
public UnionWriter(UnionVector vector) {
+ this(vector, NullableMapWriterFactory.getNullableMapWriterFactoryInstance());
+ }
+
+ public UnionWriter(UnionVector vector, NullableMapWriterFactory nullableMapWriterFactory) {
data = vector;
+ this.nullableMapWriterFactory = nullableMapWriterFactory;
}
@Override
@@ -76,7 +84,7 @@ public class UnionWriter extends AbstractFieldWriter implements FieldWriter {
private MapWriter getMapWriter() {
if (mapWriter == null) {
- mapWriter = new NullableMapWriter(data.getMap());
+ mapWriter = nullableMapWriterFactory.build(data.getMap());
mapWriter.setPosition(idx());
writers.add(mapWriter);
}
@@ -90,7 +98,7 @@ public class UnionWriter extends AbstractFieldWriter implements FieldWriter {
private ListWriter getListWriter() {
if (listWriter == null) {
- listWriter = new UnionListWriter(data.getList());
+ listWriter = new UnionListWriter(data.getList(), nullableMapWriterFactory);
listWriter.setPosition(idx());
writers.add(listWriter);
}
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/java/org/apache/arrow/vector/complex/AbstractMapVector.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/java/org/apache/arrow/vector/complex/AbstractMapVector.java b/java/vector/src/main/java/org/apache/arrow/vector/complex/AbstractMapVector.java
index 23b4997..f030d16 100644
--- a/java/vector/src/main/java/org/apache/arrow/vector/complex/AbstractMapVector.java
+++ b/java/vector/src/main/java/org/apache/arrow/vector/complex/AbstractMapVector.java
@@ -155,7 +155,7 @@ public abstract class AbstractMapVector extends AbstractContainerVector {
*/
@Override
public <T extends FieldVector> T getChild(String name, Class<T> clazz) {
- final ValueVector v = vectors.get(name.toLowerCase());
+ final ValueVector v = vectors.get(name);
if (v == null) {
return null;
}
@@ -191,7 +191,7 @@ public abstract class AbstractMapVector extends AbstractContainerVector {
*/
protected void putVector(String name, FieldVector vector) {
final ValueVector old = vectors.put(
- Preconditions.checkNotNull(name, "field name cannot be null").toLowerCase(),
+ Preconditions.checkNotNull(name, "field name cannot be null"),
Preconditions.checkNotNull(vector, "vector cannot be null")
);
if (old != null && old != vector) {
@@ -254,7 +254,7 @@ public abstract class AbstractMapVector extends AbstractContainerVector {
*/
@Override
public VectorWithOrdinal getChildVectorWithOrdinal(String name) {
- final int ordinal = vectors.getOrdinal(name.toLowerCase());
+ final int ordinal = vectors.getOrdinal(name);
if (ordinal < 0) {
return null;
}
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java
index 761b1b4..dbdd205 100644
--- a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java
+++ b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java
@@ -37,13 +37,20 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri
Mode mode = Mode.INIT;
private final String name;
private final boolean unionEnabled;
+ private final NullableMapWriterFactory nullableMapWriterFactory;
private enum Mode { INIT, MAP, LIST };
- public ComplexWriterImpl(String name, MapVector container, boolean unionEnabled){
+ public ComplexWriterImpl(String name, MapVector container, boolean unionEnabled, boolean caseSensitive){
this.name = name;
this.container = container;
this.unionEnabled = unionEnabled;
+ nullableMapWriterFactory = caseSensitive? NullableMapWriterFactory.getNullableCaseSensitiveMapWriterFactoryInstance() :
+ NullableMapWriterFactory.getNullableMapWriterFactoryInstance();
+ }
+
+ public ComplexWriterImpl(String name, MapVector container, boolean unionEnabled) {
+ this(name, container, unionEnabled, false);
}
public ComplexWriterImpl(String name, MapVector container){
@@ -122,8 +129,7 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri
switch(mode){
case INIT:
- NullableMapVector map = (NullableMapVector) container;
- mapRoot = new NullableMapWriter(map);
+ mapRoot = nullableMapWriterFactory.build((NullableMapVector) container);
mapRoot.setPosition(idx());
mode = Mode.MAP;
break;
@@ -144,7 +150,7 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri
case INIT:
NullableMapVector map = container.addOrGet(name, MinorType.MAP, NullableMapVector.class);
- mapRoot = new NullableMapWriter(map);
+ mapRoot = nullableMapWriterFactory.build(map);
mapRoot.setPosition(idx());
mode = Mode.MAP;
break;
@@ -159,7 +165,6 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri
return mapRoot;
}
-
@Override
public void allocate() {
if(mapRoot != null) {
@@ -179,7 +184,7 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri
if (container.size() > vectorCount) {
listVector.allocateNew();
}
- listRoot = new UnionListWriter(listVector);
+ listRoot = new UnionListWriter(listVector, nullableMapWriterFactory);
listRoot.setPosition(idx());
mode = Mode.LIST;
break;
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/NullableMapWriterFactory.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/NullableMapWriterFactory.java b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/NullableMapWriterFactory.java
new file mode 100644
index 0000000..d932cfb
--- /dev/null
+++ b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/NullableMapWriterFactory.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.arrow.vector.complex.impl;
+
+import org.apache.arrow.vector.complex.NullableMapVector;
+
+public class NullableMapWriterFactory {
+ private final boolean caseSensitive;
+ private static final NullableMapWriterFactory nullableMapWriterFactory = new NullableMapWriterFactory(false);
+ private static final NullableMapWriterFactory nullableCaseSensitiveWriterFactory = new NullableMapWriterFactory(true);
+
+ public NullableMapWriterFactory(boolean caseSensitive) {
+ this.caseSensitive = caseSensitive;
+ }
+
+ public NullableMapWriter build(NullableMapVector container) {
+ return this.caseSensitive? new NullableCaseSensitiveMapWriter(container) : new NullableMapWriter(container);
+ }
+
+ public static NullableMapWriterFactory getNullableMapWriterFactoryInstance() {
+ return nullableMapWriterFactory;
+ }
+
+ public static NullableMapWriterFactory getNullableCaseSensitiveMapWriterFactoryInstance() {
+ return nullableCaseSensitiveWriterFactory;
+ }
+}
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/PromotableWriter.java
----------------------------------------------------------------------
diff --git a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/PromotableWriter.java b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/PromotableWriter.java
index 94ff82c..1f7253b 100644
--- a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/PromotableWriter.java
+++ b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/PromotableWriter.java
@@ -22,6 +22,7 @@ import org.apache.arrow.vector.ValueVector;
import org.apache.arrow.vector.ZeroVector;
import org.apache.arrow.vector.complex.AbstractMapVector;
import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.NullableMapVector;
import org.apache.arrow.vector.complex.UnionVector;
import org.apache.arrow.vector.complex.writer.FieldWriter;
import org.apache.arrow.vector.types.Types.MinorType;
@@ -38,6 +39,7 @@ public class PromotableWriter extends AbstractPromotableFieldWriter {
private final AbstractMapVector parentContainer;
private final ListVector listVector;
+ private final NullableMapWriterFactory nullableMapWriterFactory;
private int position;
private enum State {
@@ -51,14 +53,24 @@ public class PromotableWriter extends AbstractPromotableFieldWriter {
private FieldWriter writer;
public PromotableWriter(ValueVector v, AbstractMapVector parentContainer) {
+ this(v, parentContainer, NullableMapWriterFactory.getNullableMapWriterFactoryInstance());
+ }
+
+ public PromotableWriter(ValueVector v, AbstractMapVector parentContainer, NullableMapWriterFactory nullableMapWriterFactory) {
this.parentContainer = parentContainer;
this.listVector = null;
+ this.nullableMapWriterFactory = nullableMapWriterFactory;
init(v);
}
public PromotableWriter(ValueVector v, ListVector listVector) {
+ this(v, listVector, NullableMapWriterFactory.getNullableMapWriterFactoryInstance());
+ }
+
+ public PromotableWriter(ValueVector v, ListVector listVector, NullableMapWriterFactory nullableMapWriterFactory) {
this.listVector = listVector;
this.parentContainer = null;
+ this.nullableMapWriterFactory = nullableMapWriterFactory;
init(v);
}
@@ -66,7 +78,7 @@ public class PromotableWriter extends AbstractPromotableFieldWriter {
if (v instanceof UnionVector) {
state = State.UNION;
unionVector = (UnionVector) v;
- writer = new UnionWriter(unionVector);
+ writer = new UnionWriter(unionVector, nullableMapWriterFactory);
} else if (v instanceof ZeroVector) {
state = State.UNTYPED;
} else {
@@ -78,7 +90,20 @@ public class PromotableWriter extends AbstractPromotableFieldWriter {
state = State.SINGLE;
vector = v;
type = v.getMinorType();
- writer = type.getNewFieldWriter(vector);
+ switch (type) {
+ case MAP:
+ writer = nullableMapWriterFactory.build((NullableMapVector) vector);
+ break;
+ case LIST:
+ writer = new UnionListWriter((ListVector) vector, nullableMapWriterFactory);
+ break;
+ case UNION:
+ writer = new UnionWriter((UnionVector) vector, nullableMapWriterFactory);
+ break;
+ default:
+ writer = type.getNewFieldWriter(vector);
+ break;
+ }
}
@Override
@@ -131,7 +156,7 @@ public class PromotableWriter extends AbstractPromotableFieldWriter {
unionVector = listVector.promoteToUnion();
}
unionVector.addVector((FieldVector)tp.getTo());
- writer = new UnionWriter(unionVector);
+ writer = new UnionWriter(unionVector, nullableMapWriterFactory);
writer.setPosition(idx());
for (int i = 0; i <= idx(); i++) {
unionVector.getMutator().setType(i, vector.getMinorType());
http://git-wip-us.apache.org/repos/asf/arrow/blob/512bc160/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java
----------------------------------------------------------------------
diff --git a/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java b/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java
index caa438a..2c0c853 100644
--- a/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java
+++ b/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java
@@ -23,7 +23,9 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.RootAllocator;
@@ -485,4 +487,78 @@ public class TestComplexWriter {
Assert.assertTrue(intType.getIsSigned());
Assert.assertEquals(ArrowTypeID.Utf8, field.getChildren().get(1).getType().getTypeID());
}
+
+ private Set<String> getFieldNames(List<Field> fields) {
+ Set<String> fieldNames = new HashSet<>();
+ for (Field field: fields) {
+ fieldNames.add(field.getName());
+ if (!field.getChildren().isEmpty()) {
+ for (String name: getFieldNames(field.getChildren())) {
+ fieldNames.add(field.getName() + "::" + name);
+ }
+ }
+ }
+ return fieldNames;
+ }
+
+ @Test
+ public void mapWriterMixedCaseFieldNames() {
+ // test case-sensitive MapWriter
+ MapVector parent = new MapVector("parent", allocator, null);
+ ComplexWriter writer = new ComplexWriterImpl("rootCaseSensitive", parent, false, true);
+ MapWriter rootWriterCaseSensitive = writer.rootAsMap();
+ rootWriterCaseSensitive.bigInt("int_field");
+ rootWriterCaseSensitive.bigInt("Int_Field");
+ rootWriterCaseSensitive.float4("float_field");
+ rootWriterCaseSensitive.float4("Float_Field");
+ MapWriter mapFieldWriterCaseSensitive = rootWriterCaseSensitive.map("map_field");
+ mapFieldWriterCaseSensitive.varChar("char_field");
+ mapFieldWriterCaseSensitive.varChar("Char_Field");
+ ListWriter listFieldWriterCaseSensitive = rootWriterCaseSensitive.list("list_field");
+ MapWriter listMapFieldWriterCaseSensitive = listFieldWriterCaseSensitive.map();
+ listMapFieldWriterCaseSensitive.bit("bit_field");
+ listMapFieldWriterCaseSensitive.bit("Bit_Field");
+
+ List<Field> fieldsCaseSensitive = parent.getField().getChildren().get(0).getChildren();
+ Set<String> fieldNamesCaseSensitive = getFieldNames(fieldsCaseSensitive);
+ Assert.assertEquals(11, fieldNamesCaseSensitive.size());
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("int_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("Int_Field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("float_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("Float_Field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("map_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("map_field::char_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("map_field::Char_Field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field::$data$"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field::$data$::bit_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field::$data$::Bit_Field"));
+
+ // test case-insensitive MapWriter
+ ComplexWriter writerCaseInsensitive = new ComplexWriterImpl("rootCaseInsensitive", parent, false, false);
+ MapWriter rootWriterCaseInsensitive = writerCaseInsensitive.rootAsMap();
+
+ rootWriterCaseInsensitive.bigInt("int_field");
+ rootWriterCaseInsensitive.bigInt("Int_Field");
+ rootWriterCaseInsensitive.float4("float_field");
+ rootWriterCaseInsensitive.float4("Float_Field");
+ MapWriter mapFieldWriterCaseInsensitive = rootWriterCaseInsensitive.map("map_field");
+ mapFieldWriterCaseInsensitive.varChar("char_field");
+ mapFieldWriterCaseInsensitive.varChar("Char_Field");
+ ListWriter listFieldWriterCaseInsensitive = rootWriterCaseInsensitive.list("list_field");
+ MapWriter listMapFieldWriterCaseInsensitive = listFieldWriterCaseInsensitive.map();
+ listMapFieldWriterCaseInsensitive.bit("bit_field");
+ listMapFieldWriterCaseInsensitive.bit("Bit_Field");
+
+ List<Field> fieldsCaseInsensitive = parent.getField().getChildren().get(1).getChildren();
+ Set<String> fieldNamesCaseInsensitive = getFieldNames(fieldsCaseInsensitive);
+ Assert.assertEquals(7, fieldNamesCaseInsensitive.size());
+ Assert.assertTrue(fieldNamesCaseInsensitive.contains("int_field"));
+ Assert.assertTrue(fieldNamesCaseInsensitive.contains("float_field"));
+ Assert.assertTrue(fieldNamesCaseInsensitive.contains("map_field"));
+ Assert.assertTrue(fieldNamesCaseInsensitive.contains("map_field::char_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field::$data$"));
+ Assert.assertTrue(fieldNamesCaseSensitive.contains("list_field::$data$::bit_field"));
+ }
}
\ No newline at end of file