use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(FromTerm fromTerm, Mutable<ILogicalOperator> tupSource) throws CompilationException {
LogicalVariable fromVar = context.newVarFromExpression(fromTerm.getLeftVariable());
Expression fromExpr = fromTerm.getLeftExpression();
Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(fromExpr, tupSource);
ILogicalOperator unnestOp;
if (fromTerm.hasPositionalVariable()) {
LogicalVariable pVar = context.newVarFromExpression(fromTerm.getPositionalVariable());
// We set the positional variable type as BIGINT type.
unnestOp = new UnnestOperator(fromVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)), pVar, BuiltinType.AINT64, new PositionWriter());
} else {
unnestOp = new UnnestOperator(fromVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)));
}
unnestOp.getInputs().add(eo.second);
// Processes joins, unnests, and nests.
Mutable<ILogicalOperator> topOpRef = new MutableObject<>(unnestOp);
if (fromTerm.hasCorrelateClauses()) {
for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
if (correlateClause.getClauseType() == ClauseType.UNNEST_CLAUSE) {
// Correlation is allowed.
topOpRef = new MutableObject<>(correlateClause.accept(this, topOpRef).first);
} else {
// Correlation is dis-allowed.
uncorrelatedLeftBranchStack.push(topOpRef);
topOpRef = new MutableObject<>(correlateClause.accept(this, tupSource).first);
}
}
}
return new Pair<>(topOpRef.getValue(), fromVar);
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator in project asterixdb by apache.
the class InlineAllNtsInSubplanVisitor method createUnnestForAggregatedList.
private Pair<ILogicalOperator, LogicalVariable> createUnnestForAggregatedList(LogicalVariable aggVar) {
LogicalVariable unnestVar = context.newVar();
// Creates an unnest function expression.
Mutable<ILogicalExpression> unnestArg = new MutableObject<ILogicalExpression>(new VariableReferenceExpression(aggVar));
List<Mutable<ILogicalExpression>> unnestArgList = new ArrayList<Mutable<ILogicalExpression>>();
unnestArgList.add(unnestArg);
Mutable<ILogicalExpression> unnestExpr = new MutableObject<ILogicalExpression>(new UnnestingFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION), unnestArgList));
ILogicalOperator unnestOp = new UnnestOperator(unnestVar, unnestExpr);
return new Pair<ILogicalOperator, LogicalVariable>(unnestOp, unnestVar);
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator in project asterixdb by apache.
the class InvertedIndexAccessMethod method analyzeGetItemFuncExpr.
public boolean analyzeGetItemFuncExpr(AbstractFunctionCallExpression funcExpr, List<AbstractLogicalOperator> assignsAndUnnests, AccessMethodAnalysisContext analysisCtx) throws AlgebricksException {
if (funcExpr.getFunctionIdentifier() != BuiltinFunctions.GET_ITEM) {
return false;
}
ILogicalExpression arg1 = funcExpr.getArguments().get(0).getValue();
ILogicalExpression arg2 = funcExpr.getArguments().get(1).getValue();
// The second arg is the item index to be accessed. It must be a constant.
if (arg2.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
return false;
}
// If it is a variable we must track its origin in the assigns to get the original function expr.
if (arg1.getExpressionTag() != LogicalExpressionTag.VARIABLE && arg1.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression matchedFuncExpr = null;
// The get-item arg is function call, directly check if it's optimizable.
if (arg1.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
matchedFuncExpr = (AbstractFunctionCallExpression) arg1;
}
// The get-item arg is a variable. Search the assigns and unnests for its origination function.
int matchedAssignOrUnnestIndex = -1;
if (arg1.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
VariableReferenceExpression varRefExpr = (VariableReferenceExpression) arg1;
// Try to find variable ref expr in all assigns.
for (int i = 0; i < assignsAndUnnests.size(); i++) {
AbstractLogicalOperator op = assignsAndUnnests.get(i);
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assign = (AssignOperator) op;
List<LogicalVariable> assignVars = assign.getVariables();
List<Mutable<ILogicalExpression>> assignExprs = assign.getExpressions();
for (int j = 0; j < assignVars.size(); j++) {
LogicalVariable var = assignVars.get(j);
if (var != varRefExpr.getVariableReference()) {
continue;
}
// We've matched the variable in the first assign. Now analyze the originating function.
ILogicalExpression matchedExpr = assignExprs.get(j).getValue();
if (matchedExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
matchedFuncExpr = (AbstractFunctionCallExpression) matchedExpr;
break;
}
} else {
UnnestOperator unnest = (UnnestOperator) op;
LogicalVariable var = unnest.getVariable();
if (var == varRefExpr.getVariableReference()) {
ILogicalExpression matchedExpr = unnest.getExpressionRef().getValue();
if (matchedExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression unnestFuncExpr = (AbstractFunctionCallExpression) matchedExpr;
if (unnestFuncExpr.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
return false;
}
matchedFuncExpr = (AbstractFunctionCallExpression) unnestFuncExpr.getArguments().get(0).getValue();
}
}
// We've already found a match.
if (matchedFuncExpr != null) {
matchedAssignOrUnnestIndex = i;
break;
}
}
}
// Check that the matched function is optimizable by this access method.
if (!secondLevelFuncIdents.contains(matchedFuncExpr.getFunctionIdentifier())) {
return false;
}
boolean selectMatchFound = analyzeSelectSimilarityCheckFuncExprArgs(matchedFuncExpr, assignsAndUnnests, matchedAssignOrUnnestIndex, analysisCtx);
boolean joinMatchFound = analyzeJoinSimilarityCheckFuncExprArgs(matchedFuncExpr, assignsAndUnnests, matchedAssignOrUnnestIndex, analysisCtx);
if (selectMatchFound || joinMatchFound) {
return true;
}
return false;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator in project asterixdb by apache.
the class RemoveUnusedAssignAndAggregateRule method removeFromAssigns.
private int removeFromAssigns(AbstractLogicalOperator op, Set<LogicalVariable> toRemove, IOptimizationContext context) throws AlgebricksException {
switch(op.getOperatorTag()) {
case ASSIGN:
AssignOperator assign = (AssignOperator) op;
if (removeUnusedVarsAndExprs(toRemove, assign.getVariables(), assign.getExpressions())) {
context.computeAndSetTypeEnvironmentForOperator(assign);
isTransformed = true;
}
return assign.getVariables().size();
case AGGREGATE:
AggregateOperator agg = (AggregateOperator) op;
if (removeUnusedVarsAndExprs(toRemove, agg.getVariables(), agg.getExpressions())) {
context.computeAndSetTypeEnvironmentForOperator(agg);
isTransformed = true;
}
return agg.getVariables().size();
case UNNEST:
UnnestOperator uOp = (UnnestOperator) op;
LogicalVariable pVar = uOp.getPositionalVariable();
if (pVar != null && toRemove != null && toRemove.contains(pVar)) {
uOp.setPositionalVariable(null);
assignedVarSet.remove(pVar);
isTransformed = true;
}
break;
case UNIONALL:
UnionAllOperator unionOp = (UnionAllOperator) op;
if (removeUnusedVarsFromUnionAll(unionOp, toRemove)) {
context.computeAndSetTypeEnvironmentForOperator(unionOp);
isTransformed = true;
}
return unionOp.getVariableMappings().size();
case GROUP:
GroupByOperator groupByOp = (GroupByOperator) op;
if (removeUnusedVarsFromGroupBy(groupByOp, toRemove)) {
context.computeAndSetTypeEnvironmentForOperator(groupByOp);
isTransformed = true;
}
return groupByOp.getGroupByList().size() + groupByOp.getNestedPlans().size() + groupByOp.getDecorList().size();
default:
break;
}
return -1;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator in project asterixdb by apache.
the class PushUnnestDownThroughUnionRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator unnest = (AbstractLogicalOperator) opRef.getValue();
if (unnest.getOperatorTag() != LogicalOperatorTag.UNNEST) {
return false;
}
UnnestOperator unnestOpRef = (UnnestOperator) opRef.getValue();
Mutable<ILogicalOperator> unionOp = unnest.getInputs().get(0);
AbstractLogicalOperator unionAbstractOp = (AbstractLogicalOperator) unionOp.getValue();
if (unionAbstractOp.getOperatorTag() != LogicalOperatorTag.UNIONALL) {
return false;
}
LogicalVariable unnestVar1 = context.newVar();
UnnestOperator unnest1 = new UnnestOperator(unnestVar1, new MutableObject<ILogicalExpression>(unnestOpRef.getExpressionRef().getValue().cloneExpression()));
LogicalVariable unnestVar2 = context.newVar();
UnnestOperator unnest2 = new UnnestOperator(unnestVar2, new MutableObject<ILogicalExpression>(unnestOpRef.getExpressionRef().getValue().cloneExpression()));
//Getting the two topmost branched and adding them as an input to the unnests:
Mutable<ILogicalOperator> branch1 = unionAbstractOp.getInputs().get(0);
ILogicalOperator agg1 = branch1.getValue();
List<LogicalVariable> agg1_var = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(agg1, agg1_var);
Mutable<ILogicalOperator> branch2 = unionAbstractOp.getInputs().get(1);
ILogicalOperator agg2 = branch2.getValue();
List<LogicalVariable> agg2_var = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(agg2, agg2_var);
//Modifying the unnest so it has the right variable
List<LogicalVariable> var_unnest_1 = new ArrayList<LogicalVariable>();
unnest1.getExpressionRef().getValue().getUsedVariables(var_unnest_1);
unnest1.getExpressionRef().getValue().substituteVar(var_unnest_1.get(0), agg1_var.get(0));
List<LogicalVariable> var_unnest2 = new ArrayList<LogicalVariable>();
unnest2.getExpressionRef().getValue().getUsedVariables(var_unnest2);
unnest2.getExpressionRef().getValue().substituteVar(var_unnest2.get(0), agg2_var.get(0));
unnest1.getInputs().add(branch1);
unnest2.getInputs().add(branch2);
context.computeAndSetTypeEnvironmentForOperator(unnest1);
context.computeAndSetTypeEnvironmentForOperator(unnest2);
//creating a new union operator with the updated logical variables
List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>(1);
Triple<LogicalVariable, LogicalVariable, LogicalVariable> union_triple_vars = new Triple<LogicalVariable, LogicalVariable, LogicalVariable>(unnestVar1, unnestVar2, unnestOpRef.getVariables().get(0));
varMap.add(union_triple_vars);
UnionAllOperator unionOpFinal = new UnionAllOperator(varMap);
unionOpFinal.getInputs().add(new MutableObject<ILogicalOperator>(unnest1));
unionOpFinal.getInputs().add(new MutableObject<ILogicalOperator>(unnest2));
context.computeAndSetTypeEnvironmentForOperator(unionOpFinal);
opRef.setValue(unionOpFinal);
return true;
}
Aggregations