/******************************************************************************* * 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.store.parquet.columnreaders; import io.netty.buffer.DrillBuf; import java.math.BigDecimal; import java.nio.ByteBuffer; import org.apache.drill.common.exceptions.ExecutionSetupException; import org.apache.drill.exec.expr.holders.Decimal28SparseHolder; import org.apache.drill.exec.expr.holders.Decimal38SparseHolder; import org.apache.drill.exec.util.DecimalUtility; import org.apache.drill.exec.vector.Decimal28SparseVector; import org.apache.drill.exec.vector.Decimal38SparseVector; import org.apache.drill.exec.vector.NullableDecimal28SparseVector; import org.apache.drill.exec.vector.NullableDecimal38SparseVector; import org.apache.drill.exec.vector.NullableVarBinaryVector; import org.apache.drill.exec.vector.NullableVarCharVector; import org.apache.drill.exec.vector.VarBinaryVector; import org.apache.drill.exec.vector.VarCharVector; import org.apache.parquet.column.ColumnDescriptor; import org.apache.parquet.format.SchemaElement; import org.apache.parquet.hadoop.metadata.ColumnChunkMetaData; public class VarLengthColumnReaders { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(VarLengthColumnReaders.class); public static class Decimal28Column extends VarLengthValuesColumn<Decimal28SparseVector> { protected Decimal28SparseVector decimal28Vector; Decimal28Column(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, Decimal28SparseVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); this.decimal28Vector = v; } @Override public boolean setSafe(int index, DrillBuf bytebuf, int start, int length) { int width = Decimal28SparseHolder.WIDTH; BigDecimal intermediate = DecimalUtility.getBigDecimalFromDrillBuf(bytebuf, start, length, schemaElement.getScale()); if (index >= decimal28Vector.getValueCapacity()) { return false; } DecimalUtility.getSparseFromBigDecimal(intermediate, decimal28Vector.getBuffer(), index * width, schemaElement.getScale(), schemaElement.getPrecision(), Decimal28SparseHolder.nDecimalDigits); return true; } @Override public int capacity() { return decimal28Vector.getBuffer().capacity(); } } public static class NullableDecimal28Column extends NullableVarLengthValuesColumn<NullableDecimal28SparseVector> { protected NullableDecimal28SparseVector nullableDecimal28Vector; NullableDecimal28Column(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, NullableDecimal28SparseVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); nullableDecimal28Vector = v; } @Override public boolean setSafe(int index, DrillBuf bytebuf, int start, int length) { int width = Decimal28SparseHolder.WIDTH; BigDecimal intermediate = DecimalUtility.getBigDecimalFromDrillBuf(bytebuf, start, length, schemaElement.getScale()); if (index >= nullableDecimal28Vector.getValueCapacity()) { return false; } DecimalUtility.getSparseFromBigDecimal(intermediate, nullableDecimal28Vector.getBuffer(), index * width, schemaElement.getScale(), schemaElement.getPrecision(), Decimal28SparseHolder.nDecimalDigits); nullableDecimal28Vector.getMutator().setIndexDefined(index); return true; } @Override public int capacity() { return nullableDecimal28Vector.getBuffer().capacity(); } } public static class Decimal38Column extends VarLengthValuesColumn<Decimal38SparseVector> { protected Decimal38SparseVector decimal28Vector; Decimal38Column(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, Decimal38SparseVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); decimal28Vector = v; } @Override public boolean setSafe(int index, DrillBuf bytebuf, int start, int length) { int width = Decimal38SparseHolder.WIDTH; BigDecimal intermediate = DecimalUtility.getBigDecimalFromDrillBuf(bytebuf, start, length, schemaElement.getScale()); if (index >= decimal28Vector.getValueCapacity()) { return false; } DecimalUtility.getSparseFromBigDecimal(intermediate, decimal28Vector.getBuffer(), index * width, schemaElement.getScale(), schemaElement.getPrecision(), Decimal38SparseHolder.nDecimalDigits); return true; } @Override public int capacity() { return decimal28Vector.getBuffer().capacity(); } } public static class NullableDecimal38Column extends NullableVarLengthValuesColumn<NullableDecimal38SparseVector> { private final NullableDecimal38SparseVector nullableDecimal38Vector; NullableDecimal38Column(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, NullableDecimal38SparseVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); nullableDecimal38Vector = v; } @Override public boolean setSafe(int index, DrillBuf bytebuf, int start, int length) { int width = Decimal38SparseHolder.WIDTH; BigDecimal intermediate = DecimalUtility.getBigDecimalFromDrillBuf(bytebuf, start, length, schemaElement.getScale()); if (index >= nullableDecimal38Vector.getValueCapacity()) { return false; } DecimalUtility.getSparseFromBigDecimal(intermediate, nullableDecimal38Vector.getBuffer(), index * width, schemaElement.getScale(), schemaElement.getPrecision(), Decimal38SparseHolder.nDecimalDigits); nullableDecimal38Vector.getMutator().setIndexDefined(index); return true; } @Override public int capacity() { return nullableDecimal38Vector.getBuffer().capacity(); } } public static class VarCharColumn extends VarLengthValuesColumn<VarCharVector> { // store a hard reference to the vector (which is also stored in the superclass) to prevent repetitive casting protected final VarCharVector.Mutator mutator; protected final VarCharVector varCharVector; VarCharColumn(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, VarCharVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); varCharVector = v; mutator = v.getMutator(); } @Override public boolean setSafe(int index, DrillBuf bytebuf, int start, int length) { if (index >= varCharVector.getValueCapacity()) { return false; } if (usingDictionary) { currDictValToWrite = pageReader.dictionaryValueReader.readBytes(); ByteBuffer buf = currDictValToWrite.toByteBuffer(); mutator.setSafe(index, buf, buf.position(), currDictValToWrite.length()); } else { mutator.setSafe(index, start, start + length, bytebuf); } return true; } @Override public int capacity() { return varCharVector.getBuffer().capacity(); } } public static class NullableVarCharColumn extends NullableVarLengthValuesColumn<NullableVarCharVector> { int nullsRead; boolean currentValNull = false; // store a hard reference to the vector (which is also stored in the superclass) to prevent repetitive casting protected final NullableVarCharVector.Mutator mutator; private final NullableVarCharVector vector; NullableVarCharColumn(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, NullableVarCharVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); vector = v; this.mutator = vector.getMutator(); } @Override public boolean setSafe(int index, DrillBuf value, int start, int length) { if (index >= vector.getValueCapacity()) { return false; } if (usingDictionary) { ByteBuffer buf = currDictValToWrite.toByteBuffer(); mutator.setSafe(index, buf, buf.position(), currDictValToWrite.length()); } else { mutator.setSafe(index, 1, start, start + length, value); } return true; } @Override public int capacity() { return vector.getBuffer().capacity(); } } public static class VarBinaryColumn extends VarLengthValuesColumn<VarBinaryVector> { // store a hard reference to the vector (which is also stored in the superclass) to prevent repetitive casting private final VarBinaryVector varBinaryVector; private final VarBinaryVector.Mutator mutator; VarBinaryColumn(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, VarBinaryVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); varBinaryVector = v; mutator = v.getMutator(); } @Override public boolean setSafe(int index, DrillBuf value, int start, int length) { if (index >= varBinaryVector.getValueCapacity()) { return false; } if (usingDictionary) { currDictValToWrite = pageReader.dictionaryValueReader.readBytes(); ByteBuffer buf = currDictValToWrite.toByteBuffer(); mutator.setSafe(index, buf, buf.position(), currDictValToWrite.length()); } else { mutator.setSafe(index, start, start + length, value); } return true; } @Override public int capacity() { return varBinaryVector.getBuffer().capacity(); } } public static class NullableVarBinaryColumn extends NullableVarLengthValuesColumn<NullableVarBinaryVector> { int nullsRead; boolean currentValNull = false; // store a hard reference to the vector (which is also stored in the superclass) to prevent repetitive casting private final NullableVarBinaryVector nullableVarBinaryVector; private final NullableVarBinaryVector.Mutator mutator; NullableVarBinaryColumn(ParquetRecordReader parentReader, int allocateSize, ColumnDescriptor descriptor, ColumnChunkMetaData columnChunkMetaData, boolean fixedLength, NullableVarBinaryVector v, SchemaElement schemaElement) throws ExecutionSetupException { super(parentReader, allocateSize, descriptor, columnChunkMetaData, fixedLength, v, schemaElement); nullableVarBinaryVector = v; mutator = v.getMutator(); } @Override public boolean setSafe(int index, DrillBuf value, int start, int length) { if (index >= nullableVarBinaryVector.getValueCapacity()) { return false; } if (usingDictionary) { ByteBuffer buf = currDictValToWrite.toByteBuffer(); mutator.setSafe(index, buf, buf.position(), currDictValToWrite.length()); } else { mutator.setSafe(index, 1, start, start + length, value); } return true; } @Override public int capacity() { return nullableVarBinaryVector.getBuffer().capacity(); } } }