Java源码示例:org.apache.calcite.rel.core.Aggregate

示例1
private static boolean isAggregateSupported(Aggregate aggregate, boolean allowFunctions) {
  if (!allowFunctions && !aggregate.getAggCallList().isEmpty()) {
    return false;
  }
  if (aggregate.getGroupType() != Aggregate.Group.SIMPLE) {
    return false;
  }
  // If any aggregate functions do not support splitting, bail out
  // If any aggregate call has a filter or is distinct, bail out
  for (AggregateCall aggregateCall : aggregate.getAggCallList()) {
    if (aggregateCall.getAggregation().unwrap(SqlSplittableAggFunction.class)
        == null) {
      return false;
    }
    if (aggregateCall.filterArg >= 0 || aggregateCall.isDistinct()) {
      return false;
    }
  }
  return true;
}
 
示例2
public MaterializedViewOnlyAggregateRule(RelOptRuleOperand operand,
    RelBuilderFactory relBuilderFactory, String description,
    boolean generateUnionRewriting, HepProgram unionRewritingPullProgram,
    RelOptRule filterProjectTransposeRule,
    RelOptRule filterAggregateTransposeRule,
    RelOptRule aggregateProjectPullUpConstantsRule,
    RelOptRule projectMergeRule) {
  super(
      operand(Aggregate.class, any()),
      relBuilderFactory,
      "MaterializedViewAggregateRule(Aggregate)",
      generateUnionRewriting, unionRewritingPullProgram,
      filterProjectTransposeRule,
      filterAggregateTransposeRule,
      aggregateProjectPullUpConstantsRule,
      projectMergeRule);
}
 
示例3
private List<RelBuilder.AggCall> getNewAggCallList(
	Aggregate oldAggregate,
	RelBuilder relBuilder,
	Mapping mapping) {

	final List<RelBuilder.AggCall> newAggCallList = new ArrayList<>();

	for (AggregateCall aggCall : oldAggregate.getAggCallList()) {
		final RexNode filterArg = aggCall.filterArg < 0 ? null
			: relBuilder.field(Mappings.apply(mapping, aggCall.filterArg));
		newAggCallList.add(
			relBuilder
				.aggregateCall(
					aggCall.getAggregation(),
					relBuilder.fields(Mappings.apply2(mapping, aggCall.getArgList())))
				.distinct(aggCall.isDistinct())
				.filter(filterArg)
				.approximate(aggCall.isApproximate())
				.sort(relBuilder.fields(aggCall.collation))
				.as(aggCall.name));
	}
	return newAggCallList;
}
 
示例4
public void onMatch(RelOptRuleCall call) {
	final Aggregate aggregate = call.rel(0);
	final RelNode input = call.rel(1);

	// Distinct is "GROUP BY c1, c2" (where c1, c2 are a set of columns on
	// which the input is unique, i.e. contain a key) and has no aggregate
	// functions or the functions we enumerated. It can be removed.
	final RelNode newInput = convert(input, aggregate.getTraitSet().simplify());

	// If aggregate was projecting a subset of columns, add a project for the
	// same effect.
	final RelBuilder relBuilder = call.builder();
	relBuilder.push(newInput);
	List<Integer> projectIndices = new ArrayList<>(aggregate.getGroupSet().asList());
	for (AggregateCall aggCall : aggregate.getAggCallList()) {
		projectIndices.addAll(aggCall.getArgList());
	}
	relBuilder.project(relBuilder.fields(projectIndices));
	// Create a project if some of the columns have become
	// NOT NULL due to aggregate functions are removed
	relBuilder.convert(aggregate.getRowType(), true);
	call.transformTo(relBuilder.build());
}
 
示例5
private RexNode getSumAggregatedRexNodeWithBinding(Aggregate oldAggRel,
    AggregateCall oldCall,
    List<AggregateCall> newCalls,
    Map<AggregateCall, RexNode> aggCallMapping,
    RelDataType operandType,
    int argOrdinal,
    int filter) {
  RelOptCluster cluster = oldAggRel.getCluster();
  final AggregateCall sumArgSquaredAggCall =
      createAggregateCallWithBinding(cluster.getTypeFactory(),
          SqlStdOperatorTable.SUM, operandType, oldAggRel, oldCall, argOrdinal, filter);

  return cluster.getRexBuilder().addAggCall(sumArgSquaredAggCall,
      oldAggRel.getGroupCount(),
      newCalls,
      aggCallMapping,
      ImmutableList.of(sumArgSquaredAggCall.getType()));
}
 
