use of org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable in project asterixdb by apache.
the class CopyLimitDownRule method rewritePre.
@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.LIMIT) {
return false;
}
LimitOperator limitOp = (LimitOperator) op;
if (!limitOp.isTopmostLimitOp()) {
return false;
}
List<LogicalVariable> limitUsedVars = new ArrayList<>();
VariableUtilities.getUsedVariables(limitOp, limitUsedVars);
Mutable<ILogicalOperator> safeOpRef = null;
Mutable<ILogicalOperator> candidateOpRef = limitOp.getInputs().get(0);
List<LogicalVariable> candidateProducedVars = new ArrayList<>();
while (true) {
candidateProducedVars.clear();
ILogicalOperator candidateOp = candidateOpRef.getValue();
LogicalOperatorTag candidateOpTag = candidateOp.getOperatorTag();
if (candidateOp.getInputs().size() > 1 || !candidateOp.isMap() || candidateOpTag == LogicalOperatorTag.SELECT || candidateOpTag == LogicalOperatorTag.LIMIT || candidateOpTag == LogicalOperatorTag.UNNEST_MAP || !OperatorPropertiesUtil.disjoint(limitUsedVars, candidateProducedVars)) {
break;
}
safeOpRef = candidateOpRef;
candidateOpRef = safeOpRef.getValue().getInputs().get(0);
}
if (safeOpRef != null) {
ILogicalOperator safeOp = safeOpRef.getValue();
Mutable<ILogicalOperator> unsafeOpRef = safeOp.getInputs().get(0);
ILogicalOperator unsafeOp = unsafeOpRef.getValue();
LimitOperator limitCloneOp = null;
if (limitOp.getOffset().getValue() == null) {
limitCloneOp = new LimitOperator(limitOp.getMaxObjects().getValue(), false);
} else {
// Need to add an offset to the given limit value
// since the original topmost limit will use the offset value.
// We can't apply the offset multiple times.
IFunctionInfo finfoAdd = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NUMERIC_ADD);
List<Mutable<ILogicalExpression>> addArgs = new ArrayList<>();
addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getMaxObjects().getValue().cloneExpression()));
addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getOffset().getValue().cloneExpression()));
ScalarFunctionCallExpression maxPlusOffset = new ScalarFunctionCallExpression(finfoAdd, addArgs);
limitCloneOp = new LimitOperator(maxPlusOffset, false);
}
limitCloneOp.setPhysicalOperator(new StreamLimitPOperator());
limitCloneOp.getInputs().add(new MutableObject<ILogicalOperator>(unsafeOp));
limitCloneOp.setExecutionMode(unsafeOp.getExecutionMode());
OperatorPropertiesUtil.computeSchemaRecIfNull((AbstractLogicalOperator) unsafeOp);
limitCloneOp.recomputeSchema();
unsafeOpRef.setValue(limitCloneOp);
context.computeAndSetTypeEnvironmentForOperator(limitCloneOp);
context.addToDontApplySet(this, limitOp);
}
return safeOpRef != null;
}
use of org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable in project asterixdb by apache.
the class AbstractDecorrelationRule method buildVarExprList.
protected void buildVarExprList(Collection<LogicalVariable> vars, IOptimizationContext context, GroupByOperator g, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException {
for (LogicalVariable ov : vars) {
LogicalVariable newVar = context.newVar();
ILogicalExpression varExpr = new VariableReferenceExpression(newVar);
outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov, new MutableObject<ILogicalExpression>(varExpr)));
for (ILogicalPlan p : g.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true, context);
}
}
}
}
use of org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable in project asterixdb by apache.
the class AbstractExtractExprRule method extractExprIntoAssignOpRef.
protected LogicalVariable extractExprIntoAssignOpRef(ILogicalExpression gExpr, Mutable<ILogicalOperator> opRef2, IOptimizationContext context) throws AlgebricksException {
LogicalVariable v = context.newVar();
AssignOperator a = new AssignOperator(v, new MutableObject<ILogicalExpression>(gExpr));
a.getInputs().add(new MutableObject<ILogicalOperator>(opRef2.getValue()));
opRef2.setValue(a);
if (gExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
context.addNotToBeInlinedVar(v);
}
context.computeAndSetTypeEnvironmentForOperator(a);
return v;
}
use of org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable in project asterixdb by apache.
the class AbstractIntroduceCombinerRule method tryToPushAgg.
protected Pair<Boolean, Mutable<ILogicalOperator>> tryToPushAgg(AggregateOperator initAgg, GroupByOperator newGbyOp, Set<SimilarAggregatesInfo> toReplaceSet, IOptimizationContext context) throws AlgebricksException {
ArrayList<LogicalVariable> pushedVars = new ArrayList<LogicalVariable>();
ArrayList<Mutable<ILogicalExpression>> pushedExprs = new ArrayList<Mutable<ILogicalExpression>>();
List<LogicalVariable> initVars = initAgg.getVariables();
List<Mutable<ILogicalExpression>> initExprs = initAgg.getExpressions();
int numExprs = initVars.size();
// First make sure that all agg funcs are two step, otherwise we cannot use local aggs.
for (int i = 0; i < numExprs; i++) {
AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) initExprs.get(i).getValue();
if (!aggFun.isTwoStep()) {
return new Pair<Boolean, Mutable<ILogicalOperator>>(false, null);
}
}
boolean haveAggToReplace = false;
for (int i = 0; i < numExprs; i++) {
Mutable<ILogicalExpression> expRef = initExprs.get(i);
AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expRef.getValue();
IFunctionInfo fi1 = aggFun.getStepOneAggregate();
// Clone the aggregate's args.
List<Mutable<ILogicalExpression>> newArgs = new ArrayList<Mutable<ILogicalExpression>>(aggFun.getArguments().size());
for (Mutable<ILogicalExpression> er : aggFun.getArguments()) {
newArgs.add(new MutableObject<ILogicalExpression>(er.getValue().cloneExpression()));
}
IFunctionInfo fi2 = aggFun.getStepTwoAggregate();
SimilarAggregatesInfo inf = new SimilarAggregatesInfo();
LogicalVariable newAggVar = context.newVar();
pushedVars.add(newAggVar);
inf.stepOneResult = new VariableReferenceExpression(newAggVar);
inf.simAggs = new ArrayList<AggregateExprInfo>();
toReplaceSet.add(inf);
AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
pushedExprs.add(new MutableObject<ILogicalExpression>(aggLocal));
AggregateExprInfo aei = new AggregateExprInfo();
aei.aggExprRef = expRef;
aei.newFunInfo = fi2;
inf.simAggs.add(aei);
haveAggToReplace = true;
}
if (!pushedVars.isEmpty()) {
AggregateOperator pushedAgg = new AggregateOperator(pushedVars, pushedExprs);
pushedAgg.setExecutionMode(ExecutionMode.LOCAL);
// If newGbyOp is null, then we optimizing an aggregate without group by.
if (newGbyOp != null) {
// Cut and paste nested input pipelines of initAgg to pushedAgg's input
Mutable<ILogicalOperator> inputRef = initAgg.getInputs().get(0);
Mutable<ILogicalOperator> bottomRef = inputRef;
while (bottomRef.getValue().getInputs().size() > 0) {
bottomRef = bottomRef.getValue().getInputs().get(0);
}
ILogicalOperator oldNts = bottomRef.getValue();
initAgg.getInputs().clear();
initAgg.getInputs().add(new MutableObject<ILogicalOperator>(oldNts));
// Hook up the nested aggregate op with the outer group by.
NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(newGbyOp));
nts.setExecutionMode(ExecutionMode.LOCAL);
bottomRef.setValue(nts);
pushedAgg.getInputs().add(inputRef);
} else {
// The local aggregate operator is fed by the input of the original aggregate operator.
pushedAgg.getInputs().add(new MutableObject<ILogicalOperator>(initAgg.getInputs().get(0).getValue()));
// Reintroduce assign op for the global agg partitioning var.
initAgg.getInputs().get(0).setValue(pushedAgg);
pushedAgg.setGlobal(false);
context.computeAndSetTypeEnvironmentForOperator(pushedAgg);
}
return new Pair<Boolean, Mutable<ILogicalOperator>>(true, new MutableObject<ILogicalOperator>(pushedAgg));
} else {
return new Pair<Boolean, Mutable<ILogicalOperator>>(haveAggToReplace, null);
}
}
use of org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable in project asterixdb by apache.
the class ExtractFunctionsFromJoinConditionRule method assignFunctionExpressions.
private boolean assignFunctionExpressions(AbstractLogicalOperator joinOp, ILogicalExpression expr, IOptimizationContext context) throws AlgebricksException {
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) expr;
FunctionIdentifier fi = fexp.getFunctionIdentifier();
boolean modified = false;
if (fi.equals(AlgebricksBuiltinFunctions.AND) || fi.equals(AlgebricksBuiltinFunctions.OR) || processArgumentsToFunction(fi)) {
for (Mutable<ILogicalExpression> a : fexp.getArguments()) {
if (assignFunctionExpressions(joinOp, a.getValue(), context)) {
modified = true;
}
}
return modified;
} else if (AlgebricksBuiltinFunctions.isComparisonFunction(fi) || isComparisonFunction(fi)) {
for (Mutable<ILogicalExpression> exprRef : fexp.getArguments()) {
if (exprRef.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
LogicalVariable newVar = context.newVar();
AssignOperator newAssign = new AssignOperator(newVar, new MutableObject<ILogicalExpression>(exprRef.getValue().cloneExpression()));
newAssign.setExecutionMode(joinOp.getExecutionMode());
// Place assign below joinOp.
List<LogicalVariable> used = new ArrayList<LogicalVariable>();
VariableUtilities.getUsedVariables(newAssign, used);
Mutable<ILogicalOperator> leftBranchRef = joinOp.getInputs().get(0);
ILogicalOperator leftBranch = leftBranchRef.getValue();
List<LogicalVariable> leftBranchVariables = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(leftBranch, leftBranchVariables);
if (leftBranchVariables.containsAll(used)) {
// place assign on left branch
newAssign.getInputs().add(new MutableObject<ILogicalOperator>(leftBranch));
leftBranchRef.setValue(newAssign);
modified = true;
} else {
Mutable<ILogicalOperator> rightBranchRef = joinOp.getInputs().get(1);
ILogicalOperator rightBranch = rightBranchRef.getValue();
List<LogicalVariable> rightBranchVariables = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(rightBranch, rightBranchVariables);
if (rightBranchVariables.containsAll(used)) {
// place assign on right branch
newAssign.getInputs().add(new MutableObject<ILogicalOperator>(rightBranch));
rightBranchRef.setValue(newAssign);
modified = true;
}
}
if (modified) {
// Replace original expr with variable reference.
exprRef.setValue(new VariableReferenceExpression(newVar));
context.computeAndSetTypeEnvironmentForOperator(newAssign);
context.computeAndSetTypeEnvironmentForOperator(joinOp);
}
}
}
return modified;
} else {
return false;
}
}
Aggregations