use of org.apache.phoenix.parse.DistinctCountParseNode in project phoenix by apache.
the class GroupByCompiler method compile.
/**
* Get list of columns in the GROUP BY clause.
* @param context query context kept between compilation of different query clauses
* @param statement SQL statement being compiled
* @return the {@link GroupBy} instance encapsulating the group by clause
* @throws ColumnNotFoundException if column name could not be resolved
* @throws AmbiguousColumnException if an unaliased column name is ambiguous across multiple tables
*/
public static GroupBy compile(StatementContext context, SelectStatement statement, boolean isOrderPreserving) throws SQLException {
List<ParseNode> groupByNodes = statement.getGroupBy();
/**
* Distinct can use an aggregate plan if there's no group by.
* Otherwise, we need to insert a step after the Merge that dedups.
* Order by only allowed on columns in the select distinct
*/
boolean isUngroupedAggregate = false;
if (groupByNodes.isEmpty()) {
if (statement.isAggregate()) {
// TODO: PHOENIX-2989 suggests some ways to optimize the latter case
if (statement.getHint().hasHint(Hint.RANGE_SCAN) || statement.getHaving() != null) {
return GroupBy.UNGROUPED_GROUP_BY;
}
groupByNodes = Lists.newArrayListWithExpectedSize(statement.getSelect().size());
for (AliasedNode aliasedNode : statement.getSelect()) {
if (aliasedNode.getNode() instanceof DistinctCountParseNode) {
// only add children of DistinctCount nodes
groupByNodes.addAll(aliasedNode.getNode().getChildren());
} else {
// if we found anything else, do not attempt any further optimization
return GroupBy.UNGROUPED_GROUP_BY;
}
}
isUngroupedAggregate = true;
} else if (statement.isDistinct()) {
groupByNodes = Lists.newArrayListWithExpectedSize(statement.getSelect().size());
for (AliasedNode aliasedNode : statement.getSelect()) {
// for distinct at all select expression as group by conditions
groupByNodes.add(aliasedNode.getNode());
}
} else {
return GroupBy.EMPTY_GROUP_BY;
}
}
// Accumulate expressions in GROUP BY
ExpressionCompiler compiler = new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY);
List<Expression> expressions = Lists.newArrayListWithExpectedSize(groupByNodes.size());
for (int i = 0; i < groupByNodes.size(); i++) {
ParseNode node = groupByNodes.get(i);
Expression expression = node.accept(compiler);
if (!expression.isStateless()) {
if (compiler.isAggregate()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_GROUP_BY).setMessage(expression.toString()).build().buildException();
}
expressions.add(expression);
}
compiler.reset();
}
if (expressions.isEmpty()) {
return GroupBy.EMPTY_GROUP_BY;
}
GroupBy groupBy = new GroupBy.GroupByBuilder().setIsOrderPreserving(isOrderPreserving).setExpressions(expressions).setKeyExpressions(expressions).setIsUngroupedAggregate(isUngroupedAggregate).build();
return groupBy;
}
Aggregations