Search in sources :

Example 66 with Aggregate

use of org.apache.calcite.rel.core.Aggregate in project calcite by apache.

the class DruidQuery method signature.

/**
 * Returns a string describing the operations inside this query.
 *
 * <p>For example, "sfpahol" means {@link TableScan} (s)
 * followed by {@link Filter} (f)
 * followed by {@link Project} (p)
 * followed by {@link Aggregate} (a)
 * followed by {@link Filter} (h)
 * followed by {@link Project} (o)
 * followed by {@link Sort} (l).
 *
 * @see #isValidSignature(String)
 */
String signature() {
    final StringBuilder b = new StringBuilder();
    boolean flag = false;
    for (RelNode rel : rels) {
        b.append(rel instanceof TableScan ? 's' : (rel instanceof Project && flag) ? 'o' : (rel instanceof Filter && flag) ? 'h' : rel instanceof Aggregate ? 'a' : rel instanceof Filter ? 'f' : rel instanceof Sort ? 'l' : rel instanceof Project ? 'p' : '!');
        flag = flag || rel instanceof Aggregate;
    }
    return b.toString();
}
Also used : TableScan(org.apache.calcite.rel.core.TableScan) Project(org.apache.calcite.rel.core.Project) AbstractRelNode(org.apache.calcite.rel.AbstractRelNode) RelNode(org.apache.calcite.rel.RelNode) Filter(org.apache.calcite.rel.core.Filter) Sort(org.apache.calcite.rel.core.Sort) Aggregate(org.apache.calcite.rel.core.Aggregate)

Example 67 with Aggregate

use of org.apache.calcite.rel.core.Aggregate in project calcite by apache.

the class DruidQuery method explainTerms.

@Override
public RelWriter explainTerms(RelWriter pw) {
    for (RelNode rel : rels) {
        if (rel instanceof TableScan) {
            TableScan tableScan = (TableScan) rel;
            pw.item("table", tableScan.getTable().getQualifiedName());
            pw.item("intervals", intervals);
        } else if (rel instanceof Filter) {
            pw.item("filter", ((Filter) rel).getCondition());
        } else if (rel instanceof Project) {
            if (((Project) rel).getInput() instanceof Aggregate) {
                pw.item("post_projects", ((Project) rel).getProjects());
            } else {
                pw.item("projects", ((Project) rel).getProjects());
            }
        } else if (rel instanceof Aggregate) {
            final Aggregate aggregate = (Aggregate) rel;
            pw.item("groups", aggregate.getGroupSet()).item("aggs", aggregate.getAggCallList());
        } else if (rel instanceof Sort) {
            final Sort sort = (Sort) rel;
            for (Ord<RelFieldCollation> ord : Ord.zip(sort.collation.getFieldCollations())) {
                pw.item("sort" + ord.i, ord.e.getFieldIndex());
            }
            for (Ord<RelFieldCollation> ord : Ord.zip(sort.collation.getFieldCollations())) {
                pw.item("dir" + ord.i, ord.e.shortString());
            }
            pw.itemIf("fetch", sort.fetch, sort.fetch != null);
        } else {
            throw new AssertionError("rel type not supported in Druid query " + rel);
        }
    }
    return pw;
}
Also used : TableScan(org.apache.calcite.rel.core.TableScan) Project(org.apache.calcite.rel.core.Project) AbstractRelNode(org.apache.calcite.rel.AbstractRelNode) RelNode(org.apache.calcite.rel.RelNode) Filter(org.apache.calcite.rel.core.Filter) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) Sort(org.apache.calcite.rel.core.Sort) Aggregate(org.apache.calcite.rel.core.Aggregate)

Example 68 with Aggregate

use of org.apache.calcite.rel.core.Aggregate in project druid by druid-io.

the class DruidQuery method computeAggregations.

/**
 * Returns aggregations corresponding to {@code aggregate.getAggCallList()}, in the same order.
 *
 * @param partialQuery          partial query
 * @param plannerContext        planner context
 * @param rowSignature          source row signature
 * @param virtualColumnRegistry re-usable virtual column references
 * @param rexBuilder            calcite RexBuilder
 * @param finalizeAggregations  true if this query should include explicit finalization for all of its
 *                              aggregators, where required. Useful for subqueries where Druid's native query layer
 *                              does not do this automatically.
 *
 * @return aggregations
 *
 * @throws CannotBuildQueryException if dimensions cannot be computed
 */
private static List<Aggregation> computeAggregations(final PartialDruidQuery partialQuery, final PlannerContext plannerContext, final RowSignature rowSignature, final VirtualColumnRegistry virtualColumnRegistry, final RexBuilder rexBuilder, final boolean finalizeAggregations) {
    final Aggregate aggregate = Preconditions.checkNotNull(partialQuery.getAggregate());
    final List<Aggregation> aggregations = new ArrayList<>();
    final String outputNamePrefix = Calcites.findUnusedPrefixForDigits("a", rowSignature.getColumnNames());
    for (int i = 0; i < aggregate.getAggCallList().size(); i++) {
        final String aggName = outputNamePrefix + i;
        final AggregateCall aggCall = aggregate.getAggCallList().get(i);
        final Aggregation aggregation = GroupByRules.translateAggregateCall(plannerContext, rowSignature, virtualColumnRegistry, rexBuilder, partialQuery.getSelectProject(), aggregations, aggName, aggCall, finalizeAggregations);
        if (aggregation == null) {
            if (null == plannerContext.getPlanningError()) {
                plannerContext.setPlanningError("Aggregation [%s] is not supported", aggCall);
            }
            throw new CannotBuildQueryException(aggregate, aggCall);
        }
        aggregations.add(aggregation);
    }
    return aggregations;
}
Also used : Aggregation(org.apache.druid.sql.calcite.aggregation.Aggregation) AggregateCall(org.apache.calcite.rel.core.AggregateCall) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList) ArrayList(java.util.ArrayList) Aggregate(org.apache.calcite.rel.core.Aggregate)