示例6
private AggregateCall createAggregateCallWithBinding(
    RelDataTypeFactory typeFactory,
    SqlAggFunction aggFunction,
    RelDataType operandType,
    Aggregate oldAggRel,
    AggregateCall oldCall,
    int argOrdinal,
    int filter) {
  final Aggregate.AggCallBinding binding =
      new Aggregate.AggCallBinding(typeFactory, aggFunction,
          ImmutableList.of(operandType), oldAggRel.getGroupCount(),
          filter >= 0);
  return AggregateCall.create(aggFunction,
      oldCall.isDistinct(),
      oldCall.isApproximate(),
      ImmutableIntList.of(argOrdinal),
      filter,
      oldCall.collation,
      aggFunction.inferReturnType(binding),
      null);
}
 
示例7
public Double getSelectivity(Aggregate rel, RelMetadataQuery mq,
    RexNode predicate) {
  final List<RexNode> notPushable = new ArrayList<>();
  final List<RexNode> pushable = new ArrayList<>();
  RelOptUtil.splitFilters(
      rel.getGroupSet(),
      predicate,
      pushable,
      notPushable);
  final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
  RexNode childPred =
      RexUtil.composeConjunction(rexBuilder, pushable, true);

  Double selectivity = mq.getSelectivity(rel.getInput(), childPred);
  if (selectivity == null) {
    return null;
  } else {
    RexNode pred =
        RexUtil.composeConjunction(rexBuilder, notPushable, true);
    return selectivity * RelMdUtil.guessSelectivity(pred);
  }
}
 
示例8
/**
 * Creates a AggregateUnionAggregateRule.
 */
public AggregateUnionAggregateRule(Class<? extends Aggregate> aggregateClass,
    Class<? extends Union> unionClass,
    Class<? extends RelNode> firstUnionInputClass,
    Class<? extends RelNode> secondUnionInputClass,
    RelBuilderFactory relBuilderFactory,
    String desc) {
  super(
      operandJ(aggregateClass, null, Aggregate::isSimple,
          operand(unionClass,
              operand(firstUnionInputClass, any()),
              operand(secondUnionInputClass, any()))),
      relBuilderFactory, desc);
}
 
示例9
@Override public void onMatch(RelOptRuleCall call) {
  final Delta delta = call.rel(0);
  Util.discard(delta);
  final Aggregate aggregate = call.rel(1);
  final LogicalDelta newDelta =
      LogicalDelta.create(aggregate.getInput());
  final LogicalAggregate newAggregate =
      LogicalAggregate.create(newDelta, aggregate.getGroupSet(),
          aggregate.groupSets, aggregate.getAggCallList());
  call.transformTo(newAggregate);
}
 
示例10
private String getGroupByIndices(Aggregate n) {
  StringBuilder res = new StringBuilder();
  int count = 0;
  for (int i : n.getGroupSet()) {
    if (++count > 1) {
      res.append(", ");
    }
    res.append(i);
  }
  return res.toString();
}
 
示例11
@Override
public Aggregate copy(RelTraitSet traitSet, RelNode input, boolean indicator, ImmutableBitSet groupSet,
        List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
    try {
        return new OLAPAggregateRel(getCluster(), traitSet, input, indicator, groupSet, groupSets, aggCalls);
    } catch (InvalidRelException e) {
        throw new IllegalStateException("Can't create OLAPAggregateRel!", e);
    }
}
 
