| /* |
| * 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.pig.impl.plan; |
| |
| import java.lang.StringBuilder; |
| import java.util.List; |
| |
| import org.apache.pig.data.DataType; |
| import org.apache.pig.impl.util.MultiMap; |
| import org.apache.pig.impl.util.Pair; |
| |
| /** |
| * A struct detailing how a projection is altered by an operator. |
| */ |
| public class ProjectionMap { |
| /** |
| * Quick way for an operator to note that its input and output are the same. |
| */ |
| private boolean mChanges = true; |
| |
| /** |
| * Map of field changes, with keys being the output fields of the operator |
| * and values being the projection map columns. Fields are numbered from 0. |
| * So for a foreach operator derived from 'B = foreach A generate $0, $2, |
| * (int)$3, udf($1)' would produce a mapping of 0->(0, 0), 2->(0, 1), |
| * 3->[(0, 2), DataType.INTEGER] |
| */ |
| private MultiMap<Integer, Column> mMappedFields; |
| |
| /** |
| * List of fields removed from the input. This includes fields that were |
| * transformed, and thus are no longer the same fields. Using the example |
| * foreach given under mappedFields, this list would contain '(0,1)'. |
| */ |
| private List<Pair<Integer, Integer>> mRemovedFields; |
| |
| /** |
| * List of fields in the output of this operator that were created by this |
| * operator. Using the example foreach given under mappedFields, this list |
| * would contain '3'. |
| */ |
| private List<Integer> mAddedFields; |
| |
| /** |
| * |
| * @param changes |
| * to indicate if this projection map changes its input or not |
| */ |
| public ProjectionMap(boolean changes) { |
| this(null, null, null, changes); |
| } |
| |
| /** |
| * |
| * @param mapFields |
| * the mapping of input column to output column |
| * @param removedFields |
| * the list of input columns that are removed |
| * @param addedFields |
| * the list of columns that are added to the output |
| */ |
| public ProjectionMap(MultiMap<Integer, Column> mapFields, |
| List<Pair<Integer, Integer>> removedFields, |
| List<Integer> addedFields) { |
| this(mapFields, removedFields, addedFields, true); |
| } |
| |
| /** |
| * |
| * @param mapFields |
| * the mapping of input column to output column |
| * @param removedFields |
| * the list of input columns that are removed |
| * @param addedFields |
| * the list of columns that are added to the output |
| * @param changes |
| * to indicate if this projection map changes its input or not |
| */ |
| private ProjectionMap(MultiMap<Integer, Column> mapFields, |
| List<Pair<Integer, Integer>> removedFields, |
| List<Integer> addedFields, boolean changes) { |
| mMappedFields = mapFields; |
| mAddedFields = addedFields; |
| mRemovedFields = removedFields; |
| mChanges = changes; |
| } |
| |
| /** |
| * |
| * @return the mapping of input column to output column |
| */ |
| public MultiMap<Integer, Column> getMappedFields() { |
| return mMappedFields; |
| } |
| |
| /** |
| * |
| * @param fields |
| * the mapping of input column to output column |
| */ |
| public void setMappedFields(MultiMap<Integer, Column> fields) { |
| mMappedFields = fields; |
| } |
| |
| /** |
| * |
| * @return the list of input columns that are removed |
| */ |
| public List<Pair<Integer, Integer>> getRemovedFields() { |
| return mRemovedFields; |
| } |
| |
| /** |
| * |
| * @param fields |
| * the list of input columns that are removed |
| */ |
| public void setRemovedFields(List<Pair<Integer, Integer>> fields) { |
| mRemovedFields = fields; |
| } |
| |
| /** |
| * |
| * @return the list of columns that are added to the output |
| */ |
| public List<Integer> getAddedFields() { |
| return mAddedFields; |
| } |
| |
| /** |
| * |
| * @param fields |
| * the list of columns that are added to the output |
| */ |
| public void setAddedFields(List<Integer> fields) { |
| mAddedFields = fields; |
| } |
| |
| /** |
| * |
| * @return if this projection map changes its input or not |
| */ |
| public boolean changes() { |
| return getChanges(); |
| } |
| |
| |
| /** |
| * |
| * @return if this projection map changes its input or not |
| */ |
| public boolean getChanges() { |
| return mChanges; |
| } |
| |
| /** |
| * |
| * @param changes |
| * if this projection map changes its input or not |
| */ |
| public void setChanges(boolean changes) { |
| mChanges = changes; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append("changes: " + mChanges); |
| sb.append(" mapped fields: " + mMappedFields); |
| sb.append(" added fields: " + mAddedFields); |
| sb.append(" removed fields: " + mRemovedFields); |
| return sb.toString(); |
| } |
| |
| /** |
| * |
| * A wrapper for projection map columns to contain the input number, input |
| * column. Additionally, if a cast is used, record the type of the cast |
| * |
| */ |
| public static class Column { |
| private Pair<Integer, Integer> mInputColumn; |
| private boolean mCast = false; |
| private byte mCastType = DataType.UNKNOWN; |
| |
| /** |
| * |
| * @param inputColumn |
| * A pair of integers representing the input number and the |
| * input column number |
| */ |
| public Column(Pair<Integer, Integer> inputColumn) { |
| this(inputColumn, false, DataType.UNKNOWN); |
| } |
| |
| /** |
| * |
| * @param inputColumn |
| * A pair of integers representing the input number and the |
| * input column number |
| * @param cast |
| * true if the input column has a cast |
| * @param castType |
| * the data type of the cast |
| */ |
| public Column(Pair<Integer, Integer> inputColumn, boolean cast, |
| byte castType) { |
| mInputColumn = inputColumn; |
| mCast = cast; |
| mCastType = castType; |
| } |
| |
| /** |
| * |
| * Get the mapped column details |
| * |
| * @return A pair of integers representing the input number and the |
| * input column number |
| */ |
| public Pair<Integer, Integer> getInputColumn() { |
| return mInputColumn; |
| } |
| |
| /** |
| * |
| * Check if the column is cast |
| * |
| * @return true if the input column has a cast; false otherwise |
| */ |
| public boolean getCast() { |
| return mCast; |
| } |
| |
| |
| /** |
| * |
| * Check if the column is cast |
| * |
| * @return true if the input column has a cast; false otherwise |
| */ |
| public boolean cast() { |
| return getCast(); |
| } |
| |
| /** |
| * |
| * Get the data type of the cast |
| * |
| * @return the data type of the cast |
| */ |
| public byte getCastType() { |
| return mCastType; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(mInputColumn); |
| if (mCast) { |
| sb.append(" cast to: " + DataType.findTypeName(mCastType)); |
| } |
| return sb.toString(); |
| } |
| } |
| } |