/** * Copyright 2018 LinkedIn Corporation. All rights reserved. * Licensed under the BSD-2 Clause license. * See LICENSE in the project root for license information. */ package com.linkedin.transport.hive; import com.google.common.base.Preconditions; import com.linkedin.transport.api.StdFactory; import com.linkedin.transport.api.data.StdArray; import com.linkedin.transport.api.data.StdBoolean; import com.linkedin.transport.api.data.StdBinary; import com.linkedin.transport.api.data.StdDouble; import com.linkedin.transport.api.data.StdFloat; import com.linkedin.transport.api.data.StdInteger; import com.linkedin.transport.api.data.StdLong; import com.linkedin.transport.api.data.StdMap; import com.linkedin.transport.api.data.StdString; import com.linkedin.transport.api.data.StdStruct; import com.linkedin.transport.api.types.StdType; import com.linkedin.transport.hive.data.HiveArray; import com.linkedin.transport.hive.data.HiveBoolean; import com.linkedin.transport.hive.data.HiveBinary; import com.linkedin.transport.hive.data.HiveDouble; import com.linkedin.transport.hive.data.HiveFloat; import com.linkedin.transport.hive.data.HiveInteger; import com.linkedin.transport.hive.data.HiveLong; import com.linkedin.transport.hive.data.HiveMap; import com.linkedin.transport.hive.data.HiveString; import com.linkedin.transport.hive.data.HiveStruct; import com.linkedin.transport.hive.types.objectinspector.CacheableObjectInspectorConverters; import com.linkedin.transport.hive.typesystem.HiveTypeFactory; import com.linkedin.transport.typesystem.AbstractBoundVariables; import com.linkedin.transport.typesystem.TypeSignature; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.MapObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; public class HiveFactory implements StdFactory { final AbstractBoundVariables<ObjectInspector> _boundVariables; final CacheableObjectInspectorConverters _converters; final HiveTypeFactory _typeFactory; public HiveFactory(AbstractBoundVariables<ObjectInspector> boundVariables) { _boundVariables = boundVariables; _converters = new CacheableObjectInspectorConverters(); _typeFactory = new HiveTypeFactory(); } @Override public StdInteger createInteger(int value) { return new HiveInteger(value, PrimitiveObjectInspectorFactory.javaIntObjectInspector, this); } @Override public StdLong createLong(long value) { return new HiveLong(value, PrimitiveObjectInspectorFactory.javaLongObjectInspector, this); } @Override public StdBoolean createBoolean(boolean value) { return new HiveBoolean(value, PrimitiveObjectInspectorFactory.javaBooleanObjectInspector, this); } @Override public StdString createString(String value) { Preconditions.checkNotNull(value, "Cannot create a null StdString"); return new HiveString(value, PrimitiveObjectInspectorFactory.javaStringObjectInspector, this); } @Override public StdFloat createFloat(float value) { return new HiveFloat(value, PrimitiveObjectInspectorFactory.javaFloatObjectInspector, this); } @Override public StdDouble createDouble(double value) { return new HiveDouble(value, PrimitiveObjectInspectorFactory.javaDoubleObjectInspector, this); } @Override public StdBinary createBinary(ByteBuffer value) { return new HiveBinary(value.array(), PrimitiveObjectInspectorFactory.javaByteArrayObjectInspector, this); } @Override public StdArray createArray(StdType stdType, int expectedSize) { ListObjectInspector listObjectInspector = (ListObjectInspector) stdType.underlyingType(); return new HiveArray( new ArrayList(expectedSize), ObjectInspectorFactory.getStandardListObjectInspector(listObjectInspector.getListElementObjectInspector()), this); } @Override public StdArray createArray(StdType stdType) { return createArray(stdType, 0); } @Override public StdMap createMap(StdType stdType) { MapObjectInspector mapObjectInspector = (MapObjectInspector) stdType.underlyingType(); return new HiveMap( new HashMap(), ObjectInspectorFactory.getStandardMapObjectInspector( mapObjectInspector.getMapKeyObjectInspector(), mapObjectInspector.getMapValueObjectInspector()), this); } @Override public StdStruct createStruct(List<String> fieldNames, List<StdType> fieldTypes) { return new HiveStruct( new ArrayList(Arrays.asList(new Object[fieldTypes.size()])), ObjectInspectorFactory.getStandardStructObjectInspector( fieldNames, fieldTypes.stream().map(f -> (ObjectInspector) f.underlyingType()).collect(Collectors.toList()) ), this); } @Override public StdStruct createStruct(List<StdType> fieldTypes) { List<String> fieldNames = IntStream.range(0, fieldTypes.size()).mapToObj(i -> "field" + i).collect(Collectors.toList()); return createStruct(fieldNames, fieldTypes); } @Override public StdStruct createStruct(StdType stdType) { StructObjectInspector structObjectInspector = (StructObjectInspector) stdType.underlyingType(); return new HiveStruct( new ArrayList(Arrays.asList(new Object[structObjectInspector.getAllStructFieldRefs().size()])), ObjectInspectorFactory.getStandardStructObjectInspector( structObjectInspector.getAllStructFieldRefs() .stream() .map(f -> f.getFieldName()) .collect(Collectors.toList()), structObjectInspector.getAllStructFieldRefs() .stream() .map(f -> f.getFieldObjectInspector()) .collect(Collectors.toList()) ), this); } @Override public StdType createStdType(String typeSignature) { return HiveWrapper.createStdType( _typeFactory.createType(TypeSignature.parse(typeSignature), _boundVariables) ); } public Converter getConverter(ObjectInspector inputOI, ObjectInspector outputOI) { return _converters.getConverter(inputOI, outputOI); } }