示例12
public Double getDistinctRowCount(Aggregate rel, RelMetadataQuery mq,
    ImmutableBitSet groupKey, RexNode predicate) {
  if (predicate == null || predicate.isAlwaysTrue()) {
    if (groupKey.isEmpty()) {
      return 1D;
    }
  }
  // determine which predicates can be applied on the child of the
  // aggregate
  final List<RexNode> notPushable = new ArrayList<>();
  final List<RexNode> pushable = new ArrayList<>();
  RelOptUtil.splitFilters(
      rel.getGroupSet(),
      predicate,
      pushable,
      notPushable);
  final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
  RexNode childPreds =
      RexUtil.composeConjunction(rexBuilder, pushable, true);

  // set the bits as they correspond to the child input
  ImmutableBitSet.Builder childKey = ImmutableBitSet.builder();
  RelMdUtil.setAggChildKeys(groupKey, rel, childKey);

  Double distinctRowCount =
      mq.getDistinctRowCount(rel.getInput(), childKey.build(), childPreds);
  if (distinctRowCount == null) {
    return null;
  } else if (notPushable.isEmpty()) {
    return distinctRowCount;
  } else {
    RexNode preds =
        RexUtil.composeConjunction(rexBuilder, notPushable, true);
    return distinctRowCount * RelMdUtil.guessSelectivity(preds);
  }
}
 
示例13
/**
 * Creates an AggregateRemoveRule.
 */
public AggregateRemoveRule(Class<? extends Aggregate> aggregateClass,
    RelBuilderFactory relBuilderFactory) {
  super(
      operandJ(aggregateClass, null, agg -> isAggregateSupported(agg),
          any()), relBuilderFactory, null);
}
 
示例14
@Deprecated // to be removed before 2.0
public AggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
    RelFactories.AggregateFactory aggregateFactory,
    Class<? extends Join> joinClass,
    RelFactories.JoinFactory joinFactory,
    RelFactories.ProjectFactory projectFactory) {
  this(aggregateClass, joinClass,
      RelBuilder.proto(aggregateFactory, joinFactory, projectFactory), false);
}
 
示例15
public Double getMinRowCount(Aggregate rel, RelMetadataQuery mq) {
  if (rel.getGroupSet().isEmpty()) {
    // Aggregate with no GROUP BY always returns 1 row (even on empty table).
    return 1D;
  }
  final Double rowCount = mq.getMinRowCount(rel.getInput());
  if (rowCount != null && rowCount >= 1D) {
    return (double) rel.getGroupSets().size();
  }
  return 0D;
}
 
示例16
public boolean hasTrickyRollup(Sort e, Aggregate aggregate) {
  return !dialect.supportsAggregateFunction(SqlKind.ROLLUP)
      && dialect.supportsGroupByWithRollup()
      && (aggregate.getGroupType() == Aggregate.Group.ROLLUP
          || aggregate.getGroupType() == Aggregate.Group.CUBE
              && aggregate.getGroupSet().cardinality() == 1)
      && e.collation.getFieldCollations().stream().allMatch(fc ->
          fc.getFieldIndex() < aggregate.getGroupSet().cardinality());
}
 
示例17
@Override public void onMatch(RelOptRuleCall call) {
  final Aggregate aggregate = call.rel(0);
  final Values values = call.rel(1);
  Util.discard(values);
  final RelBuilder relBuilder = call.builder();
  final RexBuilder rexBuilder = relBuilder.getRexBuilder();

  final List<RexLiteral> literals = new ArrayList<>();
  for (final AggregateCall aggregateCall : aggregate.getAggCallList()) {
    switch (aggregateCall.getAggregation().getKind()) {
    case COUNT:
    case SUM0:
      literals.add(
          (RexLiteral) rexBuilder.makeLiteral(
              BigDecimal.ZERO, aggregateCall.getType(), false));
      break;

    case MIN:
    case MAX:
    case SUM:
      literals.add(rexBuilder.makeNullLiteral(aggregateCall.getType()));
      break;

    default:
      // Unknown what this aggregate call should do on empty Values. Bail out to be safe.
      return;
    }
  }

  call.transformTo(
      relBuilder.values(ImmutableList.of(literals), aggregate.getRowType())
          .build());

  // New plan is absolutely better than old plan.
  call.getPlanner().prune(aggregate);
}
 
