Yingyi Bu has submitted this change and it was merged. Change subject: Cleanup type exceptions and error messages in the compiler. ......................................................................
Cleanup type exceptions and error messages in the compiler. Change-Id: I2bdb21251e53ac552e85ba30b8105f534bf9f4f3 Reviewed-on: https://asterix-gerrit.ics.uci.edu/1371 Reviewed-by: Till Westmann <[email protected]> Tested-by: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> --- M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java M asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionTest.java M asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java A asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataException.java M asterixdb/asterix-om/pom.xml A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/IncompatibleTypeException.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/InvalidExpressionException.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedItemTypeException.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedTypeException.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/AbstractResultTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/TypeCastUtils.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BooleanFunctionTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByIndexResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByNameResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/InjectFailureTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NonTaggedGetItemResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAggTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericUnaryFunctionTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordMergeTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveFieldsTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryBinaryInt64TypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryMinusTypeComputer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java A asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java M asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddFieldsDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordMergeDescriptor.java M hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java M hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java A hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java 52 files changed, 883 insertions(+), 300 deletions(-) Approvals: Till Westmann: Looks good to me, approved Jenkins: Verified; Verified Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java index 93586fc..53b78bb 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TranslationException.java @@ -21,14 +21,7 @@ import org.apache.asterix.common.exceptions.AsterixException; public class TranslationException extends AsterixException { - /** - * - */ private static final long serialVersionUID = 685960054131778068L; - - public TranslationException() { - super(); - } public TranslationException(String msg) { super(msg); diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionTest.java index 6a1d6e2..95c351b 100644 --- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionTest.java +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionTest.java @@ -71,10 +71,14 @@ try { evaluator.evaluate(null, resultPointable); } catch (Throwable e) { - if (e.getMessage() == null) { + String msg = e.getMessage(); + if (msg == null) { continue; } - if (e.getMessage().startsWith("ASX")) { + if (msg.startsWith("ASX")) { + // Verifies the error code. + int errorCode = Integer.parseInt(msg.substring(3, 7)); + Assert.assertTrue(errorCode >= 0 && errorCode < 1000); continue; } else { // Any root-level data exceptions thrown from runtime functions should have an error code. diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml index cbf715d..67e9909 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml @@ -1760,7 +1760,7 @@ <test-case FilePath="dml"> <compilation-unit name="insert-with-autogenerated-pk_adm_02"> <output-dir compare="Text">insert-with-autogenerated-pk_adm_02</output-dir> - <expected-error>Duplicate field id encountered</expected-error> + <expected-error>Duplicate field name "id"</expected-error> </compilation-unit> </test-case> <test-case FilePath="dml"> diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml index 15c856d..57be018 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -1698,7 +1698,7 @@ <test-case FilePath="dml"> <compilation-unit name="insert-with-autogenerated-pk_adm_02"> <output-dir compare="Text">insert-with-autogenerated-pk_adm_02</output-dir> - <expected-error>Duplicate field id encountered</expected-error> + <expected-error>Duplicate field name "id"</expected-error> </compilation-unit> </test-case> <test-case FilePath="dml"> @@ -2434,7 +2434,7 @@ <test-case FilePath="global-aggregate"> <compilation-unit name="q05_error"> <output-dir compare="Text">q01</output-dir> - <expected-error>The first argument of a field access should be a RECORD, but it is [ FacebookUserType: open</expected-error> + <expected-error>Type mismatch: function field-access-by-name expects its 1st input parameter to be type record, but the actual input type is orderedlist</expected-error> </compilation-unit> </test-case> <test-case FilePath="global-aggregate"> @@ -2525,7 +2525,7 @@ <test-case FilePath="group-by"> <compilation-unit name="sugar-01-negative"> <output-dir compare="Text">core-01</output-dir> - <expected-error>The first argument of a field access should be a RECORD, but it is [ EmpType</expected-error> + <expected-error>Type mismatch: function field-access-by-name expects its 1st input parameter to be type record, but the actual input type is orderedlist</expected-error> </compilation-unit> </test-case> <test-case FilePath="group-by"> @@ -3141,7 +3141,7 @@ <test-case FilePath="misc"> <compilation-unit name="query-ASTERIXDB-1577"> <output-dir compare="Text">query-ASTERIXDB-1577</output-dir> - <expected-error>The first argument of a field access should be a RECORD, but it is</expected-error> + <expected-error>Type mismatch: function field-access-by-name expects its 1st input parameter to be type record, but the actual input type is orderedlist</expected-error> </compilation-unit> </test-case> <test-case FilePath="misc"> @@ -5820,7 +5820,7 @@ <test-case FilePath="subquery"> <compilation-unit name="query-ASTERIXDB-1574"> <output-dir compare="Text">query-ASTERIXDB-1574</output-dir> - <expected-error>Unnest or index access expects the input to be a collection, but it was of type</expected-error> + <expected-error>Type mismatch: function scan-collection expects its 1st input parameter to be type unorderedlist or orderedlist, but the actual input type is record</expected-error> </compilation-unit> </test-case> <test-case FilePath="subquery"> diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java index afccede..53bb969 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java @@ -23,9 +23,6 @@ public class AsterixException extends AlgebricksException { private static final long serialVersionUID = 1L; - public AsterixException() { - } - public AsterixException(String message) { super(message); } diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java new file mode 100644 index 0000000..07d5068 --- /dev/null +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java @@ -0,0 +1,38 @@ +/* + * + * * 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.common.exceptions; + +import java.io.Serializable; + +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; + +public class CompilationException extends AlgebricksException { + + public CompilationException(int errorCode, Serializable... params) { + super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), params); + } + + public CompilationException(int errorCode, Throwable cause, Serializable... params) { + super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), params); + addSuppressed(cause); + } +} diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java index b182e35..743d5fb 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java @@ -47,10 +47,17 @@ public static final int ERROR_NEGATIVE_VALUE = 10; public static final int ERROR_OUT_OF_BOUND = 11; public static final int ERROR_COERCION = 12; - public static final int ERROR_DUPLICATE_FIELD = 13; + public static final int ERROR_DUPLICATE_FIELD_NAME = 13; // Compilation errors public static final int ERROR_PARSE_ERROR = 1001; + public static final int ERROR_COMPILATION_TYPE_MISMATCH = 1002; + public static final int ERROR_COMPILATION_TYPE_INCOMPATIBLE = 1003; + public static final int ERROR_COMPILATION_TYPE_UNSUPPORTED = 1004; + public static final int ERROR_COMPILATION_TYPE_ITEM = 1005; + public static final int ERROR_COMPILATION_INVALID_EXPRESSION = 1006; + public static final int ERROR_COMPILATION_INVALID_PARAMETER_NUMBER = 1007; + public static final int ERROR_COMPILATION_DUPLICATE_FIELD_NAME = 1008; private static final String ERROR_MESSAGE_ID_CONFLICT = "Two Extensions share the same Id: %1$s"; private static final String ERROR_MESSAGE_COMPONENT_CONFLICT = "Extension Conflict between %1$s and %2$s both " @@ -63,20 +70,24 @@ + " cannot process input type %2$s"; private static final String ERROR_MESSAGE_TYPE_ITEM = "Invalid item type: function %1$s" + " cannot process item type %2$s in an input array (or multiset)"; - public static final String ERROR_MESSAGE_INVALID_FORMAT = "Invalid format for %1$s in %2$s"; - public static final String ERROR_MESSAGE_OVERFLOW = "Overflow happend in %1$s"; - public static final String ERROR_MESSAGE_UNDERFLOW = "Underflow happend in %1$s"; - public static final String ERROR_MESSAGE_INJECTED_FAILURE = "Injected failure in %1$s"; - public static final String ERROR_MESSAGE_NEGATIVE_VALUE = "Invalid value: function %1$s expects" + private static final String ERROR_MESSAGE_INVALID_FORMAT = "Invalid format for %1$s in %2$s"; + private static final String ERROR_MESSAGE_OVERFLOW = "Overflow happend in %1$s"; + private static final String ERROR_MESSAGE_UNDERFLOW = "Underflow happend in %1$s"; + private static final String ERROR_MESSAGE_INJECTED_FAILURE = "Injected failure in %1$s"; + private static final String ERROR_MESSAGE_NEGATIVE_VALUE = "Invalid value: function %1$s expects" + " its %2$s input parameter to be a non-negative value, but gets %3$s"; - public static final String ERROR_MESSAGE_OUT_OF_BOUND = "Index out of bound in %1$s: %2$s"; - public static final String ERROR_MESSAGE_COERCION = "Invalid implicit scalar to collection coercion in %1$s"; - public static final String ERROR_MESSAGE_DUPLICATE_FIELD = "Get duplicate fields in %1$s"; + private static final String ERROR_MESSAGE_OUT_OF_BOUND = "Index out of bound in %1$s: %2$s"; + private static final String ERROR_MESSAGE_COERCION = "Invalid implicit scalar to collection coercion in %1$s"; + private static final String ERROR_MESSAGE_DUPLICATE_FIELD = "Duplicate field name \"%1$s\""; + private static final String ERROR_MESSAGE_INVALID_EXPRESSION = "Invalid expression: function %1$s expects" + + " its %2$s input parameter to be a %3$s expression, but the actual expression is %4$s"; + private static final String ERROR_MESSAGE_INVALID_PARAMETER_NUMBER = "Invalid parameter number: function %1$s " + + "cannot take %2$s parameters"; private static Map<Integer, String> errorMessageMap = new HashMap<>(); static { - // compilation errors + // runtime errors errorMessageMap.put(ERROR_TYPE_MISMATCH, ERROR_MESSAGE_TYPE_MISMATCH); errorMessageMap.put(ERROR_TYPE_INCOMPATIBLE, ERROR_MESSAGE_TYPE_INCOMPATIBLE); errorMessageMap.put(ERROR_TYPE_ITEM, ERROR_MESSAGE_TYPE_ITEM); @@ -88,7 +99,16 @@ errorMessageMap.put(ERROR_NEGATIVE_VALUE, ERROR_MESSAGE_NEGATIVE_VALUE); errorMessageMap.put(ERROR_OUT_OF_BOUND, ERROR_MESSAGE_OUT_OF_BOUND); errorMessageMap.put(ERROR_COERCION, ERROR_MESSAGE_COERCION); - errorMessageMap.put(ERROR_DUPLICATE_FIELD, ERROR_MESSAGE_DUPLICATE_FIELD); + errorMessageMap.put(ERROR_DUPLICATE_FIELD_NAME, ERROR_MESSAGE_DUPLICATE_FIELD); + + // compilation errors + errorMessageMap.put(ERROR_COMPILATION_TYPE_MISMATCH, ERROR_MESSAGE_TYPE_MISMATCH); + errorMessageMap.put(ERROR_COMPILATION_TYPE_INCOMPATIBLE, ERROR_MESSAGE_TYPE_INCOMPATIBLE); + errorMessageMap.put(ERROR_COMPILATION_TYPE_ITEM, ERROR_MESSAGE_TYPE_ITEM); + errorMessageMap.put(ERROR_COMPILATION_TYPE_UNSUPPORTED, ERROR_MESSAGE_TYPE_UNSUPPORTED); + errorMessageMap.put(ERROR_COMPILATION_INVALID_EXPRESSION, ERROR_MESSAGE_INVALID_EXPRESSION); + errorMessageMap.put(ERROR_COMPILATION_INVALID_PARAMETER_NUMBER, ERROR_MESSAGE_INVALID_PARAMETER_NUMBER); + errorMessageMap.put(ERROR_COMPILATION_DUPLICATE_FIELD_NAME, ERROR_MESSAGE_DUPLICATE_FIELD); // lifecycle management errors errorMessageMap.put(ERROR_EXTENSION_ID_CONFLICT, ERROR_MESSAGE_ID_CONFLICT); diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataException.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataException.java index 413226e..84c908f 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataException.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataException.java @@ -24,10 +24,6 @@ public class MetadataException extends AsterixException { private static final long serialVersionUID = 1L; - public MetadataException() { - super(); - } - public MetadataException(String message) { super(message); } diff --git a/asterixdb/asterix-om/pom.xml b/asterixdb/asterix-om/pom.xml index 72bf65e..eb3310f 100644 --- a/asterixdb/asterix-om/pom.xml +++ b/asterixdb/asterix-om/pom.xml @@ -80,5 +80,11 @@ <version>1.10.19</version> <scope>test</scope> </dependency> + <dependency> + <groupId>com.e-movimento.tinytools</groupId> + <artifactId>privilegedaccessor</artifactId> + <version>1.2.2</version> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java new file mode 100644 index 0000000..9ecdd94 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java @@ -0,0 +1,65 @@ +/* + * + * * 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.exceptions; + +public class ExceptionUtil { + + private ExceptionUtil() { + } + + static String toExpectedTypeString(Object... expectedItems) { + StringBuilder expectedTypes = new StringBuilder(); + int numCandidateTypes = expectedItems.length; + for (int index = 0; index < numCandidateTypes; ++index) { + if (index > 0) { + if (index == numCandidateTypes - 1) { + expectedTypes.append(" or "); + } else { + expectedTypes.append(", "); + } + } + expectedTypes.append(expectedItems[index]); + } + return expectedTypes.toString(); + } + + static String indexToPosition(int index) { + int i = index + 1; + switch (i % 100) { + case 11: + case 12: + case 13: + return i + "th"; + default: + switch (i % 10) { + case 1: + return i + "st"; + case 2: + return i + "nd"; + case 3: + return i + "rd"; + default: + return i + "th"; + } + } + } +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/IncompatibleTypeException.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/IncompatibleTypeException.java new file mode 100644 index 0000000..728cd0c --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/IncompatibleTypeException.java @@ -0,0 +1,40 @@ +/* + * + * * 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.exceptions; + +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; + +public class IncompatibleTypeException extends CompilationException { + + // Incompatible input parameters, e.g., "1.0" > 1.0 + public IncompatibleTypeException(FunctionIdentifier fid, ATypeTag typeTagLeft, ATypeTag typeTagRight) { + super(ErrorCode.ERROR_COMPILATION_TYPE_INCOMPATIBLE, fid.getName(), typeTagLeft, typeTagRight); + } + + // Incompatible input parameters, e.g., "1.0" > 1.0 + public IncompatibleTypeException(String functionName, ATypeTag typeTagLeft, ATypeTag typeTagRight) { + super(ErrorCode.ERROR_COMPILATION_TYPE_INCOMPATIBLE, functionName, typeTagLeft, typeTagRight); + } +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/InvalidExpressionException.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/InvalidExpressionException.java new file mode 100644 index 0000000..a4b3a32 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/InvalidExpressionException.java @@ -0,0 +1,48 @@ +/* + * + * * 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.exceptions; + +import static org.apache.asterix.om.exceptions.ExceptionUtil.indexToPosition; +import static org.apache.asterix.om.exceptions.ExceptionUtil.toExpectedTypeString; + +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; + +public class InvalidExpressionException extends CompilationException { + + public InvalidExpressionException(FunctionIdentifier fid, int index, ILogicalExpression actualExpr, + LogicalExpressionTag... exprKinds) { + super(ErrorCode.ERROR_COMPILATION_TYPE_INCOMPATIBLE, fid.getName(), indexToPosition(index), + actualExpr.toString(), + toExpectedTypeString(exprKinds)); + } + + public InvalidExpressionException(String functionName, int index, ILogicalExpression actualExpr, + LogicalExpressionTag... exprKinds) { + super(ErrorCode.ERROR_COMPILATION_TYPE_INCOMPATIBLE, functionName, indexToPosition(index), + actualExpr.toString(), + toExpectedTypeString(exprKinds)); + } +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java new file mode 100644 index 0000000..c0ab958 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java @@ -0,0 +1,47 @@ +/* + * + * * 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.exceptions; + +import static org.apache.asterix.om.exceptions.ExceptionUtil.indexToPosition; +import static org.apache.asterix.om.exceptions.ExceptionUtil.toExpectedTypeString; + +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; + +public class TypeMismatchException extends CompilationException { + + // Parameter type mistmatch. + public TypeMismatchException(FunctionIdentifier fid, Integer i, ATypeTag actualTypeTag, + ATypeTag... expectedTypeTags) { + super(ErrorCode.ERROR_COMPILATION_TYPE_MISMATCH, fid.getName(), indexToPosition(i), + toExpectedTypeString(expectedTypeTags), actualTypeTag); + } + + // Parameter type mistmatch. + public TypeMismatchException(String functionName, Integer i, ATypeTag actualTypeTag, ATypeTag... expectedTypeTags) { + super(ErrorCode.ERROR_COMPILATION_TYPE_MISMATCH, functionName, indexToPosition(i), + toExpectedTypeString(expectedTypeTags), actualTypeTag); + } + +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedItemTypeException.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedItemTypeException.java new file mode 100644 index 0000000..d1288aa --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedItemTypeException.java @@ -0,0 +1,40 @@ +/* + * + * * 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.exceptions; + +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; + +public class UnsupportedItemTypeException extends CompilationException { + + // Unsupported item type. + public UnsupportedItemTypeException(FunctionIdentifier fid, ATypeTag itemTypeTag) { + super(ErrorCode.ERROR_COMPILATION_TYPE_ITEM, fid.getName(), itemTypeTag); + } + + // Unsupported item type. + public UnsupportedItemTypeException(String functionName, ATypeTag itemTypeTag) { + super(ErrorCode.ERROR_COMPILATION_TYPE_ITEM, functionName, itemTypeTag); + } +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedTypeException.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedTypeException.java new file mode 100644 index 0000000..42e234f --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/UnsupportedTypeException.java @@ -0,0 +1,40 @@ +/* + * + * * 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.exceptions; + +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; + +public class UnsupportedTypeException extends CompilationException { + + // Unsupported input type. + public UnsupportedTypeException(FunctionIdentifier fid, ATypeTag actualTypeTag) { + super(ErrorCode.ERROR_COMPILATION_TYPE_UNSUPPORTED, fid.getName(), actualTypeTag); + } + + // Unsupported input type. + public UnsupportedTypeException(String funcName, ATypeTag actualTypeTag) { + super(ErrorCode.ERROR_COMPILATION_TYPE_UNSUPPORTED, funcName, actualTypeTag); + } +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/AbstractResultTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/AbstractResultTypeComputer.java index fb83091..f33db4b 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/AbstractResultTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/AbstractResultTypeComputer.java @@ -22,6 +22,7 @@ import org.apache.asterix.om.types.IAType; 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.metadata.IMetadataProvider; @@ -36,20 +37,24 @@ @Override public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { - return TypeComputeUtils.resolveResultType(expression, env, (index, type) -> checkArgType(index, type), + AbstractFunctionCallExpression functionCallExpression = (AbstractFunctionCallExpression) expression; + String funcName = functionCallExpression.getFunctionIdentifier().getName(); + return TypeComputeUtils.resolveResultType(expression, env, (index, type) -> checkArgType(funcName, index, type), this::getResultType, true); } /** * Checks whether an input type violates the requirement. * + * @param funcName + * the function name. * @param argIndex, * the index of the argument to consider. * @param type, * the type of the input argument. * @throws AlgebricksException */ - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/TypeCastUtils.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/TypeCastUtils.java index 91990f2..8c40903 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/TypeCastUtils.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/base/TypeCastUtils.java @@ -19,6 +19,7 @@ package org.apache.asterix.om.typecomputer.base; +import org.apache.asterix.om.exceptions.IncompatibleTypeException; import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.IAType; @@ -39,9 +40,11 @@ opaqueParameters = new Object[2]; opaqueParameters[0] = requiredType; opaqueParameters[1] = inputType; - if (!ATypeHierarchy.isCompatible(requiredType.getTypeTag(), - TypeComputeUtils.getActualType(inputType).getTypeTag())) { - throw new AlgebricksException(inputType + " can't be casted to " + requiredType); + ATypeTag requiredTypeTag = requiredType.getTypeTag(); + ATypeTag actualTypeTag = TypeComputeUtils.getActualType(inputType).getTypeTag(); + if (!ATypeHierarchy.isCompatible(requiredTypeTag, actualTypeTag)) { + String funcName = expr.getFunctionIdentifier().getName(); + throw new IncompatibleTypeException(funcName, actualTypeTag, requiredTypeTag); } expr.setOpaqueParameters(opaqueParameters); changed = true; diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java index ee53964..27f364a 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.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.IAType; @@ -27,10 +28,10 @@ abstract public class AbstractStringTypeComputer extends AbstractResultTypeComputer { @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { - if (type.getTypeTag() != ATypeTag.STRING) { - throw new AlgebricksException("The input type for input argument " + argIndex + "(" + type.getDisplayName() - + ")" + " is not expected."); + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); + if (actualTypeTag != ATypeTag.STRING) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.STRING); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BooleanFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BooleanFunctionTypeComputer.java index 6364d57..80ac8ef 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BooleanFunctionTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BooleanFunctionTypeComputer.java @@ -24,6 +24,7 @@ import org.apache.asterix.om.types.IAType; 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.metadata.IMetadataProvider; @@ -37,8 +38,10 @@ @Override public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { + AbstractFunctionCallExpression functionCallExpression = (AbstractFunctionCallExpression) expression; + String funcName = functionCallExpression.getFunctionIdentifier().getName(); // Boolean type computer doesn't follow the null/missing-in/out semantics. - return TypeComputeUtils.resolveResultType(expression, env, (index, type) -> checkArgType(index, type), + return TypeComputeUtils.resolveResultType(expression, env, (index, type) -> checkArgType(funcName, index, type), this::getResultType, false); } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java index e337ea8..0e351e2 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java @@ -21,6 +21,7 @@ import java.util.Iterator; +import org.apache.asterix.om.exceptions.InvalidExpressionException; import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; import org.apache.asterix.om.typecomputer.base.TypeCastUtils; import org.apache.asterix.om.types.ARecordType; @@ -31,6 +32,7 @@ import org.apache.commons.lang3.mutable.Mutable; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; 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.metadata.IMetadataProvider; @@ -43,6 +45,7 @@ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression; + String funcName = f.getFunctionIdentifier().getName(); /** * if type has been top-down propagated, use the enforced type @@ -68,8 +71,7 @@ fieldTypes[i] = e2Type; fieldNames[i] = ConstantExpressionUtil.getStringConstant(e1); if (fieldNames[i] == null) { - throw new AlgebricksException( - "Field name " + i + "(" + e1 + ") in call to closed-record-constructor is not a constant."); + throw new InvalidExpressionException(funcName, 2 * i, e1, LogicalExpressionTag.CONSTANT); } i++; } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java index bfeaac1..1792f68 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.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.AbstractCollectionType; @@ -27,19 +28,17 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; public class CollectionMemberResultType extends AbstractResultTypeComputer { - public static final CollectionMemberResultType INSTANCE = new CollectionMemberResultType(); protected CollectionMemberResultType() { - } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); if (type.getTypeTag() != ATypeTag.UNORDEREDLIST && type.getTypeTag() != ATypeTag.ORDEREDLIST) { - throw new AlgebricksException( - "Unnest or index access expects the input to be a collection, but it was of type " - + type); + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.UNORDEREDLIST, + ATypeTag.ORDEREDLIST); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByIndexResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByIndexResultType.java index f46c102..0c9d538 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByIndexResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByIndexResultType.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.ARecordType; import org.apache.asterix.om.types.ATypeTag; @@ -36,12 +37,13 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { - if (argIndex == 0 && type.getTypeTag() != ATypeTag.RECORD) { - throw new AlgebricksException("The first argument should be a RECORD, but it is " + type + "."); + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); + if (argIndex == 0 && actualTypeTag != ATypeTag.RECORD) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.RECORD); } - if (argIndex == 1 && type.getTypeTag() != ATypeTag.INT32) { - throw new AlgebricksException("The second argument should be an INT32, but it is found " + type + "."); + if (argIndex == 1 && actualTypeTag != ATypeTag.INT32) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.INT32); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByNameResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByNameResultType.java index 3e5af3c..deb667c 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByNameResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessByNameResultType.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.ARecordType; import org.apache.asterix.om.types.ATypeTag; @@ -36,14 +37,13 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { - if (argIndex == 0 && type.getTypeTag() != ATypeTag.RECORD) { - throw new AlgebricksException("The first argument of a field access should be a RECORD, but it is " + type - + "."); + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); + if (argIndex == 0 && actualTypeTag != ATypeTag.RECORD) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.RECORD); } - if (argIndex == 1 && type.getTypeTag() != ATypeTag.STRING) { - throw new AlgebricksException("The second argument of a field access should be an STRING, but it is " - + type + "."); + if (argIndex == 1 && actualTypeTag != ATypeTag.STRING) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.STRING); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java index 5f5abd1..03a6dc7 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java @@ -25,6 +25,8 @@ 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.TypeMismatchException; +import org.apache.asterix.om.exceptions.UnsupportedItemTypeException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.AOrderedListType; import org.apache.asterix.om.types.ARecordType; @@ -44,30 +46,30 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { - if (argIndex == 0 && type.getTypeTag() != ATypeTag.RECORD) { - throw new AlgebricksException("The first argument should be a RECORD, but it is " + type + "."); + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); + if (argIndex == 0 && actualTypeTag != ATypeTag.RECORD) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.RECORD); } if (argIndex == 1) { - switch (type.getTypeTag()) { + switch (actualTypeTag) { case STRING: break; case ORDEREDLIST: - checkOrderedList(type); + checkOrderedList(funcName, type); break; default: - throw new AlgebricksException( - "The second argument should be STRING or ORDEREDLIST, but it is found " + type + "."); + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.STRING, + ATypeTag.ORDEREDLIST); } } } - private void checkOrderedList(IAType type) throws AlgebricksException { + private void checkOrderedList(String funcName, IAType type) throws AlgebricksException { AOrderedListType listType = (AOrderedListType) type; ATypeTag itemTypeTag = listType.getItemType().getTypeTag(); if (itemTypeTag != ATypeTag.STRING && itemTypeTag != ATypeTag.ANY) { - throw new AlgebricksException( - "The second argument should be a valid path, but it is found " + type + "."); + throw new UnsupportedItemTypeException(funcName, itemTypeTag); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/InjectFailureTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/InjectFailureTypeComputer.java index 5d14716..df050be 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/InjectFailureTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/InjectFailureTypeComputer.java @@ -18,40 +18,32 @@ */ package org.apache.asterix.om.typecomputer.impl; -import org.apache.asterix.om.typecomputer.base.IResultTypeComputer; +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; +import org.apache.asterix.om.types.BuiltinType; import org.apache.asterix.om.types.IAType; -import org.apache.asterix.om.util.NonTaggedFormatUtil; 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.metadata.IMetadataProvider; -public class InjectFailureTypeComputer implements IResultTypeComputer { +public class InjectFailureTypeComputer extends AbstractResultTypeComputer { - private static final String errMsg1 = "inject-failure should have at least 2 parameters "; - private static final String errMsg2 = "failure condition expression should have the return type Boolean"; + public static final InjectFailureTypeComputer INSTANCE = new InjectFailureTypeComputer(); - public static IResultTypeComputer INSTANCE = new InjectFailureTypeComputer(); + protected InjectFailureTypeComputer() { + } @Override - public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, - IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { - AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression; - if (fce.getArguments().size() < 2) - throw new AlgebricksException(errMsg1); - - IAType t0 = (IAType) env.getType(fce.getArguments().get(0).getValue()); - IAType t1 = (IAType) env.getType(fce.getArguments().get(0).getValue()); - ATypeTag tag1 = t1.getTypeTag(); - if (NonTaggedFormatUtil.isOptional(t1)) - tag1 = ((AUnionType) t1).getActualType().getTypeTag(); - - if (tag1 != ATypeTag.BOOLEAN) - throw new AlgebricksException(errMsg2); - - return t0; + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); + if (actualTypeTag != ATypeTag.BOOLEAN) { + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.BOOLEAN); + } } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + return BuiltinType.ABOOLEAN; + } + } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java index 90613b6..0c0c2f9 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java @@ -18,16 +18,15 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.UnsupportedTypeException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.AUnionType; 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 MinMaxAggTypeComputer extends AbstractResultTypeComputer { - private static final String ERR_MSG = "Aggregator is not implemented for "; public static final MinMaxAggTypeComputer INSTANCE = new MinMaxAggTypeComputer(); @@ -35,7 +34,7 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); switch (tag) { case DOUBLE: @@ -53,7 +52,7 @@ case ANY: return; default: - throw new NotImplementedException(ERR_MSG + tag); + throw new UnsupportedTypeException(funcName, tag); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NonTaggedGetItemResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NonTaggedGetItemResultType.java index c72d7c8..677507e 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NonTaggedGetItemResultType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NonTaggedGetItemResultType.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; @@ -36,16 +37,16 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { + ATypeTag actualTypeTag = type.getTypeTag(); if (argIndex == 0) { if (type.getTypeTag() != ATypeTag.UNORDEREDLIST && type.getTypeTag() != ATypeTag.ORDEREDLIST) { - throw new AlgebricksException("The input type for input argument " + argIndex + "(" - + type.getDisplayName() + ")" + " is not expected."); + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.STRING, + ATypeTag.ORDEREDLIST); } } else { if (!ATypeHierarchy.isCompatible(type.getTypeTag(), ATypeTag.INT32)) { - throw new AlgebricksException("The input type for input argument " + argIndex + "(" - + type.getDisplayName() + ")" + " is not expected."); + throw new TypeMismatchException(funcName, argIndex, actualTypeTag, ATypeTag.INT32); } } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java index cabffe5..d4812c0 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java @@ -18,17 +18,16 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.IncompatibleTypeException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; 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; +import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; public class NumericAddSubMulDivTypeComputer extends AbstractResultTypeComputer { - - private static final String ERR_MSG = "Arithmetic operations are not implemented for "; public static final NumericAddSubMulDivTypeComputer INSTANCE = new NumericAddSubMulDivTypeComputer(); @@ -37,6 +36,8 @@ @Override protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + AbstractFunctionCallExpression functionCallExpression = (AbstractFunctionCallExpression) expr; + String funcName = functionCallExpression.getFunctionIdentifier().getName(); IAType t1 = strippedInputTypes[0]; IAType t2 = strippedInputTypes[1]; ATypeTag tag1 = t1.getTypeTag(); @@ -58,7 +59,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + t2.getTypeName()); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case FLOAT: @@ -77,7 +78,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + t2.getTypeName()); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case INT64: @@ -98,7 +99,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + t2.getTypeName()); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case INT32: @@ -121,7 +122,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case INT16: @@ -146,7 +147,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case INT8: @@ -173,7 +174,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case ANY: @@ -188,7 +189,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case DATE: @@ -205,7 +206,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case TIME: @@ -222,7 +223,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case DATETIME: @@ -236,7 +237,7 @@ type = BuiltinType.ADATETIME; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case DURATION: @@ -254,7 +255,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case YEARMONTHDURATION: @@ -275,7 +276,7 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; case DAYTIMEDURATION: @@ -296,11 +297,11 @@ type = BuiltinType.ANY; break; default: - throw new NotImplementedException(ERR_MSG + tag2); + throw new IncompatibleTypeException(funcName, tag1, tag2); } break; default: - throw new NotImplementedException(ERR_MSG + tag1); + throw new IncompatibleTypeException(funcName, tag1, tag2); } return type; } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAggTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAggTypeComputer.java index 81df5a1..57b11b4 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAggTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAggTypeComputer.java @@ -18,25 +18,22 @@ */ package org.apache.asterix.om.typecomputer.impl; +import org.apache.asterix.om.exceptions.UnsupportedTypeException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.AUnionType; 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 NumericAggTypeComputer extends AbstractResultTypeComputer { - - private static final String ERR_MSG = "Aggregator is not implemented for "; - public static final NumericAggTypeComputer INSTANCE = new NumericAggTypeComputer(); private NumericAggTypeComputer() { } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); switch (tag) { case DOUBLE: @@ -48,14 +45,14 @@ case ANY: break; default: - throw new NotImplementedException(ERR_MSG + type); + throw new UnsupportedTypeException(funcName, tag); } } @Override protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { ATypeTag tag = strippedInputTypes[0].getTypeTag(); - IAType type; + IAType type = null; switch (tag) { case DOUBLE: case FLOAT: @@ -67,7 +64,7 @@ type = strippedInputTypes[0]; break; default: - throw new NotImplementedException(ERR_MSG + strippedInputTypes[0]); + break; } return AUnionType.createNullableType(type, "AggResult"); } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java index 910db02..5045187 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.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; @@ -28,7 +29,6 @@ public class NumericDoubleOutputFunctionTypeComputer extends AbstractResultTypeComputer { - private static final String ERR_MSG = "Arithmetic operations are not implemented for "; public static final NumericDoubleOutputFunctionTypeComputer INSTANCE = new NumericDoubleOutputFunctionTypeComputer(); @@ -36,7 +36,7 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); switch (tag) { case INT8: @@ -47,7 +47,8 @@ case DOUBLE: break; default: - throw new AlgebricksException(ERR_MSG + type.getDisplayName()); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, ATypeTag.INT32, + ATypeTag.INT64, ATypeTag.FLOAT, ATypeTag.DOUBLE); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java index 6e32fe0..25ead33 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.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; @@ -28,14 +29,13 @@ public class NumericInt8OutputFunctionTypeComputer extends AbstractResultTypeComputer { - private static final String ERR_MSG = "Arithmetic operations are not implemented for "; public static final NumericInt8OutputFunctionTypeComputer INSTANCE = new NumericInt8OutputFunctionTypeComputer(); private NumericInt8OutputFunctionTypeComputer() { } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); switch (tag) { case INT8: @@ -46,7 +46,8 @@ case DOUBLE: break; default: - throw new AlgebricksException(ERR_MSG + type.getDisplayName()); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, ATypeTag.INT32, + ATypeTag.INT64, ATypeTag.FLOAT, ATypeTag.DOUBLE); } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java index 2335e46..aa509e7 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java @@ -23,11 +23,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 NumericRound2TypeComputer extends AbstractResultTypeComputer { @@ -39,7 +39,7 @@ } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); if (argIndex == 0) { switch (tag) { @@ -51,8 +51,8 @@ case DOUBLE: break; default: - throw new NotImplementedException( - "Arithmetic 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); } } if (argIndex == 1) { @@ -63,7 +63,8 @@ case INT64: break; default: - throw new AlgebricksException("Argument $precision cannot be type " + type.getDisplayName()); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, + ATypeTag.INT32, ATypeTag.INT64); } } } diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericUnaryFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericUnaryFunctionTypeComputer.java index 25807ba..bc68e10 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericUnaryFunctionTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericUnaryFunctionTypeComputer.java @@ -23,6 +23,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.IAType; @@ -30,15 +31,13 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; public class NumericUnaryFunctionTypeComputer extends AbstractResultTypeComputer { - - private static final String ERR_MSG = "Arithmetic operations are not implemented for "; public static final NumericUnaryFunctionTypeComputer INSTANCE = new NumericUnaryFunctionTypeComputer(); private NumericUnaryFunctionTypeComputer() { } @Override - protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + protected void checkArgType(String funcName, int argIndex, IAType type) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); switch (tag) { case INT8: @@ -50,7 +49,8 @@ case ANY: break; default: - throw new AlgebricksException(ERR_MSG + type.getDisplayName()); + throw new TypeMismatchException(funcName, argIndex, tag, ATypeTag.INT8, ATypeTag.INT16, ATypeTag.INT32, + ATypeTag.INT64, ATypeTag.FLOAT, ATypeTag.DOUBLE); } } 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.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 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 @@ 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); 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.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 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 @@ 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 @@ 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); } } 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 @@ } @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); } } 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.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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ @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 @@ 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 @@ 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 @@ 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 @@ } // 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); } } 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 @@ } @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); } } 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 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 @@ 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); } } } 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 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 @@ 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 @@ 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); } } } 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 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 @@ 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); } } } 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 @@ 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 @@ 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 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<>(); 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 @@ } @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); } } 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 @@ } @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 @@ 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); } } 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 @@ } @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); } } 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; + } + } + } +} 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.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 @@ // 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<>(); 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 @@ 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 { 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 @@ openFromParent, nestedLevel); foundMatch = true; } else { - throw new RuntimeDataException(ErrorCode.ERROR_DUPLICATE_FIELD, + throw new RuntimeDataException(ErrorCode.ERROR_DUPLICATE_FIELD_NAME, getIdentifier()); } } 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; } } 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 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 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 @@ @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(); - } - } } 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(); + } + } + +} -- To view, visit https://asterix-gerrit.ics.uci.edu/1371 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2bdb21251e53ac552e85ba30b8105f534bf9f4f3 Gerrit-PatchSet: 7 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Yingyi Bu <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Michael Blow <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]> Gerrit-Reviewer: Yingyi Bu <[email protected]> Gerrit-Reviewer: abdullah alamoudi <[email protected]>
