* Search pattern 2: $$ for aggregate [function-call: sequence()]
*/
@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
IFunctionInfo aggregateInfo;
AbstractFunctionCallExpression finalFunctionCall;
Mutable<ILogicalOperator> nextOperatorRef;
// 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 get the function through the function definition
aggregateInfo = getAggregateFunction(functionCall);
if (aggregateInfo == null) {
return false;
}
Mutable<ILogicalExpression> mutableVariableExpresion = ExpressionToolbox.findVariableExpression(mutableLogicalExpression);
if (mutableVariableExpresion == null) {
return false;
}
Mutable<ILogicalExpression> finalFunctionCallM = ExpressionToolbox
.findLastFunctionExpression(mutableLogicalExpression);
finalFunctionCall = (AbstractFunctionCallExpression) finalFunctionCallM.getValue();
// Build a subplan for replacing the sort distinct function with operators.
// Nested tuple source.
Mutable<ILogicalOperator> inputOperator = getInputOperator(assign.getInputs().get(0));
NestedTupleSourceOperator ntsOperator = new NestedTupleSourceOperator(inputOperator);
nextOperatorRef = new MutableObject<ILogicalOperator>(ntsOperator);
// Get variable that is being used for sort and distinct operators.
VariableReferenceExpression inputVariableRef = (VariableReferenceExpression) mutableVariableExpresion.getValue();
LogicalVariable inputVariable = inputVariableRef.getVariableReference();
// Unnest.
LogicalVariable unnestVariable = context.newVar();
UnnestOperator unnestOperator = getUnnestOperator(inputVariable, unnestVariable);
unnestOperator.getInputs().add(nextOperatorRef);
nextOperatorRef = new MutableObject<ILogicalOperator>(unnestOperator);
// Aggregate.
VariableReferenceExpression inputArg = new VariableReferenceExpression(unnestVariable);
finalFunctionCall.getArguments().get(0).setValue(inputArg);
Mutable<ILogicalExpression> aggregateArgs = functionCall.getArguments().get(0);
LogicalVariable aggregateVariable = assign.getVariables().get(0);
AggregateOperator aggregateOperator = getAggregateOperator(aggregateInfo, aggregateArgs, aggregateVariable);
aggregateOperator.getInputs().add(nextOperatorRef);
nextOperatorRef = new MutableObject<ILogicalOperator>(aggregateOperator);