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