use of org.apache.asterix.common.exceptions.CompilationException in project asterixdb by apache.
the class LangExpressionToPlanTranslator method eliminateSharedOperatorReference.
/**
* Eliminate shared operator references in a query plan rooted at <code>currentOpRef.getValue()</code>.
* Deep copy a new query plan subtree whenever there is a shared operator reference.
*
* @param currentOpRef,
* the operator reference to consider
* @param opRefSet,
* the set storing seen operator references so far.
* @return a mapping that maps old variables to new variables, for the ancestors of
* <code>currentOpRef</code> to replace variables properly.
* @throws CompilationException
*/
private LinkedHashMap<LogicalVariable, LogicalVariable> eliminateSharedOperatorReference(Mutable<ILogicalOperator> currentOpRef, Set<Mutable<ILogicalOperator>> opRefSet) throws CompilationException {
try {
opRefSet.add(currentOpRef);
AbstractLogicalOperator currentOperator = (AbstractLogicalOperator) currentOpRef.getValue();
// Recursively eliminates shared references in nested plans.
if (currentOperator.hasNestedPlans()) {
// Since a nested plan tree itself can never be shared with another nested plan tree in
// another operator, the operation called in the if block does not need to replace
// any variables further for <code>currentOpRef.getValue()</code> nor its ancestor.
AbstractOperatorWithNestedPlans opWithNestedPlan = (AbstractOperatorWithNestedPlans) currentOperator;
for (ILogicalPlan plan : opWithNestedPlan.getNestedPlans()) {
for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
Set<Mutable<ILogicalOperator>> nestedOpRefSet = new HashSet<>();
eliminateSharedOperatorReference(rootRef, nestedOpRefSet);
}
}
}
int childIndex = 0;
LinkedHashMap<LogicalVariable, LogicalVariable> varMap = new LinkedHashMap<>();
for (Mutable<ILogicalOperator> childRef : currentOperator.getInputs()) {
if (opRefSet.contains(childRef)) {
// There is a shared operator reference in the query plan.
// Deep copies the child plan.
LogicalOperatorDeepCopyWithNewVariablesVisitor visitor = new LogicalOperatorDeepCopyWithNewVariablesVisitor(context, null);
ILogicalOperator newChild = childRef.getValue().accept(visitor, null);
LinkedHashMap<LogicalVariable, LogicalVariable> cloneVarMap = visitor.getInputToOutputVariableMapping();
// Substitute variables according to the deep copy which generates new variables.
VariableUtilities.substituteVariables(currentOperator, cloneVarMap, null);
varMap.putAll(cloneVarMap);
// Sets the new child.
childRef = new MutableObject<>(newChild);
currentOperator.getInputs().set(childIndex, childRef);
}
// Recursively eliminate shared operator reference for the operator subtree,
// even if it is a deep copy of some other one.
LinkedHashMap<LogicalVariable, LogicalVariable> childVarMap = eliminateSharedOperatorReference(childRef, opRefSet);
// Substitute variables according to the new subtree.
VariableUtilities.substituteVariables(currentOperator, childVarMap, null);
// in childVarMap.
for (Map.Entry<LogicalVariable, LogicalVariable> entry : varMap.entrySet()) {
LogicalVariable newVar = childVarMap.get(entry.getValue());
if (newVar != null) {
entry.setValue(newVar);
}
}
varMap.putAll(childVarMap);
++childIndex;
}
// Only retain live variables for parent operators to substitute variables.
Set<LogicalVariable> liveVars = new HashSet<>();
VariableUtilities.getLiveVariables(currentOperator, liveVars);
varMap.values().retainAll(liveVars);
return varMap;
} catch (AlgebricksException e) {
throw new CompilationException(e);
}
}
use of org.apache.asterix.common.exceptions.CompilationException in project asterixdb by apache.
the class AqlPlusExpressionToPlanTranslator method visitJoinClause.
@Override
public Pair<ILogicalOperator, LogicalVariable> visitJoinClause(JoinClause jc, Mutable<ILogicalOperator> tupSource) throws CompilationException {
Mutable<ILogicalOperator> opRef = tupSource;
Pair<ILogicalOperator, LogicalVariable> leftSide = null;
for (Clause c : jc.getLeftClauses()) {
leftSide = c.accept(this, opRef);
opRef = new MutableObject<ILogicalOperator>(leftSide.first);
}
opRef = tupSource;
Pair<ILogicalOperator, LogicalVariable> rightSide = null;
for (Clause c : jc.getRightClauses()) {
rightSide = c.accept(this, opRef);
opRef = new MutableObject<ILogicalOperator>(rightSide.first);
}
Pair<ILogicalExpression, Mutable<ILogicalOperator>> whereCond = langExprToAlgExpression(jc.getWhereExpr(), tupSource);
AbstractBinaryJoinOperator join;
switch(jc.getKind()) {
case INNER:
join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(whereCond.first));
break;
case LEFT_OUTER:
join = new LeftOuterJoinOperator(new MutableObject<ILogicalExpression>(whereCond.first));
break;
default:
throw new CompilationException(ErrorCode.COMPILATION_AQLPLUS_NO_SUCH_JOIN_TYPE);
}
join.getInputs().add(new MutableObject<ILogicalOperator>(leftSide.first));
join.getInputs().add(new MutableObject<ILogicalOperator>(rightSide.first));
return new Pair<ILogicalOperator, LogicalVariable>(join, null);
}
use of org.apache.asterix.common.exceptions.CompilationException in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(SelectSetOperation selectSetOperation, Mutable<ILogicalOperator> tupSource) throws CompilationException {
SetOperationInput leftInput = selectSetOperation.getLeftInput();
if (!selectSetOperation.hasRightInputs()) {
return leftInput.accept(this, tupSource);
}
List<ILangExpression> inputExprs = new ArrayList<>();
inputExprs.add(leftInput.selectBlock() ? new SelectExpression(null, new SelectSetOperation(leftInput, null), null, null, true) : leftInput.getSubquery());
for (SetOperationRight setOperationRight : selectSetOperation.getRightInputs()) {
SetOpType setOpType = setOperationRight.getSetOpType();
if (setOpType != SetOpType.UNION || setOperationRight.isSetSemantics()) {
throw new CompilationException("Operation " + setOpType + (setOperationRight.isSetSemantics() ? " with set semantics" : "ALL") + " is not supported.");
}
SetOperationInput rightInput = setOperationRight.getSetOperationRightInput();
inputExprs.add(rightInput.selectBlock() ? new SelectExpression(null, new SelectSetOperation(rightInput, null), null, null, true) : rightInput.getSubquery());
}
return translateUnionAllFromInputExprs(inputExprs, tupSource);
}
use of org.apache.asterix.common.exceptions.CompilationException in project asterixdb by apache.
the class LangExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(UnaryExpr u, Mutable<ILogicalOperator> tupSource) throws CompilationException {
Expression expr = u.getExpr();
Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(expr, tupSource);
LogicalVariable v1 = context.newVar();
AssignOperator a;
switch(u.getExprType()) {
case POSITIVE:
a = new AssignOperator(v1, new MutableObject<>(eo.first));
break;
case NEGATIVE:
AbstractFunctionCallExpression m = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.NUMERIC_UNARY_MINUS));
m.getArguments().add(new MutableObject<>(eo.first));
a = new AssignOperator(v1, new MutableObject<>(m));
break;
case EXISTS:
a = processExists(eo.first, v1, false);
break;
case NOT_EXISTS:
a = processExists(eo.first, v1, true);
break;
default:
throw new CompilationException("Unsupported operator: " + u);
}
a.getInputs().add(eo.second);
return new Pair<>(a, v1);
}
use of org.apache.asterix.common.exceptions.CompilationException in project asterixdb by apache.
the class ValidateUtil method validatePartitioningExpressions.
/**
* Validates the partitioning expression that will be used to partition a dataset and returns expression type.
*
* @param recType
* the record type
* @param metaRecType
* the meta record type
* @param partitioningExprs
* a list of partitioning expressions that will be validated
* @param keySourceIndicators
* the key sources (record vs. meta)
* @param autogenerated
* true if auto generated, false otherwise
* @return a list of partitioning expressions types
* @throws AlgebricksException
* if composite key is autogenerated.
* if autogenerated and of a type that can't be autogenerated.
* if a field could not be found in its record type.
* if partitioning key is nullable.
* if the field type can't be a primary key.
*/
public static List<IAType> validatePartitioningExpressions(ARecordType recType, ARecordType metaRecType, List<List<String>> partitioningExprs, List<Integer> keySourceIndicators, boolean autogenerated) throws AlgebricksException {
List<IAType> partitioningExprTypes = new ArrayList<>(partitioningExprs.size());
if (autogenerated) {
if (partitioningExprs.size() > 1) {
throw new CompilationException(ErrorCode.COMPILATION_CANNOT_AUTOGENERATE_COMPOSITE_PRIMARY_KEY);
}
List<String> fieldName = partitioningExprs.get(0);
IAType fieldType = recType.getSubFieldType(fieldName);
partitioningExprTypes.add(fieldType);
ATypeTag pkTypeTag = fieldType.getTypeTag();
if (pkTypeTag != ATypeTag.UUID) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_AUTOGENERATED_TYPE, pkTypeTag.name(), ATypeTag.UUID.name());
}
} else {
partitioningExprTypes = KeyFieldTypeUtil.getKeyTypes(recType, metaRecType, partitioningExprs, keySourceIndicators);
for (int fidx = 0; fidx < partitioningExprTypes.size(); ++fidx) {
IAType fieldType = partitioningExprTypes.get(fidx);
if (fieldType == null) {
throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND, RecordUtil.toFullyQualifiedName(partitioningExprs.get(fidx)));
}
switch(fieldType.getTypeTag()) {
case TINYINT:
case SMALLINT:
case INTEGER:
case BIGINT:
case FLOAT:
case DOUBLE:
case STRING:
case BINARY:
case DATE:
case TIME:
case UUID:
case DATETIME:
case YEARMONTHDURATION:
case DAYTIMEDURATION:
break;
case UNION:
throw new CompilationException(ErrorCode.COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE, RecordUtil.toFullyQualifiedName(partitioningExprs.get(fidx)));
default:
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_PRIMARY_KEY_TYPE, fieldType.getTypeTag());
}
}
}
return partitioningExprTypes;
}
Aggregations