merge from zheilbron/hyracks_msr
diff --git a/hivesterix/hivesterix-translator/pom.xml b/hivesterix/hivesterix-translator/pom.xml
index 8a24d5e..d8c205f 100644
--- a/hivesterix/hivesterix-translator/pom.xml
+++ b/hivesterix/hivesterix-translator/pom.xml
@@ -21,7 +21,7 @@
 	<parent>
 		<artifactId>hivesterix</artifactId>
 		<groupId>edu.uci.ics.hyracks</groupId>
-		<version>0.2.7-SNAPSHOT</version>
+		<version>0.2.10-SNAPSHOT</version>
 	</parent>
 
 	<build>
@@ -42,30 +42,23 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>org.apache.hadoop.hive</groupId>
-			<artifactId>hive-exec</artifactId>
-			<version>0.7.0</version>
-			<type>jar</type>
-			<scope>compile</scope>
-		</dependency>
-		<dependency>
 			<groupId>edu.uci.ics.hyracks</groupId>
 			<artifactId>algebricks-compiler</artifactId>
-			<version>0.2.7-SNAPSHOT</version>
+			<version>0.2.10-SNAPSHOT</version>
 			<type>jar</type>
 			<scope>compile</scope>
 		</dependency>
 		<dependency>
 			<groupId>edu.uci.ics.hyracks</groupId>
 			<artifactId>hivesterix-common</artifactId>
-			<version>0.2.7-SNAPSHOT</version>
+			<version>0.2.10-SNAPSHOT</version>
 			<type>jar</type>
 			<scope>compile</scope>
 		</dependency>
 		<dependency>
 			<groupId>edu.uci.ics.hyracks</groupId>
 			<artifactId>hivesterix-runtime</artifactId>
-			<version>0.2.7-SNAPSHOT</version>
+			<version>0.2.10-SNAPSHOT</version>
 			<type>jar</type>
 			<scope>compile</scope>
 		</dependency>
diff --git a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/HiveAlgebricksTranslator.java b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/HiveAlgebricksTranslator.java
index f32d85b..76cc51d 100644
--- a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/HiveAlgebricksTranslator.java
+++ b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/HiveAlgebricksTranslator.java
@@ -12,810 +12,809 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package edu.uci.ics.hivesterix.logical.plan;

-

-import java.io.OutputStreamWriter;

-import java.io.PrintWriter;

-import java.util.ArrayList;

-import java.util.HashMap;

-import java.util.List;

-import java.util.Map;

-import java.util.Map.Entry;

-import java.util.Set;

-

-import org.apache.commons.lang3.mutable.Mutable;

-import org.apache.commons.lang3.mutable.MutableObject;

-import org.apache.hadoop.hive.ql.exec.ColumnInfo;

-import org.apache.hadoop.hive.ql.exec.ExtractOperator;

-import org.apache.hadoop.hive.ql.exec.FileSinkOperator;

-import org.apache.hadoop.hive.ql.exec.FilterOperator;

-import org.apache.hadoop.hive.ql.exec.GroupByOperator;

-import org.apache.hadoop.hive.ql.exec.JoinOperator;

-import org.apache.hadoop.hive.ql.exec.LateralViewJoinOperator;

-import org.apache.hadoop.hive.ql.exec.LimitOperator;

-import org.apache.hadoop.hive.ql.exec.MapJoinOperator;

-import org.apache.hadoop.hive.ql.exec.Operator;

-import org.apache.hadoop.hive.ql.exec.ReduceSinkOperator;

-import org.apache.hadoop.hive.ql.exec.SelectOperator;

-import org.apache.hadoop.hive.ql.exec.TableScanOperator;

-import org.apache.hadoop.hive.ql.exec.UDF;

-import org.apache.hadoop.hive.ql.exec.UDTFOperator;

-import org.apache.hadoop.hive.ql.exec.UnionOperator;

-import org.apache.hadoop.hive.ql.plan.AggregationDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeFieldDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeNullDesc;

-import org.apache.hadoop.hive.ql.plan.PartitionDesc;

-import org.apache.hadoop.hive.ql.plan.UDTFDesc;

-import org.apache.hadoop.hive.ql.plan.api.OperatorType;

-import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;

-import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge;

-import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;

-

-import edu.uci.ics.hivesterix.logical.expression.ExpressionConstant;

-import edu.uci.ics.hivesterix.logical.expression.HiveAlgebricksBuiltInFunctionMap;

-import edu.uci.ics.hivesterix.logical.expression.HiveFunctionInfo;

-import edu.uci.ics.hivesterix.logical.expression.HivesterixConstantValue;

-import edu.uci.ics.hivesterix.logical.plan.visitor.ExtractVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.FilterVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.GroupByVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.JoinVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.LateralViewJoinVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.LimitVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.MapJoinVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.ProjectVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.SortVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.TableScanWriteVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.UnionVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.Visitor;

-import edu.uci.ics.hivesterix.runtime.jobgen.Schema;

-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;

-import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;

-import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.LogicalOperatorPrettyPrintVisitor;

-import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.PlanPrettyPrinter;

-

-@SuppressWarnings("rawtypes")

-public class HiveAlgebricksTranslator implements Translator {

-

-    private int currentVariable = 0;

-

-    private List<Mutable<ILogicalOperator>> logicalOp = new ArrayList<Mutable<ILogicalOperator>>();

-

-    private boolean continueTraverse = true;

-

-    private IMetadataProvider<PartitionDesc, Object> metaData;

-

-    /**

-     * map variable name to the logical variable

-     */

-    private HashMap<String, LogicalVariable> nameToLogicalVariableMap = new HashMap<String, LogicalVariable>();

-

-    /**

-     * map field name to LogicalVariable

-     */

-    private HashMap<String, LogicalVariable> fieldToLogicalVariableMap = new HashMap<String, LogicalVariable>();

-

-    /**

-     * map logical variable to name

-     */

-    private HashMap<LogicalVariable, String> logicalVariableToFieldMap = new HashMap<LogicalVariable, String>();

-

-    /**

-     * asterix root operators

-     */

-    private List<Mutable<ILogicalOperator>> rootOperators = new ArrayList<Mutable<ILogicalOperator>>();

-

-    /**

-     * a list of visitors

-     */

-    private List<Visitor> visitors = new ArrayList<Visitor>();

-

-    /**

-     * output writer to print things out

-     */

-    private static PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(System.out));

-

-    /**

-     * map a logical variable to type info

-     */

-    private HashMap<LogicalVariable, TypeInfo> variableToType = new HashMap<LogicalVariable, TypeInfo>();

-

-    @Override

-    public LogicalVariable getVariable(String fieldName, TypeInfo type) {

-        LogicalVariable var = fieldToLogicalVariableMap.get(fieldName);

-        if (var == null) {

-            currentVariable++;

-            var = new LogicalVariable(currentVariable);

-            fieldToLogicalVariableMap.put(fieldName, var);

-            nameToLogicalVariableMap.put(var.toString(), var);

-            variableToType.put(var, type);

-            logicalVariableToFieldMap.put(var, fieldName);

-        }

-        return var;

-    }

-

-    @Override

-    public LogicalVariable getNewVariable(String fieldName, TypeInfo type) {

-        currentVariable++;

-        LogicalVariable var = new LogicalVariable(currentVariable);

-        fieldToLogicalVariableMap.put(fieldName, var);

-        nameToLogicalVariableMap.put(var.toString(), var);

-        variableToType.put(var, type);

-        logicalVariableToFieldMap.put(var, fieldName);

-        return var;

-    }

-

-    @Override

-    public void replaceVariable(LogicalVariable oldVar, LogicalVariable newVar) {

-        String name = this.logicalVariableToFieldMap.get(oldVar);

-        if (name != null) {

-            fieldToLogicalVariableMap.put(name, newVar);

-            nameToLogicalVariableMap.put(newVar.toString(), newVar);

-            nameToLogicalVariableMap.put(oldVar.toString(), newVar);

-            logicalVariableToFieldMap.put(newVar, name);

-        }

-    }

-

-    @Override

-    public IMetadataProvider<PartitionDesc, Object> getMetadataProvider() {

-        return metaData;

-    }

-

-    /**

-     * only get an variable, without rewriting it

-     * 

-     * @param fieldName

-     * @return

-     */

-    private LogicalVariable getVariableOnly(String fieldName) {

-        return fieldToLogicalVariableMap.get(fieldName);

-    }

-

-    private void updateVariable(String fieldName, LogicalVariable variable) {

-        LogicalVariable var = fieldToLogicalVariableMap.get(fieldName);

-        if (var == null) {

-            fieldToLogicalVariableMap.put(fieldName, variable);

-            nameToLogicalVariableMap.put(fieldName, variable);

-        } else if (!var.equals(variable)) {

-            fieldToLogicalVariableMap.put(fieldName, variable);

-            nameToLogicalVariableMap.put(fieldName, variable);

-        }

-    }

-

-    /**

-     * get a list of logical variables from the schema

-     * 

-     * @param schema

-     * @return

-     */

-    @Override

-    public List<LogicalVariable> getVariablesFromSchema(Schema schema) {

-        List<LogicalVariable> variables = new ArrayList<LogicalVariable>();

-        List<String> names = schema.getNames();

-

-        for (String name : names)

-            variables.add(nameToLogicalVariableMap.get(name));

-        return variables;

-    }

-

-    /**

-     * get variable to typeinfo map

-     * 

-     * @return

-     */

-    public HashMap<LogicalVariable, TypeInfo> getVariableContext() {

-        return this.variableToType;

-    }

-

-    /**

-     * get the number of variables s

-     * 

-     * @return

-     */

-    public int getVariableCounter() {

-        return currentVariable + 1;

-    }

-

-    /**

-     * translate from hive operator tree to asterix operator tree

-     * 

-     * @param hive

-     *            roots

-     * @return Algebricks roots

-     */

-    public void translate(List<Operator> hiveRoot, ILogicalOperator parentOperator,

-            HashMap<String, PartitionDesc> aliasToPathMap) throws AlgebricksException {

-        /**

-         * register visitors

-         */

-        visitors.add(new FilterVisitor());

-        visitors.add(new GroupByVisitor());

-        visitors.add(new JoinVisitor());

-        visitors.add(new LateralViewJoinVisitor());

-        visitors.add(new UnionVisitor());

-        visitors.add(new LimitVisitor());

-        visitors.add(new MapJoinVisitor());

-        visitors.add(new ProjectVisitor());

-        visitors.add(new SortVisitor());

-        visitors.add(new ExtractVisitor());

-        visitors.add(new TableScanWriteVisitor(aliasToPathMap));

-

-        List<Mutable<ILogicalOperator>> refList = translate(hiveRoot, new MutableObject<ILogicalOperator>(

-                parentOperator));

-        insertReplicateOperator(refList);

-        if (refList != null)

-            rootOperators.addAll(refList);

-    }

