/** * 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.hadoop.hive.serde2.objectinspector.primitive; import java.sql.Date; import java.sql.Timestamp; import org.apache.hadoop.hive.common.type.HiveChar; import org.apache.hadoop.hive.common.type.HiveDecimal; import org.apache.hadoop.hive.common.type.HiveIntervalYearMonth; import org.apache.hadoop.hive.common.type.HiveIntervalDayTime; import org.apache.hadoop.hive.common.type.HiveVarchar; import org.apache.hadoop.hive.common.type.TimestampTZ; import org.apache.hadoop.hive.serde2.ByteStream; import org.apache.hadoop.hive.serde2.io.HiveCharWritable; import org.apache.hadoop.hive.serde2.io.HiveVarcharWritable; import org.apache.hadoop.hive.serde2.lazy.LazyInteger; import org.apache.hadoop.hive.serde2.lazy.LazyLong; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.io.BytesWritable; import org.apache.hadoop.io.Text; /** * PrimitiveObjectInspectorConverter. * */ public class PrimitiveObjectInspectorConverter { /** * A converter for the byte type. */ public static class BooleanConverter implements Converter { PrimitiveObjectInspector inputOI; SettableBooleanObjectInspector outputOI; Object r; public BooleanConverter(PrimitiveObjectInspector inputOI, SettableBooleanObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(false); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getBoolean(input, inputOI)); } catch (NumberFormatException e) { return null; } } } /** * A converter for the byte type. */ public static class ByteConverter implements Converter { PrimitiveObjectInspector inputOI; SettableByteObjectInspector outputOI; Object r; public ByteConverter(PrimitiveObjectInspector inputOI, SettableByteObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create((byte) 0); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getByte(input, inputOI)); } catch (NumberFormatException e) { return null; } } } /** * A converter for the short type. */ public static class ShortConverter implements Converter { PrimitiveObjectInspector inputOI; SettableShortObjectInspector outputOI; Object r; public ShortConverter(PrimitiveObjectInspector inputOI, SettableShortObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create((short) 0); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getShort(input, inputOI)); } catch (NumberFormatException e) { return null; } } } /** * A converter for the int type. */ public static class IntConverter implements Converter { PrimitiveObjectInspector inputOI; SettableIntObjectInspector outputOI; Object r; public IntConverter(PrimitiveObjectInspector inputOI, SettableIntObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(0); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getInt(input, inputOI)); } catch (NumberFormatException e) { return null; } } } /** * A converter for the long type. */ public static class LongConverter implements Converter { PrimitiveObjectInspector inputOI; SettableLongObjectInspector outputOI; Object r; public LongConverter(PrimitiveObjectInspector inputOI, SettableLongObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(0); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getLong(input, inputOI)); } catch (NumberFormatException e) { return null; } } } /** * A converter for the float type. */ public static class FloatConverter implements Converter { PrimitiveObjectInspector inputOI; SettableFloatObjectInspector outputOI; Object r; public FloatConverter(PrimitiveObjectInspector inputOI, SettableFloatObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(0); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getFloat(input, inputOI)); } catch (NumberFormatException e) { return null; } } } /** * A converter for the double type. */ public static class DoubleConverter implements Converter { PrimitiveObjectInspector inputOI; SettableDoubleObjectInspector outputOI; Object r; public DoubleConverter(PrimitiveObjectInspector inputOI, SettableDoubleObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(0); } @Override public Object convert(Object input) { if (input == null) { return null; } try { return outputOI.set(r, PrimitiveObjectInspectorUtils.getDouble(input, inputOI)); } catch (NumberFormatException e) { return null; } } } public static class DateConverter implements Converter { PrimitiveObjectInspector inputOI; SettableDateObjectInspector outputOI; Object r; public DateConverter(PrimitiveObjectInspector inputOI, SettableDateObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(new Date(0)); } public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getDate(input, inputOI)); } } public static class TimestampConverter implements Converter { PrimitiveObjectInspector inputOI; SettableTimestampObjectInspector outputOI; boolean intToTimestampInSeconds = false; Object r; public TimestampConverter(PrimitiveObjectInspector inputOI, SettableTimestampObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(new Timestamp(0)); } public void setIntToTimestampInSeconds(boolean intToTimestampInSeconds) { this.intToTimestampInSeconds = intToTimestampInSeconds; } public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getTimestamp(input, inputOI, intToTimestampInSeconds)); } } public static class TimestampTZConverter implements Converter { final PrimitiveObjectInspector inputOI; final SettableTimestampTZObjectInspector outputOI; final Object r; public TimestampTZConverter(PrimitiveObjectInspector inputOI, SettableTimestampTZObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(new TimestampTZ()); } @Override public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getTimestampTZ(input, inputOI)); } } public static class HiveIntervalYearMonthConverter implements Converter { PrimitiveObjectInspector inputOI; SettableHiveIntervalYearMonthObjectInspector outputOI; Object r; public HiveIntervalYearMonthConverter(PrimitiveObjectInspector inputOI, SettableHiveIntervalYearMonthObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(new HiveIntervalYearMonth()); } public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth(input, inputOI)); } } public static class HiveIntervalDayTimeConverter implements Converter { PrimitiveObjectInspector inputOI; SettableHiveIntervalDayTimeObjectInspector outputOI; Object r; public HiveIntervalDayTimeConverter(PrimitiveObjectInspector inputOI, SettableHiveIntervalDayTimeObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(new HiveIntervalDayTime()); } public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getHiveIntervalDayTime(input, inputOI)); } } public static class HiveDecimalConverter implements Converter { PrimitiveObjectInspector inputOI; SettableHiveDecimalObjectInspector outputOI; Object r; public HiveDecimalConverter(PrimitiveObjectInspector inputOI, SettableHiveDecimalObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; this.r = outputOI.create(HiveDecimal.ZERO); } @Override public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getHiveDecimal(input, inputOI)); } } public static class BinaryConverter implements Converter{ PrimitiveObjectInspector inputOI; SettableBinaryObjectInspector outputOI; Object r; public BinaryConverter(PrimitiveObjectInspector inputOI, SettableBinaryObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; r = outputOI.create(new byte[]{}); } @Override public Object convert(Object input) { if (input == null) { return null; } return outputOI.set(r, PrimitiveObjectInspectorUtils.getBinary(input, inputOI)); } } /** * A helper class to convert any primitive to Text. */ public static class TextConverter implements Converter { private final PrimitiveObjectInspector inputOI; private final Text t = new Text(); private final ByteStream.Output out = new ByteStream.Output(); private static byte[] trueBytes = {'T', 'R', 'U', 'E'}; private static byte[] falseBytes = {'F', 'A', 'L', 'S', 'E'}; public TextConverter(PrimitiveObjectInspector inputOI) { // The output ObjectInspector is writableStringObjectInspector. this.inputOI = inputOI; } public Text convert(Object input) { if (input == null) { return null; } switch (inputOI.getPrimitiveCategory()) { case VOID: return null; case BOOLEAN: t.set(((BooleanObjectInspector) inputOI).get(input) ? trueBytes : falseBytes); return t; case BYTE: out.reset(); LazyInteger.writeUTF8NoException(out, ((ByteObjectInspector) inputOI).get(input)); t.set(out.getData(), 0, out.getLength()); return t; case SHORT: out.reset(); LazyInteger.writeUTF8NoException(out, ((ShortObjectInspector) inputOI).get(input)); t.set(out.getData(), 0, out.getLength()); return t; case INT: out.reset(); LazyInteger.writeUTF8NoException(out, ((IntObjectInspector) inputOI).get(input)); t.set(out.getData(), 0, out.getLength()); return t; case LONG: out.reset(); LazyLong.writeUTF8NoException(out, ((LongObjectInspector) inputOI).get(input)); t.set(out.getData(), 0, out.getLength()); return t; case FLOAT: t.set(String.valueOf(((FloatObjectInspector) inputOI).get(input))); return t; case DOUBLE: t.set(String.valueOf(((DoubleObjectInspector) inputOI).get(input))); return t; case STRING: if (inputOI.preferWritable()) { t.set(((StringObjectInspector) inputOI).getPrimitiveWritableObject(input)); } else { t.set(((StringObjectInspector) inputOI).getPrimitiveJavaObject(input)); } return t; case CHAR: // when converting from char, the value should be stripped of any trailing spaces. if (inputOI.preferWritable()) { // char text value is already stripped of trailing space t.set(((HiveCharObjectInspector) inputOI).getPrimitiveWritableObject(input) .getStrippedValue()); } else { t.set(((HiveCharObjectInspector) inputOI).getPrimitiveJavaObject(input).getStrippedValue()); } return t; case VARCHAR: if (inputOI.preferWritable()) { t.set(((HiveVarcharObjectInspector) inputOI).getPrimitiveWritableObject(input) .toString()); } else { t.set(((HiveVarcharObjectInspector) inputOI).getPrimitiveJavaObject(input).toString()); } return t; case DATE: t.set(((DateObjectInspector) inputOI).getPrimitiveWritableObject(input).toString()); return t; case TIMESTAMP: t.set(((TimestampObjectInspector) inputOI) .getPrimitiveWritableObject(input).toString()); return t; case TIMESTAMPTZ: t.set(((TimestampTZObjectInspector) inputOI).getPrimitiveWritableObject(input).toString()); return t; case INTERVAL_YEAR_MONTH: t.set(((HiveIntervalYearMonthObjectInspector) inputOI) .getPrimitiveWritableObject(input).toString()); return t; case INTERVAL_DAY_TIME: t.set(((HiveIntervalDayTimeObjectInspector) inputOI) .getPrimitiveWritableObject(input).toString()); return t; case BINARY: BinaryObjectInspector binaryOI = (BinaryObjectInspector) inputOI; if (binaryOI.preferWritable()) { BytesWritable bytes = binaryOI.getPrimitiveWritableObject(input); t.set(bytes.getBytes(), 0, bytes.getLength()); } else { t.set(binaryOI.getPrimitiveJavaObject(input)); } return t; case DECIMAL: t.set(((HiveDecimalObjectInspector) inputOI).getPrimitiveWritableObject(input).toString()); return t; default: throw new RuntimeException("Hive 2 Internal error: type = " + inputOI.getTypeName()); } } } /** * A helper class to convert any primitive to String. */ public static class StringConverter implements Converter { PrimitiveObjectInspector inputOI; public StringConverter(PrimitiveObjectInspector inputOI) { // The output ObjectInspector is writableStringObjectInspector. this.inputOI = inputOI; } @Override public Object convert(Object input) { return PrimitiveObjectInspectorUtils.getString(input, inputOI); } } public static class HiveVarcharConverter implements Converter { PrimitiveObjectInspector inputOI; SettableHiveVarcharObjectInspector outputOI; Object hc; public HiveVarcharConverter(PrimitiveObjectInspector inputOI, SettableHiveVarcharObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; // unfortunately we seem to get instances of varchar object inspectors without params // when an old-style UDF has an evaluate() method with varchar arguments. // If we disallow varchar in old-style UDFs and only allow GenericUDFs to be defined // with varchar arguments, then we might be able to enforce this properly. //if (typeParams == null) { // throw new RuntimeException("varchar type used without type params"); //} hc = outputOI.create(new HiveVarchar("",-1)); } @Override public Object convert(Object input) { if (input == null) { return null; } switch (inputOI.getPrimitiveCategory()) { case BOOLEAN: return outputOI.set(hc, ((BooleanObjectInspector) inputOI).get(input) ? new HiveVarchar("TRUE", -1) : new HiveVarchar("FALSE", -1)); default: return outputOI.set(hc, PrimitiveObjectInspectorUtils.getHiveVarchar(input, inputOI)); } } } public static class HiveCharConverter implements Converter { PrimitiveObjectInspector inputOI; SettableHiveCharObjectInspector outputOI; Object hc; public HiveCharConverter(PrimitiveObjectInspector inputOI, SettableHiveCharObjectInspector outputOI) { this.inputOI = inputOI; this.outputOI = outputOI; hc = outputOI.create(new HiveChar("",-1)); } @Override public Object convert(Object input) { if (input == null) { return null; } switch (inputOI.getPrimitiveCategory()) { case BOOLEAN: return outputOI.set(hc, ((BooleanObjectInspector) inputOI).get(input) ? new HiveChar("TRUE", -1) : new HiveChar("FALSE", -1)); default: return outputOI.set(hc, PrimitiveObjectInspectorUtils.getHiveChar(input, inputOI)); } } } }