use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class TypeUtil method createEnforcedType.
/**
* Merges typed index fields with specified recordType, allowing indexed fields to be optional.
* I.e. the type { "personId":int32, "name": string, "address" : { "street": string } } with typed indexes
* on age:int32, address.state:string will be merged into type { "personId":int32, "name": string,
* "age": int32? "address" : { "street": string, "state": string? } } Used by open indexes to enforce
* the type of an indexed record
*/
public static Pair<ARecordType, ARecordType> createEnforcedType(ARecordType recordType, ARecordType metaType, List<Index> indexes) throws AlgebricksException {
ARecordType enforcedRecordType = recordType;
ARecordType enforcedMetaType = metaType;
for (Index index : indexes) {
if (!index.isSecondaryIndex() || !index.isEnforcingKeyFileds()) {
continue;
}
if (index.hasMetaFields()) {
throw new AlgebricksException("Indexing an open field is only supported on the record part");
}
for (int i = 0; i < index.getKeyFieldNames().size(); i++) {
Deque<Pair<ARecordType, String>> nestedTypeStack = new ArrayDeque<>();
List<String> splits = index.getKeyFieldNames().get(i);
ARecordType nestedFieldType = enforcedRecordType;
boolean openRecords = false;
String bridgeName = nestedFieldType.getTypeName();
int j;
// Build the stack for the enforced type
for (j = 1; j < splits.size(); j++) {
nestedTypeStack.push(new Pair<>(nestedFieldType, splits.get(j - 1)));
bridgeName = nestedFieldType.getTypeName();
nestedFieldType = (ARecordType) enforcedRecordType.getSubFieldType(splits.subList(0, j));
if (nestedFieldType == null) {
openRecords = true;
break;
}
}
if (openRecords) {
// create the smallest record
enforcedRecordType = new ARecordType(splits.get(splits.size() - 2), new String[] { splits.get(splits.size() - 1) }, new IAType[] { AUnionType.createUnknownableType(index.getKeyFieldTypes().get(i)) }, true);
// create the open part of the nested field
for (int k = splits.size() - 3; k > (j - 2); k--) {
enforcedRecordType = new ARecordType(splits.get(k), new String[] { splits.get(k + 1) }, new IAType[] { AUnionType.createUnknownableType(enforcedRecordType) }, true);
}
// Bridge the gap
Pair<ARecordType, String> gapPair = nestedTypeStack.pop();
ARecordType parent = gapPair.first;
IAType[] parentFieldTypes = ArrayUtils.addAll(parent.getFieldTypes().clone(), new IAType[] { AUnionType.createUnknownableType(enforcedRecordType) });
enforcedRecordType = new ARecordType(bridgeName, ArrayUtils.addAll(parent.getFieldNames(), enforcedRecordType.getTypeName()), parentFieldTypes, true);
} else {
//Schema is closed all the way to the field
//enforced fields are either null or strongly typed
Map<String, IAType> recordNameTypesMap = TypeUtil.createRecordNameTypeMap(nestedFieldType);
// if a an enforced field already exists and the type is correct
IAType enforcedFieldType = recordNameTypesMap.get(splits.get(splits.size() - 1));
if (enforcedFieldType != null && enforcedFieldType.getTypeTag() == ATypeTag.UNION && ((AUnionType) enforcedFieldType).isUnknownableType()) {
enforcedFieldType = ((AUnionType) enforcedFieldType).getActualType();
}
if (enforcedFieldType != null && !ATypeHierarchy.canPromote(enforcedFieldType.getTypeTag(), index.getKeyFieldTypes().get(i).getTypeTag())) {
throw new AlgebricksException("Cannot enforce field " + index.getKeyFieldNames().get(i) + " to have type " + index.getKeyFieldTypes().get(i));
}
if (enforcedFieldType == null) {
recordNameTypesMap.put(splits.get(splits.size() - 1), AUnionType.createUnknownableType(index.getKeyFieldTypes().get(i)));
}
enforcedRecordType = new ARecordType(nestedFieldType.getTypeName(), recordNameTypesMap.keySet().toArray(new String[recordNameTypesMap.size()]), recordNameTypesMap.values().toArray(new IAType[recordNameTypesMap.size()]), nestedFieldType.isOpen());
}
// Create the enforced type for the nested fields in the schema, from the ground up
if (!nestedTypeStack.isEmpty()) {
while (!nestedTypeStack.isEmpty()) {
Pair<ARecordType, String> nestedTypePair = nestedTypeStack.pop();
ARecordType nestedRecType = nestedTypePair.first;
IAType[] nestedRecTypeFieldTypes = nestedRecType.getFieldTypes().clone();
nestedRecTypeFieldTypes[nestedRecType.getFieldIndex(nestedTypePair.second)] = enforcedRecordType;
enforcedRecordType = new ARecordType(nestedRecType.getTypeName() + "_enforced", nestedRecType.getFieldNames(), nestedRecTypeFieldTypes, nestedRecType.isOpen());
}
}
}
}
return new Pair<>(enforcedRecordType, enforcedMetaType);
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class ExpressionTypeComputer method getTypeForFunction.
private IAType getTypeForFunction(AbstractFunctionCallExpression expr, IVariableTypeEnvironment env, IMetadataProvider<?, ?> mp) throws AlgebricksException {
FunctionIdentifier fi = expr.getFunctionIdentifier();
// Note: built-in functions + udfs
IResultTypeComputer rtc;
FunctionSignature signature = new FunctionSignature(fi.getNamespace(), fi.getName(), fi.getArity());
if (BuiltinFunctions.isBuiltinCompilerFunction(signature, true)) {
rtc = BuiltinFunctions.getResultTypeComputer(fi);
} else {
rtc = ((ExternalFunctionInfo) expr.getFunctionInfo()).getResultTypeComputer();
}
if (rtc == null) {
throw new AlgebricksException("Type computer missing for " + fi);
}
return rtc.computeType(expr, env, mp);
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class SecondaryIndexOperationsHelper method createExternalIndexingOp.
// This method creates a source indexing operator for external data
protected ExternalScanOperatorDescriptor createExternalIndexingOp(JobSpecification spec) throws AlgebricksException {
// A record + primary keys
ISerializerDeserializer[] serdes = new ISerializerDeserializer[1 + numPrimaryKeys];
ITypeTraits[] typeTraits = new ITypeTraits[1 + numPrimaryKeys];
// payload serde and type traits for the record slot
serdes[0] = payloadSerde;
typeTraits[0] = TypeTraitProvider.INSTANCE.getTypeTrait(itemType);
// serdes and type traits for rid fields
for (int i = 1; i < serdes.length; i++) {
serdes[i] = IndexingConstants.getSerializerDeserializer(i - 1);
typeTraits[i] = IndexingConstants.getTypeTraits(i - 1);
}
// output record desc
RecordDescriptor indexerDesc = new RecordDescriptor(serdes, typeTraits);
// Create the operator and its partition constraits
Pair<ExternalScanOperatorDescriptor, AlgebricksPartitionConstraint> indexingOpAndConstraints;
try {
indexingOpAndConstraints = ExternalIndexingOperations.createExternalIndexingOp(spec, metadataProvider, dataset, itemType, indexerDesc, externalFiles);
} catch (Exception e) {
throw new AlgebricksException(e);
}
AlgebricksPartitionConstraintHelper.setPartitionConstraintInJobSpec(spec, indexingOpAndConstraints.first, indexingOpAndConstraints.second);
// Set the primary partition constraints to this partition constraints
primaryPartitionConstraint = indexingOpAndConstraints.second;
return indexingOpAndConstraints.first;
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class FullTextContainsParameterCheckRule method checkFirstAndSecondParamter.
/**
* Checks the correctness of the first and second argument. If the argument is a constant, we can check
* it now. If the argument is not a constant, we will defer the checking until run-time.
*/
void checkFirstAndSecondParamter(List<Mutable<ILogicalExpression>> exprs, String functionName) throws AlgebricksException {
// Check the first parameter - Expression1. If it's a constant, then we can check the type here.
ILogicalExpression firstExpr = exprs.get(0).getValue();
if (firstExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT && ConstantExpressionUtil.getConstantIaObjectType(firstExpr) != ATypeTag.STRING) {
throw new AlgebricksException("The first expression of " + functionName + " should be a string.");
}
// Check the second parameter - Expression2. If it's a constant, then we can check the type here.
ILogicalExpression secondExpr = exprs.get(1).getValue();
if (secondExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
ATypeTag exprTypeTag = ConstantExpressionUtil.getConstantIaObjectType(secondExpr);
switch(exprTypeTag) {
case STRING:
case MULTISET:
case ARRAY:
break;
default:
throw new AlgebricksException("The second expression of " + functionName + "should be a string, an unordered list, or an ordered list.");
}
}
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class FullTextContainsParameterCheckRule method checkParamter.
/**
* Check the correctness of the parameters of the ftcontains(). Also rearrange options as arguments.
* The expected form of ftcontains() is ftcontains(expression1, expression2, parameters as a record).
*/
private boolean checkParamter(ILogicalOperator op, Mutable<ILogicalExpression> exprRef, IOptimizationContext context) throws AlgebricksException {
ILogicalExpression expr = exprRef.getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
FunctionIdentifier fi = funcExpr.getFunctionIdentifier();
// Collects the correct number of arguments - it can be 2 if a user doesn't provide any option.
int numberOfCorrectArguments = 0;
String functionName = "";
if (fi == BuiltinFunctions.FULLTEXT_CONTAINS) {
numberOfCorrectArguments = FULLTEXT_QUERY_WITH_OPTION_NO_OF_ARGUMENTS;
functionName = BuiltinFunctions.FULLTEXT_CONTAINS.getName();
} else if (fi == BuiltinFunctions.FULLTEXT_CONTAINS_WO_OPTION) {
numberOfCorrectArguments = FULLTEXT_QUERY_WITHOUT_OPTION_NO_OF_ARGUMENTS;
functionName = BuiltinFunctions.FULLTEXT_CONTAINS_WO_OPTION.getName();
}
// If numberOfCorrectArguments is greater than zero, then this is a full-text search query.
if (numberOfCorrectArguments > 0) {
// Don't need to check this operator again.
context.addToDontApplySet(this, op);
List<Mutable<ILogicalExpression>> oldExprs = funcExpr.getArguments();
List<Mutable<ILogicalExpression>> newExprs = new ArrayList<>();
// The number of parameters should be three: exp1, exp2, and the option
if (oldExprs.size() != numberOfCorrectArguments) {
throw new AlgebricksException(functionName + " should have " + numberOfCorrectArguments + " parameters.");
}
// The last expression before the option needs to be copied first.
for (int i = 0; i <= LAST_EXPRESSION_POS_BEFORE_OPTION; i++) {
newExprs.add(new MutableObject<ILogicalExpression>((ILogicalExpression) oldExprs.get(i).getValue()));
}
// Sanity check for the types of the first two parameters
checkFirstAndSecondParamter(oldExprs, functionName);
// Checks and transforms the actual full-text parameters.
if (numberOfCorrectArguments == FULLTEXT_QUERY_WITH_OPTION_NO_OF_ARGUMENTS) {
checkValueForThirdParameter(oldExprs.get(2), newExprs);
} else {
// no option provided case: sets the default option here.
setDefaultValueForThirdParameter(newExprs);
}
// Resets the last argument.
funcExpr.getArguments().clear();
funcExpr.getArguments().addAll(newExprs);
return true;
}
return false;
}
Aggregations