Search in sources :

Example 31 with AggregateCall

use of org.apache.calcite.rel.core.AggregateCall in project hive by apache.

the class HiveExpandDistinctAggregatesRule method createGroupingSets.

/**
   * @param aggregate: the original aggregate
   * @param argList: the original argList in aggregate
   * @param cleanArgList: the new argList without duplicates
   * @param map: the mapping from the original argList to the new argList
   * @param sourceOfForCountDistinct: the sorted positions of groupset
   * @return
   */
private Aggregate createGroupingSets(Aggregate aggregate, List<List<Integer>> argList, List<List<Integer>> cleanArgList, Map<Integer, Integer> map, List<Integer> sourceOfForCountDistinct) {
    final ImmutableBitSet groupSet = ImmutableBitSet.of(sourceOfForCountDistinct);
    final List<ImmutableBitSet> origGroupSets = new ArrayList<>();
    for (int i = 0; i < argList.size(); i++) {
        List<Integer> list = argList.get(i);
        ImmutableBitSet bitSet = ImmutableBitSet.of(list);
        int prev = origGroupSets.indexOf(bitSet);
        if (prev == -1) {
            origGroupSets.add(bitSet);
            cleanArgList.add(list);
        } else {
            map.put(i, prev);
        }
    }
    // Calcite expects the grouping sets sorted and without duplicates
    Collections.sort(origGroupSets, ImmutableBitSet.COMPARATOR);
    List<AggregateCall> aggregateCalls = new ArrayList<AggregateCall>();
    // Create GroupingID column
    AggregateCall aggCall = AggregateCall.create(HiveGroupingID.INSTANCE, false, new ImmutableList.Builder<Integer>().build(), -1, this.cluster.getTypeFactory().createSqlType(SqlTypeName.INTEGER), HiveGroupingID.INSTANCE.getName());
    aggregateCalls.add(aggCall);
    return new HiveAggregate(cluster, cluster.traitSetOf(HiveRelNode.CONVENTION), aggregate.getInput(), true, groupSet, origGroupSets, aggregateCalls);
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) HiveAggregate(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RexBuilder(org.apache.calcite.rex.RexBuilder) ArrayList(java.util.ArrayList)

Example 32 with AggregateCall

use of org.apache.calcite.rel.core.AggregateCall in project hive by apache.

the class HiveAggregate method deriveRowType.

public static RelDataType deriveRowType(RelDataTypeFactory typeFactory, final RelDataType inputRowType, boolean indicator, ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets, final List<AggregateCall> aggCalls) {
    final List<Integer> groupList = groupSet.asList();
    assert groupList.size() == groupSet.cardinality();
    final RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
    final List<RelDataTypeField> fieldList = inputRowType.getFieldList();
    final Set<String> containedNames = Sets.newHashSet();
    for (int groupKey : groupList) {
        containedNames.add(fieldList.get(groupKey).getName());
        builder.add(fieldList.get(groupKey));
    }
    if (indicator) {
        for (int groupKey : groupList) {
            final RelDataType booleanType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BOOLEAN), false);
            String name = "i$" + fieldList.get(groupKey).getName();
            int i = 0;
            while (containedNames.contains(name)) {
                name += "_" + i++;
            }
            containedNames.add(name);
            builder.add(name, booleanType);
        }
    }
    for (Ord<AggregateCall> aggCall : Ord.zip(aggCalls)) {
        String name;
        if (aggCall.e.name != null) {
            name = aggCall.e.name;
        } else {
            name = "$f" + (groupList.size() + aggCall.i);
        }
        int i = 0;
        while (containedNames.contains(name)) {
            name += "_" + i++;
        }
        containedNames.add(name);
        builder.add(name, aggCall.e.type);
    }
    return builder.build();
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 33 with AggregateCall

use of org.apache.calcite.rel.core.AggregateCall in project hive by apache.

the class HiveSubQRemoveRelBuilder method aggregate.

/** Creates an {@link org.apache.calcite.rel.core.Aggregate} with a list of
   * calls. */
