*/
public class ConsolidateAssignAggregateRule extends AbstractVXQueryAggregateRule {
@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
IFunctionInfo aggregateInfo;
AbstractFunctionCallExpression finalFunctionCall;
Mutable<ILogicalExpression> mutableVariableExpresion;
// Check if assign is for aggregate function.
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
return false;
}
AssignOperator assign = (AssignOperator) op;
Mutable<ILogicalExpression> mutableLogicalExpression = assign.getExpressions().get(0);
ILogicalExpression logicalExpression = mutableLogicalExpression.getValue();
if (logicalExpression.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression functionCall = (AbstractFunctionCallExpression) logicalExpression;
// TODO Use the function definition
aggregateInfo = getAggregateFunction(functionCall);
if (aggregateInfo == null) {
return false;
}
mutableVariableExpresion = ExpressionToolbox.findVariableExpression(mutableLogicalExpression);
if (mutableVariableExpresion == null) {
return false;
}
Mutable<ILogicalExpression> finalFunctionCallM = ExpressionToolbox
.findLastFunctionExpression(mutableLogicalExpression);
finalFunctionCall = (AbstractFunctionCallExpression) finalFunctionCallM.getValue();
// Variable details.
VariableReferenceExpression variableReference = (VariableReferenceExpression) mutableVariableExpresion
.getValue();
int variableId = variableReference.getVariableReference().getId();
// Search for variable see if it is a aggregate sequence.
AbstractLogicalOperator opSearch = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
opSearch = findSequenceAggregateOperator(opSearch, variableId);
if (opSearch == null) {
return false;
}
AggregateOperator aggregate = (AggregateOperator) opSearch;
// Check to see if the expression is a function and sort-distinct-nodes-asc-or-atomics.
ILogicalExpression logicalExpressionSearch = (ILogicalExpression) aggregate.getExpressions().get(0).getValue();
if (logicalExpressionSearch.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression functionCallSearch = (AbstractFunctionCallExpression) logicalExpressionSearch;
if (!functionCallSearch.getFunctionIdentifier().equals(BuiltinOperators.SEQUENCE.getFunctionIdentifier())) {
return false;
}
// Set the aggregate function to use new aggregate option.
functionCallSearch.setFunctionInfo(aggregateInfo);
// Alter arguments to include the aggregate arguments.
finalFunctionCall.getArguments().get(0).setValue(functionCallSearch.getArguments().get(0).getValue());
// Move the arguments for the assign function into aggregate.
functionCallSearch.getArguments().get(0).setValue(functionCall.getArguments().get(0).getValue());
// Remove the aggregate assign, by creating a no op.
assign.getExpressions().get(0).setValue(variableReference);
// Add an assign operator to set up partitioning variable.