示例18
@Deprecated // to be removed before 2.0
public FlinkAggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
		RelFactories.AggregateFactory aggregateFactory,
		Class<? extends Join> joinClass,
		RelFactories.JoinFactory joinFactory) {
	this(aggregateClass, joinClass,
			RelBuilder.proto(aggregateFactory, joinFactory), false);
}
 
示例19
/**
 * 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 RelBuilder convertMonopole(RelBuilder relBuilder, Aggregate aggregate,
		List<Integer> argList, int filterArg) {
	// 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.
	final Map<Integer, Integer> sourceOf = new HashMap<>();
	createSelectDistinct(relBuilder, aggregate, argList, filterArg, sourceOf);

	// Create an aggregate on top, with the new aggregate list.
	final List<AggregateCall> newAggCalls =
			com.google.common.collect.Lists.newArrayList(aggregate.getAggCallList());
	rewriteAggCalls(newAggCalls, argList, sourceOf);
	final int cardinality = aggregate.getGroupSet().cardinality();
	relBuilder.push(
			aggregate.copy(aggregate.getTraitSet(), relBuilder.build(),
					aggregate.indicator, ImmutableBitSet.range(cardinality), null,
					newAggCalls));
	return relBuilder;
}
 
示例20
public Result visitChild(int i, RelNode e) {
  if (e instanceof Union) {
    return visitUnion((Union) e);
  } else if (e instanceof Join) {
    return visitJoin((Join) e);
  } else if (e instanceof Filter) {
    return visitFilter((Filter) e);
  } else if (e instanceof Project) {
    return visitProject((Project) e);
  } else if (e instanceof Aggregate) {
    return visitAggregate((Aggregate) e);
  } else if (e instanceof TableScan) {
    return visitTableScan((TableScan) e);
  } else if (e instanceof Intersect) {
    return visitIntersect((Intersect) e);
  } else if (e instanceof Minus) {
    return visitMinus((Minus) e);
  } else if (e instanceof Calc) {
    return visitCalc((Calc) e);
  } else if (e instanceof Sort) {
    return visitSort((Sort) e);
  } else if (e instanceof TableModify) {
    return visitTableModify((TableModify) e);
  } else if (e instanceof Limit) {
    return visitLimit((Limit) e);
  } else {
    throw new AssertionError("Need to Implement for " + e.getClass().getName()); // TODO:
  }
}
 
示例21
/** Creates a MaterializedViewAggregateRule. */
protected MaterializedViewAggregateRule(RelOptRuleOperand operand, RelBuilderFactory relBuilderFactory,
        String description, boolean generateUnionRewriting, HepProgram unionRewritingPullProgram) {
    super(operand, relBuilderFactory, description, generateUnionRewriting, unionRewritingPullProgram, false);
    this.filterProjectTransposeRule = new FilterProjectTransposeRule(Filter.class, Project.class, true, true,
            relBuilderFactory);
    this.filterAggregateTransposeRule = new FilterAggregateTransposeRule(Filter.class, relBuilderFactory,
            Aggregate.class);
    this.aggregateProjectPullUpConstantsRule = new AggregateProjectPullUpConstantsRule(Aggregate.class,
            Filter.class, relBuilderFactory, "AggFilterPullUpConstants");
    this.projectMergeRule = new ProjectMergeRule(true, relBuilderFactory);
}
 
示例22
@Override public void onMatch(RelOptRuleCall call) {
  final Project project = call.rel(0);
  final Join join = call.rel(1);
  final RelNode left = call.rel(2);
  final Aggregate aggregate = call.rel(3);
  perform(call, project, join, left, aggregate);
}
 
示例23
protected SemiJoinRule(Class<Join> joinClass, Class<Aggregate> aggregateClass,
    RelBuilderFactory relBuilderFactory, String description) {
  super(
      operandJ(joinClass, null, NOT_GENERATE_NULLS_ON_LEFT,
          some(operand(RelNode.class, any()),
              operand(aggregateClass, any()))),
      relBuilderFactory, description);
}
 
