Search in sources :

Example 1 with DistinctCountParseNode

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;
}
Also used : AliasedNode(org.apache.phoenix.parse.AliasedNode) Hint(org.apache.phoenix.parse.HintNode.Hint) DistinctCountParseNode(org.apache.phoenix.parse.DistinctCountParseNode) Expression(org.apache.phoenix.expression.Expression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) DistinctCountParseNode(org.apache.phoenix.parse.DistinctCountParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) SQLExceptionInfo(org.apache.phoenix.exception.SQLExceptionInfo)

Aggregations

SQLExceptionInfo (org.apache.phoenix.exception.SQLExceptionInfo)1 CoerceExpression (org.apache.phoenix.expression.CoerceExpression)1 Expression (org.apache.phoenix.expression.Expression)1 AliasedNode (org.apache.phoenix.parse.AliasedNode)1 DistinctCountParseNode (org.apache.phoenix.parse.DistinctCountParseNode)1 Hint (org.apache.phoenix.parse.HintNode.Hint)1 ParseNode (org.apache.phoenix.parse.ParseNode)1