Merge branch 'master' into jarodwen/hotfix/issue425
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java
index bee8c40..48d3f27 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PushAggFuncIntoStandaloneAggregateRule.java
@@ -33,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.AggregateFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 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;
@@ -43,7 +42,7 @@
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
 /**
- * Pushes aggregate functions into a stand alone aggregate operator (no group by). 
+ * Pushes aggregate functions into a stand alone aggregate operator (no group by).
  */
 public class PushAggFuncIntoStandaloneAggregateRule implements IAlgebraicRewriteRule {
 
@@ -60,6 +59,7 @@
         if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
             return false;
         }
+
         Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
         AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
@@ -71,7 +71,7 @@
         if (op3.getOperatorTag() == LogicalOperatorTag.GROUP) {
             return false;
         }
-        
+
         AssignOperator assignOp = (AssignOperator) op;
         AggregateOperator aggOp = (AggregateOperator) op2;
         if (aggOp.getVariables().size() != 1) {
@@ -87,56 +87,73 @@
         if (origAggFuncExpr.getFunctionIdentifier() != AsterixBuiltinFunctions.LISTIFY) {
             return false;
         }
-        
+
         LogicalVariable aggVar = aggOp.getVariables().get(0);
         List<LogicalVariable> used = new LinkedList<LogicalVariable>();
         VariableUtilities.getUsedVariables(assignOp, used);
         if (!used.contains(aggVar)) {
             return false;
         }
-        
-        Mutable<ILogicalExpression> srcAssignExprRef = fingAggFuncExprRef(assignOp.getExpressions(), aggVar);
-        if (srcAssignExprRef == null) {
-        	return false;
+
+        List<Mutable<ILogicalExpression>> srcAssignExprRefs = new LinkedList<Mutable<ILogicalExpression>>();
+        fingAggFuncExprRef(assignOp.getExpressions(), aggVar, srcAssignExprRefs);
+        if (srcAssignExprRefs.isEmpty()) {
+            return false;
         }
-        AbstractFunctionCallExpression assignFuncExpr = (AbstractFunctionCallExpression) srcAssignExprRef.getValue();
-        FunctionIdentifier aggFuncIdent = AsterixBuiltinFunctions.getAggregateFunction(assignFuncExpr.getFunctionIdentifier());
-        
-        // Push the agg func into the agg op.                
-        AbstractFunctionCallExpression aggOpExpr = (AbstractFunctionCallExpression) aggOp.getExpressions().get(0).getValue();
-        List<Mutable<ILogicalExpression>> aggArgs = new ArrayList<Mutable<ILogicalExpression>>();
-        aggArgs.add(aggOpExpr.getArguments().get(0));
-        AggregateFunctionCallExpression aggFuncExpr = AsterixBuiltinFunctions.makeAggregateFunctionExpression(aggFuncIdent, aggArgs);
-        aggOp.getExpressions().get(0).setValue(aggFuncExpr);
-        
-        // The assign now just "renames" the variable to make sure the upstream plan still works.
-        srcAssignExprRef.setValue(new VariableReferenceExpression(aggVar));
-        
+
+        AbstractFunctionCallExpression aggOpExpr = (AbstractFunctionCallExpression) aggOp.getExpressions().get(0)
+                .getValue();
+        aggOp.getExpressions().clear();
+        aggOp.getVariables().clear();
+
+        for (Mutable<ILogicalExpression> srcAssignExprRef : srcAssignExprRefs) {
+            AbstractFunctionCallExpression assignFuncExpr = (AbstractFunctionCallExpression) srcAssignExprRef
+                    .getValue();
+            FunctionIdentifier aggFuncIdent = AsterixBuiltinFunctions.getAggregateFunction(assignFuncExpr
+                    .getFunctionIdentifier());
+
+            // Push the agg func into the agg op.                
+
+            List<Mutable<ILogicalExpression>> aggArgs = new ArrayList<Mutable<ILogicalExpression>>();
+            aggArgs.add(aggOpExpr.getArguments().get(0));
+            AggregateFunctionCallExpression aggFuncExpr = AsterixBuiltinFunctions.makeAggregateFunctionExpression(
+                    aggFuncIdent, aggArgs);
+            LogicalVariable newVar = context.newVar();
+            aggOp.getVariables().add(newVar);
+            aggOp.getExpressions().add(new MutableObject<ILogicalExpression>(aggFuncExpr));
+
+            // The assign now just "renames" the variable to make sure the upstream plan still works.
+            srcAssignExprRef.setValue(new VariableReferenceExpression(newVar));
+        }
+
         context.computeAndSetTypeEnvironmentForOperator(aggOp);
         context.computeAndSetTypeEnvironmentForOperator(assignOp);
-        
+
         return true;
     }
-    
-    private Mutable<ILogicalExpression> fingAggFuncExprRef(List<Mutable<ILogicalExpression>> exprRefs, LogicalVariable aggVar) {
-    	for (Mutable<ILogicalExpression> exprRef : exprRefs) {
+
+    private void fingAggFuncExprRef(List<Mutable<ILogicalExpression>> exprRefs, LogicalVariable aggVar,
+            List<Mutable<ILogicalExpression>> srcAssignExprRefs) {
+        for (Mutable<ILogicalExpression> exprRef : exprRefs) {
             ILogicalExpression expr = exprRef.getValue();
             if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
                 continue;
             }
             AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-            FunctionIdentifier funcIdent = AsterixBuiltinFunctions.getAggregateFunction(funcExpr.getFunctionIdentifier());
+            FunctionIdentifier funcIdent = AsterixBuiltinFunctions.getAggregateFunction(funcExpr
+                    .getFunctionIdentifier());
             if (funcIdent == null) {
-            	// Recursively look in func args.
-            	return fingAggFuncExprRef(funcExpr.getArguments(), aggVar);
+                // Recursively look in func args.
+                fingAggFuncExprRef(funcExpr.getArguments(), aggVar, srcAssignExprRefs);
+
+            } else {
+                // Check if this is the expr that uses aggVar.
+                Collection<LogicalVariable> usedVars = new HashSet<LogicalVariable>();
+                funcExpr.getUsedVariables(usedVars);
+                if (usedVars.contains(aggVar)) {
+                    srcAssignExprRefs.add(exprRef);
+                }
             }
-            // Check if this is the expr that uses aggVar.
-            Collection<LogicalVariable> usedVars = new HashSet<LogicalVariable>();
-            funcExpr.getUsedVariables(usedVars);
-            if (usedVars.contains(aggVar)) {
-            	return exprRef;
-            }
-    	}
-    	return null;
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.1.ddl.aql
new file mode 100644
index 0000000..84bd013
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.1.ddl.aql
@@ -0,0 +1,5 @@
+/*
+* Description  : Run aggregates over both ordered list and unordered list with only null items.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.2.update.aql
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.2.update.aql
@@ -0,0 +1 @@
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.3.query.aql
new file mode 100644
index 0000000..72e70b3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null/agg_null.3.query.aql
@@ -0,0 +1,9 @@
+/*
+* Description  : Run aggregates over both ordered list and unordered list with only null items.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+let $l1 := [null]
+let $l2 := {{null, null}}
+return { "count1": count($l1), "average1": avg($l1), "sum1": sum($l1), "min1": min($l1), "max1": max($l1), "count2": count($l2), "average2": avg($l2), "sum2": sum($l2), "min2": min($l2), "max2": max($l2) } 
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.1.ddl.aql
new file mode 100644
index 0000000..da8a4a2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.1.ddl.aql
@@ -0,0 +1,16 @@
+/*
+* Description  : Run aggregates over records, with only null items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type TestType as open {
+  id: int32,
+  val: double
+}
+
+create dataset Test(TestType) primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.2.update.aql
new file mode 100644
index 0000000..4e0db2b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.2.update.aql
@@ -0,0 +1,11 @@
+/*
+* Description  : Run aggregates over records, with only null items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+use dataverse test;
+
+insert into dataset Test ({"id": 0, "val": 4.32, "valplus": 473847});
+insert into dataset Test ({"id": 1, "val": 5.32});
+insert into dataset Test ({"id": 2, "val": 6.32, "valplus": 38473827484738239});
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.3.query.aql
new file mode 100644
index 0000000..bdab44e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec/agg_null_rec.3.query.aql
@@ -0,0 +1,10 @@
+/*
+* Description  : Run aggregates over records, with only null items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+use dataverse test;
+
+let $l := for $t in dataset Test return $t.valplus
+return { "count": count($l), "average": avg($l), "sum": sum($l), "min": min($l), "max": max($l) }  
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.1.ddl.aql
new file mode 100644
index 0000000..da8a4a2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.1.ddl.aql
@@ -0,0 +1,16 @@
+/*
+* Description  : Run aggregates over records, with only null items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type TestType as open {
+  id: int32,
+  val: double
+}
+
+create dataset Test(TestType) primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.2.update.aql
new file mode 100644
index 0000000..4e0db2b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.2.update.aql
@@ -0,0 +1,11 @@
+/*
+* Description  : Run aggregates over records, with only null items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+use dataverse test;
+
+insert into dataset Test ({"id": 0, "val": 4.32, "valplus": 473847});
+insert into dataset Test ({"id": 1, "val": 5.32});
+insert into dataset Test ({"id": 2, "val": 6.32, "valplus": 38473827484738239});
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.3.query.aql
new file mode 100644
index 0000000..ab0560a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_null_rec_1/agg_null_rec_1.3.query.aql
@@ -0,0 +1,12 @@
+/*
+* Description  : Run aggregates over records, with only null items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+use dataverse test;
+
+let $l := for $t in dataset Test return $t
+return { "count": count($l), "average": avg(for $i in $l return $i.val), "sum":
+sum(for $i in $l return $i.val), "min": min(for $i in $l return $i.valplus),
+"max": max(for $i in $l return $i.valplus) }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.1.ddl.aql
new file mode 100644
index 0000000..343be89
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.1.ddl.aql
@@ -0,0 +1,6 @@
+/*
+* Description  : Run aggregates over an ordered list with numbers of different types
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.2.update.aql
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.2.update.aql
@@ -0,0 +1 @@
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.3.query.aql
new file mode 100644
index 0000000..3e9c1ae
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number/agg_number.3.query.aql
@@ -0,0 +1,15 @@
+/*
+* Description  : Run aggregates over an ordered list with numbers of different types
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+let $l1 := [float("2.0"), double("3.0"), 93847382783847382, 1]
+let $l2 := {{float("2.0"), double("3.0"), 93847382783847382, 1}}
+let $a1 := count($l2)
+let $a2 := avg($l2)
+let $a3 := sum($l2)
+let $a4 := min($l2)
+let $a5 := max($l2)
+return { "count1": count($l1), "average1": avg($l1), "sum1": sum($l1), "min1": min($l1), "max1": max($l1), "count2": $a1, "average2": $a2, "sum2": $a3, "min2": $a4, "max2": $a5 }
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.1.ddl.aql
new file mode 100644
index 0000000..3b6f853a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.1.ddl.aql
@@ -0,0 +1,16 @@
+/*
+* Description  : Run aggregates over records, with different numeric typed items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type TestType as open {
+  id: int32,
+  val: double
+}
+
+create dataset Test(TestType) primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.2.update.aql
new file mode 100644
index 0000000..86aeb85
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.2.update.aql
@@ -0,0 +1,11 @@
+/*
+* Description  : Run aggregates over records, with different numeric typed items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+use dataverse test;
+
+insert into dataset Test ({"id": 0, "val": 4.32, "valplus": 2});
+insert into dataset Test ({"id": 1, "val": 5.32, "valplus": 32.98});
+insert into dataset Test ({"id": 2, "val": 6.32, "valplus": 38473827484738239});
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.3.query.aql
new file mode 100644
index 0000000..256be92
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/agg_number_rec/agg_number_rec.3.query.aql
@@ -0,0 +1,10 @@
+/*
+* Description  : Run aggregates over records, with different numeric typed items for the aggregating fields.
+* Expected Res : Success
+* Date         : Jun 2nd 2013
+*/
+
+use dataverse test;
+
+let $l := for $t in dataset Test return $t.valplus
+return { "count": count($l), "average": avg($l), "sum": sum($l), "min": min($l), "max": max($l) }  
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.1.ddl.aql
new file mode 100644
index 0000000..9270281
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.1.ddl.aql
@@ -0,0 +1,5 @@
+/*
+* Description  : Run avg over an ordered list with mixed types
+* Expected Res : Failure
+* Date         : Jun 2nd 2013
+*/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.2.update.aql
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.2.update.aql
@@ -0,0 +1 @@
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.3.query.aql
new file mode 100644
index 0000000..05d42c2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/avg_mixed/avg_mixed.3.query.aql
@@ -0,0 +1,11 @@
+/*
+* Description  : Run avg over an ordered list with mixed types
+* Expected Res : Failure
+* Date         : Jun 2nd 2013
+*/
+
+avg(
+ for $x in [float("2.0"), "hello world", 93847382783847382, date("2013-01-01")]
+ return $x
+)
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.1.ddl.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.1.ddl.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.2.update.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.2.update.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.3.query.aql
new file mode 100644
index 0000000..6714628
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.3.query.aql
@@ -0,0 +1,2 @@
+let $l := [23, 748374857483]
+return min($l)
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.1.ddl.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.1.ddl.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.2.update.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.2.update.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.3.query.aql
new file mode 100644
index 0000000..b67542d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.3.query.aql
@@ -0,0 +1,2 @@
+let $l := [748374857483, 23, 0.5]
+return min($l)
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.ddl.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.ddl.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.2.update.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.2.update.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.3.query.aql
new file mode 100644
index 0000000..69b7057
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.3.query.aql
@@ -0,0 +1,2 @@
+let $l := [23, 748374857483]
+return sum($l)
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.1.ddl.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.1.ddl.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.2.update.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.2.update.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.3.query.aql
new file mode 100644
index 0000000..308f6f4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.3.query.aql
@@ -0,0 +1,2 @@
+let $l := [748374857483, 23, 0.5]
+return sum($l)
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.1.ddl.aql
new file mode 100644
index 0000000..b6ea924
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.1.ddl.aql
@@ -0,0 +1,5 @@
+/*
+* Description  : Run min over an ordered list with mixed types
+* Expected Res : Failure
+* Date         : Jun 2nd 2013
+*/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.2.update.aql
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.2.update.aql
@@ -0,0 +1 @@
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.3.query.aql
new file mode 100644
index 0000000..f66d3c2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/min_mixed/min_mixed.3.query.aql
@@ -0,0 +1,11 @@
+/*
+* Description  : Run min over an ordered list with mixed types
+* Expected Res : Failure
+* Date         : Jun 2nd 2013
+*/
+
+min(
+ for $x in [float("2.0"), "hello world", 93847382783847382, date("2013-01-01")]
+ return $x
+)
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.1.ddl.aql
new file mode 100644
index 0000000..8e691a3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.1.ddl.aql
@@ -0,0 +1,5 @@
+/*
+* Description  : Run sum over an ordered list with mixed types
+* Expected Res : Failure
+* Date         : Jun 2nd 2013
+*/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.2.update.aql
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.2.update.aql
@@ -0,0 +1 @@
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.3.query.aql
new file mode 100644
index 0000000..7b4e530
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/sum_mixed/sum_mixed.3.query.aql
@@ -0,0 +1,11 @@
+/*
+* Description  : Run sum over an ordered list with mixed types
+* Expected Res : Failure
+* Date         : Jun 2nd 2013
+*/
+
+sum(
+ for $x in [float("2.0"), "hello world", 93847382783847382, date("2013-01-01")]
+ return $x
+)
+
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null/agg_null.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null/agg_null.1.adm
new file mode 100644
index 0000000..62ba20b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null/agg_null.1.adm
@@ -0,0 +1 @@
+{ "count1": 1i64, "average1": null, "sum1": null, "min1": null, "max1": null, "count2": 2i64, "average2": null, "sum2": null, "min2": null, "max2": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null_rec/agg_null_rec.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null_rec/agg_null_rec.1.adm
new file mode 100644
index 0000000..96e82eb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null_rec/agg_null_rec.1.adm
@@ -0,0 +1 @@
+{ "count": 3i64, "average": null, "sum": null, "min": null, "max": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null_rec_1/agg_null_rec.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null_rec_1/agg_null_rec.1.adm
new file mode 100644
index 0000000..76d1409
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_null_rec_1/agg_null_rec.1.adm
@@ -0,0 +1 @@
+{ "count": 3i64, "average": 5.32d, "sum": 15.96d, "min": null, "max": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/agg_number/agg_number.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_number/agg_number.1.adm
new file mode 100644
index 0000000..0ceea6a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_number/agg_number.1.adm
@@ -0,0 +1 @@
+{ "count1": 4i64, "count2": 4i64, "average1": 2.3461845695961844E16d, "sum1": 9.3847382783847376E16, "min1": 1.0d, "max1": 9.3847382783847376E16, "average2": 2.3461845695961844E16d, "sum2": 9.3847382783847376E16, "min2": 1.0d, "max2": 9.3847382783847376E16 }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/agg_number_rec/agg_number_rec.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_number_rec/agg_number_rec.1.adm
new file mode 100644
index 0000000..7cedaad
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/agg_number_rec/agg_number_rec.1.adm
@@ -0,0 +1 @@
+{ "count": 3i64, "average": 1.2824609161579424E16d, "sum": 3.8473827484738272E16d, "min": 2.0d, "max": 3.847382748473824E16d }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/avg_mixed/avg_mixed.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/avg_mixed/avg_mixed.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/avg_mixed/avg_mixed.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.1.adm
new file mode 100644
index 0000000..7900e71
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_min_hetero_list/issue425_min_hetero_list.1.adm
@@ -0,0 +1 @@
+23i64
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.1.adm
new file mode 100644
index 0000000..1bf31ef
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_min_hetero_list_1/issue425_min_hetero_list_1.1.adm
@@ -0,0 +1 @@
+0.5d
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.adm
new file mode 100644
index 0000000..dc572c0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.adm
@@ -0,0 +1 @@
+748374857506i64
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.1.adm
new file mode 100644
index 0000000..7c07cb7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list_1/issue425_sum_hetero_list_1.1.adm
@@ -0,0 +1 @@
+748374857506.5d
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/sum_mixed/sum_mixed.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/sum_mixed/sum_mixed.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/sum_mixed/sum_mixed.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 9711930..d6c6733 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -1,6 +1,69 @@
 <test-suite xmlns="urn:xml.testframework.asterix.ics.uci.edu" ResultOffsetPath="results" QueryOffsetPath="queries" QueryFileExtension=".aql">
   <test-group name="aggregate">
     <test-case FilePath="aggregate">
+      <compilation-unit name="agg_null">
+        <output-dir compare="Text">agg_null</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="agg_null_rec">
+        <output-dir compare="Text">agg_null_rec</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="agg_null_rec_1">
+        <output-dir compare="Text">agg_null_rec_1</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="agg_number_rec">
+        <output-dir compare="Text">agg_number_rec</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="avg_mixed">
+        <output-dir compare="Text">avg_mixed</output-dir>
+        <expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="sum_mixed">
+        <output-dir compare="Text">sum_mixed</output-dir>
+        <expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="min_mixed">
+        <output-dir compare="Text">min_mixed</output-dir>
+        <expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="agg_number">
+        <output-dir compare="Text">agg_number</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="issue425_min_hetero_list_1">
+        <output-dir compare="Text">issue425_min_hetero_list_1</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="issue425_min_hetero_list">
+        <output-dir compare="Text">issue425_min_hetero_list</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="issue425_sum_hetero_list_1">
+        <output-dir compare="Text">issue425_sum_hetero_list_1</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="issue425_sum_hetero_list">
+        <output-dir compare="Text">issue425_sum_hetero_list</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate">
       <compilation-unit name="query-issue400">
         <output-dir compare="Text">query-issue400</output-dir>
       </compilation-unit>
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java
index e88596d..fafedd6 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java
@@ -1,4 +1,3 @@
-
 package edu.uci.ics.asterix.om.types;
 
 /**
@@ -21,7 +20,7 @@
     FLOAT(11),
     DOUBLE(12),
     STRING(13),
-    NULL(14),    
+    NULL(14),
     BOOLEAN(15),
     DATETIME(16),
     DATE(17),
@@ -57,4 +56,6 @@
         return value;
     }
 
+    public final static int TYPE_COUNT = ATypeTag.values().length;
+
 }
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/ATypeHierarchy.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/ATypeHierarchy.java
new file mode 100644
index 0000000..254a904
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/ATypeHierarchy.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.util.BitSet;
+import java.util.HashMap;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+
+public class ATypeHierarchy {
+
+    private static BitSet typeHierachyMap = new BitSet(ATypeTag.TYPE_COUNT * ATypeTag.TYPE_COUNT);
+    private static HashMap<Integer, ITypePromoteComputer> promoteComputerMap = new HashMap<Integer, ITypePromoteComputer>();
+
+    // allow type promotion to the type itself
+    static {
+        for (int i = 0; i < ATypeTag.TYPE_COUNT; i++) {
+            typeHierachyMap.set(i * ATypeTag.TYPE_COUNT + i);
+        }
+    }
+
+    // add default type promotion rules
+    static {
+        addPromotionRule(ATypeTag.INT8, ATypeTag.INT16, IntegerToInt16TypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.INT32, IntegerToInt32TypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.INT64, IntegerToInt64TypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.INT32, IntegerToInt32TypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.INT64, IntegerToInt64TypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT32, ATypeTag.INT64, IntegerToInt64TypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.DOUBLE, IntegerToDoubleTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.DOUBLE, IntegerToDoubleTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT32, ATypeTag.DOUBLE, IntegerToDoubleTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT64, ATypeTag.DOUBLE, IntegerToDoubleTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.FLOAT, ATypeTag.DOUBLE, FloatToDoubleTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.FLOAT, IntegerToFloatTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.FLOAT, IntegerToFloatTypePromoteComputer.INSTANCE);
+        addPromotionRule(ATypeTag.INT32, ATypeTag.FLOAT, IntegerToFloatTypePromoteComputer.INSTANCE);
+    }
+
+    public static void addPromotionRule(ATypeTag type1, ATypeTag type2, ITypePromoteComputer promoteComputer) {
+        int index = type1.ordinal() * ATypeTag.TYPE_COUNT + type2.ordinal();
+        typeHierachyMap.set(index);
+        promoteComputerMap.put(index, promoteComputer);
+    }
+
+    public static ITypePromoteComputer getTypePromoteComputer(ATypeTag type1, ATypeTag type2) {
+        if (canPromote(type1, type2)) {
+            return promoteComputerMap.get(type1.ordinal() * ATypeTag.TYPE_COUNT + type2.ordinal());
+        }
+        return null;
+    }
+
+    public static boolean canPromote(ATypeTag type1, ATypeTag type2) {
+        return typeHierachyMap.get(type1.ordinal() * ATypeTag.TYPE_COUNT + type2.ordinal());
+    }
+
+    public static boolean isCompatible(ATypeTag type1, ATypeTag type2) {
+        return canPromote(type1, type2) | canPromote(type2, type1);
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/AbstractIntegerTypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/AbstractIntegerTypePromoteComputer.java
new file mode 100644
index 0000000..12bfaf4
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/AbstractIntegerTypePromoteComputer.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+
+public abstract class AbstractIntegerTypePromoteComputer implements ITypePromoteComputer {
+
+    public void promoteIntegerType(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue,
+            ATypeTag targetType, int targetTypeLength) throws IOException {
+        storageForPromotedValue.getDataOutput().writeByte(targetType.serialize());
+        long num = 0;
+        for (int i = start; i < start + length; i++) {
+            num += (data[i] & 0xff) << ((length - 1 - (i - start)) * 8);
+        }
+
+        for (int i = targetTypeLength - 1; i >= 0; i--) {
+            storageForPromotedValue.getDataOutput().writeByte((byte)((num >>> (i * 8)) & 0xFF));
+        }
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/FloatToDoubleTypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/FloatToDoubleTypePromoteComputer.java
new file mode 100644
index 0000000..a3cfbc8
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/FloatToDoubleTypePromoteComputer.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+
+public class FloatToDoubleTypePromoteComputer implements ITypePromoteComputer {
+
+    public static final FloatToDoubleTypePromoteComputer INSTANCE = new FloatToDoubleTypePromoteComputer();
+
+    private FloatToDoubleTypePromoteComputer() {
+
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.types.hierachy.ITypePromoteComputer#promote(byte[], int, int, edu.uci.ics.hyracks.data.std.api.IMutableValueStorage)
+     */
+    @Override
+    public void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue)
+            throws IOException {
+        storageForPromotedValue.getDataOutput().writeByte(ATypeTag.DOUBLE.serialize());
+        DoubleSerializerDeserializer.INSTANCE.serialize((double) (FloatSerializerDeserializer.getFloat(data, start)),
+                storageForPromotedValue.getDataOutput());
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/ITypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/ITypePromoteComputer.java
new file mode 100644
index 0000000..e8612af
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/ITypePromoteComputer.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+
+public interface ITypePromoteComputer {
+
+    void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue) throws IOException;
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToDoubleTypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToDoubleTypePromoteComputer.java
new file mode 100644
index 0000000..014dc2a
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToDoubleTypePromoteComputer.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+
+public class IntegerToDoubleTypePromoteComputer implements ITypePromoteComputer {
+
+    public static final IntegerToDoubleTypePromoteComputer INSTANCE = new IntegerToDoubleTypePromoteComputer();
+
+    private IntegerToDoubleTypePromoteComputer() {
+
+    }
+
+    @Override
+    public void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue)
+            throws IOException {
+        storageForPromotedValue.getDataOutput().writeByte(ATypeTag.DOUBLE.serialize());
+        long val = 0L;
+        for (int i = 0; i < length; i++) {
+            val += ((long)(data[start + i] & 0xff)) << (8 * (length - 1 - i));
+        }
+        DoubleSerializerDeserializer.INSTANCE.serialize(Double.valueOf(val), storageForPromotedValue.getDataOutput());
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToFloatTypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToFloatTypePromoteComputer.java
new file mode 100644
index 0000000..c1bd9e5
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToFloatTypePromoteComputer.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+
+public class IntegerToFloatTypePromoteComputer implements ITypePromoteComputer {
+
+    public static final IntegerToFloatTypePromoteComputer INSTANCE = new IntegerToFloatTypePromoteComputer();
+
+    private IntegerToFloatTypePromoteComputer() {
+
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.types.hierachy.ITypePromoteComputer#promote(byte[], int, int, edu.uci.ics.hyracks.data.std.api.IMutableValueStorage)
+     */
+    @Override
+    public void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue)
+            throws IOException {
+        storageForPromotedValue.getDataOutput().writeByte(ATypeTag.FLOAT.serialize());
+        float val = 0;
+        for (int i = 0; i < length; i++) {
+            val += (data[start + i] & 0xff) << (8 * (length - 1 - i));
+        }
+        FloatSerializerDeserializer.INSTANCE.serialize(val, storageForPromotedValue.getDataOutput());
+
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt16TypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt16TypePromoteComputer.java
new file mode 100644
index 0000000..8835a57
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt16TypePromoteComputer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+
+public class IntegerToInt16TypePromoteComputer extends AbstractIntegerTypePromoteComputer {
+
+    public static final IntegerToInt16TypePromoteComputer INSTANCE = new IntegerToInt16TypePromoteComputer();
+
+    private IntegerToInt16TypePromoteComputer() {
+
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.types.hierachy.ITypePromoteComputer#promote(byte[], int, int, edu.uci.ics.hyracks.data.std.api.IMutableValueStorage)
+     */
+    @Override
+    public void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue)
+            throws IOException {
+        promoteIntegerType(data, start, length, storageForPromotedValue, ATypeTag.INT16, 2);
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt32TypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt32TypePromoteComputer.java
new file mode 100644
index 0000000..8a808bf
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt32TypePromoteComputer.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+
+public class IntegerToInt32TypePromoteComputer extends AbstractIntegerTypePromoteComputer {
+
+    public static final IntegerToInt32TypePromoteComputer INSTANCE = new IntegerToInt32TypePromoteComputer();
+
+    private IntegerToInt32TypePromoteComputer() {
+    }
+
+    @Override
+    public void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue)
+            throws IOException {
+        promoteIntegerType(data, start, length, storageForPromotedValue, ATypeTag.INT32, 4);
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt64TypePromoteComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt64TypePromoteComputer.java
new file mode 100644
index 0000000..b24604d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/hierachy/IntegerToInt64TypePromoteComputer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.types.hierachy;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.data.std.api.IMutableValueStorage;
+
+public class IntegerToInt64TypePromoteComputer extends AbstractIntegerTypePromoteComputer {
+
+    public static final IntegerToInt64TypePromoteComputer INSTANCE = new IntegerToInt64TypePromoteComputer();
+
+    private IntegerToInt64TypePromoteComputer() {
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.types.hierachy.ITypePromoteComputer#promote(byte[], int, int, edu.uci.ics.hyracks.data.std.api.IMutableValueStorage)
+     */
+    @Override
+    public void promote(byte[] data, int start, int length, IMutableValueStorage storageForPromotedValue)
+            throws IOException {
+        promoteIntegerType(data, start, length, storageForPromotedValue, ATypeTag.INT64, 8);
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java
index 93c7026..7815606 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java
@@ -31,9 +31,9 @@
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADouble;
-import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AInt64;
 import edu.uci.ics.asterix.om.base.AMutableDouble;
-import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
 import edu.uci.ics.asterix.om.base.ANull;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
@@ -44,6 +44,7 @@
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.hierachy.ATypeHierarchy;
 import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
 import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
@@ -83,7 +84,7 @@
         ARecordType tmpRecType;
         try {
             tmpRecType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
-                    new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, true);
+                    new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT64 }, true);
         } catch (AsterixException e) {
             throw new AlgebricksException(e);
         }
@@ -103,10 +104,10 @@
                     private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(inputVal);
                     private double sum;
-                    private int count;
+                    private long count;
                     private ATypeTag aggType;
                     private AMutableDouble aDouble = new AMutableDouble(0);
-                    private AMutableInt32 aInt32 = new AMutableInt32(0);
+                    private AMutableInt64 aInt64 = new AMutableInt64(0);
 
                     private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
                     private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
@@ -122,8 +123,8 @@
                     private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ADOUBLE);
                     @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<AInt32> intSerde = AqlSerializerDeserializerProvider.INSTANCE
-                            .getSerializerDeserializer(BuiltinType.AINT32);
+                    private ISerializerDeserializer<AInt64> intSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.AINT64);
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ANULL);
@@ -146,10 +147,13 @@
                             return;
                         } else if (aggType == ATypeTag.SYSTEM_NULL) {
                             aggType = typeTag;
-                        } else if (typeTag != ATypeTag.SYSTEM_NULL && typeTag != aggType) {
+                        } else if (typeTag != ATypeTag.SYSTEM_NULL && !ATypeHierarchy.isCompatible(typeTag, aggType)) {
                             throw new AlgebricksException("Unexpected type " + typeTag
                                     + " in aggregation input stream. Expected type " + aggType + ".");
+                        } else if (ATypeHierarchy.canPromote(aggType, typeTag)) {
+                            aggType = typeTag;
                         }
+
                         if (typeTag != ATypeTag.SYSTEM_NULL) {
                             ++count;
                         }
@@ -224,8 +228,8 @@
                                     doubleSerde.serialize(aDouble, sumBytesOutput);
                                 }
                                 countBytes.reset();
-                                aInt32.setValue(count);
-                                intSerde.serialize(aInt32, countBytesOutput);
+                                aInt64.setValue(count);
+                                intSerde.serialize(aInt64, countBytesOutput);
                                 recordEval.evaluate(null);
                             } catch (IOException e) {
                                 throw new AlgebricksException(e);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
index d262ef4..eb5d6bd 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
@@ -23,13 +23,13 @@
 
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADouble;
-import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AInt64;
 import edu.uci.ics.asterix.om.base.AMutableDouble;
-import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
 import edu.uci.ics.asterix.om.base.ANull;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
@@ -79,7 +79,7 @@
         ARecordType tmpRecType;
         try {
             tmpRecType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
-                    new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, false);
+                    new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT64 }, false);
         } catch (AsterixException e) {
             throw new AlgebricksException(e);
         }
@@ -99,9 +99,9 @@
                     private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval = args[0].createEvaluator(inputVal);
                     private double globalSum;
-                    private int globalCount;
+                    private long globalCount;
                     private AMutableDouble aDouble = new AMutableDouble(0);
-                    private AMutableInt32 aInt32 = new AMutableInt32(0);
+                    private AMutableInt64 aInt64 = new AMutableInt64(0);
 
                     private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
                     private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
@@ -114,8 +114,8 @@
                             new ICopyEvaluator[] { evalSum, evalCount }, avgBytes, out);
 
                     @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<AInt32> intSerde = AqlSerializerDeserializerProvider.INSTANCE
-                            .getSerializerDeserializer(BuiltinType.AINT32);
+                    private ISerializerDeserializer<AInt64> longSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.AINT64);
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ADOUBLE);
@@ -171,7 +171,7 @@
                         int offset2 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 1, nullBitmapSize,
                                 false);
                         if (offset2 != 0) // the count is not null
