use of org.apache.calcite.rel.core.Aggregate in project hive by apache.
the class HiveAggregateSplitRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Aggregate aggregate = call.rel(0);
final RelBuilder relBuilder = call.builder();
// If any aggregate is distinct, bail out
// If any aggregate is the grouping id, bail out
// If any aggregate call has a filter, bail out
// If any aggregate functions do not support splitting, bail out
final ImmutableBitSet bottomAggregateGroupSet = aggregate.getGroupSet();
final List<AggregateCall> topAggregateCalls = new ArrayList<>();
for (int i = 0; i < aggregate.getAggCallList().size(); i++) {
AggregateCall aggregateCall = aggregate.getAggCallList().get(i);
if (aggregateCall.isDistinct()) {
return;
}
if (aggregateCall.getAggregation().equals(HiveGroupingID.INSTANCE)) {
return;
}
if (aggregateCall.filterArg >= 0) {
return;
}
SqlAggFunction aggFunction = HiveRelBuilder.getRollup(aggregateCall.getAggregation());
if (aggFunction == null) {
return;
}
topAggregateCalls.add(AggregateCall.create(aggFunction, aggregateCall.isDistinct(), aggregateCall.isApproximate(), ImmutableList.of(bottomAggregateGroupSet.cardinality() + i), -1, aggregateCall.collation, aggregateCall.type, aggregateCall.name));
}
if (aggregate.getCluster().getMetadataQuery().areColumnsUnique(aggregate.getInput(), bottomAggregateGroupSet)) {
// Nothing to do, probably already pushed
return;
}
final ImmutableBitSet topAggregateGroupSet = ImmutableBitSet.range(0, bottomAggregateGroupSet.cardinality());
final Map<Integer, Integer> map = new HashMap<>();
bottomAggregateGroupSet.forEach(k -> map.put(k, map.size()));
ImmutableList<ImmutableBitSet> topAggregateGroupSets = ImmutableBitSet.ORDERING.immutableSortedCopy(ImmutableBitSet.permute(aggregate.groupSets, map));
relBuilder.push(aggregate.getInput()).aggregate(relBuilder.groupKey(bottomAggregateGroupSet), aggregate.getAggCallList()).aggregate(relBuilder.groupKey(topAggregateGroupSet, topAggregateGroupSets), topAggregateCalls);
call.transformTo(relBuilder.build());
}
use of org.apache.calcite.rel.core.Aggregate in project hive by apache.
the class HiveExpandDistinctAggregatesRule method convertMonopole.
/**
* Converts an aggregate relational expression that contains just one
* distinct aggregate function (or perhaps several over the same arguments)
* and no non-distinct aggregate functions.
*/
private RelNode convertMonopole(Aggregate aggregate, List<Integer> argList) {
// For example,
// SELECT deptno, COUNT(DISTINCT sal), SUM(DISTINCT sal)
// FROM emp
// GROUP BY deptno
//
// becomes
//
// SELECT deptno, COUNT(distinct_sal), SUM(distinct_sal)
// FROM (
// SELECT DISTINCT deptno, sal AS distinct_sal
// FROM EMP GROUP BY deptno)
// GROUP BY deptno
// Project the columns of the GROUP BY plus the arguments
// to the agg function.
Map<Integer, Integer> sourceOf = new HashMap<Integer, Integer>();
final Aggregate distinct = createSelectDistinct(aggregate, argList, sourceOf);
// Create an aggregate on top, with the new aggregate list.
final List<AggregateCall> newAggCalls = 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, newAggCalls);
}
use of org.apache.calcite.rel.core.Aggregate in project hive by apache.
the class HiveAggregateReduceFunctionsRule method onMatch.
public void onMatch(RelOptRuleCall ruleCall) {
Aggregate oldAggRel = (Aggregate) ruleCall.rels[0];
reduceAggs(ruleCall, oldAggRel);
}
use of org.apache.calcite.rel.core.Aggregate in project hive by apache.
the class HiveAggregateProjectMergeRule method apply.
public static RelNode apply(HiveAggregate aggregate, HiveProject project) {
final List<Integer> newKeys = Lists.newArrayList();
final Map<Integer, Integer> map = new HashMap<>();
for (int key : aggregate.getGroupSet()) {
final RexNode rex = project.getProjects().get(key);
if (rex instanceof RexInputRef) {
final int newKey = ((RexInputRef) rex).getIndex();
newKeys.add(newKey);
map.put(key, newKey);
} else {
// Cannot handle "GROUP BY expression"
return null;
}
}
final ImmutableBitSet newGroupSet = aggregate.getGroupSet().permute(map);
ImmutableList<ImmutableBitSet> newGroupingSets = null;
if (aggregate.indicator) {
newGroupingSets = ImmutableBitSet.ORDERING.immutableSortedCopy(ImmutableBitSet.permute(aggregate.getGroupSets(), map));
}
final ImmutableList.Builder<AggregateCall> aggCalls = ImmutableList.builder();
for (AggregateCall aggregateCall : aggregate.getAggCallList()) {
final ImmutableList.Builder<Integer> newArgs = ImmutableList.builder();
for (int arg : aggregateCall.getArgList()) {
final RexNode rex = project.getProjects().get(arg);
if (rex instanceof RexInputRef) {
newArgs.add(((RexInputRef) rex).getIndex());
} else {
// Cannot handle "AGG(expression)"
return null;
}
}
final int newFilterArg;
if (aggregateCall.filterArg >= 0) {
final RexNode rex = project.getProjects().get(aggregateCall.filterArg);
if (!(rex instanceof RexInputRef)) {
return null;
}
newFilterArg = ((RexInputRef) rex).getIndex();
} else {
newFilterArg = -1;
}
aggCalls.add(aggregateCall.copy(newArgs.build(), newFilterArg));
}
final Aggregate newAggregate = aggregate.copy(aggregate.getTraitSet(), project.getInput(), aggregate.indicator, newGroupSet, newGroupingSets, aggCalls.build());
// Add a project if the group set is not in the same order or
// contains duplicates.
RelNode rel = newAggregate;
if (!newKeys.equals(newGroupSet.asList())) {
final List<Integer> posList = Lists.newArrayList();
for (int newKey : newKeys) {
posList.add(newGroupSet.indexOf(newKey));
}
if (aggregate.indicator) {
for (int newKey : newKeys) {
posList.add(aggregate.getGroupCount() + newGroupSet.indexOf(newKey));
}
}
for (int i = newAggregate.getGroupCount() + newAggregate.getIndicatorCount(); i < newAggregate.getRowType().getFieldCount(); i++) {
posList.add(i);
}
rel = HiveRelOptUtil.createProject(HiveRelFactories.HIVE_BUILDER.create(aggregate.getCluster(), null), rel, posList);
}
return rel;
}
use of org.apache.calcite.rel.core.Aggregate in project hive by apache.
the class SubstitutionVisitor method toMutable.
private static MutableRel toMutable(RelNode rel) {
if (rel instanceof TableScan) {
return MutableScan.of((TableScan) rel);
}
if (rel instanceof Values) {
return MutableValues.of((Values) rel);
}
if (rel instanceof Project) {
final Project project = (Project) rel;
final MutableRel input = toMutable(project.getInput());
return MutableProject.of(input, project.getProjects(), project.getRowType().getFieldNames());
}
if (rel instanceof Filter) {
final Filter filter = (Filter) rel;
final MutableRel input = toMutable(filter.getInput());
return MutableFilter.of(input, filter.getCondition());
}
if (rel instanceof Aggregate) {
final Aggregate aggregate = (Aggregate) rel;
final MutableRel input = toMutable(aggregate.getInput());
return MutableAggregate.of(input, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList());
}
if (rel instanceof Join) {
final Join join = (Join) rel;
final MutableRel left = toMutable(join.getLeft());
final MutableRel right = toMutable(join.getRight());
return MutableJoin.of(join.getCluster(), left, right, join.getCondition(), join.getJoinType(), join.getVariablesSet());
}
if (rel instanceof Sort) {
final Sort sort = (Sort) rel;
final MutableRel input = toMutable(sort.getInput());
return MutableSort.of(input, sort.getCollation(), sort.offset, sort.fetch);
}
throw new RuntimeException("cannot translate " + rel + " to MutableRel");
}
Aggregations