public HiveSubQRemoveRelBuilder aggregate(GroupKey groupKey, Iterable<AggCall> aggCalls) {
    final RelDataType inputRowType = peek().getRowType();
    final List<RexNode> extraNodes = projects(inputRowType);
    final GroupKeyImpl groupKey_ = (GroupKeyImpl) groupKey;
    final ImmutableBitSet groupSet = ImmutableBitSet.of(registerExpressions(extraNodes, groupKey_.nodes));
    final ImmutableList<ImmutableBitSet> groupSets;
    if (groupKey_.nodeLists != null) {
        final int sizeBefore = extraNodes.size();
        final SortedSet<ImmutableBitSet> groupSetSet = new TreeSet<>(ImmutableBitSet.ORDERING);
        for (ImmutableList<RexNode> nodeList : groupKey_.nodeLists) {
            final ImmutableBitSet groupSet2 = ImmutableBitSet.of(registerExpressions(extraNodes, nodeList));
            if (!groupSet.contains(groupSet2)) {
                throw new IllegalArgumentException("group set element " + nodeList + " must be a subset of group key");
            }
            groupSetSet.add(groupSet2);
        }
        groupSets = ImmutableList.copyOf(groupSetSet);
        if (extraNodes.size() > sizeBefore) {
            throw new IllegalArgumentException("group sets contained expressions not in group key: " + extraNodes.subList(sizeBefore, extraNodes.size()));
        }
    } else {
        groupSets = ImmutableList.of(groupSet);
    }
    for (AggCall aggCall : aggCalls) {
        if (aggCall instanceof AggCallImpl) {
            final AggCallImpl aggCall1 = (AggCallImpl) aggCall;
            registerExpressions(extraNodes, aggCall1.operands);
            if (aggCall1.filter != null) {
                registerExpression(extraNodes, aggCall1.filter);
            }
        }
    }
    if (extraNodes.size() > inputRowType.getFieldCount()) {
        project(extraNodes);
    }
    final RelNode r = build();
    final List<AggregateCall> aggregateCalls = new ArrayList<>();
    for (AggCall aggCall : aggCalls) {
        final AggregateCall aggregateCall;
        if (aggCall instanceof AggCallImpl) {
            final AggCallImpl aggCall1 = (AggCallImpl) aggCall;
            final List<Integer> args = registerExpressions(extraNodes, aggCall1.operands);
            final int filterArg = aggCall1.filter == null ? -1 : registerExpression(extraNodes, aggCall1.filter);
            aggregateCall = AggregateCall.create(aggCall1.aggFunction, aggCall1.distinct, args, filterArg, groupSet.cardinality(), r, null, aggCall1.alias);
        } else {
            aggregateCall = ((AggCallImpl2) aggCall).aggregateCall;
        }
        aggregateCalls.add(aggregateCall);
    }
    assert ImmutableBitSet.ORDERING.isStrictlyOrdered(groupSets) : groupSets;
    for (ImmutableBitSet set : groupSets) {
        assert groupSet.contains(set);
    }
    RelNode aggregate = aggregateFactory.createAggregate(r, groupKey_.indicator, groupSet, groupSets, aggregateCalls);
    push(aggregate);
    return this;
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelNode(org.apache.calcite.rel.RelNode) TreeSet(java.util.TreeSet) RexNode(org.apache.calcite.rex.RexNode)

Example 34 with AggregateCall

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

the class GroupByRules method applyAggregate.

/**
   * Applies a filter -> project -> aggregate chain to a druidRel. Do not call this method unless
   * {@link #canApplyAggregate(DruidRel, Filter, Project, Aggregate)} returns true.
   *
   * @return new rel, or null if the chain cannot be applied
   */
private static DruidRel applyAggregate(final DruidRel druidRel, final Filter filter0, final Project project0, final Aggregate aggregate, final DruidOperatorTable operatorTable, final boolean approximateCountDistinct) {
    Preconditions.checkState(canApplyAggregate(druidRel, filter0, project0, aggregate), "Cannot applyAggregate.");
    final RowSignature sourceRowSignature;
    final boolean isNestedQuery = druidRel.getQueryBuilder().getGrouping() != null;
    if (isNestedQuery) {
        // Nested groupBy; source row signature is the output signature of druidRel.
        sourceRowSignature = druidRel.getOutputRowSignature();
    } else {
        sourceRowSignature = druidRel.getSourceRowSignature();
    }
    // Filter that should be applied before aggregating.
    final DimFilter filter;
    if (filter0 != null) {
        filter = Expressions.toFilter(operatorTable, druidRel.getPlannerContext(), sourceRowSignature, filter0.getCondition());
        if (filter == null) {
            // Can't plan this filter.
            return null;
        }
    } else if (druidRel.getQueryBuilder().getFilter() != null && !isNestedQuery) {
        // We're going to replace the existing druidRel, so inherit its filter.
        filter = druidRel.getQueryBuilder().getFilter();
    } else {
        filter = null;
    }
    // Projection that should be applied before aggregating.
    final Project project;
    if (project0 != null) {
        project = project0;
    } else if (druidRel.getQueryBuilder().getSelectProjection() != null && !isNestedQuery) {
        // We're going to replace the existing druidRel, so inherit its projection.
        project = druidRel.getQueryBuilder().getSelectProjection().getProject();
    } else {
        project = null;
    }
    final List<DimensionSpec> dimensions = Lists.newArrayList();
    final List<Aggregation> aggregations = Lists.newArrayList();
    final List<String> rowOrder = Lists.newArrayList();
    // Translate groupSet.
    final ImmutableBitSet groupSet = aggregate.getGroupSet();
    int dimOutputNameCounter = 0;
    for (int i : groupSet) {
        if (project != null && project.getChildExps().get(i) instanceof RexLiteral) {
            // Ignore literals in GROUP BY, so a user can write e.g. "GROUP BY 'dummy'" to group everything into a single
            // row. Add dummy rowOrder entry so NULLs come out. This is not strictly correct but it works as long as
            // nobody actually expects to see the literal.
            rowOrder.add(dimOutputName(dimOutputNameCounter++));
        } else {
            final RexNode rexNode = Expressions.fromFieldAccess(sourceRowSignature, project, i);
            final RowExtraction rex = Expressions.toRowExtraction(operatorTable, druidRel.getPlannerContext(), sourceRowSignature.getRowOrder(), rexNode);
            if (rex == null) {
                return null;
            }
            final SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
            final ValueType outputType = Calcites.getValueTypeForSqlTypeName(sqlTypeName);
            if (outputType == null) {
                throw new ISE("Cannot translate sqlTypeName[%s] to Druid type for field[%s]", sqlTypeName, rowOrder.get(i));
            }
            final DimensionSpec dimensionSpec = rex.toDimensionSpec(sourceRowSignature, dimOutputName(dimOutputNameCounter++), outputType);
            if (dimensionSpec == null) {
                return null;
            }
            dimensions.add(dimensionSpec);
            rowOrder.add(dimensionSpec.getOutputName());
        }
    }
    // Translate aggregates.
    for (int i = 0; i < aggregate.getAggCallList().size(); i++) {
        final AggregateCall aggCall = aggregate.getAggCallList().get(i);
        final Aggregation aggregation = translateAggregateCall(druidRel.getPlannerContext(), sourceRowSignature, project, aggCall, operatorTable, aggregations, i, approximateCountDistinct);
        if (aggregation == null) {
            return null;
        }
        aggregations.add(aggregation);
        rowOrder.add(aggregation.getOutputName());
    }
    if (isNestedQuery) {
        // Nested groupBy.
        return DruidNestedGroupBy.from(druidRel, filter, Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder);
    } else {
        // groupBy on a base dataSource.
        return druidRel.withQueryBuilder(druidRel.getQueryBuilder().withFilter(filter).withGrouping(Grouping.create(dimensions, aggregations), aggregate.getRowType(), rowOrder));
    }
}
Also used : DimensionSpec(io.druid.query.dimension.DimensionSpec) RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) ValueType(io.druid.segment.column.ValueType) RowExtraction(io.druid.sql.calcite.expression.RowExtraction) Aggregation(io.druid.sql.calcite.aggregation.Aggregation) AggregateCall(org.apache.calcite.rel.core.AggregateCall) Project(org.apache.calcite.rel.core.Project) ISE(io.druid.java.util.common.ISE) RowSignature(io.druid.sql.calcite.table.RowSignature) DimFilter(io.druid.query.filter.DimFilter) NotDimFilter(io.druid.query.filter.NotDimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) RexNode(org.apache.calcite.rex.RexNode)

