Improved the variable inlining rule and also some error messages.

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_inline_vars@776 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java
index 302d0d7..64574cd 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java
@@ -248,6 +248,9 @@
                 }
             }
         }
+        if (modified) {
+            context.computeAndSetTypeEnvironmentForOperator(op);
+        }
         return new Pair<Boolean, Boolean>(modified, ecChange);
     }
 
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixProperInlineVariablesRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixProperInlineVariablesRule.java
index 579752a..5503b8b 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixProperInlineVariablesRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixProperInlineVariablesRule.java
@@ -25,7 +25,6 @@
 
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
 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.IOptimizationContext;
@@ -34,7 +33,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 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.operators.logical.AbstractLogicalOperator;
@@ -139,14 +137,18 @@
             case PROJECT:
             // We can currently only order/group by a variable reference expression.
             case ORDER:
-            case GROUP:
-            case DISTINCT:
-            case AGGREGATE:
             case INNERJOIN:
             case LEFTOUTERJOIN: {
                 break;
             }
+            // Remove non-live vars here.
+            case GROUP:
+            case DISTINCT:
+            case AGGREGATE: {
+                break;
+            }
             default: {
+                inlineVisitor.setOperator(op);
                 if (op.acceptExpressionTransform(inlineVisitor)) {
                     modified = true;
                 }
@@ -162,8 +164,12 @@
     }
 
     private class InlineVariablesVisitor implements ILogicalExpressionReferenceTransform {
-        private IOptimizationContext context;
+        
         private final Map<LogicalVariable, ILogicalExpression> varAssignRhs;
+        private final Set<LogicalVariable> liveVars = new HashSet<LogicalVariable>();
+        private final List<LogicalVariable> rhsUsedVars = new ArrayList<LogicalVariable>();        
+        private ILogicalOperator op;
+        private IOptimizationContext context;
         
         public InlineVariablesVisitor(Map<LogicalVariable, ILogicalExpression> varAssignRhs) {
             this.varAssignRhs = varAssignRhs;
@@ -173,12 +179,17 @@
             this.context = context;
         }
 
+        public void setOperator(ILogicalOperator op) throws AlgebricksException {
+            this.op = op;
+            liveVars.clear();
+        }
+        
         @Override
-        public boolean transform(Mutable<ILogicalExpression> exprRef) {
+        public boolean transform(Mutable<ILogicalExpression> exprRef) throws AlgebricksException {            
             ILogicalExpression e = exprRef.getValue();
             switch (((AbstractLogicalExpression) e).getExpressionTag()) {
                 case VARIABLE: {
-                    // look for a required substitution
+                    // Make sure has not been excluded from inlining.
                     LogicalVariable var = ((VariableReferenceExpression) e).getVariableReference();
                     if (context.shouldNotBeInlined(var)) {
                         return false;
@@ -188,6 +199,18 @@
                         // Variable was not produced by an assign.
                         return false;
                     }
+                    // Make sure used variables from rhs are live.
+                    if (liveVars.isEmpty()) {
+                        VariableUtilities.getLiveVariables(op, liveVars);
+                    }
+                    rhsUsedVars.clear();
+                    rhs.getUsedVariables(rhsUsedVars);
+                    for (LogicalVariable rhsUsedVar : rhsUsedVars) {
+                        if (!liveVars.contains(rhsUsedVar)) {
+                            return false;
+                        }
+                    }
+                    
                     // Replace variable reference with rhs expr.
                     exprRef.setValue(rhs);
                     
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java
index dc00fe1..c121ff6 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java
@@ -142,7 +142,11 @@
         @Override
         public ClosedDataInfo visitVariableReferenceExpression(VariableReferenceExpression expr, Void arg)
                 throws AlgebricksException {
-            boolean dataIsClosed = isClosedRec((IAType) env.getVarType(expr.getVariableReference()));
+            Object varType = env.getVarType(expr.getVariableReference());
+            if (varType == null) {
+                throw new AlgebricksException("Could not infer type for variable '" + expr.getVariableReference() + "'.");
+            }
+            boolean dataIsClosed = isClosedRec((IAType) varType);
             return new ClosedDataInfo(false, dataIsClosed, expr);
         }