-                            globalCount += AInt32SerializerDeserializer.getInt(serBytes, offset2);
+                            globalCount += AInt64SerializerDeserializer.getLong(serBytes, offset2);
 
                     }
 
@@ -201,8 +201,8 @@
                                 doubleSerde.serialize(aDouble, sumBytesOutput);
                             }
                             countBytes.reset();
-                            aInt32.setValue(globalCount);
-                            intSerde.serialize(aInt32, countBytesOutput);
+                            aInt64.setValue(globalCount);
+                            longSerde.serialize(aInt64, countBytesOutput);
                             recordEval.evaluate(null);
                         } catch (IOException e) {
                             throw new AlgebricksException(e);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java
index 5400d78..256af09 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java
@@ -30,9 +30,9 @@
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.ADouble;
-import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AInt64;
 import edu.uci.ics.asterix.om.base.AMutableDouble;
-import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
 import edu.uci.ics.asterix.om.base.ANull;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
@@ -43,6 +43,7 @@
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.hierachy.ATypeHierarchy;
 import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
 import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
@@ -90,7 +91,7 @@
                 ARecordType tmpRecType;
                 try {
                     tmpRecType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
-                            new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, false);
+                            new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT64 }, false);
                 } catch (AsterixException e) {
                     throw new AlgebricksException(e);
                 }
