partial fix for issue 676
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ConcatNonNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ConcatNonNullTypeComputer.java
index 7bf2668..7680c15 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ConcatNonNullTypeComputer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ConcatNonNullTypeComputer.java
@@ -15,12 +15,7 @@
 
 package edu.uci.ics.asterix.om.typecomputer.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
-import edu.uci.ics.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.AUnionType;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -46,29 +41,18 @@
         if (f.getArguments().size() < 1) {
             return BuiltinType.ANULL;
         }
-        List<IAType> possibleTypes = new ArrayList<IAType>();
+
+        TypeCompatibilityChecker tcc = new TypeCompatibilityChecker();
         for (int i = 0; i < f.getArguments().size(); i++) {
             ILogicalExpression arg = f.getArguments().get(i).getValue();
             IAType type = (IAType) env.getType(arg);
-            if (type.getTypeTag() == ATypeTag.UNION) {
-                List<IAType> typeList = ((AUnionType) type).getUnionList();
-                for (IAType t : typeList) {
-                    if (t.getTypeTag() != ATypeTag.NULL) {
-                        //CONCAT_NON_NULL cannot return null because it's only used for if-else construct
-                        if (!possibleTypes.contains(t))
-                            possibleTypes.add(t);
-                    }
-                }
-            } else {
-                if (!possibleTypes.contains(type))
-                    possibleTypes.add(type);
-            }
+            tcc.addPossibleType(type);
         }
-        if (possibleTypes.size() == 1) {
-            return possibleTypes.get(0);
-        } else {
+
+        IAType result = tcc.getCompatibleType();
+        if (result == null) {
             throw new AlgebricksException("The two branches of the if-else clause should return the same type.");
         }
+        return result;
     }
-
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSwitchCaseComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSwitchCaseComputer.java
index c1450ca..bd67f18 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSwitchCaseComputer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSwitchCaseComputer.java
@@ -15,10 +15,7 @@
 package edu.uci.ics.asterix.om.typecomputer.impl;
 
 import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
-import edu.uci.ics.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.AUnionType;
 import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -40,46 +37,27 @@
         if (fce.getArguments().size() < 3)
             throw new AlgebricksException(errMsg1);
 
-        IAType t0;
-        IAType t1;
-        IAType ti;
-
-        ATypeTag tag0;
-        ATypeTag tag1;
-        ATypeTag tagi;
-        try {
-            t0 = (IAType) env.getType(fce.getArguments().get(0).getValue());
-            t1 = (IAType) env.getType(fce.getArguments().get(2).getValue());
-            tag0 = t0.getTypeTag();
-            tag1 = t1.getTypeTag();
-            if (t0.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t0))
-                tag0 = ((AUnionType) t0).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
-                        .getTypeTag();
-            if (t1.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t1))
-                tag1 = ((AUnionType) t1).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
-                        .getTypeTag();
-            for (int i = 2; i < fce.getArguments().size(); i += 2) {
-                ti = (IAType) env.getType(fce.getArguments().get(i).getValue());
-                tagi = ti.getTypeTag();
-                if (ti.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) ti))
-                    tagi = ((AUnionType) ti).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
-                            .getTypeTag();
-                if (tag1 != tagi)
-                    if (!t1.toString().equals(ti.toString()))
-                        throw new AlgebricksException(errMsg2);
-            }
-            for (int i = 1; i < fce.getArguments().size(); i += 2) {
-                ti = (IAType) env.getType(fce.getArguments().get(i).getValue());
-                tagi = ti.getTypeTag();
-                if (ti.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) ti))
-                    tagi = ((AUnionType) ti).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
-                            .getTypeTag();
-                if (tag0 != tagi)
-                    throw new AlgebricksException(errMsg3);
-            }
-        } catch (AlgebricksException e) {
-            throw new AlgebricksException(e);
+        TypeCompatibilityChecker tcc = new TypeCompatibilityChecker();
+        for (int i = 2; i < fce.getArguments().size(); i += 2) {
+            IAType ti = (IAType) env.getType(fce.getArguments().get(i).getValue());
+            tcc.addPossibleType(ti);
         }
-        return t1;
+        IAType valueType = tcc.getCompatibleType();
+        if (valueType == null) {
+            throw new AlgebricksException(errMsg2);
+        }
+
+        IAType switchType = (IAType) env.getType(fce.getArguments().get(0).getValue());
+        tcc.reset();
+        tcc.addPossibleType(switchType);
+        for (int i = 1; i < fce.getArguments().size(); i += 2) {
+            IAType ti = (IAType) env.getType(fce.getArguments().get(i).getValue());
+            tcc.addPossibleType(ti);
+        }
+        IAType caseType = tcc.getCompatibleType();
+        if (caseType == null) {
+            throw new AlgebricksException(errMsg3);
+        }
+        return valueType;
     }
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TypeCompatibilityChecker.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TypeCompatibilityChecker.java
new file mode 100644
index 0000000..0739b2f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TypeCompatibilityChecker.java
@@ -0,0 +1,61 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+
+class TypeCompatibilityChecker {
+    private final List<IAType> possibleTypes;
+    private boolean nullEncountered;
+
+    public TypeCompatibilityChecker() {
+        possibleTypes = new ArrayList<IAType>();
+        nullEncountered = false;
+    }
+
+    public void reset() {
+        possibleTypes.clear();
+        nullEncountered = false;
+    }
+
+    public void addPossibleType(IAType type) {
+        if (type.getTypeTag() == ATypeTag.UNION) {
+            List<IAType> typeList = ((AUnionType) type).getUnionList();
+            for (IAType t : typeList) {
+                if (t.getTypeTag() != ATypeTag.NULL) {
+                    //CONCAT_NON_NULL cannot return null because it's only used for if-else construct
+                    if (!possibleTypes.contains(t))
+                        possibleTypes.add(t);
+                } else {
+                    nullEncountered = true;
+                }
+            }
+        } else {
+            if (type.getTypeTag() != ATypeTag.NULL) {
+                if (!possibleTypes.contains(type)) {
+                    possibleTypes.add(type);
+                }
+            } else {
+                nullEncountered = true;
+            }
+        }
+    }
+
+    public IAType getCompatibleType() {
+        switch (possibleTypes.size()) {
+            case 0:
+                return BuiltinType.ANULL;
+            case 1:
+                if (nullEncountered) {
+                    return AUnionType.createNullableType(possibleTypes.get(0));
+                } else {
+                    return possibleTypes.get(0);
+                }
+        }
+        return null;
+    }
+}
\ No newline at end of file