/** * Do a shallow clone of oldAggRel and update aggCalls. Could be refactored * into Aggregate and subclasses - but it's only needed for some * subclasses. * * @param relBuilder Builder of relational expressions; at the top of its * stack is its input * @param oldAggregate LogicalAggregate to clone. * @param newCalls New list of AggregateCalls */ protected void newAggregateRel(RelBuilder relBuilder, Aggregate oldAggregate, List<AggregateCall> newCalls) { relBuilder.aggregate( relBuilder.groupKey(oldAggregate.getGroupSet(), oldAggregate.getGroupSets()), newCalls); }
private static boolean isEmptyGrpAggr(RelNode gbNode) { // Verify if both groupset and aggrfunction are empty) Aggregate aggrnode = (Aggregate) gbNode; if (aggrnode.getGroupSet().isEmpty() && aggrnode.getAggCallList().isEmpty()) { return true; } return false; }
private static boolean isEmptyGrpAggr(RelNode gbNode) { // Verify if both groupset and aggrfunction are empty) Aggregate aggrnode = (Aggregate) gbNode; if (aggrnode.getGroupSet().isEmpty() && aggrnode.getAggCallList().isEmpty()) { return true; } return false; }
private ImmutableBitSet generateNewGroupset(Aggregate aggregate, ImmutableBitSet fieldsUsed) { ImmutableBitSet originalGroupSet = aggregate.getGroupSet(); if (aggregate.getGroupSet().contains(key)) { groupByUniqueKey = key; break; ImmutableBitSet nonKeyColumns = aggregate.getGroupSet().except(groupByUniqueKey); ImmutableBitSet columnsToRemove = nonKeyColumns.except(fieldsUsed); ImmutableBitSet newGroupSet = aggregate.getGroupSet().except(columnsToRemove);
public void handle(Filter filter) { RelNode child = filter.getInput(); if (child instanceof Aggregate && !((Aggregate) child).getGroupSet().isEmpty()) { ASTConverter.this.having = filter; } else { ASTConverter.this.where = filter; } }
aggregate.getInput(), aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), newAggregateCalls
public void handle(Filter filter) { RelNode child = filter.getInput(); if (child instanceof Aggregate && !((Aggregate) child).getGroupSet().isEmpty()) { ASTConverter.this.having = filter; } else { ASTConverter.this.where = filter; } }
private static boolean validGBParent(RelNode gbNode, RelNode parent) { boolean validParent = true; // TOODO: Verify GB having is not a seperate filter (if so we shouldn't // introduce derived table) if (parent instanceof Join || parent instanceof SetOp || parent instanceof Aggregate || (parent instanceof Filter && ((Aggregate) gbNode).getGroupSet().isEmpty())) { validParent = false; } if (parent instanceof Project) { for (RexNode child : parent.getChildExps()) { if (child instanceof RexOver || child instanceof RexWinAggCall) { // Hive can't handle select rank() over(order by sum(c1)/sum(c2)) from t1 group by c3 // but can handle select rank() over (order by c4) from // (select sum(c1)/sum(c2) as c4 from t1 group by c3) t2; // so introduce a project on top of this gby. return false; } } } return validParent; }
private static boolean validGBParent(RelNode gbNode, RelNode parent) { boolean validParent = true; // TOODO: Verify GB having is not a seperate filter (if so we shouldn't // introduce derived table) if (parent instanceof Join || parent instanceof SetOp || parent instanceof Aggregate || (parent instanceof Filter && ((Aggregate) gbNode).getGroupSet().isEmpty())) { validParent = false; } if (parent instanceof Project) { for (RexNode child : parent.getChildExps()) { if (child instanceof RexOver || child instanceof RexWinAggCall) { // Hive can't handle select rank() over(order by sum(c1)/sum(c2)) from t1 group by c3 // but can handle select rank() over (order by c4) from // (select sum(c1)/sum(c2) as c4 from t1 group by c3) t2; // so introduce a project on top of this gby. return false; } } } return validParent; }
private boolean isAggWithConstantGbyKeys(final Aggregate aggregate, RelOptRuleCall call) { final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder(); final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(aggregate.getInput()); if (predicates == null) { return false; } final NavigableMap<Integer, RexNode> map = new TreeMap<>(); for (int key : aggregate.getGroupSet()) { final RexInputRef ref = rexBuilder.makeInputRef(aggregate.getInput(), key); if (predicates.constantMap.containsKey(ref)) { map.put(key, predicates.constantMap.get(ref)); } } // None of the group expressions are constant. Nothing to do. if (map.isEmpty()) { return false; } final int groupCount = aggregate.getGroupCount(); if (groupCount == map.size()) { return true; } return false; }
public RelNode align(Aggregate rel, List<RelFieldCollation> collations) { // 1) We extract the group by positions that are part of the collations and // sort them so they respect it LinkedHashSet<Integer> aggregateColumnsOrder = new LinkedHashSet<>(); ImmutableList.Builder<RelFieldCollation> propagateCollations = ImmutableList.builder(); if (rel.getGroupType() == Group.SIMPLE && !collations.isEmpty()) { for (RelFieldCollation c : collations) { if (c.getFieldIndex() < rel.getGroupCount()) { // Group column found if (aggregateColumnsOrder.add(c.getFieldIndex())) { propagateCollations.add(c.copy(rel.getGroupSet().nth(c.getFieldIndex()))); } } } } for (int i = 0; i < rel.getGroupCount(); i++) { if (!aggregateColumnsOrder.contains(i)) { // Not included in the input collations, but can be propagated as this Aggregate // will enforce it propagateCollations.add(new RelFieldCollation(rel.getGroupSet().nth(i))); } } // 2) We propagate final RelNode child = dispatchAlign(rel.getInput(), propagateCollations.build()); // 3) We annotate the Aggregate operator with this info final HiveAggregate newAggregate = (HiveAggregate) rel.copy(rel.getTraitSet(), ImmutableList.of(child)); newAggregate.setAggregateColumnsOrder(aggregateColumnsOrder); return newAggregate; }
if ((!singleAggregate.getGroupSet().isEmpty()) || (singleAggregate.getAggCallList().size() != 1) || !(singleAggregate.getAggCallList().get(0).getAggregation() if (!aggregate.getGroupSet().isEmpty()) { return;
int outputNameCounter = 0; for (int i : aggregate.getGroupSet()) {
Lists.newArrayList(aggregate.getAggCallList()); rewriteAggCalls(newAggCalls, argList, sourceOf); final int cardinality = aggregate.getGroupSet().cardinality(); return aggregate.copy(aggregate.getTraitSet(), distinct, aggregate.indicator, ImmutableBitSet.range(cardinality), null,
public RelNode align(Aggregate rel, List<RelFieldCollation> collations) { // 1) We extract the group by positions that are part of the collations and // sort them so they respect it LinkedHashSet<Integer> aggregateColumnsOrder = new LinkedHashSet<>(); ImmutableList.Builder<RelFieldCollation> propagateCollations = ImmutableList.builder(); if (!rel.indicator && !collations.isEmpty()) { for (RelFieldCollation c : collations) { if (c.getFieldIndex() < rel.getGroupCount()) { // Group column found if (aggregateColumnsOrder.add(c.getFieldIndex())) { propagateCollations.add(c.copy(rel.getGroupSet().nth(c.getFieldIndex()))); } } } } for (int i = 0; i < rel.getGroupCount(); i++) { if (!aggregateColumnsOrder.contains(i)) { // Not included in the input collations, but can be propagated as this Aggregate // will enforce it propagateCollations.add(new RelFieldCollation(rel.getGroupSet().nth(i))); } } // 2) We propagate final RelNode child = dispatchAlign(rel.getInput(), propagateCollations.build()); // 3) We annotate the Aggregate operator with this info final HiveAggregate newAggregate = (HiveAggregate) rel.copy(rel.getTraitSet(), ImmutableList.of(child)); newAggregate.setAggregateColumnsOrder(aggregateColumnsOrder); return newAggregate; }
cost += COST_PER_COLUMN * partialQuery.getAggregate().getGroupSet().size(); cost += COST_PER_COLUMN * partialQuery.getAggregate().getAggCallList().size();
final RexBuilder rexBuilder = agg.getCluster().getRexBuilder(); ImmutableBitSet groupKeys = agg.getGroupSet(); Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION, input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());
@Override public void onMatch(RelOptRuleCall call) { final Aggregate topAggregate = call.rel(0); final Join join = call.rel(1); final RelNode left = call.rel(2); final Aggregate aggregate = call.rel(3); // Gather columns used by aggregate operator final ImmutableBitSet.Builder topRefs = ImmutableBitSet.builder(); topRefs.addAll(topAggregate.getGroupSet()); for (AggregateCall aggCall : topAggregate.getAggCallList()) { topRefs.addAll(aggCall.getArgList()); if (aggCall.filterArg != -1) { topRefs.set(aggCall.filterArg); } } perform(call, topRefs.build(), topAggregate, join, left, aggregate); } }
final RelBuilder relBuilder = call.builder(); RelNode newRightInput = relBuilder.project(relBuilder.push(rightAggregate.getInput()). fields(rightAggregate.getGroupSet().asList())).build(); RelNode newSemiJoin = call.builder().push(left).push(newRightInput) .semiJoin(semijoin.getCondition()).build();
Schema(Schema src, Aggregate gBy) { for (int i : gBy.getGroupSet()) { ColumnInfo cI = src.get(i); add(cI); } List<AggregateCall> aggs = gBy.getAggCallList(); for (AggregateCall agg : aggs) { if (agg.getAggregation() == HiveGroupingID.INSTANCE) { add(new ColumnInfo(null,VirtualColumn.GROUPINGID.getName())); continue; } int argCount = agg.getArgList().size(); ASTBuilder b = agg.isDistinct() ? ASTBuilder.construct(HiveParser.TOK_FUNCTIONDI, "TOK_FUNCTIONDI") : argCount == 0 ? ASTBuilder.construct(HiveParser.TOK_FUNCTIONSTAR, "TOK_FUNCTIONSTAR") : ASTBuilder.construct(HiveParser.TOK_FUNCTION, "TOK_FUNCTION"); b.add(HiveParser.Identifier, agg.getAggregation().getName()); for (int i : agg.getArgList()) { RexInputRef iRef = new RexInputRef(i, gBy.getCluster().getTypeFactory() .createSqlType(SqlTypeName.ANY)); b.add(iRef.accept(new RexVisitor(src, false, gBy.getCluster().getRexBuilder()))); } add(new ColumnInfo(null, b.node())); } }