// but it's certainly pleasant to have the final result grouped
// on nodes by group by columns.
final boolean newLevel = !(_it.isHashedBy(affectedComponent, groupByColumns));
if (newLevel) {
affectedComponent.setHashIndexes(groupByColumns);
new OperatorComponent(affectedComponent,
ParserUtil.generateUniqueName("OPERATOR"), _cg.getQueryPlan())
.addOperator(firstAgg);
} else
affectedComponent.addOperator(firstAgg);
} else {
// Sometimes groupByVEs contains other functions, so we have to
// use projections instead of simple groupBy
// always new level
if (affectedComponent.getHashExpressions() != null
&& !affectedComponent.getHashExpressions().isEmpty())
throw new RuntimeException(
"Too complex: cannot have hashExpression both for joinCondition and groupBy!");
// WARNING: groupByVEs cannot be used on two places: that's why
// we do deep copy
final ProjectOperator groupByProj = new ProjectOperator(
(List<ValueExpression>) DeepCopy.copy(groupByVEs));
if (!(groupByProj.getExpressions() == null || groupByProj.getExpressions()
.isEmpty()))
firstAgg.setGroupByProjection(groupByProj);
// current component
affectedComponent.setHashExpressions((List<ValueExpression>) DeepCopy
.copy(groupByVEs));
new OperatorComponent(affectedComponent, ParserUtil.generateUniqueName("OPERATOR"),
_cg.getQueryPlan()).addOperator(firstAgg);
}
} else
throw new RuntimeException("For now only one aggregate function supported!");