@@ -104,7 +105,7 @@
                     private ICopyEvaluator eval = args[0].createEvaluator(inputVal);
                     private ATypeTag aggType;
                     private double sum;
-                    private int count;
+                    private long count;
 
                     private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
                     private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
@@ -119,13 +120,13 @@
                     private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ADOUBLE);
                     @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
-                            .getSerializerDeserializer(BuiltinType.AINT32);
+                    private ISerializerDeserializer<AInt64> longSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.AINT64);
                     @SuppressWarnings("unchecked")
                     private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
                             .getSerializerDeserializer(BuiltinType.ANULL);
                     private AMutableDouble aDouble = new AMutableDouble(0);
-                    private AMutableInt32 aInt32 = new AMutableInt32(0);
+                    private AMutableInt64 aInt64 = new AMutableInt64(0);
 
                     @Override
                     public void init() {
@@ -145,13 +146,17 @@
                             return;
                         } else if (aggType == ATypeTag.SYSTEM_NULL) {
                             aggType = typeTag;
-                        } else if (typeTag != ATypeTag.SYSTEM_NULL && typeTag != aggType) {
+                        } else if (typeTag != ATypeTag.SYSTEM_NULL && !ATypeHierarchy.isCompatible(typeTag, aggType)) {
                             throw new AlgebricksException("Unexpected type " + typeTag
                                     + " in aggregation input stream. Expected type " + aggType + ".");
+                        } else if (ATypeHierarchy.canPromote(aggType, typeTag)) {
+                            aggType = typeTag;
                         }
