[NO ISSUE][COMP] Improve error reporting in TypeTranslator
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- Add error code and source location to exceptions
raised by TypeTranslator
- Pass dataset item type when calling
QueryTranslator.validateExternalDatasetProperties()
Change-Id: I2b62c162f37e72245cdbf70fe9f8307bbf9b2bf1
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/6885
Reviewed-by: Till Westmann <tillw@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TypeTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TypeTranslator.java
index cdb6346..cb6515b 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TypeTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/TypeTranslator.java
@@ -29,6 +29,8 @@
import org.apache.asterix.common.annotations.IRecordFieldDataGen;
import org.apache.asterix.common.annotations.RecordDataGenAnnotation;
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
import org.apache.asterix.lang.common.expression.RecordTypeDefinition.RecordKind;
@@ -50,6 +52,7 @@
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.types.TypeSignature;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
public class TypeTranslator {
@@ -70,7 +73,7 @@
firstPass(typeExpr, typeName, typeMap, incompleteFieldTypes, incompleteItemTypes,
incompleteTopLevelTypeReferences, typeDataverse);
secondPass(mdTxnCtx, typeMap, incompleteFieldTypes, incompleteItemTypes, incompleteTopLevelTypeReferences,
- typeDataverse);
+ typeDataverse, typeExpr.getSourceLocation());
for (IAType type : typeMap.values()) {
if (type.getTypeTag().isDerivedType()) {
@@ -87,7 +90,8 @@
throws AlgebricksException {
if (BuiltinTypeMap.getBuiltinType(typeName) != null) {
- throw new AlgebricksException("Cannot redefine builtin type " + typeName + " .");
+ throw new CompilationException(ErrorCode.COMPILATION_ERROR, typeExpr.getSourceLocation(),
+ "Cannot redefine builtin type " + typeName);
}
TypeSignature typeSignature = new TypeSignature(typeDataverse, typeName);
switch (typeExpr.getTypeKind()) {
@@ -133,15 +137,15 @@
private static void secondPass(MetadataTransactionContext mdTxnCtx, Map<TypeSignature, IAType> typeMap,
Map<String, Map<ARecordType, List<Integer>>> incompleteFieldTypes,
Map<TypeSignature, List<AbstractCollectionType>> incompleteItemTypes,
- Map<TypeSignature, List<TypeSignature>> incompleteTopLevelTypeReferences, String typeDataverse)
- throws AlgebricksException {
+ Map<TypeSignature, List<TypeSignature>> incompleteTopLevelTypeReferences, String typeDataverse,
+ SourceLocation sourceLoc) throws AlgebricksException {
// solve remaining top level references
for (TypeSignature typeSignature : incompleteTopLevelTypeReferences.keySet()) {
IAType t;
Datatype dt = MetadataManager.INSTANCE.getDatatype(mdTxnCtx, typeSignature.getNamespace(),
typeSignature.getName());
if (dt == null) {
- throw new AlgebricksException("Could not resolve type " + typeSignature);
+ throw new CompilationException(ErrorCode.UNKNOWN_TYPE, sourceLoc, typeSignature.getName());
} else {
t = dt.getDatatype();
}
@@ -158,7 +162,7 @@
trefName);
}
if (dt == null) {
- throw new AlgebricksException("Could not resolve type " + trefName);
+ throw new CompilationException(ErrorCode.UNKNOWN_TYPE, sourceLoc, trefName);
} else {
t = dt.getDatatype();
}
@@ -185,7 +189,7 @@
dt = MetadataManager.INSTANCE.getDatatype(mdTxnCtx, typeSignature.getNamespace(),
typeSignature.getName());
if (dt == null) {
- throw new AlgebricksException("Could not resolve type " + typeSignature);
+ throw new CompilationException(ErrorCode.UNKNOWN_TYPE, sourceLoc, typeSignature.getName());
}
t = dt.getDatatype();
} else {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 1be3894..f6536ac 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -649,10 +649,11 @@
throw new CompilationException(ErrorCode.DATASET_EXISTS, sourceLoc, datasetName, dataverseName);
}
}
+ Datatype itemTypeEntity;
IAType itemType;
switch (itemTypeExpr.getTypeKind()) {
case TYPEREFERENCE:
- Datatype itemTypeEntity = metadataProvider.findTypeEntity(itemTypeDataverseName, itemTypeName);
+ itemTypeEntity = metadataProvider.findTypeEntity(itemTypeDataverseName, itemTypeName);
if (itemTypeEntity == null || itemTypeEntity.getIsAnonymous()) {
// anonymous types cannot be referred from CREATE DATASET
throw new AsterixException(ErrorCode.UNKNOWN_TYPE, sourceLoc, itemTypeFullyQualifiedName);
@@ -663,8 +664,8 @@
case RECORD:
itemType = translateType(itemTypeDataverseName, itemTypeName, itemTypeExpr, mdTxnCtx);
validateDatasetItemType(dsType, itemType, false, sourceLoc);
- MetadataManager.INSTANCE.addDatatype(mdTxnCtx,
- new Datatype(itemTypeDataverseName, itemTypeName, itemType, true));
+ itemTypeEntity = new Datatype(itemTypeDataverseName, itemTypeName, itemType, true);
+ MetadataManager.INSTANCE.addDatatype(mdTxnCtx, itemTypeEntity);
break;
default:
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
@@ -740,7 +741,8 @@
createExternalDatasetProperties(dataverseName, dd, metadataProvider, mdTxnCtx);
ExternalDataUtils.normalize(properties);
ExternalDataUtils.validate(properties);
- validateExternalDatasetProperties(externalDetails, properties, dd.getSourceLocation(), mdTxnCtx);
+ validateExternalDatasetProperties(externalDetails, properties, itemTypeEntity,
+ dd.getSourceLocation(), mdTxnCtx);
datasetDetails = new ExternalDatasetDetails(externalDetails.getAdapter(), properties, new Date(),
TransactionState.COMMIT);
break;
@@ -3238,8 +3240,8 @@
}
protected void validateExternalDatasetProperties(ExternalDetailsDecl externalDetails,
- Map<String, String> properties, SourceLocation srcLoc, MetadataTransactionContext mdTxnCtx)
- throws AlgebricksException, HyracksDataException {
+ Map<String, String> properties, Datatype itemType, SourceLocation srcLoc,
+ MetadataTransactionContext mdTxnCtx) throws AlgebricksException, HyracksDataException {
// Validate adapter specific properties
String adapter = externalDetails.getAdapter();
Map<String, String> details = new HashMap<>(properties);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-dataset-inline-type-2/create-dataset-inline-type-2.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-dataset-inline-type-2/create-dataset-inline-type-2.5.ddl.sqlpp
new file mode 100644
index 0000000..62c0694
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-dataset-inline-type-2/create-dataset-inline-type-2.5.ddl.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/* Create dataset that attempts to use unknown type
+ in inline type definition */
+
+USE test;
+
+CREATE DATASET Cust3X(
+ c_custkey integer not unknown,
+ c_name my_unknown_type
+) PRIMARY KEY c_custkey;
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 44e2bff..63773dd 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -3888,6 +3888,7 @@
<output-dir compare="Text">create-dataset-inline-type-2</output-dir>
<expected-error>ASX1082: Cannot find datatype with name test.$d$t$i$Cust1</expected-error>
<expected-error>ASX1082: Cannot find datatype with name test.$d$t$i$Cust2</expected-error>
+ <expected-error>ASX1082: Cannot find datatype with name my_unknown_type</expected-error>
</compilation-unit>
</test-case>
<test-case FilePath="ddl">
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 7538887..f4061e1 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -773,10 +773,10 @@
{
RecordTypeDefinition recordTypeDef = null;
RecordTypeDefinition.RecordKind recordKind = null;
- Token recordKindToken = null;
+ Token startToken = null, recordKindToken = null;
}
{
- <LEFTPAREN> recordTypeDef = DatasetRecordTypeDef() <RIGHTPAREN>
+ <LEFTPAREN> { startToken = token; } recordTypeDef = DatasetRecordTypeDef() <RIGHTPAREN>
( recordKind = RecordTypeKind() { recordKindToken = token; } <TYPE> )?
{
if (recordKind == null) {
@@ -785,7 +785,7 @@
throw createUnexpectedTokenError(recordKindToken);
}
recordTypeDef.setRecordKind(recordKind);
- return recordTypeDef;
+ return addSourceLocation(recordTypeDef, startToken);
}
}