// 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.
// Create a new assign for a TRUE variable.
LogicalVariable trueVar = context.newVar();
IPointable p = (BooleanPointable) BooleanPointable.FACTORY.createPointable();
XDMConstants.setTrue(p);
VXQueryConstantValue cv = new VXQueryConstantValue(SequenceType.create(BuiltinTypeRegistry.XS_BOOLEAN,
Quantifier.QUANT_ONE), p.getByteArray());
AssignOperator trueAssignOp = new AssignOperator(trueVar, new MutableObject<ILogicalExpression>(
new ConstantExpression(cv)));
ILogicalOperator aggInput = aggregate.getInputs().get(0).getValue();
aggregate.getInputs().get(0).setValue(trueAssignOp);
trueAssignOp.getInputs().add(new MutableObject<ILogicalOperator>(aggInput));
// Set partitioning variable.
// TODO Review why this is not valid in 0.2.6
// aggregate.setPartitioningVariable(trueVar);