blob: 09418463b7f015c3bc8e153c91b51a79296efeb3 [file] [log] [blame]
/*
* 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.pojo;
import io.netty.buffer.DrillBuf;
import java.math.BigDecimal;
import java.sql.Timestamp;
import org.apache.drill.common.exceptions.ExecutionSetupException;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.common.types.Types;
import org.apache.drill.exec.expr.holders.NullableVarCharHolder;
import org.apache.drill.exec.vector.BigIntVector;
import org.apache.drill.exec.vector.BitVector;
import org.apache.drill.exec.vector.Float4Vector;
import org.apache.drill.exec.vector.Float8Vector;
import org.apache.drill.exec.vector.IntVector;
import org.apache.drill.exec.vector.NullableBigIntVector;
import org.apache.drill.exec.vector.NullableBitVector;
import org.apache.drill.exec.vector.NullableFloat4Vector;
import org.apache.drill.exec.vector.NullableFloat8Vector;
import org.apache.drill.exec.vector.NullableIntVector;
import org.apache.drill.exec.vector.NullableTimeStampVector;
import org.apache.drill.exec.vector.NullableVarCharVector;
import com.google.common.base.Charsets;
import org.apache.drill.exec.vector.VarDecimalVector;
public class PojoWriters {
/**
* Creates matching writer to the given field type.
*
* @param type field type
* @param fieldName field name
* @param buffer drill buffer
* @return pojo writer
* @throws ExecutionSetupException in case if writer was not found for the given type
*/
public static PojoWriter getWriter(Class<?> type, String fieldName, DrillBuf buffer) throws ExecutionSetupException {
if (type == Integer.class) {
return new NIntWriter(fieldName);
} else if (type == Long.class) {
return new NBigIntWriter(fieldName);
} else if (type == Boolean.class) {
return new NBooleanWriter(fieldName);
} else if (type == Float.class) {
return new NFloatWriter(fieldName);
} else if (type == Double.class) {
return new NDoubleWriter(fieldName);
} else if (type.isEnum()) {
return new EnumWriter(fieldName, buffer);
} else if (type == String.class) {
return new StringWriter(fieldName, buffer);
} else if (type == BigDecimal.class) {
return new DecimalWriter(fieldName);
} else if (type == Timestamp.class) {
return new NTimeStampWriter(fieldName);
// primitives
} else if (type == int.class) {
return new IntWriter(fieldName);
} else if (type == float.class) {
return new FloatWriter(fieldName);
} else if (type == double.class) {
return new DoubleWriter(fieldName);
} else if (type == boolean.class) {
return new BitWriter(fieldName);
} else if (type == long.class) {
return new LongWriter(fieldName);
}
throw new ExecutionSetupException(String.format("PojoRecordReader doesn't yet support conversions from the type [%s].", type));
}
/**
* Pojo writer for int. Does not expect to write null value.
*/
public static class IntWriter extends AbstractPojoWriter<IntVector> {
public IntWriter(String fieldName) {
super(fieldName, Types.required(MinorType.INT));
}
@Override
public void writeField(Object value, int outboundIndex) {
vector.getMutator().setSafe(outboundIndex, (int) value);
}
}
/**
* Pojo writer for boolean. Does not expect to write null value.
*/
public static class BitWriter extends AbstractPojoWriter<BitVector> {
public BitWriter(String fieldName) {
super(fieldName, Types.required(MinorType.BIT));
}
@Override
public void writeField(Object value, int outboundIndex) {
vector.getMutator().setSafe(outboundIndex, (boolean) value ? 1 : 0);
}
}
/**
* Pojo writer for long. Does not expect to write null value.
*/
public static class LongWriter extends AbstractPojoWriter<BigIntVector> {
public LongWriter(String fieldName) {
super(fieldName, Types.required(MinorType.BIGINT));
}
@Override
public void writeField(Object value, int outboundIndex) {
vector.getMutator().setSafe(outboundIndex, (long) value);
}
}
/**
* Pojo writer for float. Does not expect to write null value.
*/
public static class FloatWriter extends AbstractPojoWriter<Float4Vector> {
public FloatWriter(String fieldName) {
super(fieldName, Types.required(MinorType.FLOAT4));
}
@Override
public void writeField(Object value, int outboundIndex) {
vector.getMutator().setSafe(outboundIndex, (float) value);
}
}
/**
* Pojo writer for double. Does not expect to write null value.
*/
public static class DoubleWriter extends AbstractPojoWriter<Float8Vector> {
public DoubleWriter(String fieldName) {
super(fieldName, Types.required(MinorType.FLOAT8));
}
@Override
public void writeField(Object value, int outboundIndex) {
vector.getMutator().setSafe(outboundIndex, (double) value);
}
}
/**
* Pojo writer for decimal. If null is encountered does not write it.
*/
public static class DecimalWriter extends AbstractPojoWriter<VarDecimalVector> {
public DecimalWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.VARDECIMAL));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, (BigDecimal) value);
}
}
}
/**
* Parent class for String and Enum writers. Writes data using nullable varchar holder.
*/
private abstract static class AbstractStringWriter extends AbstractPojoWriter<NullableVarCharVector> {
private DrillBuf data;
private final NullableVarCharHolder holder = new NullableVarCharHolder();
public AbstractStringWriter(String fieldName, DrillBuf managedBuf) {
super(fieldName, Types.optional(MinorType.VARCHAR));
this.data = managedBuf;
ensureLength(100);
}
void ensureLength(int len) {
data = data.reallocIfNeeded(len);
}
public void writeString(String s, int outboundIndex) {
holder.isSet = 1;
byte[] bytes = s.getBytes(Charsets.UTF_8);
ensureLength(bytes.length);
data.clear();
data.writeBytes(bytes);
holder.buffer = data;
holder.start = 0;
holder.end = bytes.length;
vector.getMutator().setSafe(outboundIndex, holder);
}
}
/**
* Pojo writer for Enum. If null is encountered does not write it.
*/
public static class EnumWriter extends AbstractStringWriter{
public EnumWriter(String fieldName, DrillBuf managedBuf) {
super(fieldName, managedBuf);
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value == null) {
return;
}
writeString(((Enum<?>) value).name(), outboundIndex);
}
}
/**
* Pojo writer for String. If null is encountered does not write it.
*/
public static class StringWriter extends AbstractStringWriter {
public StringWriter(String fieldName, DrillBuf managedBuf) {
super(fieldName, managedBuf);
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
writeString((String) value, outboundIndex);
}
}
}
/**
* Pojo writer for Integer. If null is encountered does not write it.
*/
public static class NIntWriter extends AbstractPojoWriter<NullableIntVector> {
public NIntWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.INT));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, (Integer) value);
}
}
}
/**
* Pojo writer for Long. If null is encountered does not write it.
*/
public static class NBigIntWriter extends AbstractPojoWriter<NullableBigIntVector> {
public NBigIntWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.BIGINT));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, (Long) value);
}
}
}
/**
* Pojo writer for Boolean. If null is encountered does not write it.
*/
public static class NBooleanWriter extends AbstractPojoWriter<NullableBitVector> {
public NBooleanWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.BIT));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, (Boolean) value ? 1 : 0);
}
}
}
/**
* Pojo writer for Float. If null is encountered does not write it.
*/
public static class NFloatWriter extends AbstractPojoWriter<NullableFloat4Vector> {
public NFloatWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.FLOAT4));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, (Float) value);
}
}
}
/**
* Pojo writer for Double. If null is encountered does not write it.
*/
public static class NDoubleWriter extends AbstractPojoWriter<NullableFloat8Vector> {
public NDoubleWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.FLOAT8));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, (Double) value);
}
}
}
/**
* Pojo writer for Timestamp. If null is encountered does not write it.
*/
public static class NTimeStampWriter extends AbstractPojoWriter<NullableTimeStampVector> {
public NTimeStampWriter(String fieldName) {
super(fieldName, Types.optional(MinorType.TIMESTAMP));
}
@Override
public void writeField(Object value, int outboundIndex) {
if (value != null) {
vector.getMutator().setSafe(outboundIndex, ((Timestamp) value).getTime());
}
}
}
}