+                        
                         if (typeTag != ATypeTag.SYSTEM_NULL) {
                             ++count;
                         }
+
                         switch (typeTag) {
                             case INT8: {
                                 byte val = AInt8SerializerDeserializer.getByte(inputVal.getByteArray(), 1);
@@ -197,7 +202,7 @@
                     @Override
                     public void finish() throws AlgebricksException {
                         try {
-                            if (count == 0) {
+                            if (count == 0 && aggType != ATypeTag.NULL) {
                                 out.writeByte(ATypeTag.SYSTEM_NULL.serialize());
                                 return;
                             }
@@ -210,8 +215,8 @@
                                 doubleSerde.serialize(aDouble, sumBytesOutput);
                             }
                             countBytes.reset();
-                            aInt32.setValue(count);
-                            int32Serde.serialize(aInt32, countBytesOutput);
+                            aInt64.setValue(count);
+                            longSerde.serialize(aInt64, countBytesOutput);
                             recordEval.evaluate(null);
                         } catch (IOException e) {
                             throw new AlgebricksException(e);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java
index bc3508f..59004d8 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java
@@ -6,6 +6,8 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.hierachy.ATypeHierarchy;
+import edu.uci.ics.asterix.om.types.hierachy.ITypePromoteComputer;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyAggregateFunction;
 import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
@@ -19,10 +21,12 @@
 public class MinMaxAggregateFunction implements ICopyAggregateFunction {
     private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
     private ArrayBackedValueStorage outputVal = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage tempValForCasting = new ArrayBackedValueStorage();
     private DataOutput out;
     private ICopyEvaluator eval;
     private ATypeTag aggType;
     private IBinaryComparator cmp;
+    private ITypePromoteComputer tpc;
     private final boolean isMin;
     private final boolean isLocalAgg;
 
@@ -38,6 +42,7 @@
     public void init() {
         aggType = ATypeTag.SYSTEM_NULL;
         outputVal.reset();
+        tempValForCasting.reset();
     }
 
     @Override
@@ -62,13 +67,54 @@
             cmp = cmpFactory.createBinaryComparator();
             // Initialize min value.
             outputVal.assign(inputVal);
-        } else if (typeTag != ATypeTag.SYSTEM_NULL && typeTag != aggType) {
+        } else if (typeTag != ATypeTag.SYSTEM_NULL && !ATypeHierarchy.isCompatible(typeTag, aggType)) {
             throw new AlgebricksException("Unexpected type " + typeTag + " in aggregation input stream. Expected type "
                     + aggType + ".");
-        }
-        if (cmp.compare(inputVal.getByteArray(), inputVal.getStartOffset(), inputVal.getLength(),
-                outputVal.getByteArray(), outputVal.getStartOffset(), outputVal.getLength()) < 0) {
-            outputVal.assign(inputVal);
+        } else {
+            if (ATypeHierarchy.canPromote(aggType, typeTag)) {
+                tpc = ATypeHierarchy.getTypePromoteComputer(aggType, typeTag);
+                aggType = typeTag;
+                cmp = AqlBinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(aggType, isMin)
+                        .createBinaryComparator();
+                if (tpc != null) {
+                    tempValForCasting.reset();
+                    try {
+                        tpc.promote(outputVal.getByteArray(), outputVal.getStartOffset() + 1, outputVal.getLength() - 1,
+                                tempValForCasting);
+                    } catch (IOException e) {
+                        throw new AlgebricksException(e);
+                    }
+                    outputVal.reset();
+                    outputVal.assign(tempValForCasting);
+                }
+                if (cmp.compare(inputVal.getByteArray(), inputVal.getStartOffset(), inputVal.getLength(),
+                        outputVal.getByteArray(), outputVal.getStartOffset(), outputVal.getLength()) < 0) {
+                    outputVal.assign(inputVal);
+                }
+
+            } else {
+                tpc = ATypeHierarchy.getTypePromoteComputer(typeTag, aggType);
+                if (tpc != null) {
+                    tempValForCasting.reset();
+                    try {
+                        tpc.promote(inputVal.getByteArray(), inputVal.getStartOffset() + 1, inputVal.getLength() - 1,
+                                tempValForCasting);
+                    } catch (IOException e) {
+                        throw new AlgebricksException(e);
+                    }
+                    if (cmp.compare(tempValForCasting.getByteArray(), tempValForCasting.getStartOffset(),
+                            tempValForCasting.getLength(), outputVal.getByteArray(), outputVal.getStartOffset(),
+                            outputVal.getLength()) < 0) {
+                        outputVal.assign(tempValForCasting);
+                    }
+                } else {
+                    if (cmp.compare(inputVal.getByteArray(), inputVal.getStartOffset(), inputVal.getLength(),
+                            outputVal.getByteArray(), outputVal.getStartOffset(), outputVal.getLength()) < 0) {
+                        outputVal.assign(inputVal);
+                    }
+                }
+
+            }
         }
     }
 
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateFunction.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateFunction.java
index d0e82ce..4c153d1 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateFunction.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateFunction.java
@@ -20,6 +20,7 @@
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.hierachy.ATypeHierarchy;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
 import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyAggregateFunction;
@@ -70,10 +71,15 @@
             return;
         } else if (aggType == ATypeTag.SYSTEM_NULL) {
             aggType = typeTag;
-        } else if (typeTag != ATypeTag.SYSTEM_NULL && typeTag != aggType) {
+        } else if (typeTag != ATypeTag.SYSTEM_NULL && !ATypeHierarchy.isCompatible(typeTag, aggType)) {
             throw new AlgebricksException("Unexpected type " + typeTag
-                    + " in aggregation input stream. Expected type " + aggType + ".");
+                    + " in aggregation input stream. Expected type (or a promotable type to)" + aggType + ".");
         }
+
+        if (ATypeHierarchy.canPromote(aggType, typeTag)) {
+            aggType = typeTag;
+        }
+
         switch (typeTag) {
             case INT8: {
                 byte val = AInt8SerializerDeserializer.getByte(inputVal.getByteArray(), 1);
@@ -179,6 +185,9 @@
                     }
                     break;
                 }
+                default:
+                    throw new AlgebricksException("SumAggregationFunction: incompatible type for the result ("
+                            + aggType + "). ");
             }
         } catch (IOException e) {
             throw new AlgebricksException(e);
diff --git a/asterix-transactions/.gitignore b/asterix-transactions/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/asterix-transactions/.gitignore
@@ -0,0 +1 @@
+/target