/* * 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.accumulo; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.hadoop.hive.accumulo.columns.ColumnEncoding; import org.apache.hadoop.hive.accumulo.columns.ColumnMapping; import org.apache.hadoop.hive.accumulo.columns.HiveAccumuloColumnMapping; import org.apache.hadoop.hive.accumulo.columns.HiveAccumuloMapColumnMapping; import org.apache.hadoop.hive.accumulo.columns.HiveAccumuloRowIdColumnMapping; import org.apache.hadoop.hive.accumulo.serde.AccumuloRowIdFactory; import org.apache.hadoop.hive.serde2.SerDeException; import org.apache.hadoop.hive.serde2.lazy.ByteArrayRef; import org.apache.hadoop.hive.serde2.lazy.LazyFactory; import org.apache.hadoop.hive.serde2.lazy.LazyObjectBase; import org.apache.hadoop.hive.serde2.lazy.LazyStruct; import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazyMapObjectInspector; import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazySimpleStructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.StructField; import org.apache.hadoop.io.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * Parses column tuples in each AccumuloHiveRow and creates Lazy objects for each field. * */ public class LazyAccumuloRow extends LazyStruct { private static final Logger log = LoggerFactory.getLogger(LazyAccumuloRow.class); private AccumuloHiveRow row; private List<ColumnMapping> columnMappings; private ArrayList<Object> cachedList = new ArrayList<Object>(); private AccumuloRowIdFactory rowIdFactory; public LazyAccumuloRow(LazySimpleStructObjectInspector inspector) { super(inspector); } public void init(AccumuloHiveRow hiveRow, List<ColumnMapping> columnMappings, AccumuloRowIdFactory rowIdFactory) { this.row = hiveRow; this.columnMappings = columnMappings; this.rowIdFactory = rowIdFactory; setParsed(false); } private void parse() { if (getFields() == null) { // Will properly set string or binary serialization via createLazyField(...) initLazyFields(oi.getAllStructFieldRefs()); } if (!getParsed()) { Arrays.fill(getFieldInited(), false); setParsed(true); } } @Override public Object getField(int id) { if (!getParsed()) { parse(); } return uncheckedGetField(id); } /* * split pairs by delimiter. */ private Object uncheckedGetField(int id) { if (getFieldInited()[id]) { return getFields()[id].getObject(); } getFieldInited()[id] = true; ColumnMapping columnMapping = columnMappings.get(id); LazyObjectBase field = getFields()[id]; if (columnMapping instanceof HiveAccumuloMapColumnMapping) { HiveAccumuloMapColumnMapping mapColumnMapping = (HiveAccumuloMapColumnMapping) columnMapping; LazyAccumuloMap map = (LazyAccumuloMap) field; map.init(row, mapColumnMapping); } else { byte[] value; if (columnMapping instanceof HiveAccumuloRowIdColumnMapping) { // Use the rowID directly value = row.getRowId().getBytes(); } else if (columnMapping instanceof HiveAccumuloColumnMapping) { HiveAccumuloColumnMapping accumuloColumnMapping = (HiveAccumuloColumnMapping) columnMapping; // Use the colfam and colqual to get the value value = row.getValue( new Text(accumuloColumnMapping.getColumnFamilyBytes()), new Text(accumuloColumnMapping.getColumnQualifierBytes())); } else { log.error("Could not process ColumnMapping of type " + columnMapping.getClass() + " at offset " + id + " in column mapping: " + columnMapping.getMappingSpec()); throw new IllegalArgumentException("Cannot process ColumnMapping of type " + columnMapping.getClass()); } if (value == null || isNull(oi.getNullSequence(), value, 0, value.length)) { field.setNull(); } else { ByteArrayRef ref = new ByteArrayRef(); ref.setData(value); field.init(ref, 0, value.length); } } return field.getObject(); } @Override public ArrayList<Object> getFieldsAsList() { if (!getParsed()) { parse(); } cachedList.clear(); for (int i = 0; i < getFields().length; i++) { cachedList.add(uncheckedGetField(i)); } return cachedList; } @Override protected LazyObjectBase createLazyField(int fieldID, StructField fieldRef) throws SerDeException { final ColumnMapping columnMapping = columnMappings.get(fieldID); if (columnMapping instanceof HiveAccumuloRowIdColumnMapping) { return rowIdFactory.createRowId(fieldRef.getFieldObjectInspector()); } else if (columnMapping instanceof HiveAccumuloMapColumnMapping) { return new LazyAccumuloMap((LazyMapObjectInspector) fieldRef.getFieldObjectInspector()); } else { return LazyFactory.createLazyObject(fieldRef.getFieldObjectInspector(), ColumnEncoding.BINARY == columnMapping.getEncoding()); } } }