Merge branch 'master' into jarodwen/hotfix/issue425
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/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..e440e5c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/issue425_sum_hetero_list/issue425_sum_hetero_list.1.adm
@@ -0,0 +1 @@
+3
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 7ff782a..4419671 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -1,6 +1,11 @@
 <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="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/ATypeHierarchy.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeHierarchy.java
new file mode 100644
index 0000000..793908e
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeHierarchy.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import java.util.BitSet;
+
+public class ATypeHierarchy {
+
+    private static BitSet typeHierachyMap = new BitSet(ATypeTag.TYPE_COUNT * ATypeTag.TYPE_COUNT);
+
+    // 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);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.INT32);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.INT64);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.INT32);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.INT64);
+        addPromotionRule(ATypeTag.INT32, ATypeTag.INT64);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.DOUBLE);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.DOUBLE);
+        addPromotionRule(ATypeTag.INT32, ATypeTag.DOUBLE);
+        addPromotionRule(ATypeTag.INT64, ATypeTag.DOUBLE);
+        addPromotionRule(ATypeTag.FLOAT, ATypeTag.DOUBLE);
+        addPromotionRule(ATypeTag.INT8, ATypeTag.FLOAT);
+        addPromotionRule(ATypeTag.INT16, ATypeTag.FLOAT);
+        addPromotionRule(ATypeTag.INT32, ATypeTag.FLOAT);
+    }
+
+    public static void addPromotionRule(ATypeTag type1, ATypeTag type2) {
+        typeHierachyMap.set((type1.serialize() - 1) * ATypeTag.TYPE_COUNT + (type2.serialize() - 1));
+    }
+
+    public static boolean canPromote(ATypeTag type1, ATypeTag type2) {
+        return typeHierachyMap.get((type1.serialize() - 1) * ATypeTag.TYPE_COUNT + (type2.serialize() - 1));
+    }
+
+}
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-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..799e936 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
@@ -17,6 +17,7 @@
 import edu.uci.ics.asterix.om.base.AMutableInt64;
 import edu.uci.ics.asterix.om.base.AMutableInt8;
 import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeHierarchy;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
@@ -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.canPromote(aggType, typeTag)) {
             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 (typeTag != ATypeTag.SYSTEM_NULL) {
+            aggType = typeTag;
+        }
+
         switch (typeTag) {
             case INT8: {
                 byte val = AInt8SerializerDeserializer.getByte(inputVal.getByteArray(), 1);