-

-    /**

-     * translate operator DAG

-     * 

-     * @param hiveRoot

-     * @param AlgebricksParentOperator

-     * @return

-     */

-    private List<Mutable<ILogicalOperator>> translate(List<Operator> hiveRoot,

-            Mutable<ILogicalOperator> AlgebricksParentOperator) throws AlgebricksException {

-

-        for (Operator hiveOperator : hiveRoot) {

-            continueTraverse = true;

-            Mutable<ILogicalOperator> currentOperatorRef = null;

-            if (hiveOperator.getType() == OperatorType.FILTER) {

-                FilterOperator fop = (FilterOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.REDUCESINK) {

-                ReduceSinkOperator fop = (ReduceSinkOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.JOIN) {

-                JoinOperator fop = (JoinOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null) {

-                        continueTraverse = true;

-                        break;

-                    } else

-                        continueTraverse = false;

-                }

-                if (currentOperatorRef == null)

-                    return null;

-            } else if (hiveOperator.getType() == OperatorType.LATERALVIEWJOIN) {

-                LateralViewJoinOperator fop = (LateralViewJoinOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-                if (currentOperatorRef == null)

-                    return null;

-            } else if (hiveOperator.getType() == OperatorType.MAPJOIN) {

-                MapJoinOperator fop = (MapJoinOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null) {

-                        continueTraverse = true;

-                        break;

-                    } else

-                        continueTraverse = false;

-                }

-                if (currentOperatorRef == null)

-                    return null;

-            } else if (hiveOperator.getType() == OperatorType.SELECT) {

-                SelectOperator fop = (SelectOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.EXTRACT) {

-                ExtractOperator fop = (ExtractOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.GROUPBY) {

-                GroupByOperator fop = (GroupByOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.TABLESCAN) {

-                TableScanOperator fop = (TableScanOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.FILESINK) {

-                FileSinkOperator fop = (FileSinkOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.LIMIT) {

-                LimitOperator lop = (LimitOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(lop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.UDTF) {

-                UDTFOperator lop = (UDTFOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(lop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null)

-                        break;

-                }

-            } else if (hiveOperator.getType() == OperatorType.UNION) {

-                UnionOperator lop = (UnionOperator) hiveOperator;

-                for (Visitor visitor : visitors) {

-                    currentOperatorRef = visitor.visit(lop, AlgebricksParentOperator, this);

-                    if (currentOperatorRef != null) {

-                        continueTraverse = true;

-                        break;

-                    } else

-                        continueTraverse = false;

-                }

-            } else

-                ;

-            if (hiveOperator.getChildOperators() != null && hiveOperator.getChildOperators().size() > 0

-                    && continueTraverse) {

-                @SuppressWarnings("unchecked")

-                List<Operator> children = hiveOperator.getChildOperators();

-                if (currentOperatorRef == null)

-                    currentOperatorRef = AlgebricksParentOperator;

-                translate(children, currentOperatorRef);

-            }

-            if (hiveOperator.getChildOperators() == null || hiveOperator.getChildOperators().size() == 0)

-                logicalOp.add(currentOperatorRef);

-        }

-        return logicalOp;

-    }

-

-    /**

-     * used in select, group by to get no-column-expression columns

-     * 

-     * @param cols

-     * @return

-     */

-    public ILogicalOperator getAssignOperator(Mutable<ILogicalOperator> parent, List<ExprNodeDesc> cols,

-            ArrayList<LogicalVariable> variables) {

-

-        ArrayList<Mutable<ILogicalExpression>> expressions = new ArrayList<Mutable<ILogicalExpression>>();

-

-        /**

-         * variables to be appended in the assign operator

-         */

-        ArrayList<LogicalVariable> appendedVariables = new ArrayList<LogicalVariable>();

-

-        // one variable can only be assigned once

-        for (ExprNodeDesc hiveExpr : cols) {

-            rewriteExpression(hiveExpr);

-

-            if (hiveExpr instanceof ExprNodeColumnDesc) {

-                ExprNodeColumnDesc desc2 = (ExprNodeColumnDesc) hiveExpr;

-                String fieldName = desc2.getTabAlias() + "." + desc2.getColumn();

-

-                // System.out.println("project expr: " + fieldName);

-

-                if (fieldName.indexOf("$$") < 0) {

-                    LogicalVariable var = getVariable(fieldName, hiveExpr.getTypeInfo());

-                    desc2.setColumn(var.toString());

-                    desc2.setTabAlias("");

-                    variables.add(var);

-                } else {

-                    LogicalVariable var = nameToLogicalVariableMap.get(desc2.getColumn());

-                    String name = this.logicalVariableToFieldMap.get(var);

-                    var = this.getVariableOnly(name);

-                    variables.add(var);

-                }

-            } else {

-                Mutable<ILogicalExpression> asterixExpr = translateScalarFucntion(hiveExpr);

-                expressions.add(asterixExpr);

-                LogicalVariable var = getVariable(hiveExpr.getExprString() + asterixExpr.hashCode(),

-                        hiveExpr.getTypeInfo());

-                variables.add(var);

-                appendedVariables.add(var);

-            }

-        }

-

-        /**

-         * create an assign operator to deal with appending

-         */

-        ILogicalOperator assignOp = null;

-        if (appendedVariables.size() > 0) {

-            assignOp = new AssignOperator(appendedVariables, expressions);

-            assignOp.getInputs().add(parent);

-        }

-        return assignOp;

-    }

-

-    private ILogicalPlan plan;

-

-    public ILogicalPlan genLogicalPlan() {

-        plan = new ALogicalPlanImpl(rootOperators);

-        return plan;

-    }

-

-    public void printOperators() throws AlgebricksException {

-        LogicalOperatorPrettyPrintVisitor pvisitor = new LogicalOperatorPrettyPrintVisitor();

-        StringBuilder buffer = new StringBuilder();

-        PlanPrettyPrinter.printPlan(plan, buffer, pvisitor, 0);

-        outputWriter.println(buffer);

-        outputWriter.println("rewritten variables: ");

-        outputWriter.flush();

-        printVariables();

-

-    }

-

-    public static void setOutputPrinter(PrintWriter writer) {

-        outputWriter = writer;

-    }

-

-    private void printVariables() {

-        Set<Entry<String, LogicalVariable>> entries = fieldToLogicalVariableMap.entrySet();

-

-        for (Entry<String, LogicalVariable> entry : entries) {

-            outputWriter.println(entry.getKey() + " -> " + entry.getValue());

-        }

-        outputWriter.flush();

-    }

-

-    /**

-     * generate the object inspector for the output of an operator

-     * 

-     * @param operator

-     *            The Hive operator

-     * @return an ObjectInspector object

-     */

-    public Schema generateInputSchema(Operator operator) {

-        List<String> variableNames = new ArrayList<String>();

-        List<TypeInfo> typeList = new ArrayList<TypeInfo>();

-        List<ColumnInfo> columns = operator.getSchema().getSignature();

-

-        for (ColumnInfo col : columns) {

-            // typeList.add();

-            TypeInfo type = col.getType();

-            typeList.add(type);

-

-            String fieldName = col.getInternalName();

-            variableNames.add(fieldName);

-        }

-

-        return new Schema(variableNames, typeList);

-    }

-

-    /**

-     * rewrite the names of output columns for feature expression evaluators to

-     * use

-     * 

-     * @param operator

-     */

-    public void rewriteOperatorOutputSchema(Operator operator) {

-        List<ColumnInfo> columns = operator.getSchema().getSignature();

-

-        for (ColumnInfo column : columns) {

-            String columnName = column.getTabAlias() + "." + column.getInternalName();

-            if (columnName.indexOf("$$") < 0) {

-                LogicalVariable var = getVariable(columnName, column.getType());

-                column.setInternalName(var.toString());

-            }

-        }

-    }

-

-    @Override

-    public void rewriteOperatorOutputSchema(List<LogicalVariable> variables, Operator operator) {

-

-        //printOperatorSchema(operator);

-        List<ColumnInfo> columns = operator.getSchema().getSignature();

-        if (variables.size() != columns.size()) {

-            throw new IllegalStateException("output cardinality error " + operator.getName() + " variable size: "

-                    + variables.size() + " expected " + columns.size());

-        }

-

-        for (int i = 0; i < variables.size(); i++) {

-            LogicalVariable var = variables.get(i);

-            ColumnInfo column = columns.get(i);

-            String fieldName = column.getTabAlias() + "." + column.getInternalName();

-            if (fieldName.indexOf("$$") < 0) {

-                updateVariable(fieldName, var);

-                column.setInternalName(var.toString());

-            }

-        }

-        //printOperatorSchema(operator);

-    }

-

-    /**

-     * rewrite an expression and substitute variables

-     * 

-     * @param expr

-     *            hive expression

-     */

-    public void rewriteExpression(ExprNodeDesc expr) {

-        if (expr instanceof ExprNodeColumnDesc) {

-            ExprNodeColumnDesc desc = (ExprNodeColumnDesc) expr;

-            String fieldName = desc.getTabAlias() + "." + desc.getColumn();

-            if (fieldName.indexOf("$$") < 0) {

-                LogicalVariable var = getVariableOnly(fieldName);

-                if (var == null) {

-                    fieldName = "." + desc.getColumn();

-                    var = getVariableOnly(fieldName);

-                    if (var == null) {

-                        fieldName = "null." + desc.getColumn();

-                        var = getVariableOnly(fieldName);

-                        if (var == null) {

-                            throw new IllegalStateException(fieldName + " is wrong!!! ");

-                        }

-                    }

-                }

-                String name = this.logicalVariableToFieldMap.get(var);

-                var = getVariableOnly(name);

-                desc.setColumn(var.toString());

-            }

-        } else {

-            if (expr.getChildren() != null && expr.getChildren().size() > 0) {

-                List<ExprNodeDesc> children = expr.getChildren();

-                for (ExprNodeDesc desc : children)

-                    rewriteExpression(desc);

-            }

-        }

-    }

-

-    /**

-     * rewrite an expression and substitute variables

-     * 

-     * @param expr

-     *            hive expression

-     */

-    public void rewriteExpressionPartial(ExprNodeDesc expr) {

-        if (expr instanceof ExprNodeColumnDesc) {

-            ExprNodeColumnDesc desc = (ExprNodeColumnDesc) expr;

-            String fieldName = desc.getTabAlias() + "." + desc.getColumn();

-            if (fieldName.indexOf("$$") < 0) {

-                LogicalVariable var = getVariableOnly(fieldName);

-                desc.setColumn(var.toString());

-            }

-        } else {

-            if (expr.getChildren() != null && expr.getChildren().size() > 0) {

-                List<ExprNodeDesc> children = expr.getChildren();

-                for (ExprNodeDesc desc : children)

-                    rewriteExpressionPartial(desc);

-            }

-        }

-    }

-

-    // private void printOperatorSchema(Operator operator) {

-    // // System.out.println(operator.getName());

-    // // List<ColumnInfo> columns = operator.getSchema().getSignature();

-    // // for (ColumnInfo column : columns) {

-    // // System.out.print(column.getTabAlias() + "." +

-    // // column.getInternalName() + "  ");

-    // // }

-    // // System.out.println();

-    // }

-

-    /**

-     * translate scalar function expression

-     * 

-     * @param hiveExpr

-     * @return

-     */

-    public Mutable<ILogicalExpression> translateScalarFucntion(ExprNodeDesc hiveExpr) {

-        ILogicalExpression AlgebricksExpr;

-

-        if (hiveExpr instanceof ExprNodeGenericFuncDesc) {

-            List<Mutable<ILogicalExpression>> arguments = new ArrayList<Mutable<ILogicalExpression>>();

-            List<ExprNodeDesc> children = hiveExpr.getChildren();

-

-            for (ExprNodeDesc child : children)

-                arguments.add(translateScalarFucntion(child));

-

-            ExprNodeGenericFuncDesc funcExpr = (ExprNodeGenericFuncDesc) hiveExpr;

-            GenericUDF genericUdf = funcExpr.getGenericUDF();

-            UDF udf = null;

-            if (genericUdf instanceof GenericUDFBridge) {

-                GenericUDFBridge bridge = (GenericUDFBridge) genericUdf;

-                try {

-                    udf = bridge.getUdfClass().newInstance();

-                } catch (Exception e) {

-                    e.printStackTrace();

-                }

-            }

-

-            /**

-             * set up the hive function

-             */

-            Object hiveFunction = genericUdf;

-            if (udf != null)

-                hiveFunction = udf;

-

-            FunctionIdentifier funcId = HiveAlgebricksBuiltInFunctionMap.INSTANCE.getAlgebricksFunctionId(hiveFunction

-                    .getClass());

-            if (funcId == null) {

-                funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, hiveFunction.getClass().getName());

-            }

-

-            Object functionInfo = null;

-            if (genericUdf instanceof GenericUDFBridge) {

-                functionInfo = funcExpr;

-            }

-

-            /**

-             * generate the function call expression

-             */

-            ScalarFunctionCallExpression AlgebricksFuncExpr = new ScalarFunctionCallExpression(new HiveFunctionInfo(

-                    funcId, functionInfo), arguments);

-            AlgebricksExpr = AlgebricksFuncExpr;

-

-        } else if (hiveExpr instanceof ExprNodeColumnDesc) {

-            ExprNodeColumnDesc column = (ExprNodeColumnDesc) hiveExpr;

-            LogicalVariable var = this.getVariable(column.getColumn());

-            AlgebricksExpr = new VariableReferenceExpression(var);

-

-        } else if (hiveExpr instanceof ExprNodeFieldDesc) {

-            FunctionIdentifier funcId;

-            funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, ExpressionConstant.FIELDACCESS);

-

-            ScalarFunctionCallExpression AlgebricksFuncExpr = new ScalarFunctionCallExpression(new HiveFunctionInfo(

-                    funcId, hiveExpr));

-            AlgebricksExpr = AlgebricksFuncExpr;

-        } else if (hiveExpr instanceof ExprNodeConstantDesc) {

-            ExprNodeConstantDesc hiveConst = (ExprNodeConstantDesc) hiveExpr;

-            Object value = hiveConst.getValue();

-            AlgebricksExpr = new ConstantExpression(new HivesterixConstantValue(value));

-        } else if (hiveExpr instanceof ExprNodeNullDesc) {

-            FunctionIdentifier funcId;

-            funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, ExpressionConstant.NULL);

-

-            ScalarFunctionCallExpression AlgebricksFuncExpr = new ScalarFunctionCallExpression(new HiveFunctionInfo(

-                    funcId, hiveExpr));

-

-            AlgebricksExpr = AlgebricksFuncExpr;

-        } else {

-            throw new IllegalStateException("unknown hive expression");

-        }

-        return new MutableObject<ILogicalExpression>(AlgebricksExpr);

-    }

-

-    /**

-     * translate aggregation function expression

-     * 

-     * @param aggregateDesc

-     * @return

-     */

-    public Mutable<ILogicalExpression> translateAggregation(AggregationDesc aggregateDesc) {

-

-        String UDAFName = aggregateDesc.getGenericUDAFName();

-

-        List<Mutable<ILogicalExpression>> arguments = new ArrayList<Mutable<ILogicalExpression>>();

-        List<ExprNodeDesc> children = aggregateDesc.getParameters();

-

-        for (ExprNodeDesc child : children)

-            arguments.add(translateScalarFucntion(child));

-

-        FunctionIdentifier funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, UDAFName + "("

-                + aggregateDesc.getMode() + ")");

-        HiveFunctionInfo funcInfo = new HiveFunctionInfo(funcId, aggregateDesc);

-        AggregateFunctionCallExpression aggregationExpression = new AggregateFunctionCallExpression(funcInfo, false,

-                arguments);

-        return new MutableObject<ILogicalExpression>(aggregationExpression);

-    }

-

-    /**

-     * translate aggregation function expression

-     * 

-     * @param aggregator

-     * @return

-     */

-    public Mutable<ILogicalExpression> translateUnnestFunction(UDTFDesc udtfDesc, Mutable<ILogicalExpression> argument) {

-

-        String UDTFName = udtfDesc.getUDTFName();

-

-        FunctionIdentifier funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, UDTFName);

-        UnnestingFunctionCallExpression unnestingExpression = new UnnestingFunctionCallExpression(new HiveFunctionInfo(

-                funcId, udtfDesc));

-        unnestingExpression.getArguments().add(argument);

-        return new MutableObject<ILogicalExpression>(unnestingExpression);

-    }

-

-    /**

-     * get typeinfo

-     */

-    @Override

-    public TypeInfo getType(LogicalVariable var) {

-        return variableToType.get(var);

-    }

-

-    /**

-     * get variable from variable name

-     */

-    @Override

-    public LogicalVariable getVariable(String name) {

-        return nameToLogicalVariableMap.get(name);

-    }

-

-    @Override

-    public LogicalVariable getVariableFromFieldName(String fieldName) {

-        return this.getVariableOnly(fieldName);

-    }

-

-    /**

-     * set the metadata provider

-     */

-    @Override

-    public void setMetadataProvider(IMetadataProvider<PartitionDesc, Object> metadata) {

-        this.metaData = metadata;

-    }

-

-    /**

-     * insert ReplicateOperator when necessary

-     */

-    private void insertReplicateOperator(List<Mutable<ILogicalOperator>> roots) {

-        Map<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> childToParentsMap = new HashMap<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>>();

-        buildChildToParentsMapping(roots, childToParentsMap);

-        for (Entry<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> entry : childToParentsMap.entrySet()) {

-            List<Mutable<ILogicalOperator>> pList = entry.getValue();

-            if (pList.size() > 1) {

-                ILogicalOperator rop = new ReplicateOperator(pList.size());

-                Mutable<ILogicalOperator> ropRef = new MutableObject<ILogicalOperator>(rop);

-                Mutable<ILogicalOperator> childRef = entry.getKey();

-                rop.getInputs().add(childRef);

-                for (Mutable<ILogicalOperator> parentRef : pList) {

-                    ILogicalOperator parentOp = parentRef.getValue();

-                    int index = parentOp.getInputs().indexOf(childRef);

-                    parentOp.getInputs().set(index, ropRef);

-                }

-            }

-        }

-    }

-

-    /**

-     * build the mapping from child to Parents

-     * 

-     * @param roots

-     * @param childToParentsMap

-     */

-    private void buildChildToParentsMapping(List<Mutable<ILogicalOperator>> roots,

-            Map<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> map) {

-        for (Mutable<ILogicalOperator> opRef : roots) {

-            List<Mutable<ILogicalOperator>> childRefs = opRef.getValue().getInputs();

-            for (Mutable<ILogicalOperator> childRef : childRefs) {

-                List<Mutable<ILogicalOperator>> parentList = map.get(childRef);

-                if (parentList == null) {

-                    parentList = new ArrayList<Mutable<ILogicalOperator>>();

-                    map.put(childRef, parentList);

-                }

-                if (!parentList.contains(opRef))

-                    parentList.add(opRef);

-            }

-            buildChildToParentsMapping(childRefs, map);

-        }

-    }

-}

+package edu.uci.ics.hivesterix.logical.plan;
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hadoop.hive.ql.exec.ColumnInfo;
+import org.apache.hadoop.hive.ql.exec.ExtractOperator;
+import org.apache.hadoop.hive.ql.exec.FileSinkOperator;
+import org.apache.hadoop.hive.ql.exec.FilterOperator;
+import org.apache.hadoop.hive.ql.exec.GroupByOperator;
+import org.apache.hadoop.hive.ql.exec.JoinOperator;
+import org.apache.hadoop.hive.ql.exec.LateralViewJoinOperator;
+import org.apache.hadoop.hive.ql.exec.LimitOperator;
+import org.apache.hadoop.hive.ql.exec.MapJoinOperator;
+import org.apache.hadoop.hive.ql.exec.Operator;
+import org.apache.hadoop.hive.ql.exec.ReduceSinkOperator;
+import org.apache.hadoop.hive.ql.exec.SelectOperator;
+import org.apache.hadoop.hive.ql.exec.TableScanOperator;
+import org.apache.hadoop.hive.ql.exec.UDF;
+import org.apache.hadoop.hive.ql.exec.UDTFOperator;
+import org.apache.hadoop.hive.ql.exec.UnionOperator;
+import org.apache.hadoop.hive.ql.plan.AggregationDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeFieldDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeNullDesc;
+import org.apache.hadoop.hive.ql.plan.PartitionDesc;
+import org.apache.hadoop.hive.ql.plan.UDTFDesc;
+import org.apache.hadoop.hive.ql.plan.api.OperatorType;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
+
+import edu.uci.ics.hivesterix.logical.expression.ExpressionConstant;
+import edu.uci.ics.hivesterix.logical.expression.HiveAlgebricksBuiltInFunctionMap;
+import edu.uci.ics.hivesterix.logical.expression.HiveFunctionInfo;
+import edu.uci.ics.hivesterix.logical.expression.HivesterixConstantValue;
+import edu.uci.ics.hivesterix.logical.plan.visitor.ExtractVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.FilterVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.GroupByVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.JoinVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.LateralViewJoinVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.LimitVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.MapJoinVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.ProjectVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.SortVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.TableScanWriteVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.UnionVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.Visitor;
+import edu.uci.ics.hivesterix.runtime.jobgen.Schema;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
+import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.LogicalOperatorPrettyPrintVisitor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.PlanPrettyPrinter;
+
+@SuppressWarnings("rawtypes")
+public class HiveAlgebricksTranslator implements Translator {
+
+    private int currentVariable = 0;
+
+    private List<Mutable<ILogicalOperator>> logicalOp = new ArrayList<Mutable<ILogicalOperator>>();
+
+    private boolean continueTraverse = true;
+
+    private IMetadataProvider<PartitionDesc, Object> metaData;
+
+    /**
+     * map variable name to the logical variable
+     */
+    private HashMap<String, LogicalVariable> nameToLogicalVariableMap = new HashMap<String, LogicalVariable>();
+
+    /**
+     * map field name to LogicalVariable
+     */
+    private HashMap<String, LogicalVariable> fieldToLogicalVariableMap = new HashMap<String, LogicalVariable>();
+
+    /**
+     * map logical variable to name
+     */
+    private HashMap<LogicalVariable, String> logicalVariableToFieldMap = new HashMap<LogicalVariable, String>();
+
+    /**
+     * asterix root operators
+     */
+    private List<Mutable<ILogicalOperator>> rootOperators = new ArrayList<Mutable<ILogicalOperator>>();
+
+    /**
+     * a list of visitors
+     */
+    private List<Visitor> visitors = new ArrayList<Visitor>();
+
+    /**
+     * output writer to print things out
+     */
+    private static PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(System.out));
+
+    /**
+     * map a logical variable to type info
+     */
+    private HashMap<LogicalVariable, TypeInfo> variableToType = new HashMap<LogicalVariable, TypeInfo>();
+
+    @Override
+    public LogicalVariable getVariable(String fieldName, TypeInfo type) {
+        LogicalVariable var = fieldToLogicalVariableMap.get(fieldName);
+        if (var == null) {
+            currentVariable++;
+            var = new LogicalVariable(currentVariable);
+            fieldToLogicalVariableMap.put(fieldName, var);
+            nameToLogicalVariableMap.put(var.toString(), var);
+            variableToType.put(var, type);
+            logicalVariableToFieldMap.put(var, fieldName);
+        }
+        return var;
+    }
+
+    @Override
+    public LogicalVariable getNewVariable(String fieldName, TypeInfo type) {
+        currentVariable++;
+        LogicalVariable var = new LogicalVariable(currentVariable);
+        fieldToLogicalVariableMap.put(fieldName, var);
+        nameToLogicalVariableMap.put(var.toString(), var);
+        variableToType.put(var, type);
+        logicalVariableToFieldMap.put(var, fieldName);
+        return var;
+    }
+
+    @Override
+    public void replaceVariable(LogicalVariable oldVar, LogicalVariable newVar) {
+        String name = this.logicalVariableToFieldMap.get(oldVar);
+        if (name != null) {
+            fieldToLogicalVariableMap.put(name, newVar);
+            nameToLogicalVariableMap.put(newVar.toString(), newVar);
+            nameToLogicalVariableMap.put(oldVar.toString(), newVar);
+            logicalVariableToFieldMap.put(newVar, name);
+        }
+    }
+
+    @Override
+    public IMetadataProvider<PartitionDesc, Object> getMetadataProvider() {
+        return metaData;
+    }
+
+    /**
+     * only get an variable, without rewriting it
+     * 
+     * @param fieldName
+     * @return
+     */
+    private LogicalVariable getVariableOnly(String fieldName) {
+        return fieldToLogicalVariableMap.get(fieldName);
+    }
+
+    public void updateVariable(String fieldName, LogicalVariable variable) {
+        LogicalVariable var = fieldToLogicalVariableMap.get(fieldName);
+        if (var == null) {
+            fieldToLogicalVariableMap.put(fieldName, variable);
+            nameToLogicalVariableMap.put(fieldName, variable);
+        } else if (!var.equals(variable)) {
+            fieldToLogicalVariableMap.put(fieldName, variable);
+            nameToLogicalVariableMap.put(fieldName, variable);
+        }
+    }
+
+    /**
+     * get a list of logical variables from the schema
+     * 
+     * @param schema
+     * @return
+     */
+    @Override
+    public List<LogicalVariable> getVariablesFromSchema(Schema schema) {
+        List<LogicalVariable> variables = new ArrayList<LogicalVariable>();
+        List<String> names = schema.getNames();
+
+        for (String name : names)
+            variables.add(nameToLogicalVariableMap.get(name));
+        return variables;
+    }
+
+    /**
+     * get variable to typeinfo map
+     * 
+     * @return
+     */
+    public HashMap<LogicalVariable, TypeInfo> getVariableContext() {
+        return this.variableToType;
+    }
+
+    /**
+     * get the number of variables s
+     * 
+     * @return
+     */
+    public int getVariableCounter() {
+        return currentVariable + 1;
+    }
+
+    /**
+     * translate from hive operator tree to asterix operator tree
+     * 
+     * @param hive
+     *            roots
+     * @return Algebricks roots
+     */
+    public void translate(List<Operator> hiveRoot, ILogicalOperator parentOperator,
+            HashMap<String, PartitionDesc> aliasToPathMap) throws AlgebricksException {
+        /**
+         * register visitors
+         */
+        visitors.add(new FilterVisitor());
+        visitors.add(new GroupByVisitor());
+        visitors.add(new JoinVisitor());
+        visitors.add(new LateralViewJoinVisitor());
+        visitors.add(new UnionVisitor());
+        visitors.add(new LimitVisitor());
+        visitors.add(new MapJoinVisitor());
+        visitors.add(new ProjectVisitor());
+        visitors.add(new SortVisitor());
+        visitors.add(new ExtractVisitor());
+        visitors.add(new TableScanWriteVisitor(aliasToPathMap));
+
+        List<Mutable<ILogicalOperator>> refList = translate(hiveRoot, new MutableObject<ILogicalOperator>(
+                parentOperator));
+        insertReplicateOperator(refList);
+        if (refList != null)
+            rootOperators.addAll(refList);
+    }
+
+    /**
+     * translate operator DAG
+     * 
+     * @param hiveRoot
+     * @param AlgebricksParentOperator
+     * @return
+     */
+    private List<Mutable<ILogicalOperator>> translate(List<Operator> hiveRoot,
+            Mutable<ILogicalOperator> AlgebricksParentOperator) throws AlgebricksException {
+
+        for (Operator hiveOperator : hiveRoot) {
+            continueTraverse = true;
+            Mutable<ILogicalOperator> currentOperatorRef = null;
+            if (hiveOperator.getType() == OperatorType.FILTER) {
+                FilterOperator fop = (FilterOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.REDUCESINK) {
+                ReduceSinkOperator fop = (ReduceSinkOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.JOIN) {
+                JoinOperator fop = (JoinOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null) {
+                        continueTraverse = true;
+                        break;
+                    } else
+                        continueTraverse = false;
+                }
+                if (currentOperatorRef == null)
+                    return null;
+            } else if (hiveOperator.getType() == OperatorType.LATERALVIEWJOIN) {
+                LateralViewJoinOperator fop = (LateralViewJoinOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+                if (currentOperatorRef == null)
+                    return null;
+            } else if (hiveOperator.getType() == OperatorType.MAPJOIN) {
+                MapJoinOperator fop = (MapJoinOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null) {
+                        continueTraverse = true;
+                        break;
+                    } else
+                        continueTraverse = false;
+                }
+                if (currentOperatorRef == null)
+                    return null;
+            } else if (hiveOperator.getType() == OperatorType.SELECT) {
+                SelectOperator fop = (SelectOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.EXTRACT) {
+                ExtractOperator fop = (ExtractOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.GROUPBY) {
+                GroupByOperator fop = (GroupByOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.TABLESCAN) {
+                TableScanOperator fop = (TableScanOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.FILESINK) {
+                FileSinkOperator fop = (FileSinkOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(fop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.LIMIT) {
+                LimitOperator lop = (LimitOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(lop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.UDTF) {
+                UDTFOperator lop = (UDTFOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(lop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null)
+                        break;
+                }
+            } else if (hiveOperator.getType() == OperatorType.UNION) {
+                UnionOperator lop = (UnionOperator) hiveOperator;
+                for (Visitor visitor : visitors) {
+                    currentOperatorRef = visitor.visit(lop, AlgebricksParentOperator, this);
+                    if (currentOperatorRef != null) {
+                        continueTraverse = true;
+                        break;
+                    } else
+                        continueTraverse = false;
+                }
+            } else
+                ;
+            if (hiveOperator.getChildOperators() != null && hiveOperator.getChildOperators().size() > 0
+                    && continueTraverse) {
+                @SuppressWarnings("unchecked")
+                List<Operator> children = hiveOperator.getChildOperators();
+                if (currentOperatorRef == null)
+                    currentOperatorRef = AlgebricksParentOperator;
+                translate(children, currentOperatorRef);
+            }
+            if (hiveOperator.getChildOperators() == null || hiveOperator.getChildOperators().size() == 0)
+                logicalOp.add(currentOperatorRef);
+        }
+        return logicalOp;
+    }
+
+    /**
+     * used in select, group by to get no-column-expression columns
+     * 
+     * @param cols
+     * @return
+     */
+    public ILogicalOperator getAssignOperator(Mutable<ILogicalOperator> parent, List<ExprNodeDesc> cols,
+            ArrayList<LogicalVariable> variables) {
+
+        ArrayList<Mutable<ILogicalExpression>> expressions = new ArrayList<Mutable<ILogicalExpression>>();
+
+        /**
+         * variables to be appended in the assign operator
+         */
+        ArrayList<LogicalVariable> appendedVariables = new ArrayList<LogicalVariable>();
+
+        // one variable can only be assigned once
+        for (ExprNodeDesc hiveExpr : cols) {
+            rewriteExpression(hiveExpr);
+
+            if (hiveExpr instanceof ExprNodeColumnDesc) {
+                ExprNodeColumnDesc desc2 = (ExprNodeColumnDesc) hiveExpr;
+                String fieldName = desc2.getTabAlias() + "." + desc2.getColumn();
+
+                // System.out.println("project expr: " + fieldName);
+
+                if (fieldName.indexOf("$$") < 0) {
+                    LogicalVariable var = getVariable(fieldName, hiveExpr.getTypeInfo());
+                    desc2.setColumn(var.toString());
+                    desc2.setTabAlias("");
+                    variables.add(var);
+                } else {
+                    LogicalVariable var = nameToLogicalVariableMap.get(desc2.getColumn());
+                    String name = this.logicalVariableToFieldMap.get(var);
+                    var = this.getVariableOnly(name);
+                    variables.add(var);
+                }
+            } else {
+                Mutable<ILogicalExpression> asterixExpr = translateScalarFucntion(hiveExpr);
+                expressions.add(asterixExpr);
+                LogicalVariable var = getVariable(hiveExpr.getExprString() + asterixExpr.hashCode(),
+                        hiveExpr.getTypeInfo());
+                variables.add(var);
+                appendedVariables.add(var);
+            }
+        }
+
+        /**
+         * create an assign operator to deal with appending
+         */
+        ILogicalOperator assignOp = null;
+        if (appendedVariables.size() > 0) {
+            assignOp = new AssignOperator(appendedVariables, expressions);
+            assignOp.getInputs().add(parent);
+        }
+        return assignOp;
+    }
+
+    private ILogicalPlan plan;
+
+    public ILogicalPlan genLogicalPlan() {
+        plan = new ALogicalPlanImpl(rootOperators);
+        return plan;
+    }
+
+    public void printOperators() throws AlgebricksException {
+        LogicalOperatorPrettyPrintVisitor pvisitor = new LogicalOperatorPrettyPrintVisitor();
+        StringBuilder buffer = new StringBuilder();
+        PlanPrettyPrinter.printPlan(plan, buffer, pvisitor, 0);
+        outputWriter.println(buffer);
+        outputWriter.println("rewritten variables: ");
+        outputWriter.flush();
+        printVariables();
+
+    }
+
+    public static void setOutputPrinter(PrintWriter writer) {
+        outputWriter = writer;
+    }
+
+    private void printVariables() {
+        Set<Entry<String, LogicalVariable>> entries = fieldToLogicalVariableMap.entrySet();
+
+        for (Entry<String, LogicalVariable> entry : entries) {
+            outputWriter.println(entry.getKey() + " -> " + entry.getValue());
+        }
+        outputWriter.flush();
+    }
+
+    /**
+     * generate the object inspector for the output of an operator
+     * 
+     * @param operator
+     *            The Hive operator
+     * @return an ObjectInspector object
+     */
+    public Schema generateInputSchema(Operator operator) {
+        List<String> variableNames = new ArrayList<String>();
+        List<TypeInfo> typeList = new ArrayList<TypeInfo>();
+        List<ColumnInfo> columns = operator.getSchema().getSignature();
+
+        for (ColumnInfo col : columns) {
+            // typeList.add();
+            TypeInfo type = col.getType();
+            typeList.add(type);
+
+            String fieldName = col.getInternalName();
+            variableNames.add(fieldName);
+        }
+
+        return new Schema(variableNames, typeList);
+    }
+
+    /**
+     * rewrite the names of output columns for feature expression evaluators to
+     * use
+     * 
+     * @param operator
+     */
+    public void rewriteOperatorOutputSchema(Operator operator) {
+        List<ColumnInfo> columns = operator.getSchema().getSignature();
+        for (ColumnInfo column : columns) {
+            String columnName = column.getTabAlias() + "." + column.getInternalName();
+            if (columnName.indexOf("$$") < 0) {
+                LogicalVariable var = getVariable(columnName, column.getType());
+                column.setInternalName(var.toString());
+            }
+        }
+    }
+
+    @Override
+    public void rewriteOperatorOutputSchema(List<LogicalVariable> variables, Operator operator) {
+        // printOperatorSchema(operator);
+        List<ColumnInfo> columns = operator.getSchema().getSignature();
+        // if (variables.size() != columns.size()) {
+        // throw new IllegalStateException("output cardinality error " +
+        // operator.getName() + " variable size: "
+        // + variables.size() + " expected " + columns.size());
+        // }
+        for (int i = 0; i < variables.size(); i++) {
+            LogicalVariable var = variables.get(i);
+            ColumnInfo column = columns.get(i);
+            String fieldName = column.getTabAlias() + "." + column.getInternalName();
+            if (fieldName.indexOf("$$") < 0) {
+                updateVariable(fieldName, var);
+                column.setInternalName(var.toString());
+            }
+        }
+
+        // printOperatorSchema(operator);
+    }
+
+    /**
+     * rewrite an expression and substitute variables
+     * 
+     * @param expr
+     *            hive expression
+     */
+    public void rewriteExpression(ExprNodeDesc expr) {
+        if (expr instanceof ExprNodeColumnDesc) {
+            ExprNodeColumnDesc desc = (ExprNodeColumnDesc) expr;
+            String fieldName = desc.getTabAlias() + "." + desc.getColumn();
+            if (fieldName.indexOf("$$") < 0) {
+                LogicalVariable var = getVariableOnly(fieldName);
+                if (var == null) {
+                    fieldName = "." + desc.getColumn();
+                    var = getVariableOnly(fieldName);
+                    if (var == null) {
+                        fieldName = "null." + desc.getColumn();
+                        var = getVariableOnly(fieldName);
+                        if (var == null) {
+                            throw new IllegalStateException(fieldName + " is wrong!!! ");
+                        }
+                    }
+                }
+                String name = this.logicalVariableToFieldMap.get(var);
+                var = getVariableOnly(name);
+                desc.setColumn(var.toString());
+            }
+        } else {
+            if (expr.getChildren() != null && expr.getChildren().size() > 0) {
+                List<ExprNodeDesc> children = expr.getChildren();
+                for (ExprNodeDesc desc : children)
+                    rewriteExpression(desc);
+            }
+        }
+    }
+
+    /**
+     * rewrite an expression and substitute variables
+     * 
+     * @param expr
+     *            hive expression
+     */
+    public void rewriteExpressionPartial(ExprNodeDesc expr) {
+        if (expr instanceof ExprNodeColumnDesc) {
+            ExprNodeColumnDesc desc = (ExprNodeColumnDesc) expr;
+            String fieldName = desc.getTabAlias() + "." + desc.getColumn();
+            if (fieldName.indexOf("$$") < 0) {
+                LogicalVariable var = getVariableOnly(fieldName);
+                desc.setColumn(var.toString());
+            }
+        } else {
+            if (expr.getChildren() != null && expr.getChildren().size() > 0) {
+                List<ExprNodeDesc> children = expr.getChildren();
+                for (ExprNodeDesc desc : children)
+                    rewriteExpressionPartial(desc);
+            }
+        }
+    }
+
+    // private void printOperatorSchema(Operator operator) {
+    // // System.out.println(operator.getName());
+    // // List<ColumnInfo> columns = operator.getSchema().getSignature();
+    // // for (ColumnInfo column : columns) {
+    // // System.out.print(column.getTabAlias() + "." +
+    // // column.getInternalName() + "  ");
+    // // }
+    // // System.out.println();
+    // }
+
+    /**
+     * translate scalar function expression
+     * 
+     * @param hiveExpr
+     * @return
+     */
+    public Mutable<ILogicalExpression> translateScalarFucntion(ExprNodeDesc hiveExpr) {
+        ILogicalExpression AlgebricksExpr;
+
+        if (hiveExpr instanceof ExprNodeGenericFuncDesc) {
+            List<Mutable<ILogicalExpression>> arguments = new ArrayList<Mutable<ILogicalExpression>>();
+            List<ExprNodeDesc> children = hiveExpr.getChildren();
+
+            for (ExprNodeDesc child : children)
+                arguments.add(translateScalarFucntion(child));
+
+            ExprNodeGenericFuncDesc funcExpr = (ExprNodeGenericFuncDesc) hiveExpr;
+            GenericUDF genericUdf = funcExpr.getGenericUDF();
+            UDF udf = null;
+            if (genericUdf instanceof GenericUDFBridge) {
+                GenericUDFBridge bridge = (GenericUDFBridge) genericUdf;
+                try {
+                    udf = bridge.getUdfClass().newInstance();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+            /**
+             * set up the hive function
+             */
+            Object hiveFunction = genericUdf;
+            if (udf != null)
+                hiveFunction = udf;
+
+            FunctionIdentifier funcId = HiveAlgebricksBuiltInFunctionMap.INSTANCE.getAlgebricksFunctionId(hiveFunction
+                    .getClass());
+            if (funcId == null) {
+                funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, hiveFunction.getClass().getName());
+            }
+
+            Object functionInfo = null;
+            if (genericUdf instanceof GenericUDFBridge) {
+                functionInfo = funcExpr;
+            }
+
+            /**
+             * generate the function call expression
+             */
+            ScalarFunctionCallExpression AlgebricksFuncExpr = new ScalarFunctionCallExpression(new HiveFunctionInfo(
+                    funcId, functionInfo), arguments);
+            AlgebricksExpr = AlgebricksFuncExpr;
+
+        } else if (hiveExpr instanceof ExprNodeColumnDesc) {
+            ExprNodeColumnDesc column = (ExprNodeColumnDesc) hiveExpr;
+            LogicalVariable var = this.getVariable(column.getColumn());
+            AlgebricksExpr = new VariableReferenceExpression(var);
+
+        } else if (hiveExpr instanceof ExprNodeFieldDesc) {
+            FunctionIdentifier funcId;
+            funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, ExpressionConstant.FIELDACCESS);
+
+            ScalarFunctionCallExpression AlgebricksFuncExpr = new ScalarFunctionCallExpression(new HiveFunctionInfo(
+                    funcId, hiveExpr));
+            AlgebricksExpr = AlgebricksFuncExpr;
+        } else if (hiveExpr instanceof ExprNodeConstantDesc) {
+            ExprNodeConstantDesc hiveConst = (ExprNodeConstantDesc) hiveExpr;
+            Object value = hiveConst.getValue();
+            AlgebricksExpr = new ConstantExpression(new HivesterixConstantValue(value));
+        } else if (hiveExpr instanceof ExprNodeNullDesc) {
+            FunctionIdentifier funcId;
+            funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, ExpressionConstant.NULL);
+
+            ScalarFunctionCallExpression AlgebricksFuncExpr = new ScalarFunctionCallExpression(new HiveFunctionInfo(
+                    funcId, hiveExpr));
+
+            AlgebricksExpr = AlgebricksFuncExpr;
+        } else {
+            throw new IllegalStateException("unknown hive expression");
+        }
+        return new MutableObject<ILogicalExpression>(AlgebricksExpr);
+    }
+
+    /**
+     * translate aggregation function expression
+     * 
+     * @param aggregateDesc
+     * @return
+     */
+    public Mutable<ILogicalExpression> translateAggregation(AggregationDesc aggregateDesc) {
+
+        String UDAFName = aggregateDesc.getGenericUDAFName();
+
+        List<Mutable<ILogicalExpression>> arguments = new ArrayList<Mutable<ILogicalExpression>>();
+        List<ExprNodeDesc> children = aggregateDesc.getParameters();
+
+        for (ExprNodeDesc child : children)
+            arguments.add(translateScalarFucntion(child));
+
+        FunctionIdentifier funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, UDAFName + "("
+                + aggregateDesc.getMode() + ")");
+        HiveFunctionInfo funcInfo = new HiveFunctionInfo(funcId, aggregateDesc);
+        AggregateFunctionCallExpression aggregationExpression = new AggregateFunctionCallExpression(funcInfo, false,
+                arguments);
+        return new MutableObject<ILogicalExpression>(aggregationExpression);
+    }
+
+    /**
+     * translate aggregation function expression
+     * 
+     * @param aggregator
+     * @return
+     */
+    public Mutable<ILogicalExpression> translateUnnestFunction(UDTFDesc udtfDesc, Mutable<ILogicalExpression> argument) {
+
+        String UDTFName = udtfDesc.getUDTFName();
+
+        FunctionIdentifier funcId = new FunctionIdentifier(ExpressionConstant.NAMESPACE, UDTFName);
+        UnnestingFunctionCallExpression unnestingExpression = new UnnestingFunctionCallExpression(new HiveFunctionInfo(
+                funcId, udtfDesc));
+        unnestingExpression.getArguments().add(argument);
+        return new MutableObject<ILogicalExpression>(unnestingExpression);
+    }
+
+    /**
+     * get typeinfo
+     */
+    @Override
+    public TypeInfo getType(LogicalVariable var) {
+        return variableToType.get(var);
+    }
+
+    /**
+     * get variable from variable name
+     */
+    @Override
+    public LogicalVariable getVariable(String name) {
+        return nameToLogicalVariableMap.get(name);
+    }
+
+    @Override
+    public LogicalVariable getVariableFromFieldName(String fieldName) {
+        return this.getVariableOnly(fieldName);
+    }
+
+    /**
+     * set the metadata provider
+     */
+    @Override
+    public void setMetadataProvider(IMetadataProvider<PartitionDesc, Object> metadata) {
+        this.metaData = metadata;
+    }
+
+    /**
+     * insert ReplicateOperator when necessary
+     */
+    private void insertReplicateOperator(List<Mutable<ILogicalOperator>> roots) {
+        Map<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> childToParentsMap = new HashMap<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>>();
+        buildChildToParentsMapping(roots, childToParentsMap);
+        for (Entry<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> entry : childToParentsMap.entrySet()) {
+            List<Mutable<ILogicalOperator>> pList = entry.getValue();
+            if (pList.size() > 1) {
+                ILogicalOperator rop = new ReplicateOperator(pList.size());
+                Mutable<ILogicalOperator> ropRef = new MutableObject<ILogicalOperator>(rop);
+                Mutable<ILogicalOperator> childRef = entry.getKey();
+                rop.getInputs().add(childRef);
+                for (Mutable<ILogicalOperator> parentRef : pList) {
+                    ILogicalOperator parentOp = parentRef.getValue();
+                    int index = parentOp.getInputs().indexOf(childRef);
+                    parentOp.getInputs().set(index, ropRef);
+                }
+            }
+        }
+    }
+
+    /**
+     * build the mapping from child to Parents
+     * 
+     * @param roots
+     * @param childToParentsMap
+     */
+    private void buildChildToParentsMapping(List<Mutable<ILogicalOperator>> roots,
+            Map<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> map) {
+        for (Mutable<ILogicalOperator> opRef : roots) {
+            List<Mutable<ILogicalOperator>> childRefs = opRef.getValue().getInputs();
+            for (Mutable<ILogicalOperator> childRef : childRefs) {
+                List<Mutable<ILogicalOperator>> parentList = map.get(childRef);
+                if (parentList == null) {
+                    parentList = new ArrayList<Mutable<ILogicalOperator>>();
+                    map.put(childRef, parentList);
+                }
+                if (!parentList.contains(opRef))
+                    parentList.add(opRef);
+            }
+            buildChildToParentsMapping(childRefs, map);
+        }
+    }
+}
diff --git a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/LateralViewJoinVisitor.java b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/LateralViewJoinVisitor.java
index f4161a4..aa1837c 100644
--- a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/LateralViewJoinVisitor.java
+++ b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/LateralViewJoinVisitor.java
@@ -12,113 +12,145 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package edu.uci.ics.hivesterix.logical.plan.visitor;

-

-import java.util.ArrayList;

-import java.util.List;

-

-import org.apache.commons.lang3.mutable.Mutable;

-import org.apache.commons.lang3.mutable.MutableObject;

-import org.apache.hadoop.hive.ql.exec.LateralViewJoinOperator;

-import org.apache.hadoop.hive.ql.exec.Operator;

-import org.apache.hadoop.hive.ql.exec.UDTFOperator;

-import org.apache.hadoop.hive.ql.plan.UDTFDesc;

-import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;

-

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.DefaultVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;

-import edu.uci.ics.hivesterix.runtime.jobgen.Schema;

-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;

-

-/**

- * The lateral view join operator is used for FROM src LATERAL VIEW udtf()...

- * This operator was implemented with the following operator DAG in mind.

- * For a query such as

- * SELECT pageid, adid.* FROM example_table LATERAL VIEW explode(adid_list) AS

- * adid

- * The top of the operator DAG will look similar to

- * [Table Scan] | [Lateral View Forward] / \ [Select](*) [Select](adid_list) | |

- * | [UDTF] (explode) \ / [Lateral View Join] | | [Select] (pageid, adid.*) |

- * ....

- * Rows from the table scan operator are first to a lateral view forward

- * operator that just forwards the row and marks the start of a LV. The select

- * operator on the left picks all the columns while the select operator on the

- * right picks only the columns needed by the UDTF.

- * The output of select in the left branch and output of the UDTF in the right

- * branch are then sent to the lateral view join (LVJ). In most cases, the UDTF

- * will generate > 1 row for every row received from the TS, while the left

- * select operator will generate only one. For each row output from the TS, the

- * LVJ outputs all possible rows that can be created by joining the row from the

- * left select and one of the rows output from the UDTF.

- * Additional lateral views can be supported by adding a similar DAG after the

- * previous LVJ operator.

- */

-

-@SuppressWarnings("rawtypes")

-public class LateralViewJoinVisitor extends DefaultVisitor {

-

-    private UDTFDesc udtf;

-

-    private List<Mutable<ILogicalOperator>> parents = new ArrayList<Mutable<ILogicalOperator>>();

-

-    @Override

-    public Mutable<ILogicalOperator> visit(LateralViewJoinOperator operator,

-            Mutable<ILogicalOperator> AlgebricksParentOperatorRef, Translator t) throws AlgebricksException {

-

-        parents.add(AlgebricksParentOperatorRef);

-        if (operator.getParentOperators().size() > parents.size()) {

-            return null;

-        }

-

-        Operator parent0 = operator.getParentOperators().get(0);

-        ILogicalOperator parentOperator;

-        ILogicalExpression unnestArg;

-        if (parent0 instanceof UDTFOperator) {

-            List<LogicalVariable> unnestVars = new ArrayList<LogicalVariable>();

-            VariableUtilities.getLiveVariables(parents.get(1).getValue(), unnestVars);

-            unnestArg = new VariableReferenceExpression(unnestVars.get(0));

-            parentOperator = parents.get(1).getValue();

-        } else {

-            List<LogicalVariable> unnestVars = new ArrayList<LogicalVariable>();

-            VariableUtilities.getLiveVariables(parents.get(0).getValue(), unnestVars);

-            unnestArg = new VariableReferenceExpression(unnestVars.get(0));

-            parentOperator = parents.get(0).getValue();

-        }

-

-        LogicalVariable var = t.getVariable(udtf.toString(), TypeInfoFactory.unknownTypeInfo);

-

-        Mutable<ILogicalExpression> unnestExpr = t.translateUnnestFunction(udtf, new MutableObject<ILogicalExpression>(

-                unnestArg));

-        ILogicalOperator currentOperator = new UnnestOperator(var, unnestExpr);

-

-        List<LogicalVariable> outputVars = new ArrayList<LogicalVariable>();

-        VariableUtilities.getLiveVariables(parentOperator, outputVars);

-        outputVars.add(var);

-        currentOperator.getInputs().add(new MutableObject<ILogicalOperator>(parentOperator));

-

-        parents.clear();

-        udtf = null;

-        t.rewriteOperatorOutputSchema(outputVars, operator);

-        return new MutableObject<ILogicalOperator>(currentOperator);

-    }

-

-    @Override

-    public Mutable<ILogicalOperator> visit(UDTFOperator operator,

-            Mutable<ILogicalOperator> AlgebricksParentOperatorRef, Translator t) {

-        Schema currentSchema = t.generateInputSchema(operator.getParentOperators().get(0));

-        udtf = (UDTFDesc) operator.getConf();

-

-        // populate the schema from upstream operator

-        operator.setSchema(operator.getParentOperators().get(0).getSchema());

-        List<LogicalVariable> latestOutputSchema = t.getVariablesFromSchema(currentSchema);

-        t.rewriteOperatorOutputSchema(latestOutputSchema, operator);

-        return null;

-    }

-

-}

+package edu.uci.ics.hivesterix.logical.plan.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hadoop.hive.ql.exec.ColumnInfo;
+import org.apache.hadoop.hive.ql.exec.LateralViewJoinOperator;
+import org.apache.hadoop.hive.ql.exec.Operator;
+import org.apache.hadoop.hive.ql.exec.UDTFOperator;
+import org.apache.hadoop.hive.ql.plan.LateralViewJoinDesc;
+import org.apache.hadoop.hive.ql.plan.UDTFDesc;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.DefaultVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;
+import edu.uci.ics.hivesterix.runtime.jobgen.Schema;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+
+/**
+ * The lateral view join operator is used for FROM src LATERAL VIEW udtf()...
+ * This operator was implemented with the following operator DAG in mind.
+ * For a query such as
+ * SELECT pageid, adid.* FROM example_table LATERAL VIEW explode(adid_list) AS
+ * adid
+ * The top of the operator DAG will look similar to
+ * [Table Scan] | [Lateral View Forward] / \ [Select](*) [Select](adid_list) | |
+ * | [UDTF] (explode) \ / [Lateral View Join] | | [Select] (pageid, adid.*) |
+ * ....
+ * Rows from the table scan operator are first to a lateral view forward
+ * operator that just forwards the row and marks the start of a LV. The select
+ * operator on the left picks all the columns while the select operator on the
+ * right picks only the columns needed by the UDTF.
+ * The output of select in the left branch and output of the UDTF in the right
+ * branch are then sent to the lateral view join (LVJ). In most cases, the UDTF
+ * will generate > 1 row for every row received from the TS, while the left
+ * select operator will generate only one. For each row output from the TS, the
+ * LVJ outputs all possible rows that can be created by joining the row from the
+ * left select and one of the rows output from the UDTF.
+ * Additional lateral views can be supported by adding a similar DAG after the
+ * previous LVJ operator.
+ */
+
+@SuppressWarnings("rawtypes")
+public class LateralViewJoinVisitor extends DefaultVisitor {
+
+    private UDTFDesc udtf;
+
+    private List<Mutable<ILogicalOperator>> parents = new ArrayList<Mutable<ILogicalOperator>>();
+
+    @Override
+    public Mutable<ILogicalOperator> visit(LateralViewJoinOperator operator,
+            Mutable<ILogicalOperator> AlgebricksParentOperatorRef, Translator t) throws AlgebricksException {
+
+        parents.add(AlgebricksParentOperatorRef);
+        if (operator.getParentOperators().size() > parents.size()) {
+            return null;
+        }
+
+        ILogicalOperator parentOperator = null;
+        ILogicalExpression unnestArg = null;
+        List<LogicalVariable> projectVariables = new ArrayList<LogicalVariable>();
+        for (Mutable<ILogicalOperator> parentLOpRef : parents) {
+            VariableUtilities.getLiveVariables(parentLOpRef.getValue(), projectVariables);
+        }
+        for (Operator parentOp : operator.getParentOperators()) {
+            if (parentOp instanceof UDTFOperator) {
+                int index = operator.getParentOperators().indexOf(parentOp);
+                List<LogicalVariable> unnestVars = new ArrayList<LogicalVariable>();
+                VariableUtilities.getLiveVariables(parents.get(index).getValue(), unnestVars);
+                unnestArg = new VariableReferenceExpression(unnestVars.get(0));
+                parentOperator = parents.get(index).getValue();
+            }
+        }
+
+        LogicalVariable var = t.getVariable(udtf.toString(), TypeInfoFactory.unknownTypeInfo);
+        Mutable<ILogicalExpression> unnestExpr = t.translateUnnestFunction(udtf, new MutableObject<ILogicalExpression>(
+                unnestArg));
+        ILogicalOperator currentOperator = new UnnestOperator(var, unnestExpr);
+
+        List<LogicalVariable> outputVars = new ArrayList<LogicalVariable>();
+        VariableUtilities.getLiveVariables(parents.get(0).getValue(), outputVars);
+        outputVars.add(var);
+        ILogicalOperator inputProjectOperator = new ProjectOperator(projectVariables);
+        currentOperator.getInputs().add(new MutableObject<ILogicalOperator>(inputProjectOperator));
+        inputProjectOperator.getInputs().addAll(parentOperator.getInputs());
+
+        parents.clear();
+        udtf = null;
+        List<ColumnInfo> inputSchema = operator.getSchema().getSignature();
+        rewriteOperatorDesc(outputVars, operator.getConf(), inputSchema, t);
+        //t.rewriteOperatorOutputSchema(outputVars, operator);
+        return new MutableObject<ILogicalOperator>(currentOperator);
+    }
+
+    @Override
+    public Mutable<ILogicalOperator> visit(UDTFOperator operator,
+            Mutable<ILogicalOperator> AlgebricksParentOperatorRef, Translator t) {
+        Schema currentSchema = t.generateInputSchema(operator.getParentOperators().get(0));
+        udtf = (UDTFDesc) operator.getConf();
+
+        // populate the schema from upstream operator
+        operator.setSchema(operator.getParentOperators().get(0).getSchema());
+        List<LogicalVariable> latestOutputSchema = t.getVariablesFromSchema(currentSchema);
+        t.rewriteOperatorOutputSchema(latestOutputSchema, operator);
+        return null;
+    }
+
+    private void rewriteOperatorDesc(List<LogicalVariable> variables, LateralViewJoinDesc desc,
+            List<ColumnInfo> schema, Translator t) {
+        List<String> outputFieldNames = desc.getOutputInternalColNames();
+        for (int i = 0; i < variables.size(); i++) {
+            LogicalVariable var = variables.get(i);
+            String fieldName = outputFieldNames.get(i);
+            String tabAlias = findTabAlias(fieldName, schema);
+            fieldName = tabAlias + "." + fieldName;
+            if (fieldName.indexOf("$$") < 0) {
+                //outputFieldNames.set(i, var.toString());
+                t.updateVariable(fieldName, var);
+            }
+        }
+    }
+
+    private String findTabAlias(String fieldName, List<ColumnInfo> schema) {
+        for (int i = 0; i < schema.size(); i++) {
+            ColumnInfo column = schema.get(i);
+            if (column.getInternalName().equals(fieldName)) {
+                return column.getTabAlias();
+            }
+        }
+        return "null";
+    }
+
+}
diff --git a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/MapJoinVisitor.java b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/MapJoinVisitor.java
index 186b291..3ed9786 100644
--- a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/MapJoinVisitor.java
+++ b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/MapJoinVisitor.java
@@ -14,36 +14,36 @@
  */
 package edu.uci.ics.hivesterix.logical.plan.visitor;

 

-import java.io.Serializable;

-import java.util.ArrayList;

-import java.util.HashMap;

-import java.util.Iterator;

-import java.util.List;

-import java.util.Map;

-import java.util.Map.Entry;

-import java.util.Set;

-

-import org.apache.commons.lang3.mutable.Mutable;

-import org.apache.commons.lang3.mutable.MutableObject;

-import org.apache.hadoop.hive.ql.exec.ColumnInfo;

-import org.apache.hadoop.hive.ql.exec.MapJoinOperator;

-import org.apache.hadoop.hive.ql.exec.Operator;

-import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;

-import org.apache.hadoop.hive.ql.plan.MapJoinDesc;

-import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPAnd;

-import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqual;

-import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;

-import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;

-

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.DefaultVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;

+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hadoop.hive.ql.exec.ColumnInfo;
+import org.apache.hadoop.hive.ql.exec.MapJoinOperator;
+import org.apache.hadoop.hive.ql.exec.Operator;
+import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
+import org.apache.hadoop.hive.ql.plan.MapJoinDesc;
+import org.apache.hadoop.hive.ql.plan.OperatorDesc;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPAnd;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqual;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.DefaultVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
 

 @SuppressWarnings("rawtypes")

 public class MapJoinVisitor extends DefaultVisitor {

@@ -56,7 +56,7 @@
     @Override

     public Mutable<ILogicalOperator> visit(MapJoinOperator operator,

             Mutable<ILogicalOperator> AlgebricksParentOperatorRef, Translator t) {

-        List<Operator<? extends Serializable>> joinSrc = operator.getParentOperators();

+        List<Operator<? extends OperatorDesc>> joinSrc = operator.getParentOperators();

         List<Mutable<ILogicalOperator>> parents = opMap.get(operator);

         if (parents == null) {

             parents = new ArrayList<Mutable<ILogicalOperator>>();

diff --git a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/TableScanWriteVisitor.java b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/TableScanWriteVisitor.java
index 74cebaa..25abdec 100644
--- a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/TableScanWriteVisitor.java
+++ b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/TableScanWriteVisitor.java
@@ -69,9 +69,9 @@
 

     @Override

     public Mutable<ILogicalOperator> visit(TableScanOperator operator,

-            Mutable<ILogicalOperator> AlgebricksParentOperator, Translator t) throws AlgebricksException {

+            Mutable<ILogicalOperator> AlgebricksParentOperator, Translator t) throws AlgebricksException {    	

         TableScanDesc desc = (TableScanDesc) operator.getConf();

-        if (desc == null) {

+        if (desc == null || desc.getAlias()==null) {

             List<LogicalVariable> schema = new ArrayList<LogicalVariable>();

             VariableUtilities.getLiveVariables(AlgebricksParentOperator.getValue(), schema);

             t.rewriteOperatorOutputSchema(schema, operator);

@@ -124,7 +124,6 @@
     @Override

     public Mutable<ILogicalOperator> visit(FileSinkOperator hiveOperator,

             Mutable<ILogicalOperator> AlgebricksParentOperator, Translator t) {

-

         if (hiveOperator.getChildOperators() != null && hiveOperator.getChildOperators().size() > 0)

             return null;

 

diff --git a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/UnionVisitor.java b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/UnionVisitor.java
index 1cb5121..c710f3f 100644
--- a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/UnionVisitor.java
+++ b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/UnionVisitor.java
@@ -14,21 +14,21 @@
  */
 package edu.uci.ics.hivesterix.logical.plan.visitor;

 

-import java.util.ArrayList;

-import java.util.List;

-

-import org.apache.commons.lang3.mutable.Mutable;

-import org.apache.commons.lang3.mutable.MutableObject;

-import org.apache.hadoop.hive.ql.exec.UnionOperator;

-import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;

-

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.DefaultVisitor;

-import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;

-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;

-import edu.uci.ics.hyracks.algebricks.common.utils.Triple;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;

+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hadoop.hive.ql.exec.UnionOperator;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.DefaultVisitor;
+import edu.uci.ics.hivesterix.logical.plan.visitor.base.Translator;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
 

 public class UnionVisitor extends DefaultVisitor {

 

@@ -46,8 +46,8 @@
         List<LogicalVariable> leftVars = new ArrayList<LogicalVariable>();

         List<LogicalVariable> rightVars = new ArrayList<LogicalVariable>();

 

-        VariableUtilities.getUsedVariables(parents.get(0).getValue(), leftVars);

-        VariableUtilities.getUsedVariables(parents.get(1).getValue(), rightVars);

+        VariableUtilities.getLiveVariables(parents.get(0).getValue(), leftVars);

+        VariableUtilities.getLiveVariables(parents.get(1).getValue(), rightVars);

 

         List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> triples = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>();

         List<LogicalVariable> unionVars = new ArrayList<LogicalVariable>();

diff --git a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/base/Translator.java b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/base/Translator.java
index 32b0f66..5b6ac50 100644
--- a/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/base/Translator.java
+++ b/hivesterix/hivesterix-translator/src/main/java/edu/uci/ics/hivesterix/logical/plan/visitor/base/Translator.java
@@ -12,173 +12,181 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package edu.uci.ics.hivesterix.logical.plan.visitor.base;

-

-import java.util.ArrayList;

-import java.util.List;

-

-import org.apache.commons.lang3.mutable.Mutable;

-import org.apache.hadoop.hive.ql.exec.Operator;

-import org.apache.hadoop.hive.ql.plan.AggregationDesc;

-import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;

-import org.apache.hadoop.hive.ql.plan.PartitionDesc;

-import org.apache.hadoop.hive.ql.plan.UDTFDesc;

-import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;

-

-import edu.uci.ics.hivesterix.runtime.jobgen.Schema;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

-import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;

-

-@SuppressWarnings("rawtypes")

-public interface Translator {

-

-    /**

-     * generate input schema

-     * 

-     * @param operator

-     * @return

-     */

-    public Schema generateInputSchema(Operator operator);

-

-    /**

-     * rewrite the names of output columns for feture expression evaluators to

-     * use

-     * 

-     * @param operator

-     */

-    public void rewriteOperatorOutputSchema(List<LogicalVariable> vars, Operator operator);

-

-    /**

-     * rewrite the names of output columns for feture expression evaluators to

-     * use

-     * 

-     * @param operator

-     */

-    public void rewriteOperatorOutputSchema(Operator operator);

-

-    /**

-     * rewrite an expression and substitute variables

-     * 

-     * @param expr

-     *            hive expression

-     */

-    public void rewriteExpression(ExprNodeDesc expr);

-

-    /**

-     * rewrite an expression and substitute variables

-     * 

-     * @param expr

-     *            hive expression

-     */

-    public void rewriteExpressionPartial(ExprNodeDesc expr);

-

-    /**

-     * get an assign operator as a child of parent

-     * 

-     * @param parent

-     * @param cols

-     * @param variables

-     * @return

-     */

-    public ILogicalOperator getAssignOperator(Mutable<ILogicalOperator> parent, List<ExprNodeDesc> cols,

-            ArrayList<LogicalVariable> variables);

-

-    /**

-     * get type for a logical variable

-     * 

-     * @param var

-     * @return type info

-     */

-    public TypeInfo getType(LogicalVariable var);

-

-    /**

-     * translate an expression from hive to Algebricks

-     * 

-     * @param desc

-     * @return

-     */

-    public Mutable<ILogicalExpression> translateScalarFucntion(ExprNodeDesc desc);

-

-    /**

-     * translate an aggregation from hive to Algebricks

-     * 

-     * @param aggregateDesc

-     * @return

-     */

-    public Mutable<ILogicalExpression> translateAggregation(AggregationDesc aggregateDesc);

-

-    /**

-     * translate unnesting (UDTF) function expression

-     * 

-     * @param aggregator

-     * @return

-     */

-    public Mutable<ILogicalExpression> translateUnnestFunction(UDTFDesc udtfDesc, Mutable<ILogicalExpression> argument);

-

-    /**

-     * get variable from a schema

-     * 

-     * @param schema

-     * @return

-     */

-    public List<LogicalVariable> getVariablesFromSchema(Schema schema);

-

-    /**

-     * get variable from name

-     * 

-     * @param name

-     * @return

-     */

-    public LogicalVariable getVariable(String name);

-

-    /**

-     * get variable from field name

-     * 

-     * @param name

-     * @return

-     */

-    public LogicalVariable getVariableFromFieldName(String name);

-

-    /**

-     * get variable from name, type

-     * 

-     * @param fieldName

-     * @param type

-     * @return

-     */

-    public LogicalVariable getVariable(String fieldName, TypeInfo type);

-

-    /**

-     * get new variable from name, type

-     * 

-     * @param fieldName

-     * @param type

-     * @return

-     */

-    public LogicalVariable getNewVariable(String fieldName, TypeInfo type);

-

-    /**

-     * set the metadata provider

-     * 

-     * @param metadata

-     */

-    public void setMetadataProvider(IMetadataProvider<PartitionDesc, Object> metadata);

-

-    /**

-     * get the metadata provider

-     * 

-     * @param metadata

-     */

-    public IMetadataProvider<PartitionDesc, Object> getMetadataProvider();

-

-    /**

-     * replace the variable

-     * 

-     * @param oldVar

-     * @param newVar

-     */

-    public void replaceVariable(LogicalVariable oldVar, LogicalVariable newVar);

-

-}

+package edu.uci.ics.hivesterix.logical.plan.visitor.base;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hadoop.hive.ql.exec.Operator;
+import org.apache.hadoop.hive.ql.plan.AggregationDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.ql.plan.PartitionDesc;
+import org.apache.hadoop.hive.ql.plan.UDTFDesc;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
+
+import edu.uci.ics.hivesterix.runtime.jobgen.Schema;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+@SuppressWarnings("rawtypes")
+public interface Translator {
+
+    /**
+     * generate input schema
+     * 
+     * @param operator
+     * @return
+     */
+    public Schema generateInputSchema(Operator operator);
+
+    /**
+     * rewrite the names of output columns for feture expression evaluators to
+     * use
+     * 
+     * @param operator
+     */
+    public void rewriteOperatorOutputSchema(List<LogicalVariable> vars, Operator operator);
+
+    /**
+     * rewrite the names of output columns for feture expression evaluators to
+     * use
+     * 
+     * @param operator
+     */
+    public void rewriteOperatorOutputSchema(Operator operator);
+
+    /**
+     * rewrite an expression and substitute variables
+     * 
+     * @param expr
+     *            hive expression
+     */
+    public void rewriteExpression(ExprNodeDesc expr);
+
+    /**
+     * rewrite an expression and substitute variables
+     * 
+     * @param expr
+     *            hive expression
+     */
+    public void rewriteExpressionPartial(ExprNodeDesc expr);
+
+    /**
+     * get an assign operator as a child of parent
+     * 
+     * @param parent
+     * @param cols
+     * @param variables
+     * @return
+     */
+    public ILogicalOperator getAssignOperator(Mutable<ILogicalOperator> parent, List<ExprNodeDesc> cols,
+            ArrayList<LogicalVariable> variables);
+
+    /**
+     * get type for a logical variable
+     * 
+     * @param var
+     * @return type info
+     */
+    public TypeInfo getType(LogicalVariable var);
+
+    /**
+     * translate an expression from hive to Algebricks
+     * 
+     * @param desc
+     * @return
+     */
+    public Mutable<ILogicalExpression> translateScalarFucntion(ExprNodeDesc desc);
+
+    /**
+     * translate an aggregation from hive to Algebricks
+     * 
+     * @param aggregateDesc
+     * @return
+     */
+    public Mutable<ILogicalExpression> translateAggregation(AggregationDesc aggregateDesc);
+
+    /**
+     * translate unnesting (UDTF) function expression
+     * 
+     * @param aggregator
+     * @return
+     */
+    public Mutable<ILogicalExpression> translateUnnestFunction(UDTFDesc udtfDesc, Mutable<ILogicalExpression> argument);
+
+    /**
+     * get variable from a schema
+     * 
+     * @param schema
+     * @return
+     */
+    public List<LogicalVariable> getVariablesFromSchema(Schema schema);
+
+    /**
+     * get variable from name
+     * 
+     * @param name
+     * @return
+     */
+    public LogicalVariable getVariable(String name);
+
+    /**
+     * get variable from field name
+     * 
+     * @param name
+     * @return
+     */
+    public LogicalVariable getVariableFromFieldName(String name);
+
+    /**
+     * get variable from name, type
+     * 
+     * @param fieldName
+     * @param type
+     * @return
+     */
+    public LogicalVariable getVariable(String fieldName, TypeInfo type);
+
+    /**
+     * get new variable from name, type
+     * 
+     * @param fieldName
+     * @param type
+     * @return
+     */
+    public LogicalVariable getNewVariable(String fieldName, TypeInfo type);
+
+    /**
+     * update a name-variable binding
+     * 
+     * @param fieldName
+     * @param variable
+     */
+    public void updateVariable(String fieldName, LogicalVariable variable);
+
+    /**
+     * set the metadata provider
+     * 
+     * @param metadata
+     */
+    public void setMetadataProvider(IMetadataProvider<PartitionDesc, Object> metadata);
+
+    /**
+     * get the metadata provider
+     * 
+     * @param metadata
+     */
+    public IMetadataProvider<PartitionDesc, Object> getMetadataProvider();
+
+    /**
+     * replace the variable
+     * 
+     * @param oldVar
+     * @param newVar
+     */
+    public void replaceVariable(LogicalVariable oldVar, LogicalVariable newVar);
+
+}