Example 35 with AggregateCall

use of org.apache.calcite.rel.core.AggregateCall in project drill by apache.

the class WindowPrel method getPhysicalOperator.

@Override
public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws IOException {
    Prel child = (Prel) this.getInput();
    PhysicalOperator childPOP = child.getPhysicalOperator(creator);
    final List<String> childFields = getInput().getRowType().getFieldNames();
    // We don't support distinct partitions
    checkState(groups.size() == 1, "Only one window is expected in WindowPrel");
    Group window = groups.get(0);
    List<NamedExpression> withins = Lists.newArrayList();
    List<NamedExpression> aggs = Lists.newArrayList();
    List<Order.Ordering> orderings = Lists.newArrayList();
    for (int group : BitSets.toIter(window.keys)) {
        FieldReference fr = new FieldReference(childFields.get(group), ExpressionPosition.UNKNOWN);
        withins.add(new NamedExpression(fr, fr));
    }
    for (AggregateCall aggCall : window.getAggregateCalls(this)) {
        FieldReference ref = new FieldReference(aggCall.getName());
        LogicalExpression expr = toDrill(aggCall, childFields);
        aggs.add(new NamedExpression(expr, ref));
    }
    for (RelFieldCollation fieldCollation : window.orderKeys.getFieldCollations()) {
        orderings.add(new Order.Ordering(fieldCollation.getDirection(), new FieldReference(childFields.get(fieldCollation.getFieldIndex())), fieldCollation.nullDirection));
    }
    WindowPOP windowPOP = new WindowPOP(childPOP, withins, aggs, orderings, window.isRows, WindowPOP.newBound(window.lowerBound), WindowPOP.newBound(window.upperBound));
    creator.addMetadata(this, windowPOP);
    return windowPOP;
}
Also used : Order(org.apache.drill.common.logical.data.Order) FieldReference(org.apache.drill.common.expression.FieldReference) WindowPOP(org.apache.drill.exec.physical.config.WindowPOP) AggregateCall(org.apache.calcite.rel.core.AggregateCall) LogicalExpression(org.apache.drill.common.expression.LogicalExpression) PhysicalOperator(org.apache.drill.exec.physical.base.PhysicalOperator) NamedExpression(org.apache.drill.common.logical.data.NamedExpression) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation)

Aggregations

AggregateCall (org.apache.calcite.rel.core.AggregateCall)40 RexNode (org.apache.calcite.rex.RexNode)21 ArrayList (java.util.ArrayList)20 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)17 RelNode (org.apache.calcite.rel.RelNode)16 RelDataType (org.apache.calcite.rel.type.RelDataType)13 RexBuilder (org.apache.calcite.rex.RexBuilder)13 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)12 HashMap (java.util.HashMap)11 RexInputRef (org.apache.calcite.rex.RexInputRef)11 HiveAggregate (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate)10 Aggregate (org.apache.calcite.rel.core.Aggregate)9 ImmutableList (com.google.common.collect.ImmutableList)8 SqlAggFunction (org.apache.calcite.sql.SqlAggFunction)8 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)6 Pair (org.apache.calcite.util.Pair)6 BigDecimal (java.math.BigDecimal)5 List (java.util.List)5 RexLiteral (org.apache.calcite.rex.RexLiteral)5 SqlCountAggFunction (org.apache.calcite.sql.fun.SqlCountAggFunction)5