http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/31b59622/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/RepeatedMapReaderImpl.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/RepeatedMapReaderImpl.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/RepeatedMapReaderImpl.java index ab778ff..8f788af 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/RepeatedMapReaderImpl.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/RepeatedMapReaderImpl.java @@ -77,6 +77,7 @@ import org.apache.hadoop.io.Text; + import java.util.Map; import java.util.Map.Entry; @@ -117,6 +118,13 @@ public class RepeatedMapReaderImpl extends AbstractFieldReader{ return reader; } + public FieldReader reader() { + if (currentOffset == NO_VALUES) + return NullReader.INSTANCE; + + setChildrenPosition(currentOffset); + return new SingleLikeRepeatedMapReaderImpl(vector, this); + } private int currentOffset; private int maxOffset; @@ -163,6 +171,10 @@ public class RepeatedMapReaderImpl extends AbstractFieldReader{ } } + public boolean isNull() { + return currentOffset == NO_VALUES; + } + @Override public Object readObject() { return vector.getAccessor().getObject(idx()); @@ -178,7 +190,7 @@ public class RepeatedMapReaderImpl extends AbstractFieldReader{ @Override public boolean isSet() { - return false; + return true; } public void copyAsValue(MapWriter writer){
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/31b59622/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/SingleLikeRepeatedMapReaderImpl.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/SingleLikeRepeatedMapReaderImpl.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/SingleLikeRepeatedMapReaderImpl.java new file mode 100644 index 0000000..3f89a9f --- /dev/null +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/complex/impl/SingleLikeRepeatedMapReaderImpl.java @@ -0,0 +1,89 @@ +/** + * 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. + */ + +package org.apache.drill.exec.vector.complex.impl; + +import java.util.Iterator; + +import org.apache.drill.common.types.TypeProtos.MajorType; +import org.apache.drill.common.types.TypeProtos.MinorType; +import org.apache.drill.common.types.Types; +import org.apache.drill.exec.vector.complex.RepeatedMapVector; +import org.apache.drill.exec.vector.complex.reader.FieldReader; +import org.apache.drill.exec.vector.complex.writer.BaseWriter.MapWriter; + +public class SingleLikeRepeatedMapReaderImpl extends AbstractFieldReader{ + + private RepeatedMapReaderImpl delegate; + + public SingleLikeRepeatedMapReaderImpl(RepeatedMapVector vector, FieldReader delegate) { + this.delegate = (RepeatedMapReaderImpl) delegate; + } + + @Override + public int size() { + throw new UnsupportedOperationException("You can't call size on a single map reader."); + } + + @Override + public boolean next() { + throw new UnsupportedOperationException("You can't call next on a single map reader."); + } + + @Override + public MajorType getType() { + return Types.required(MinorType.MAP); + } + + + @Override + public void copyAsValue(MapWriter writer) { + delegate.copyAsValueSingle(writer); + } + + public void copyAsValueSingle(MapWriter writer){ + delegate.copyAsValueSingle(writer); + } + + @Override + public FieldReader reader(String name) { + return delegate.reader(name); + } + + @Override + public void setPosition(int index) { + delegate.setPosition(index); + } + + @Override + public Object readObject() { + return delegate.readObject(); + } + + @Override + public Iterator<String> iterator() { + return delegate.iterator(); + } + + @Override + public boolean isSet() { + return ! delegate.isNull(); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/31b59622/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java b/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java new file mode 100644 index 0000000..74c724d --- /dev/null +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/vector/complex/writer/TestComplexTypeReader.java @@ -0,0 +1,167 @@ +/** + * 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. + */ + +package org.apache.drill.exec.vector.complex.writer; + +import org.apache.drill.BaseTestQuery; +import org.junit.Test; + +public class TestComplexTypeReader extends BaseTestQuery{ + static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestComplexTypeReader.class); + + @Test + // Repeated map (map) -> json. + public void testX() throws Exception{ + test("select convert_to(z[0], 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //map -> json. + public void testX2() throws Exception{ + test("select convert_to(x, 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //Map (mapfield) -> json. + public void testX3() throws Exception{ + test("select convert_to(x['y'], 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //float value -> json + public void testX4() throws Exception{ + test("select convert_to(`float`, 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //integer value -> json + public void testX5() throws Exception{ + test("select convert_to(`integer`, 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + // repeated map -> json. + public void testX6() throws Exception{ + test("select convert_to(z, 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list (Repeated BigInt) -> json + public void testX7() throws Exception{ + test("select convert_to(rl[1], 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list (Repeated BigInt) -> json + public void testX8() throws Exception{ + test("select convert_to(rl[0][1], 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list -> json + public void testX9() throws Exception{ + test("select convert_to(rl, 'JSON') from cp.`jsoninput/input2.json`;"); + } + + @Test + public void testY() throws Exception{ + test("select z[0] from cp.`jsoninput/input2.json`;"); + } + + @Test + public void testY2() throws Exception{ + test("select x from cp.`jsoninput/input2.json`;"); + } + + @Test + public void testY3() throws Exception{ + test("select x['y'] from cp.`jsoninput/input2.json`;"); + } + + @Test + public void testY6() throws Exception{ + test("select z from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list (Repeated BigInt) + public void testZ() throws Exception{ + test("select rl[1] from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list (Repeated BigInt ( BigInt) ) ) + public void testZ1() throws Exception{ + test("select rl[0][1] from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list (Repeated BigInt ( BigInt) ) ). The first index is out of boundary + public void testZ2() throws Exception{ + test("select rl[1000][1] from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated list (Repeated BigInt ( BigInt) ) ). The second index is out of boundary + public void testZ3() throws Exception{ + test("select rl[0][1000] from cp.`jsoninput/input2.json`;"); + } + + @Test + //repeated map --> Json. It will go beyond the buffer of size 256 allocated in setup. + public void testA0() throws Exception{ + test(" select convert_to(types, 'JSON') from cp.`jsoninput/vvtypes.json`;"); + } + + @Test + //repeated map (map) --> Json. + public void testA1() throws Exception{ + test(" select convert_to(types[1], 'JSON') from cp.`jsoninput/vvtypes.json`;"); + } + + @Test + //repeated map (map (repeated map) ) --> Json. + public void testA2() throws Exception{ + test(" select convert_to(types[1]['minor'], 'JSON') from cp.`jsoninput/vvtypes.json`;"); + } + + @Test + //repeated map (map( repeated map (map (varchar)))) --> Json. + public void testA3() throws Exception{ + test(" select convert_to(types[1]['minor'][0]['valueHolder'], 'JSON') from cp.`jsoninput/vvtypes.json`;"); + } + + @Test + //repeated map (map) . + public void testB1() throws Exception{ + test(" select types[1] from cp.`jsoninput/vvtypes.json`;"); + } + + @Test + //repeated map (map (repeated map) ). + public void testB2() throws Exception{ + test(" select types[1]['minor'] from cp.`jsoninput/vvtypes.json`;"); + } + + @Test + //repeated map (map( repeated map (map (varchar)))). + public void testB3() throws Exception{ + test(" select types[1]['minor'][0]['valueHolder'] from cp.`jsoninput/vvtypes.json`;"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/31b59622/exec/java-exec/src/test/resources/jsoninput/vvtypes.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/jsoninput/vvtypes.json b/exec/java-exec/src/test/resources/jsoninput/vvtypes.json new file mode 100644 index 0000000..60cd1ea --- /dev/null +++ b/exec/java-exec/src/test/resources/jsoninput/vvtypes.json @@ -0,0 +1,140 @@ +{ + modes: [ + {name: "Optional", prefix: "Nullable"}, + {name: "Required", prefix: ""}, + {name: "Repeated", prefix: "Repeated"} + ], + types: [ + { + major: "Fixed", + width: 1, + javaType: "byte", + boxedType: "Byte", + minor: [ + { class: "TinyInt", valueHolder: "IntHolder"}, + { class: "UInt1", valueHolder: "UInt1Holder"} + ] + }, + { + major: "Fixed", + width: 2, + javaType: "char", + boxedType: "Character", + minor: [ + { class: "UInt2", valueHolder: "UInt2Holder"} + ] + }, { + major: "Fixed", + width: 2, + javaType: "short", + boxedType: "Short", + minor: [ + { class: "SmallInt", valueHolder: "Int2Holder"} + ] + }, + { + major: "Fixed", + width: 4, + javaType: "int", + boxedType: "Integer", + minor: [ + { class: "Int", valueHolder: "IntHolder" }, + { class: "UInt4", valueHolder: "UInt4Holder" }, + { class: "Float4", javaType: "float" , boxedType: "Float" }, + { class: "Time", javaType: "int", friendlyType: "DateTime" }, + { class: "IntervalYear", javaType: "int", friendlyType: "Period" }, + { class: "Decimal9", maxPrecisionDigits: 9, friendlyType: "BigDecimal" } + ] + }, + { + major: "Fixed", + width: 8, + javaType: "long", + boxedType: "Long", + minor: [ + { class: "BigInt" }, + { class: "UInt8" }, + { class: "Float8", javaType: "double" , boxedType: "Double" }, + { class: "Date", javaType: "long", friendlyType: "DateTime" }, + { class: "TimeStamp", javaType: "long", friendlyType: "DateTime" }, + { class: "Decimal18", maxPrecisionDigits: 18, friendlyType: "BigDecimal" } + ] + }, + { + major: "Fixed", + width: 12, + javaType: "ByteBuf", + boxedType: "ByteBuf", + minor: [ + { class: "TimeStampTZ", milliSecondsSize: 8, friendlyType: "DateTime" }, + { class: "IntervalDay", milliSecondsOffset: 4, friendlyType: "Period" } + ] + }, + { + major: "Fixed", + width: 16, + javaType: "ByteBuf", + boxedType: "ByteBuf", + minor: [ + { class: "Interval", daysOffset: 4, milliSecondsOffset: 8, friendlyType: "Period" } + ] + }, + { + major: "Fixed", + width: 12, + javaType: "ByteBuf", + boxedType: "ByteBuf", + minor: [ + { class: "Decimal28Dense", maxPrecisionDigits: 28, nDecimalDigits: 3, friendlyType: "BigDecimal" } + ] + }, + { + major: "Fixed", + width: 16, + javaType: "ByteBuf", + boxedType: "ByteBuf", + + minor: [ + { class: "Decimal38Dense", maxPrecisionDigits: 38, nDecimalDigits: 4, friendlyType: "BigDecimal" } + ] + }, + { + major: "Fixed", + width: 24, + javaType: "ByteBuf", + boxedType: "ByteBuf", + minor: [ + { class: "Decimal38Sparse", maxPrecisionDigits: 38, nDecimalDigits: 6, friendlyType: "BigDecimal" } + ] + }, + { + major: "Fixed", + width: 20, + javaType: "ByteBuf", + boxedType: "ByteBuf", + minor: [ + { class: "Decimal28Sparse", maxPrecisionDigits: 28, nDecimalDigits: 5, friendlyType: "BigDecimal" } + ] + }, + { + major: "VarLen", + width: 4, + javaType: "int", + boxedType: "ByteBuf", + minor: [ + { class: "VarBinary" , friendlyType: "byte[]" }, + { class: "VarChar" , friendlyType: "Text" }, + { class: "Var16Char" , friendlyType: "String" } + ] + }, + { + major: "Bit", + width: 1, + javaType: "int", + boxedType: "ByteBuf", + minor: [ + { class: "Bit" , friendlyType: "Boolean" } + ] + } + ] +}
