Search in sources :

Example 1 with AggregationFunctionColumnNode

use of com.facebook.presto.druid.DruidAggregationColumnNode.AggregationFunctionColumnNode in project presto by prestodb.

the class DruidPushdownUtils method computeAggregationNodes.

public static List<DruidAggregationColumnNode> computeAggregationNodes(AggregationNode aggregationNode) {
    int groupByKeyIndex = 0;
    ImmutableList.Builder<DruidAggregationColumnNode> nodeBuilder = ImmutableList.builder();
    for (VariableReferenceExpression outputColumn : aggregationNode.getOutputVariables()) {
        AggregationNode.Aggregation aggregation = aggregationNode.getAggregations().get(outputColumn);
        if (aggregation != null) {
            if (aggregation.getFilter().isPresent() || aggregation.isDistinct() || aggregation.getOrderBy().isPresent()) {
                throw new PrestoException(DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION, "Unsupported aggregation node " + aggregationNode);
            }
            if (aggregation.getMask().isPresent()) {
                // E.g. `SELECT count(distinct COL_A), sum(COL_B) FROM myTable` to Druid as `SELECT distinctCount(COL_A), sum(COL_B) FROM myTable`
                if (aggregation.getCall().getDisplayName().equalsIgnoreCase(COUNT_FUNCTION_NAME) && aggregation.getMask().get().getName().equalsIgnoreCase(aggregation.getArguments().get(0) + DISTINCT_MASK)) {
                    nodeBuilder.add(new AggregationFunctionColumnNode(outputColumn, new CallExpression(aggregation.getCall().getSourceLocation(), DRUID_COUNT_DISTINCT_FUNCTION_NAME, aggregation.getCall().getFunctionHandle(), aggregation.getCall().getType(), aggregation.getCall().getArguments())));
                    continue;
                }
                // Druid doesn't support push down aggregation functions other than count on top of distinct function.
                throw new PrestoException(DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION, "Unsupported aggregation node with mask " + aggregationNode);
            }
            if (handlePushDownSingleDistinctCount(nodeBuilder, aggregationNode, outputColumn, aggregation)) {
                continue;
            }
            nodeBuilder.add(new AggregationFunctionColumnNode(outputColumn, aggregation.getCall()));
        } else {
            // group by output
            VariableReferenceExpression inputColumn = aggregationNode.getGroupingKeys().get(groupByKeyIndex);
            nodeBuilder.add(new GroupByColumnNode(inputColumn, outputColumn));
            groupByKeyIndex++;
        }
    }
    return nodeBuilder.build();
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) GroupByColumnNode(com.facebook.presto.druid.DruidAggregationColumnNode.GroupByColumnNode) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) PrestoException(com.facebook.presto.spi.PrestoException) AggregationFunctionColumnNode(com.facebook.presto.druid.DruidAggregationColumnNode.AggregationFunctionColumnNode) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Example 2 with AggregationFunctionColumnNode

use of com.facebook.presto.druid.DruidAggregationColumnNode.AggregationFunctionColumnNode in project presto by prestodb.

the class DruidPushdownUtils method handlePushDownSingleDistinctCount.

/**
 * Try to push down query like: `SELECT count(distinct $COLUMN) FROM myTable` to Druid as `SELECT distinctCount($COLUMN) FROM myTable`.
 * This function only handles the case of an AggregationNode (COUNT on $COLUMN) on top of an AggregationNode(of non-aggregate on $COLUMN).
 *
 * @return true if push down successfully otherwise false.
 */
private static boolean handlePushDownSingleDistinctCount(ImmutableList.Builder<DruidAggregationColumnNode> nodeBuilder, AggregationNode aggregationNode, VariableReferenceExpression outputColumn, AggregationNode.Aggregation aggregation) {
    if (!aggregation.getCall().getDisplayName().equalsIgnoreCase(COUNT_FUNCTION_NAME)) {
        return false;
    }
    List<RowExpression> arguments = aggregation.getCall().getArguments();
    if (arguments.size() != 1) {
        return false;
    }
    RowExpression aggregationArgument = arguments.get(0);
    // Handle the case of Count Aggregation on top of a Non-Agg GroupBy Aggregation.
    if (!(aggregationNode.getSource() instanceof AggregationNode)) {
        return false;
    }
    AggregationNode sourceAggregationNode = (AggregationNode) aggregationNode.getSource();
    Set<String> sourceAggregationGroupSet = getGroupKeys(sourceAggregationNode.getGroupingKeys());
    Set<String> aggregationGroupSet = getGroupKeys(aggregationNode.getGroupingKeys());
    aggregationGroupSet.add(aggregationArgument.toString());
    if (!sourceAggregationGroupSet.containsAll(aggregationGroupSet) && aggregationGroupSet.containsAll(sourceAggregationGroupSet)) {
        return false;
    }
    nodeBuilder.add(new AggregationFunctionColumnNode(outputColumn, new CallExpression(aggregation.getCall().getSourceLocation(), DRUID_COUNT_DISTINCT_FUNCTION_NAME, aggregation.getFunctionHandle(), aggregation.getCall().getType(), ImmutableList.of(aggregationArgument))));
    return true;
}
Also used : RowExpression(com.facebook.presto.spi.relation.RowExpression) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) AggregationFunctionColumnNode(com.facebook.presto.druid.DruidAggregationColumnNode.AggregationFunctionColumnNode) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Aggregations

AggregationFunctionColumnNode (com.facebook.presto.druid.DruidAggregationColumnNode.AggregationFunctionColumnNode)2 AggregationNode (com.facebook.presto.spi.plan.AggregationNode)2 CallExpression (com.facebook.presto.spi.relation.CallExpression)2 GroupByColumnNode (com.facebook.presto.druid.DruidAggregationColumnNode.GroupByColumnNode)1 PrestoException (com.facebook.presto.spi.PrestoException)1 RowExpression (com.facebook.presto.spi.relation.RowExpression)1 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)1 ImmutableList (com.google.common.collect.ImmutableList)1