Example 69 with Aggregate

use of org.apache.calcite.rel.core.Aggregate in project druid by druid-io.

the class DruidQuery method computeSubtotals.

/**
 * Builds a {@link Subtotals} object based on {@link Aggregate#getGroupSets()}.
 */
private static Subtotals computeSubtotals(final PartialDruidQuery partialQuery, final RowSignature rowSignature) {
    final Aggregate aggregate = partialQuery.getAggregate();
    // dimBitMapping maps from input field position to group set position (dimension number).
    final int[] dimBitMapping;
    if (partialQuery.getSelectProject() != null) {
        dimBitMapping = new int[partialQuery.getSelectProject().getRowType().getFieldCount()];
    } else {
        dimBitMapping = new int[rowSignature.size()];
    }
    int i = 0;
    for (int dimBit : aggregate.getGroupSet()) {
        dimBitMapping[dimBit] = i++;
    }
    // Use dimBitMapping to remap groupSets (which is input-field-position based) into subtotals (which is
    // dimension-list-position based).
    final List<IntList> subtotals = new ArrayList<>();
    for (ImmutableBitSet groupSet : aggregate.getGroupSets()) {
        final IntList subtotal = new IntArrayList();
        for (int dimBit : groupSet) {
            subtotal.add(dimBitMapping[dimBit]);
        }
        subtotals.add(subtotal);
    }
    return new Subtotals(subtotals);
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList) ArrayList(java.util.ArrayList) Aggregate(org.apache.calcite.rel.core.Aggregate) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList) IntList(it.unimi.dsi.fastutil.ints.IntList)

Example 70 with Aggregate

use of org.apache.calcite.rel.core.Aggregate in project druid by druid-io.

the class ProjectAggregatePruneUnusedCallRule method onMatch.

@Override
public void onMatch(final RelOptRuleCall call) {
    final Project project = call.rel(0);
    final Aggregate aggregate = call.rel(1);
    final ImmutableBitSet projectBits = RelOptUtil.InputFinder.bits(project.getChildExps(), null);
    final int fieldCount = aggregate.getGroupCount() + aggregate.getAggCallList().size();
    if (fieldCount != aggregate.getRowType().getFieldCount()) {
        throw new ISE("Expected[%s] to have[%s] fields but it had[%s]", aggregate, fieldCount, aggregate.getRowType().getFieldCount());
    }
    final ImmutableBitSet callsToKeep = projectBits.intersect(ImmutableBitSet.range(aggregate.getGroupCount(), fieldCount));
    if (callsToKeep.cardinality() < aggregate.getAggCallList().size()) {
        // There are some aggregate calls to prune.
        final List<AggregateCall> newAggregateCalls = new ArrayList<>();
        for (int i : callsToKeep) {
            newAggregateCalls.add(aggregate.getAggCallList().get(i - aggregate.getGroupCount()));
        }
        final Aggregate newAggregate = aggregate.copy(aggregate.getTraitSet(), aggregate.getInput(), aggregate.getGroupSet(), aggregate.getGroupSets(), newAggregateCalls);
        // Project that will match the old Aggregate in its row type, so we can layer the original "project" on top.
        final List<RexNode> fixUpProjects = new ArrayList<>();
        final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
        // Project the group set unchanged.
        for (int i = 0; i < aggregate.getGroupCount(); i++) {
            fixUpProjects.add(rexBuilder.makeInputRef(newAggregate, i));
        }
        // Replace pruned-out aggregators with NULLs.
        for (int i = aggregate.getGroupCount(), j = aggregate.getGroupCount(); i < fieldCount; i++) {
            if (callsToKeep.get(i)) {
                fixUpProjects.add(rexBuilder.makeInputRef(newAggregate, j++));
            } else {
                fixUpProjects.add(rexBuilder.makeNullLiteral(aggregate.getRowType().getFieldList().get(i).getType()));
            }
        }
        call.transformTo(call.builder().push(newAggregate).project(fixUpProjects).project(project.getChildExps()).build());
        call.getPlanner().setImportance(project, 0.0);
    }
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) Project(org.apache.calcite.rel.core.Project) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) ISE(org.apache.druid.java.util.common.ISE) Aggregate(org.apache.calcite.rel.core.Aggregate) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

Aggregate (org.apache.calcite.rel.core.Aggregate)75 RelNode (org.apache.calcite.rel.RelNode)44 ArrayList (java.util.ArrayList)39 AggregateCall (org.apache.calcite.rel.core.AggregateCall)37 RexNode (org.apache.calcite.rex.RexNode)32 RelBuilder (org.apache.calcite.tools.RelBuilder)27 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)27 LogicalAggregate (org.apache.calcite.rel.logical.LogicalAggregate)23 RexBuilder (org.apache.calcite.rex.RexBuilder)22 Project (org.apache.calcite.rel.core.Project)21 HashMap (java.util.HashMap)17 RexInputRef (org.apache.calcite.rex.RexInputRef)15 Join (org.apache.calcite.rel.core.Join)14 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)14 RelDataType (org.apache.calcite.rel.type.RelDataType)14 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)14 Filter (org.apache.calcite.rel.core.Filter)13 HiveAggregate (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate)13 List (java.util.List)12 ImmutableList (com.google.common.collect.ImmutableList)11