use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class InsertUpsertCheckUtil method containsDatasetAccessInternal.
// Checks whether a query plan rooted at <code>op</code> contains dataset accesses.
private static boolean containsDatasetAccessInternal(ILogicalOperator op) {
if (op.getOperatorTag() == LogicalOperatorTag.UNNEST) {
UnnestOperator unnestOp = (UnnestOperator) op;
ILogicalExpression unnestExpr = unnestOp.getExpressionRef().getValue();
UnnestingFunctionCallExpression unnestingFuncExpr = (UnnestingFunctionCallExpression) unnestExpr;
return unnestingFuncExpr.getFunctionIdentifier().equals(BuiltinFunctions.DATASET);
}
if (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN && containsDatasetAccess((SubplanOperator) op)) {
return true;
}
for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
if (containsDatasetAccessInternal(childRef.getValue())) {
return true;
}
}
return false;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class AqlExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(FLWOGRExpression flwor, Mutable<ILogicalOperator> tupSource) throws CompilationException {
Mutable<ILogicalOperator> flworPlan = tupSource;
boolean isTop = context.isTopFlwor();
if (!isTop) {
context.enterSubplan();
}
if (isTop) {
context.setTopFlwor(false);
}
for (Clause c : flwor.getClauseList()) {
Pair<ILogicalOperator, LogicalVariable> pC = c.accept(this, flworPlan);
flworPlan = new MutableObject<>(pC.first);
}
Expression r = flwor.getReturnExpr();
boolean noForClause = flwor.noForClause();
Pair<ILogicalOperator, LogicalVariable> result;
if (r.getKind() == Kind.VARIABLE_EXPRESSION) {
VariableExpr v = (VariableExpr) r;
LogicalVariable var = context.getVar(v.getVar().getId());
result = produceFlworPlan(noForClause, isTop, flworPlan, var);
} else {
Mutable<ILogicalOperator> baseOp = new MutableObject<>(flworPlan.getValue());
Pair<ILogicalOperator, LogicalVariable> rRes = r.accept(this, baseOp);
ILogicalOperator rOp = rRes.first;
ILogicalOperator resOp;
if (expressionNeedsNoNesting(r)) {
baseOp.setValue(flworPlan.getValue());
resOp = rOp;
} else {
SubplanOperator s = new SubplanOperator(rOp);
s.getInputs().add(flworPlan);
resOp = s;
baseOp.setValue(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(s)));
}
Mutable<ILogicalOperator> resOpRef = new MutableObject<>(resOp);
result = produceFlworPlan(noForClause, isTop, resOpRef, rRes.second);
}
if (!isTop) {
context.exitSubplan();
}
return result;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(JoinClause joinClause, Mutable<ILogicalOperator> inputRef) throws CompilationException {
Mutable<ILogicalOperator> leftInputRef = uncorrelatedLeftBranchStack.pop();
if (joinClause.getJoinType() == JoinType.INNER) {
Pair<ILogicalOperator, LogicalVariable> rightBranch = generateUnnestForBinaryCorrelateRightBranch(joinClause, inputRef, true);
// A join operator with condition TRUE.
AbstractBinaryJoinOperator joinOperator = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE), leftInputRef, new MutableObject<ILogicalOperator>(rightBranch.first));
Mutable<ILogicalOperator> joinOpRef = new MutableObject<>(joinOperator);
// Add an additional filter operator.
Pair<ILogicalExpression, Mutable<ILogicalOperator>> conditionExprOpPair = langExprToAlgExpression(joinClause.getConditionExpression(), joinOpRef);
SelectOperator filter = new SelectOperator(new MutableObject<ILogicalExpression>(conditionExprOpPair.first), false, null);
filter.getInputs().add(conditionExprOpPair.second);
return new Pair<>(filter, rightBranch.second);
} else {
// Creates a subplan operator.
SubplanOperator subplanOp = new SubplanOperator();
Mutable<ILogicalOperator> ntsRef = new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(subplanOp)));
subplanOp.getInputs().add(leftInputRef);
// Enters the translation for a subplan.
context.enterSubplan();
// Adds an unnest operator to unnest to right expression.
Pair<ILogicalOperator, LogicalVariable> rightBranch = generateUnnestForBinaryCorrelateRightBranch(joinClause, ntsRef, true);
AbstractUnnestNonMapOperator rightUnnestOp = (AbstractUnnestNonMapOperator) rightBranch.first;
// Adds an additional filter operator for the join condition.
Pair<ILogicalExpression, Mutable<ILogicalOperator>> conditionExprOpPair = langExprToAlgExpression(joinClause.getConditionExpression(), new MutableObject<ILogicalOperator>(rightUnnestOp));
SelectOperator filter = new SelectOperator(new MutableObject<ILogicalExpression>(conditionExprOpPair.first), false, null);
filter.getInputs().add(conditionExprOpPair.second);
ILogicalOperator currentTopOp = filter;
LogicalVariable varToListify;
boolean hasRightPosVar = rightUnnestOp.getPositionalVariable() != null;
if (hasRightPosVar) {
// Creates record to get correlation between the two aggregate variables.
ScalarFunctionCallExpression recordCreationFunc = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR), // Field name for the listified right unnest var.
new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AString("unnestvar")))), // The listified right unnest var
new MutableObject<ILogicalExpression>(new VariableReferenceExpression(rightUnnestOp.getVariable())), // Field name for the listified right unnest positional var.
new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AString("posvar")))), // The listified right unnest positional var.
new MutableObject<ILogicalExpression>(new VariableReferenceExpression(rightUnnestOp.getPositionalVariable())));
// Assigns the record constructor function to a record variable.
LogicalVariable recordVar = context.newVar();
AssignOperator assignOp = new AssignOperator(recordVar, new MutableObject<ILogicalExpression>(recordCreationFunc));
assignOp.getInputs().add(new MutableObject<ILogicalOperator>(currentTopOp));
// Sets currentTopOp and varToListify for later usages.
currentTopOp = assignOp;
varToListify = recordVar;
} else {
varToListify = rightUnnestOp.getVariable();
}
// Adds an aggregate operator to listfy unnest variables.
AggregateFunctionCallExpression fListify = BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.LISTIFY, mkSingletonArrayList(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(varToListify))));
LogicalVariable aggVar = context.newSubplanOutputVar();
AggregateOperator aggOp = new AggregateOperator(mkSingletonArrayList(aggVar), mkSingletonArrayList(new MutableObject<ILogicalExpression>(fListify)));
aggOp.getInputs().add(new MutableObject<ILogicalOperator>(currentTopOp));
// Exits the translation of a subplan.
context.exitSubplan();
// Sets the nested subplan of the subplan operator.
ILogicalPlan subplan = new ALogicalPlanImpl(new MutableObject<ILogicalOperator>(aggOp));
subplanOp.getNestedPlans().add(subplan);
// Outer unnest the aggregated var from the subplan.
LogicalVariable outerUnnestVar = context.newVar();
LeftOuterUnnestOperator outerUnnestOp = new LeftOuterUnnestOperator(outerUnnestVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(new VariableReferenceExpression(aggVar))));
outerUnnestOp.getInputs().add(new MutableObject<ILogicalOperator>(subplanOp));
currentTopOp = outerUnnestOp;
if (hasRightPosVar) {
ScalarFunctionCallExpression fieldAccessForRightUnnestVar = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_INDEX), new MutableObject<ILogicalExpression>(new VariableReferenceExpression(outerUnnestVar)), new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(0)))));
ScalarFunctionCallExpression fieldAccessForRightPosVar = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_INDEX), new MutableObject<ILogicalExpression>(new VariableReferenceExpression(outerUnnestVar)), new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(1)))));
// Creates variables for assign.
LogicalVariable rightUnnestVar = context.newVar();
LogicalVariable rightPosVar = context.newVar();
// Relate the assigned variables to the variable expression in AST.
context.setVar(joinClause.getRightVariable(), rightUnnestVar);
context.setVar(joinClause.getPositionalVariable(), rightPosVar);
// Varaibles to assign.
List<LogicalVariable> assignVars = new ArrayList<>();
assignVars.add(rightUnnestVar);
assignVars.add(rightPosVar);
// Expressions for assign.
List<Mutable<ILogicalExpression>> assignExprs = new ArrayList<>();
assignExprs.add(new MutableObject<ILogicalExpression>(fieldAccessForRightUnnestVar));
assignExprs.add(new MutableObject<ILogicalExpression>(fieldAccessForRightPosVar));
// Creates the assign operator.
AssignOperator assignOp = new AssignOperator(assignVars, assignExprs);
assignOp.getInputs().add(new MutableObject<ILogicalOperator>(currentTopOp));
currentTopOp = assignOp;
} else {
context.setVar(joinClause.getRightVariable(), outerUnnestVar);
}
return new Pair<>(currentTopOp, null);
}
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class SubplanPOperator method computeDeliveredProperties.
@Override
public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
IPhysicalPropertiesVector childsProperties = op2.getPhysicalOperator().getDeliveredProperties();
List<ILocalStructuralProperty> propsLocal = new ArrayList<>();
if (childsProperties.getLocalProperties() != null) {
propsLocal.addAll(childsProperties.getLocalProperties());
}
// ... get local properties for newly created variables...
SubplanOperator subplan = (SubplanOperator) op;
for (ILogicalPlan plan : subplan.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : plan.getRoots()) {
AbstractLogicalOperator rOp = (AbstractLogicalOperator) r.getValue();
propsLocal.addAll(rOp.getPhysicalOperator().getDeliveredProperties().getLocalProperties());
}
}
deliveredProperties = new StructuralPropertiesVector(childsProperties.getPartitioningProperty(), propsLocal);
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class SubplanPOperator method contributeRuntimeOperator.
@Override
public void contributeRuntimeOperator(IHyracksJobBuilder builder, JobGenContext context, ILogicalOperator op, IOperatorSchema opSchema, IOperatorSchema[] inputSchemas, IOperatorSchema outerPlanSchema) throws AlgebricksException {
SubplanOperator subplan = (SubplanOperator) op;
if (subplan.getNestedPlans().size() != 1) {
throw new NotImplementedException("Subplan currently works only for one nested plan with one root.");
}
AlgebricksPipeline[] subplans = compileSubplans(inputSchemas[0], subplan, opSchema, context);
assert subplans.length == 1;
AlgebricksPipeline np = subplans[0];
RecordDescriptor inputRecordDesc = JobGenHelper.mkRecordDescriptor(context.getTypeEnvironment(op.getInputs().get(0).getValue()), inputSchemas[0], context);
IMissingWriterFactory[] missingWriterFactories = new IMissingWriterFactory[np.getOutputWidth()];
for (int i = 0; i < missingWriterFactories.length; i++) {
missingWriterFactories[i] = context.getMissingWriterFactory();
}
SubplanRuntimeFactory runtime = new SubplanRuntimeFactory(np, missingWriterFactories, inputRecordDesc, null);
RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(context.getTypeEnvironment(op), opSchema, context);
builder.contributeMicroOperator(subplan, runtime, recDesc);
ILogicalOperator src = op.getInputs().get(0).getValue();
builder.contributeGraphEdge(src, 0, op, 0);
}
Aggregations