use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class PushGroupByThroughProduct method canPushThrough.
private PushTestResult canPushThrough(GroupByOperator gby, ILogicalOperator branch, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> toPush, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> notToPush) throws AlgebricksException {
Collection<LogicalVariable> fromBranch = new HashSet<LogicalVariable>();
VariableUtilities.getLiveVariables(branch, fromBranch);
Collection<LogicalVariable> usedInGbyExprList = new ArrayList<LogicalVariable>();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getGroupByList()) {
p.second.getValue().getUsedVariables(usedInGbyExprList);
}
if (!fromBranch.containsAll(usedInGbyExprList)) {
return PushTestResult.FALSE;
}
Set<LogicalVariable> free = new HashSet<LogicalVariable>();
for (ILogicalPlan p : gby.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getValue(), free);
}
}
if (!fromBranch.containsAll(free)) {
return PushTestResult.FALSE;
}
Set<LogicalVariable> decorVarRhs = new HashSet<LogicalVariable>();
decorVarRhs.clear();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
ILogicalExpression expr = p.second.getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return PushTestResult.FALSE;
}
VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
LogicalVariable v = varRef.getVariableReference();
if (decorVarRhs.contains(v)) {
return PushTestResult.REPEATED_DECORS;
}
decorVarRhs.add(v);
if (fromBranch.contains(v)) {
toPush.add(p);
} else {
notToPush.add(p);
}
}
return PushTestResult.TRUE;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class PushAggFuncIntoStandaloneAggregateRule method pushAggregateFunction.
private boolean pushAggregateFunction(AggregateOperator aggOp, AssignOperator assignOp, IOptimizationContext context) throws AlgebricksException {
Mutable<ILogicalOperator> opRef3 = aggOp.getInputs().get(0);
AbstractLogicalOperator op3 = (AbstractLogicalOperator) opRef3.getValue();
// If there's a group by below the agg, then we want to have the agg pushed into the group by.
if (op3.getOperatorTag() == LogicalOperatorTag.GROUP) {
return false;
}
if (aggOp.getVariables().size() != 1) {
return false;
}
ILogicalExpression aggExpr = aggOp.getExpressions().get(0).getValue();
if (aggExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression origAggFuncExpr = (AbstractFunctionCallExpression) aggExpr;
if (origAggFuncExpr.getFunctionIdentifier() != BuiltinFunctions.LISTIFY) {
return false;
}
LogicalVariable aggVar = aggOp.getVariables().get(0);
List<LogicalVariable> used = new LinkedList<LogicalVariable>();
VariableUtilities.getUsedVariables(assignOp, used);
if (!used.contains(aggVar)) {
return false;
}
List<Mutable<ILogicalExpression>> srcAssignExprRefs = new LinkedList<Mutable<ILogicalExpression>>();
if (fingAggFuncExprRef(assignOp.getExpressions(), aggVar, srcAssignExprRefs) == false) {
return false;
}
if (srcAssignExprRefs.isEmpty()) {
return false;
}
AbstractFunctionCallExpression aggOpExpr = (AbstractFunctionCallExpression) aggOp.getExpressions().get(0).getValue();
aggOp.getExpressions().clear();
aggOp.getVariables().clear();
for (Mutable<ILogicalExpression> srcAssignExprRef : srcAssignExprRefs) {
AbstractFunctionCallExpression assignFuncExpr = (AbstractFunctionCallExpression) srcAssignExprRef.getValue();
FunctionIdentifier aggFuncIdent = BuiltinFunctions.getAggregateFunction(assignFuncExpr.getFunctionIdentifier());
// Push the agg func into the agg op.
List<Mutable<ILogicalExpression>> aggArgs = new ArrayList<Mutable<ILogicalExpression>>();
aggArgs.add(aggOpExpr.getArguments().get(0));
AggregateFunctionCallExpression aggFuncExpr = BuiltinFunctions.makeAggregateFunctionExpression(aggFuncIdent, aggArgs);
LogicalVariable newVar = context.newVar();
aggOp.getVariables().add(newVar);
aggOp.getExpressions().add(new MutableObject<ILogicalExpression>(aggFuncExpr));
// The assign now just "renames" the variable to make sure the upstream plan still works.
srcAssignExprRef.setValue(new VariableReferenceExpression(newVar));
}
context.computeAndSetTypeEnvironmentForOperator(aggOp);
context.computeAndSetTypeEnvironmentForOperator(assignOp);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AsterixIntroduceGroupByCombinerRule method processNullTest.
@SuppressWarnings("unchecked")
@Override
protected void processNullTest(IOptimizationContext context, GroupByOperator nestedGby, List<LogicalVariable> aggregateVarsProducedByCombiner) {
IFunctionInfo finfoEq = context.getMetadataProvider().lookupFunction(BuiltinFunctions.IS_SYSTEM_NULL);
SelectOperator selectNonSystemNull;
if (aggregateVarsProducedByCombiner.size() == 1) {
ILogicalExpression isSystemNullTest = new ScalarFunctionCallExpression(finfoEq, new MutableObject<ILogicalExpression>(new VariableReferenceExpression(aggregateVarsProducedByCombiner.get(0))));
IFunctionInfo finfoNot = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NOT);
ScalarFunctionCallExpression nonSystemNullTest = new ScalarFunctionCallExpression(finfoNot, new MutableObject<ILogicalExpression>(isSystemNullTest));
selectNonSystemNull = new SelectOperator(new MutableObject<ILogicalExpression>(nonSystemNullTest), false, null);
} else {
List<Mutable<ILogicalExpression>> isSystemNullTestList = new ArrayList<Mutable<ILogicalExpression>>();
for (LogicalVariable aggVar : aggregateVarsProducedByCombiner) {
ILogicalExpression isSystemNullTest = new ScalarFunctionCallExpression(finfoEq, new MutableObject<ILogicalExpression>(new VariableReferenceExpression(aggVar)));
IFunctionInfo finfoNot = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NOT);
ScalarFunctionCallExpression nonSystemNullTest = new ScalarFunctionCallExpression(finfoNot, new MutableObject<ILogicalExpression>(isSystemNullTest));
isSystemNullTestList.add(new MutableObject<ILogicalExpression>(nonSystemNullTest));
}
IFunctionInfo finfoAnd = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.AND);
selectNonSystemNull = new SelectOperator(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(finfoAnd, isSystemNullTestList)), false, null);
}
//add the not-system-null check into the nested pipeline
Mutable<ILogicalOperator> ntsBeforeNestedGby = nestedGby.getInputs().get(0);
nestedGby.getInputs().set(0, new MutableObject<ILogicalOperator>(selectNonSystemNull));
selectNonSystemNull.getInputs().add(ntsBeforeNestedGby);
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class NestGroupByRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
if (op1.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
return false;
}
SubplanOperator subplan = (SubplanOperator) op1;
if (subplan.getNestedPlans().size() != 1) {
return false;
}
ILogicalPlan p = subplan.getNestedPlans().get(0);
if (p.getRoots().size() != 1) {
return false;
}
Set<LogicalVariable> free = new HashSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, free);
if (free.size() != 1) {
return false;
}
LogicalVariable fVar = null;
for (LogicalVariable v : free) {
fVar = v;
break;
}
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
if (op2.getOperatorTag() != LogicalOperatorTag.GROUP) {
return false;
}
GroupByOperator gby = (GroupByOperator) op2;
if (gby.getNestedPlans().size() != 1) {
return false;
}
ILogicalPlan p2 = gby.getNestedPlans().get(0);
if (p2.getRoots().size() != 1) {
return false;
}
Mutable<ILogicalOperator> r2 = p2.getRoots().get(0);
AbstractLogicalOperator opr2 = (AbstractLogicalOperator) r2.getValue();
if (opr2.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
return false;
}
AggregateOperator aggOuter = (AggregateOperator) opr2;
int posInAggList = aggOuter.getVariables().indexOf(fVar);
if (posInAggList < 0) {
return false;
}
AbstractLogicalOperator outerAggSon = (AbstractLogicalOperator) aggOuter.getInputs().get(0).getValue();
if (outerAggSon.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
return false;
}
ILogicalExpression eAgg = aggOuter.getExpressions().get(posInAggList).getValue();
if (eAgg.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression listifyCall = (AbstractFunctionCallExpression) eAgg;
if (listifyCall.getFunctionIdentifier() != BuiltinFunctions.LISTIFY) {
return false;
}
ILogicalExpression argListify = listifyCall.getArguments().get(0).getValue();
if (argListify.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return false;
}
Mutable<ILogicalOperator> r = p.getRoots().get(0);
AbstractLogicalOperator opInS = (AbstractLogicalOperator) r.getValue();
if (opInS.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
return false;
}
AggregateOperator aggInner = (AggregateOperator) opInS;
do {
opInS = (AbstractLogicalOperator) opInS.getInputs().get(0).getValue();
} while (opInS.getOperatorTag() == LogicalOperatorTag.ASSIGN);
if (opInS.getOperatorTag() != LogicalOperatorTag.GROUP) {
return false;
}
AbstractLogicalOperator unnestParent = opInS;
AbstractLogicalOperator opUnder = (AbstractLogicalOperator) opInS.getInputs().get(0).getValue();
// skip Assigns
while (opUnder.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
unnestParent = opUnder;
opUnder = (AbstractLogicalOperator) opUnder.getInputs().get(0).getValue();
}
if (opUnder.getOperatorTag() != LogicalOperatorTag.UNNEST) {
return false;
}
UnnestOperator unnest = (UnnestOperator) opUnder;
AbstractLogicalOperator unnestSon = (AbstractLogicalOperator) unnest.getInputs().get(0).getValue();
if (unnestSon.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
return false;
}
NestedTupleSourceOperator innerNts = (NestedTupleSourceOperator) unnestSon;
ILogicalExpression eUnnest = unnest.getExpressionRef().getValue();
if (eUnnest.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression uf = (AbstractFunctionCallExpression) eUnnest;
if (uf.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
return false;
}
ILogicalExpression scanArg = uf.getArguments().get(0).getValue();
if (scanArg.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return false;
}
if (((VariableReferenceExpression) scanArg).getVariableReference() != fVar) {
return false;
}
LogicalVariable uVar = unnest.getVariable();
GroupByOperator innerGby = (GroupByOperator) opInS;
Set<LogicalVariable> freeInInnerGby = new HashSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInSubplans(innerGby, freeInInnerGby);
for (LogicalVariable v : freeInInnerGby) {
if (v != uVar) {
return false;
}
}
unnestParent.getInputs().get(0).setValue(innerNts);
LogicalVariable listifiedVar = ((VariableReferenceExpression) argListify).getVariableReference();
substInSubplan(aggInner, uVar, listifiedVar, context);
gby.getNestedPlans().add(p);
innerNts.getDataSourceReference().setValue(gby);
opRef.setValue(gby);
OperatorPropertiesUtil.typePlan(p, context);
OperatorPropertiesUtil.typePlan(p2, context);
context.computeAndSetTypeEnvironmentForOperator(gby);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AbstractPreclusteredGroupByPOperator method getRequiredPropertiesForChildren.
@Override
public PhysicalRequirements getRequiredPropertiesForChildren(ILogicalOperator op, IPhysicalPropertiesVector reqdByParent, IOptimizationContext context) {
GroupByOperator gby = (GroupByOperator) op;
StructuralPropertiesVector[] pv = new StructuralPropertiesVector[1];
if (gby.isGroupAll() && gby.isGlobal()) {
if (op.getExecutionMode() == ExecutionMode.UNPARTITIONED) {
pv[0] = new StructuralPropertiesVector(IPartitioningProperty.UNPARTITIONED, null);
return new PhysicalRequirements(pv, IPartitioningRequirementsCoordinator.NO_COORDINATION);
} else {
return emptyUnaryRequirements();
}
}
List<ILocalStructuralProperty> localProps = new ArrayList<>();
Set<LogicalVariable> gbvars = new ListSet<>(columnList);
LocalGroupingProperty groupProp = new LocalGroupingProperty(gbvars, new ArrayList<>(columnList));
boolean goon = true;
for (ILogicalPlan p : gby.getNestedPlans()) {
// groupings
for (Mutable<ILogicalOperator> r : p.getRoots()) {
AbstractLogicalOperator op1 = (AbstractLogicalOperator) r.getValue();
if (op1.getOperatorTag() == LogicalOperatorTag.AGGREGATE) {
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
IPhysicalOperator pop2 = op2.getPhysicalOperator();
if (pop2 instanceof AbstractPreclusteredGroupByPOperator) {
List<LogicalVariable> gbyColumns = ((AbstractPreclusteredGroupByPOperator) pop2).getGbyColumns();
List<LogicalVariable> sndOrder = new ArrayList<>();
sndOrder.addAll(gbyColumns);
Set<LogicalVariable> freeVars = new HashSet<>();
try {
OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(op2, freeVars);
} catch (AlgebricksException e) {
throw new IllegalStateException(e);
}
// Only considers group key variables defined out-side the outer-most group-by operator.
sndOrder.retainAll(freeVars);
groupProp.getColumnSet().addAll(sndOrder);
groupProp.getPreferredOrderEnforcer().addAll(sndOrder);
goon = false;
break;
}
}
}
if (!goon) {
break;
}
}
localProps.add(groupProp);
if (reqdByParent != null) {
// propagate parent requirements
List<ILocalStructuralProperty> lpPar = reqdByParent.getLocalProperties();
if (lpPar != null) {
boolean allOk = true;
List<ILocalStructuralProperty> props = new ArrayList<>(lpPar.size());
for (ILocalStructuralProperty prop : lpPar) {
if (prop.getPropertyType() != PropertyType.LOCAL_ORDER_PROPERTY) {
allOk = false;
break;
}
LocalOrderProperty lop = (LocalOrderProperty) prop;
List<OrderColumn> orderColumns = new ArrayList<>();
List<OrderColumn> ords = lop.getOrderColumns();
for (OrderColumn ord : ords) {
Pair<LogicalVariable, Mutable<ILogicalExpression>> p = getGbyPairByRhsVar(gby, ord.getColumn());
if (p == null) {
p = getDecorPairByRhsVar(gby, ord.getColumn());
if (p == null) {
allOk = false;
break;
}
}
ILogicalExpression e = p.second.getValue();
if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
throw new IllegalStateException("Right hand side of group-by assignment should have been normalized to a variable reference.");
}
LogicalVariable v = ((VariableReferenceExpression) e).getVariableReference();
orderColumns.add(new OrderColumn(v, ord.getOrder()));
}
props.add(new LocalOrderProperty(orderColumns));
}
List<FunctionalDependency> fdList = new ArrayList<>();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorPair : gby.getDecorList()) {
List<LogicalVariable> hd = gby.getGbyVarList();
List<LogicalVariable> tl = new ArrayList<>();
tl.add(((VariableReferenceExpression) decorPair.second.getValue()).getVariableReference());
fdList.add(new FunctionalDependency(hd, tl));
}
if (allOk && PropertiesUtil.matchLocalProperties(localProps, props, new HashMap<>(), fdList)) {
localProps = props;
}
}
}
IPartitioningProperty pp = null;
AbstractLogicalOperator aop = (AbstractLogicalOperator) op;
if (aop.getExecutionMode() == ExecutionMode.PARTITIONED) {
pp = new UnorderedPartitionedProperty(new ListSet<>(columnList), context.getComputationNodeDomain());
}
pv[0] = new StructuralPropertiesVector(pp, localProps);
return new PhysicalRequirements(pv, IPartitioningRequirementsCoordinator.NO_COORDINATION);
}
Aggregations