示例24
@Override public Aggregate copy(RelTraitSet traitSet, RelNode input,
    ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets,
    List<AggregateCall> aggCalls) {
  try {
    return new MongoAggregate(getCluster(), traitSet, input,
        groupSet, groupSets, aggCalls);
  } catch (InvalidRelException e) {
    // Semantic error not possible. Must be a bug. Convert to
    // internal error.
    throw new AssertionError(e);
  }
}
 
示例25
RemoveCorrelationForScalarAggregateRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(LogicalCorrelate.class,
          operand(RelNode.class, any()),
          operand(LogicalProject.class,
              operandJ(LogicalAggregate.class, null, Aggregate::isSimple,
                  operand(LogicalProject.class,
                      operand(RelNode.class, any()))))),
      relBuilderFactory, null);
}
 
示例26
/**
 * If the node is an Aggregate, it returns a list of references to the grouping columns.
 * Otherwise, it returns a list of references to all columns in the node.
 * The returned list is immutable.
 */
private static List<RexNode> extractReferences(RexBuilder rexBuilder, RelNode node) {
    ImmutableList.Builder<RexNode> exprs = ImmutableList.builder();
    if (node instanceof Aggregate) {
        Aggregate aggregate = (Aggregate) node;
        for (int i = 0; i < aggregate.getGroupCount(); i++) {
            exprs.add(rexBuilder.makeInputRef(aggregate, i));
        }
    } else {
        for (int i = 0; i < node.getRowType().getFieldCount(); i++) {
            exprs.add(rexBuilder.makeInputRef(node, i));
        }
    }
    return exprs.build();
}
 
示例27
/**
 * Creates a FilterAggregateTransposeRule.
 *
 * <p>If {@code filterFactory} is null, creates the same kind of filter as
 * matched in the rule. Similarly {@code aggregateFactory}.</p>
 */
public FilterAggregateTransposeRule(
    Class<? extends Filter> filterClass,
    RelBuilderFactory builderFactory,
    Class<? extends Aggregate> aggregateClass) {
  this(
      operand(filterClass,
          operand(aggregateClass, any())),
      builderFactory);
}
 
示例28
/** Creates an AggregateUnionTransposeRule. */
public AggregateUnionTransposeRule(Class<? extends Aggregate> aggregateClass,
    Class<? extends Union> unionClass, RelBuilderFactory relBuilderFactory) {
  super(
      operand(aggregateClass,
          operand(unionClass, any())),
      relBuilderFactory, null);
}
 
示例29
public Double getRowCount(Aggregate rel, RelMetadataQuery mq) {
  if (ProjectableSqlAggFunctions.isProjectableAggregate(rel)) {
    return mq.getRowCount(rel.getInput());
  }

  // try the next handler
  return null;
}
 
示例30
private RelNode getNewAggregate(Aggregate oldAggregate, RelBuilder relBuilder, Mapping mapping) {

		final ImmutableBitSet newGroupSet =
			Mappings.apply(mapping, oldAggregate.getGroupSet());

		final Iterable<ImmutableBitSet> newGroupSets =
			oldAggregate.getGroupSets().stream()
				.map(bitSet -> Mappings.apply(mapping, bitSet))
				.collect(Collectors.toList());

		final List<RelBuilder.AggCall> newAggCallList =
			getNewAggCallList(oldAggregate, relBuilder, mapping);

		final RelBuilder.GroupKey groupKey =
			relBuilder.groupKey(newGroupSet, newGroupSets);

		if (oldAggregate instanceof LogicalWindowAggregate) {
			if (newGroupSet.size() == 0 && newAggCallList.size() == 0) {
				// Return the old LogicalWindowAggregate directly, as we can't get an empty Aggregate
				// from the relBuilder.
				return oldAggregate;
			} else {
				relBuilder.aggregate(groupKey, newAggCallList);
				Aggregate newAggregate = (Aggregate) relBuilder.build();
				LogicalWindowAggregate oldLogicalWindowAggregate = (LogicalWindowAggregate) oldAggregate;

				return LogicalWindowAggregate.create(
					oldLogicalWindowAggregate.getWindow(),
					oldLogicalWindowAggregate.getNamedProperties(),
					newAggregate);
			}
		} else {
			relBuilder.aggregate(groupKey, newAggCallList);
			return relBuilder.build();
		}
	}