Repository: asterixdb Updated Branches: refs/heads/master 1170755c9 -> 165121bab
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java index 6d29c36..8c643dc 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java @@ -27,6 +27,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import org.apache.asterix.om.exceptions.InvalidExpressionException; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; import org.apache.asterix.om.types.AOrderedListType; import org.apache.asterix.om.types.ARecordType; @@ -56,11 +58,12 @@ public class RecordAddFieldsTypeComputer implements IResultTypeComputer { public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expression; - IAType type0 = (IAType) env.getType(funcExpr.getArguments().get(0).getValue()); + String funcName = funcExpr.getFunctionIdentifier().getName(); + IAType type0 = (IAType) env.getType(funcExpr.getArguments().get(0).getValue()); ARecordType inputRecordType = TypeComputeUtils.extractRecordType(type0); if (inputRecordType == null) { - throw new AlgebricksException("Input record cannot be null"); + throw new TypeMismatchException(funcName, 0, type0.getTypeTag(), ATypeTag.RECORD); } ILogicalExpression arg1 = funcExpr.getArguments().get(1).getValue(); @@ -106,7 +109,8 @@ public class RecordAddFieldsTypeComputer implements IResultTypeComputer { if (fn[j].equals(FIELD_NAME_NAME)) { ILogicalExpression fieldNameExpr = recConsExpr.getArguments().get(j).getValue(); if (ConstantExpressionUtil.getStringConstant(fieldNameExpr) == null) { - throw new AlgebricksException(fieldNameExpr + " is not supported."); + throw new InvalidExpressionException(funcName, 1, fieldNameExpr, + LogicalExpressionTag.CONSTANT); } // Get the actual "field-name" string fieldName = ConstantExpressionUtil.getStringArgument(recConsExpr, j + 1); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordMergeTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordMergeTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordMergeTypeComputer.java index d3d089e..2b4cbe8 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordMergeTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordMergeTypeComputer.java @@ -23,7 +23,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.asterix.common.exceptions.AsterixException; +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; import org.apache.asterix.om.types.ARecordType; import org.apache.asterix.om.types.ATypeTag; @@ -47,15 +49,19 @@ public class RecordMergeTypeComputer implements IResultTypeComputer { public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression; + String funcName = f.getFunctionIdentifier().getName(); + IAType t0 = (IAType) env.getType(f.getArguments().get(0).getValue()); IAType t1 = (IAType) env.getType(f.getArguments().get(1).getValue()); boolean unknownable = TypeHelper.canBeUnknown(t0) || TypeHelper.canBeUnknown(t1); ARecordType recType0 = TypeComputeUtils.extractRecordType(t0); - ARecordType recType1 = TypeComputeUtils.extractRecordType(t1); + if (recType0 == null) { + throw new TypeMismatchException(funcName, 0, t0.getTypeTag(), ATypeTag.RECORD); + } - if (recType0 == null || recType1 == null) { - throw new AlgebricksException( - "record-merge expects possibly NULL records as arguments, but got (" + t0 + ", " + t1 + ")"); + ARecordType recType1 = TypeComputeUtils.extractRecordType(t1); + if (recType1 == null) { + throw new TypeMismatchException(funcName, 1, t1.getTypeTag(), ATypeTag.RECORD); } List<String> resultFieldNames = new ArrayList<>(); @@ -84,17 +90,12 @@ public class RecordMergeTypeComputer implements IResultTypeComputer { if (pos >= 0) { IAType resultFieldType = resultFieldTypes.get(pos); if (resultFieldType.getTypeTag() != fieldTypes[i].getTypeTag()) { - throw new AlgebricksException("Duplicate field " + fieldNames[i] + " encountered"); + throw new CompilationException(ErrorCode.ERROR_COMPILATION_DUPLICATE_FIELD_NAME, fieldNames[i]); } - try { - // Assuming fieldTypes[i].getTypeTag() = resultFieldType.getTypeTag() - if (fieldTypes[i].getTypeTag() == ATypeTag.RECORD) { - resultFieldTypes.set(pos, mergedNestedType(fieldTypes[i], resultFieldType)); - } - } catch (AsterixException e) { - throw new AlgebricksException(e); + // Assuming fieldTypes[i].getTypeTag() = resultFieldType.getTypeTag() + if (fieldTypes[i].getTypeTag() == ATypeTag.RECORD) { + resultFieldTypes.set(pos, mergedNestedType(fieldNames[i], fieldTypes[i], resultFieldType)); } - } else { additionalFieldNames.add(fieldNames[i]); additionalFieldTypes.add(fieldTypes[i]); @@ -115,36 +116,32 @@ public class RecordMergeTypeComputer implements IResultTypeComputer { return resultType; } - private IAType mergedNestedType(IAType fieldType1, IAType fieldType0) throws AlgebricksException, AsterixException { + private IAType mergedNestedType(String fieldName, IAType fieldType1, IAType fieldType0) throws AlgebricksException { if (fieldType1.getTypeTag() != ATypeTag.RECORD || fieldType0.getTypeTag() != ATypeTag.RECORD) { - throw new AlgebricksException("Duplicate field " + fieldType1.getTypeName() + " encountered"); + throw new CompilationException(ErrorCode.ERROR_COMPILATION_DUPLICATE_FIELD_NAME, fieldName); } ARecordType resultType = (ARecordType) fieldType0; ARecordType fieldType1Copy = (ARecordType) fieldType1; for (int i = 0; i < fieldType1Copy.getFieldTypes().length; i++) { - try { - int pos = resultType.getFieldIndex(fieldType1Copy.getFieldNames()[i]); - if (pos >= 0) { - // If a sub-record do merge, else ignore and let the values decide what to do - if (fieldType1Copy.getFieldTypes()[i].getTypeTag() == ATypeTag.RECORD) { - IAType[] oldTypes = resultType.getFieldTypes(); - oldTypes[pos] = mergedNestedType(fieldType1Copy.getFieldTypes()[i], - resultType.getFieldTypes()[pos]); - resultType = new ARecordType(resultType.getTypeName(), resultType.getFieldNames(), oldTypes, + String fname = fieldType1Copy.getFieldNames()[i]; + int pos = resultType.getFieldIndex(fname); + if (pos >= 0) { + // If a sub-record do merge, else ignore and let the values decide what to do + if (fieldType1Copy.getFieldTypes()[i].getTypeTag() == ATypeTag.RECORD) { + IAType[] oldTypes = resultType.getFieldTypes(); + oldTypes[pos] = mergedNestedType(fname, fieldType1Copy.getFieldTypes()[i], + resultType.getFieldTypes()[pos]); + resultType = new ARecordType(resultType.getTypeName(), resultType.getFieldNames(), oldTypes, resultType.isOpen()); - } - } else { - IAType[] combinedFieldTypes = ArrayUtils.addAll(resultType.getFieldTypes().clone(), + } + } else { + IAType[] combinedFieldTypes = ArrayUtils.addAll(resultType.getFieldTypes().clone(), fieldType1Copy.getFieldTypes()[i]); - resultType = new ARecordType(resultType.getTypeName(), + resultType = new ARecordType(resultType.getTypeName(), ArrayUtils.addAll(resultType.getFieldNames(), fieldType1Copy.getFieldNames()[i]), combinedFieldTypes, resultType.isOpen()); - } - - } catch (AsterixException e) { - throw new AlgebricksException(e); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java index 10b115f..660297c 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java @@ -18,7 +18,7 @@ */ package org.apache.asterix.om.typecomputer.impl; -import org.apache.asterix.om.functions.AsterixBuiltinFunctions; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.AOrderedListType; import org.apache.asterix.om.types.ATypeTag; @@ -34,11 +34,10 @@ public class RecordPairsTypeComputer extends AbstractResultTypeComputer { } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag typeTag = type.getTypeTag(); if (typeTag != ATypeTag.RECORD) { - throw new AlgebricksException("Function " + AsterixBuiltinFunctions.RECORD_PAIRS - + " expects a record as the input, " + "but get a " + typeTag); + throw new TypeMismatchException(funcName, argIndex, typeTag, ATypeTag.RECORD); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveFieldsTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveFieldsTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveFieldsTypeComputer.java index ec29857..2758666 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveFieldsTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveFieldsTypeComputer.java @@ -31,6 +31,9 @@ import org.apache.asterix.om.base.AOrderedList; import org.apache.asterix.om.base.AString; import org.apache.asterix.om.base.IAObject; import org.apache.asterix.om.constants.AsterixConstantValue; +import org.apache.asterix.om.exceptions.InvalidExpressionException; +import org.apache.asterix.om.exceptions.TypeMismatchException; +import org.apache.asterix.om.exceptions.UnsupportedTypeException; import org.apache.asterix.om.pointables.base.DefaultOpenFieldType; import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; import org.apache.asterix.om.types.AOrderedListType; @@ -61,11 +64,11 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { private RecordRemoveFieldsTypeComputer() { } - private void getPathFromConstantExpression(ILogicalExpression expression, Set<String> fieldNameSet, + private void getPathFromConstantExpression(String funcName, ILogicalExpression expression, Set<String> fieldNameSet, List<List<String>> pathList) throws AlgebricksException { ConstantExpression ce = (ConstantExpression) expression; if (!(ce.getValue() instanceof AsterixConstantValue)) { - throw new AlgebricksException("Expecting a list of strings and found " + ce.getValue() + " instead."); + throw new InvalidExpressionException(funcName, 1, ce, LogicalExpressionTag.CONSTANT); } IAObject item = ((AsterixConstantValue) ce.getValue()).getObject(); ATypeTag type = item.getType().getTypeTag(); @@ -86,11 +89,12 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { pathList.add(path); break; default: - throw new AlgebricksException("Unsupport type: " + type); + throw new UnsupportedTypeException(funcName, type); } } - private List<String> getListFromExpression(ILogicalExpression expression) throws AlgebricksException { + private List<String> getListFromExpression(String funcName, ILogicalExpression expression) + throws AlgebricksException { AbstractFunctionCallExpression funcExp = (AbstractFunctionCallExpression) expression; List<Mutable<ILogicalExpression>> args = funcExp.getArguments(); @@ -100,31 +104,31 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { // Input list has only one level of nesting (list of list or list of strings) ConstantExpression ce = (ConstantExpression) arg.getValue(); if (!(ce.getValue() instanceof AsterixConstantValue)) { - throw new AlgebricksException("Expecting a list of strings and found " + ce.getValue() + " instead."); + throw new InvalidExpressionException(funcName, 1, ce, LogicalExpressionTag.CONSTANT); } IAObject item = ((AsterixConstantValue) ce.getValue()).getObject(); ATypeTag type = item.getType().getTypeTag(); if (type == ATypeTag.STRING) { list.add(((AString) item).getStringValue()); } else { - throw new AlgebricksException(type + " is currently not supported. Please check your function call."); + throw new UnsupportedTypeException(funcName, type); } } return list; } - private void getPathFromFunctionExpression(ILogicalExpression expression, Set<String> fieldNameSet, + private void getPathFromFunctionExpression(String funcName, ILogicalExpression expression, Set<String> fieldNameSet, List<List<String>> pathList) throws AlgebricksException { - - List<String> path = getListFromExpression(expression); + List<String> path = getListFromExpression(funcName, expression); // Add the path head to remove set fieldNameSet.add(path.get(0)); pathList.add(path); } - private void computeTypeFromNonConstantExpression(ILogicalExpression expression, Set<String> fieldNameSet, + private void computeTypeFromNonConstantExpression(String funcName, ILogicalExpression expression, + Set<String> fieldNameSet, List<List<String>> pathList) throws AlgebricksException { AbstractFunctionCallExpression funcExp = (AbstractFunctionCallExpression) expression; List<Mutable<ILogicalExpression>> args = funcExp.getArguments(); @@ -133,13 +137,14 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { ILogicalExpression le = arg.getValue(); switch (le.getExpressionTag()) { case CONSTANT: - getPathFromConstantExpression(le, fieldNameSet, pathList); + getPathFromConstantExpression(funcName, le, fieldNameSet, pathList); break; case FUNCTION_CALL: - getPathFromFunctionExpression(le, fieldNameSet, pathList); + getPathFromFunctionExpression(funcName, le, fieldNameSet, pathList); break; default: - throw new AlgebricksException("Unsupported expression: " + le); + throw new InvalidExpressionException(funcName, 1, le, LogicalExpressionTag.CONSTANT, + LogicalExpressionTag.FUNCTION_CALL); } } } @@ -147,15 +152,15 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { @Override public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { - AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expression; - IAType type0 = (IAType) env.getType(funcExpr.getArguments().get(0).getValue()); + String funcName = funcExpr.getFunctionIdentifier().getName(); + IAType type0 = (IAType) env.getType(funcExpr.getArguments().get(0).getValue()); List<List<String>> pathList = new ArrayList<>(); Set<String> fieldNameSet = new HashSet<>(); Deque<String> fieldPathStack = new ArrayDeque<>(); - ARecordType inputRecordType = getRecordTypeFromType(type0, expression); + ARecordType inputRecordType = getRecordTypeFromType(funcName, type0); if (inputRecordType == null) { return BuiltinType.ANY; } @@ -164,9 +169,7 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { IAType inputListType = (IAType) env.getType(arg1); AOrderedListType inputOrderedListType = TypeComputeUtils.extractOrderedListType(inputListType); if (inputOrderedListType == null) { - throw new AlgebricksException( - "The function 'remove-fields' expects an ordered list as the second argument, but got " - + inputListType); + throw new TypeMismatchException(funcName, 1, inputListType.getTypeTag(), ATypeTag.ORDEREDLIST); } ATypeTag tt = inputOrderedListType.getItemType().getTypeTag(); @@ -177,7 +180,7 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { return DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE; } } else { // tt == ATypeTag.ANY, meaning the list is nested - computeTypeFromNonConstantExpression(arg1, fieldNameSet, pathList); + computeTypeFromNonConstantExpression(funcName, arg1, fieldNameSet, pathList); IAType resultType = buildOutputType(fieldPathStack, inputRecordType, fieldNameSet, pathList); return resultType; } @@ -320,7 +323,7 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { destFieldTypes.toArray(new IAType[n]), isOpen); } - private static ARecordType getRecordTypeFromType(IAType type0, ILogicalExpression expression) + private static ARecordType getRecordTypeFromType(String funcName, IAType type0) throws AlgebricksException { switch (type0.getTypeTag()) { case RECORD: @@ -337,8 +340,7 @@ public class RecordRemoveFieldsTypeComputer implements IResultTypeComputer { } // Falls through for other cases. default: - throw new AlgebricksException( - "Unsupported type " + type0 + " for field access expression: " + expression); + throw new TypeMismatchException(funcName, 0, type0.getTypeTag(), ATypeTag.RECORD); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java index ebee611..0eeba85 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java @@ -18,6 +18,7 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.AUnionType; @@ -35,11 +36,10 @@ public class ScalarVersionOfAggregateResultType extends AbstractResultTypeComput } @Override - public void checkArgType(int argIndex, IAType type) throws AlgebricksException { + public void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); if (tag != ATypeTag.ANY && tag != ATypeTag.ORDEREDLIST && tag != ATypeTag.UNORDEREDLIST) { - throw new AlgebricksException( - "Type of argument in aggregation should be a collection type instead of " + type.getDisplayName()); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.ORDEREDLIST, ATypeTag.UNORDEREDLIST); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java index 7bb83d0..21fbed3 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java @@ -18,6 +18,7 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; @@ -29,10 +30,10 @@ public class StringIntToStringTypeComputer extends AbstractResultTypeComputer { public static final StringIntToStringTypeComputer INSTANCE = new StringIntToStringTypeComputer(); @Override - public void checkArgType(int argIndex, IAType type) throws AlgebricksException { + public void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); if (argIndex == 0 && tag != ATypeTag.STRING) { - throw new AlgebricksException("First argument should be string Type."); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.STRING); } if (argIndex == 1) { switch (tag) { @@ -42,7 +43,8 @@ public class StringIntToStringTypeComputer extends AbstractResultTypeComputer { case INT64: break; default: - throw new AlgebricksException("Second argument should be integer Type."); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, + ATypeTag.INT32, ATypeTag.INT64); } } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java index 3fcb9bb..cdfb723 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java @@ -18,6 +18,7 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.AUnionType; @@ -41,13 +42,11 @@ public class SubsetCollectionTypeComputer implements IResultTypeComputer { public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> mp) throws AlgebricksException { AbstractFunctionCallExpression fun = (AbstractFunctionCallExpression) expression; - IAType t; - try { - t = (IAType) env.getType(fun.getArguments().get(0).getValue()); - } catch (AlgebricksException e) { - throw new AlgebricksException(e); - } - switch (t.getTypeTag()) { + String funcName = fun.getFunctionIdentifier().getName(); + + IAType t = (IAType) env.getType(fun.getArguments().get(0).getValue()); + ATypeTag actualTypeTag = t.getTypeTag(); + switch (actualTypeTag) { case UNORDEREDLIST: case ORDEREDLIST: { AbstractCollectionType act = (AbstractCollectionType) t; @@ -56,7 +55,8 @@ public class SubsetCollectionTypeComputer implements IResultTypeComputer { case UNION: { AUnionType ut = (AUnionType) t; if (!ut.isUnknownableType()) { - throw new AlgebricksException("Expecting collection type. Found " + t); + throw new TypeMismatchException(funcName, 0, actualTypeTag, ATypeTag.UNORDEREDLIST, + ATypeTag.ORDEREDLIST); } IAType t2 = ut.getActualType(); ATypeTag tag2 = t2.getTypeTag(); @@ -64,13 +64,14 @@ public class SubsetCollectionTypeComputer implements IResultTypeComputer { AbstractCollectionType act = (AbstractCollectionType) t2; return act.getItemType(); } - throw new AlgebricksException("Expecting collection type. Found " + t); + throw new TypeMismatchException(funcName, 0, actualTypeTag, ATypeTag.UNORDEREDLIST, + ATypeTag.ORDEREDLIST); } case ANY: return BuiltinType.ANY; - default: { - throw new AlgebricksException("Expecting collection type. Found " + t); - } + default: + throw new TypeMismatchException(funcName, 0, actualTypeTag, ATypeTag.UNORDEREDLIST, + ATypeTag.ORDEREDLIST); } } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java index 38dbe2a..87a3790 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java @@ -18,6 +18,7 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; @@ -29,10 +30,10 @@ public class SubstringTypeComputer extends AbstractResultTypeComputer { public static final SubstringTypeComputer INSTANCE = new SubstringTypeComputer(); @Override - public void checkArgType(int argIndex, IAType type) throws AlgebricksException { + public void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); if (argIndex == 0 && tag != ATypeTag.STRING) { - throw new AlgebricksException("First argument should be string Type."); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.STRING); } if (argIndex > 0 && argIndex <= 2) { switch (tag) { @@ -42,7 +43,8 @@ public class SubstringTypeComputer extends AbstractResultTypeComputer { case INT64: break; default: - throw new AlgebricksException("Second argument should be integer Type."); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, + ATypeTag.INT32, ATypeTag.INT64); } } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java index 22fe89f..c112bf2 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java @@ -21,6 +21,8 @@ package org.apache.asterix.om.typecomputer.impl; import java.util.ArrayList; import java.util.List; +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; import org.apache.asterix.dataflow.data.common.TypeResolverUtil; import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; import org.apache.asterix.om.types.IAType; @@ -32,8 +34,6 @@ import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider; public class SwitchCaseComputer implements IResultTypeComputer { - private static final String ERR_MSG = "switch case should have at least 3 parameters"; - public static final IResultTypeComputer INSTANCE = new SwitchCaseComputer(); private SwitchCaseComputer() { @@ -43,8 +43,11 @@ public class SwitchCaseComputer implements IResultTypeComputer { public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression; - if (fce.getArguments().size() < 3) { - throw new AlgebricksException(ERR_MSG); + String funcName = fce.getFunctionIdentifier().getName(); + + int argNumber = fce.getArguments().size(); + if (argNumber < 3) { + throw new CompilationException(ErrorCode.ERROR_COMPILATION_INVALID_PARAMETER_NUMBER, funcName, argNumber); } int argSize = fce.getArguments().size(); List<IAType> types = new ArrayList<>(); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryBinaryInt64TypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryBinaryInt64TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryBinaryInt64TypeComputer.java index 7f04614..d52ac88 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryBinaryInt64TypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryBinaryInt64TypeComputer.java @@ -19,6 +19,7 @@ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; @@ -33,14 +34,10 @@ public class UnaryBinaryInt64TypeComputer extends AbstractResultTypeComputer { } @Override - public void checkArgType(int argIndex, IAType type) throws AlgebricksException { + public void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); - if (argIndex == 0) { - if (tag != ATypeTag.BINARY) { - throw new AlgebricksException("The argument should be binary Type."); - } - } else { - throw new AlgebricksException("Wrong Argument Number."); + if (tag != ATypeTag.BINARY) { + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.BINARY); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryMinusTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryMinusTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryMinusTypeComputer.java index c53fcb0..5c734d2 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryMinusTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryMinusTypeComputer.java @@ -18,11 +18,11 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.IAType; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; -import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; public class UnaryMinusTypeComputer extends AbstractResultTypeComputer { @@ -33,7 +33,7 @@ public class UnaryMinusTypeComputer extends AbstractResultTypeComputer { } @Override - public void checkArgType(int argIndex, IAType type) throws AlgebricksException { + public void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); switch (tag) { case INT8: @@ -44,8 +44,8 @@ public class UnaryMinusTypeComputer extends AbstractResultTypeComputer { case DOUBLE: break; default: - throw new NotImplementedException( - "Negative operations are not implemented for " + type.getDisplayName()); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, ATypeTag.INT32, + ATypeTag.INT64, ATypeTag.FLOAT, ATypeTag.DOUBLE); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java index 3e0a3fa..e744ef1 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java @@ -18,6 +18,7 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; @@ -33,14 +34,10 @@ public class UnaryStringInt64TypeComputer extends AbstractResultTypeComputer { } @Override - public void checkArgType(int argIndex, IAType type) throws AlgebricksException { + public void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); - if (argIndex == 0) { - if (tag != ATypeTag.STRING) { - throw new AlgebricksException("Second argument should be string Type."); - } - } else { - throw new AlgebricksException("Wrong Argument Number."); + if (tag != ATypeTag.STRING) { + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.STRING); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java new file mode 100644 index 0000000..305f3e8 --- /dev/null +++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java @@ -0,0 +1,129 @@ + +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one + * * or more contributor license agreements. See the NOTICE file + * * distributed with this work for additional information + * * regarding copyright ownership. The ASF licenses this file + * * to you 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 at + * * + * * 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 org.apache.asterix.om.typecomputer; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.om.types.IAType; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; +import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; +import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; +import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider; +import org.junit.Assert; +import org.junit.Test; +import org.reflections.Reflections; +import org.reflections.scanners.SubTypesScanner; + +public class ExceptionTest { + + @Test + public void test() throws Exception { + // Tests all usual type computers. + Reflections reflections = new Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false)); + Set<Class<? extends IResultTypeComputer>> classes = reflections.getSubTypesOf(IResultTypeComputer.class); + int numTypeComputers = 0; + for (Class<? extends IResultTypeComputer> c : classes) { + if (Modifier.isAbstract(c.getModifiers())) { + continue; + } + testTypeComputer(c); + ++numTypeComputers; + } + // Currently, there are 78 type computers. + Assert.assertTrue(numTypeComputers >= 78); + } + + private void testTypeComputer(Class<? extends IResultTypeComputer> c) throws Exception { + // Mocks the type environment. + IVariableTypeEnvironment mockTypeEnv = mock(IVariableTypeEnvironment.class); + // Mocks the metadata provider. + IMetadataProvider<?, ?> mockMetadataProvider = mock(IMetadataProvider.class); + + // Mocks function expression. + AbstractFunctionCallExpression mockExpr = mock(AbstractFunctionCallExpression.class); + FunctionIdentifier fid = mock(FunctionIdentifier.class); + when(mockExpr.getFunctionIdentifier()).thenReturn(fid); + when(fid.getName()).thenReturn("testFunction"); + + int numCombination = (int) Math.pow(ATypeTag.values().length, 2); + // Sets two arguments for the mocked function expression. + for (int index = 0; index < numCombination; ++index) { + try { + List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>(); + for (int argIndex = 0; argIndex < 2; ++argIndex) { + int base = (int) Math.pow(ATypeTag.values().length, argIndex); + ILogicalExpression mockArg = mock(ILogicalExpression.class); + argRefs.add(new MutableObject<>(mockArg)); + IAType mockType = mock(IAType.class); + when(mockTypeEnv.getType(mockArg)).thenReturn(mockType); + int serializedTypeTag = (index / base) % ATypeTag.values().length + 1; + ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag]; + if (typeTag == null) { + // For some reason, type tag 39 does not exist. + typeTag = ATypeTag.ANY; + } + when(mockType.getTypeTag()).thenReturn(typeTag); + } + + // Sets up arguments for the mocked expression. + when(mockExpr.getArguments()).thenReturn(argRefs); + + // Sets up required/actual types of the mocked expression. + Object[] opaqueParameters = new Object[2]; + opaqueParameters[0] = BuiltinType.ANY; + opaqueParameters[1] = BuiltinType.ANY; + when(mockExpr.getOpaqueParameters()).thenReturn(opaqueParameters); + + // Invokes a type computer. + IResultTypeComputer instance = (IResultTypeComputer) c.getField("INSTANCE").get(null); + instance.computeType(mockExpr, mockTypeEnv, mockMetadataProvider); + } catch (AlgebricksException ae) { + String msg = ae.getMessage(); + if (msg.startsWith("ASX")) { + // Verifies the error code. + int errorCode = Integer.parseInt(msg.substring(3, 7)); + Assert.assertTrue(errorCode >= 1000 && errorCode < 2000); + continue; + } else { + // Any root-level compilation exceptions thrown from type computers should have an error code. + Assert.assertTrue(!(ae instanceof AlgebricksException) || (ae.getCause() != null)); + } + } catch (ClassCastException e) { + continue; + } + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java index f48aa7c..1ff62b9 100644 --- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java +++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java @@ -38,6 +38,7 @@ import org.apache.commons.lang3.mutable.MutableObject; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider; import org.junit.Assert; import org.junit.Test; @@ -83,6 +84,9 @@ public class TypeComputerTest { // Mocks function expression. AbstractFunctionCallExpression mockExpr = mock(AbstractFunctionCallExpression.class); + FunctionIdentifier fid = mock(FunctionIdentifier.class); + when(mockExpr.getFunctionIdentifier()).thenReturn(fid); + when(fid.getName()).thenReturn("testFunction"); // A function at most has six argument. List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>(); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddFieldsDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddFieldsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddFieldsDescriptor.java index d9f3e68..e8a2c42 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddFieldsDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddFieldsDescriptor.java @@ -239,7 +239,7 @@ public class RecordAddFieldsDescriptor extends AbstractScalarFunctionDynamicDesc tempValReference.set(entry.buf, entry.off, entry.len); // If value is not equal throw conflicting duplicate field, otherwise ignore if (!PointableHelper.byteArrayEqual(valuePointable, tempValReference)) { - throw new RuntimeDataException(ErrorCode.ERROR_DUPLICATE_FIELD, + throw new RuntimeDataException(ErrorCode.ERROR_DUPLICATE_FIELD_NAME, getIdentifier()); } } else { http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordMergeDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordMergeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordMergeDescriptor.java index 8e0d7ce..070e404 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordMergeDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordMergeDescriptor.java @@ -160,7 +160,7 @@ public class RecordMergeDescriptor extends AbstractScalarFunctionDynamicDescript openFromParent, nestedLevel); foundMatch = true; } else { - throw new RuntimeDataException(ErrorCode.ERROR_DUPLICATE_FIELD, + throw new RuntimeDataException(ErrorCode.ERROR_DUPLICATE_FIELD_NAME, getIdentifier()); } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java b/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java index ef4d775..6e53e2a 100644 --- a/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java +++ b/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java @@ -18,21 +18,87 @@ */ package org.apache.hyracks.algebricks.common.exceptions; +import java.io.Serializable; + +import org.apache.hyracks.api.util.ErrorMessageUtil; + public class AlgebricksException extends Exception { private static final long serialVersionUID = 1L; - public AlgebricksException() { + public static final int UNKNOWN = 0; + private final String component; + private final int errorCode; + private final Serializable[] params; + private final String nodeId; + private transient volatile String msgCache; + + public AlgebricksException(String component, int errorCode, String message, Throwable cause, String nodeId, + Serializable... params) { + super(message, cause); + this.component = component; + this.errorCode = errorCode; + this.nodeId = nodeId; + this.params = params; } public AlgebricksException(String message) { - super(message); + this(ErrorMessageUtil.NONE, UNKNOWN, message, null, null); } public AlgebricksException(Throwable cause) { - super(cause); + this(ErrorMessageUtil.NONE, UNKNOWN, cause.getMessage(), cause, null); + } + + public AlgebricksException(Throwable cause, String nodeId) { + this(ErrorMessageUtil.NONE, UNKNOWN, cause.getMessage(), cause, nodeId); + } + + public AlgebricksException(String message, Throwable cause, String nodeId) { + this(ErrorMessageUtil.NONE, UNKNOWN, message, cause, nodeId); } public AlgebricksException(String message, Throwable cause) { - super(message, cause); + this(ErrorMessageUtil.NONE, UNKNOWN, message, cause, (String) null); + } + + public AlgebricksException(String component, int errorCode, Serializable... params) { + this(component, errorCode, null, null, null, params); + } + + public AlgebricksException(Throwable cause, int errorCode, Serializable... params) { + this(ErrorMessageUtil.NONE, errorCode, cause.getMessage(), cause, null, params); + } + + public AlgebricksException(String component, int errorCode, String message, Serializable... params) { + this(component, errorCode, message, null, null, params); + } + + public AlgebricksException(String component, int errorCode, Throwable cause, Serializable... params) { + this(component, errorCode, cause.getMessage(), cause, null, params); + } + + public AlgebricksException(String component, int errorCode, String message, Throwable cause, + Serializable... params) { + this(component, errorCode, message, cause, null, params); + } + + public String getComponent() { + return component; + } + + public Object[] getParams() { + return params; + } + + public String getNodeId() { + return nodeId; + } + + @Override + public String getMessage() { + if (msgCache == null) { + msgCache = ErrorMessageUtil.formatMessage(component, errorCode, super.getMessage(), params); + } + return msgCache; } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java index a79ab1d..8a0e94b 100644 --- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java @@ -19,20 +19,17 @@ package org.apache.hyracks.api.exceptions; import java.io.Serializable; -import java.util.Formatter; -import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.hyracks.api.util.ErrorMessageUtil; + /** * The main execution time exception type for runtime errors in a hyracks environment */ public class HyracksDataException extends HyracksException { private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(HyracksDataException.class.getName()); - public static final String NONE = ""; public static final int UNKNOWN = 0; - private final String component; private final int errorCode; private final Serializable[] params; @@ -49,23 +46,23 @@ public class HyracksDataException extends HyracksException { } public HyracksDataException(String message) { - this(NONE, UNKNOWN, message, (Throwable) null, (String) null); + this(ErrorMessageUtil.NONE, UNKNOWN, message, null, null); } public HyracksDataException(Throwable cause) { - this(NONE, UNKNOWN, cause.getMessage(), cause, (String) null); + this(ErrorMessageUtil.NONE, UNKNOWN, cause.getMessage(), cause, null); } public HyracksDataException(Throwable cause, String nodeId) { - this(NONE, UNKNOWN, cause.getMessage(), cause, nodeId); + this(ErrorMessageUtil.NONE, UNKNOWN, cause.getMessage(), cause, nodeId); } public HyracksDataException(String message, Throwable cause, String nodeId) { - this(NONE, UNKNOWN, message, cause, nodeId); + this(ErrorMessageUtil.NONE, UNKNOWN, message, cause, nodeId); } public HyracksDataException(String message, Throwable cause) { - this(NONE, UNKNOWN, message, cause, (String) null); + this(ErrorMessageUtil.NONE, UNKNOWN, message, cause, (String) null); } public HyracksDataException(String component, int errorCode, Serializable... params) { @@ -73,7 +70,7 @@ public class HyracksDataException extends HyracksException { } public HyracksDataException(Throwable cause, int errorCode, Serializable... params) { - this(NONE, errorCode, cause.getMessage(), cause, null, params); + this(ErrorMessageUtil.NONE, errorCode, cause.getMessage(), cause, null, params); } public HyracksDataException(String component, int errorCode, String message, Serializable... params) { @@ -108,37 +105,9 @@ public class HyracksDataException extends HyracksException { @Override public String getMessage() { if (msgCache == null) { - msgCache = formatMessage(component, errorCode, super.getMessage(), params); + msgCache = ErrorMessageUtil.formatMessage(component, errorCode, super.getMessage(), params); } return msgCache; } - /** - * formats a error message - * Example: - * formatMessage(HYRACKS, ErrorCode.UNKNOWN, "%1$s -- %2$s", "one", "two") returns "HYR0000: one -- two" - * - * @param component - * the software component in which the error originated - * @param errorCode - * the error code itself - * @param message - * the user provided error message (a format string as specified in {@link java.util.Formatter}) - * @param params - * an array of objects taht will be provided to the {@link java.util.Formatter} - * @return the formatted string - */ - public static String formatMessage(String component, int errorCode, String message, Serializable... params) { - try (Formatter fmt = new Formatter()) { - if (!NONE.equals(component)) { - fmt.format("%1$s%2$04d: ", component, errorCode); - } - fmt.format(message == null ? "null" : message, (Object[]) params); - return fmt.out().toString(); - } catch (Exception e) { - // Do not throw further exceptions during exception processing. - LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); - return e.getMessage(); - } - } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/165121ba/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java ---------------------------------------------------------------------- diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java new file mode 100644 index 0000000..fd1e850 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java @@ -0,0 +1,67 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one + * * or more contributor license agreements. See the NOTICE file + * * distributed with this work for additional information + * * regarding copyright ownership. The ASF licenses this file + * * to you 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 at + * * + * * 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 org.apache.hyracks.api.util; + +import java.io.Serializable; +import java.util.Formatter; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ErrorMessageUtil { + + private static final Logger LOGGER = Logger.getLogger(ErrorMessageUtil.class.getName()); + public static final String NONE = ""; + + private ErrorMessageUtil() { + + } + + /** + * formats a error message + * Example: + * formatMessage(HYRACKS, ErrorCode.UNKNOWN, "%1$s -- %2$s", "one", "two") returns "HYR0000: one -- two" + * + * @param component + * the software component in which the error originated + * @param errorCode + * the error code itself + * @param message + * the user provided error message (a format string as specified in {@link java.util.Formatter}) + * @param params + * an array of objects taht will be provided to the {@link java.util.Formatter} + * @return the formatted string + */ + public static String formatMessage(String component, int errorCode, String message, Serializable... params) { + try (Formatter fmt = new Formatter()) { + if (!NONE.equals(component)) { + fmt.format("%1$s%2$04d: ", component, errorCode); + } + fmt.format(message == null ? "null" : message, (Object[]) params); + return fmt.out().toString(); + } catch (Exception e) { + // Do not throw further exceptions during exception processing. + LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); + return e.getMessage(); + } + } + +}
