Java Code Examples for org.apache.calcite.rel.core.AggregateCall#getAggregation()

The following examples show how to use org.apache.calcite.rel.core.AggregateCall#getAggregation() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RexBuilder.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a reference to an aggregate call, checking for repeated calls.
 *
 * <p>Argument types help to optimize for repeated aggregates.
 * For instance count(42) is equivalent to count(*).</p>
 *
 * @param aggCall aggregate call to be added
 * @param groupCount number of groups in the aggregate relation
 * @param aggCalls destination list of aggregate calls
 * @param aggCallMapping the dictionary of already added calls
 * @param aggArgTypes Argument types, not null
 *
 * @return Rex expression for the given aggregate call
 */
public RexNode addAggCall(AggregateCall aggCall, int groupCount,
    List<AggregateCall> aggCalls,
    Map<AggregateCall, RexNode> aggCallMapping,
    final List<RelDataType> aggArgTypes) {
  if (aggCall.getAggregation() instanceof SqlCountAggFunction
      && !aggCall.isDistinct()) {
    final List<Integer> args = aggCall.getArgList();
    final List<Integer> nullableArgs = nullableArgs(args, aggArgTypes);
    if (!nullableArgs.equals(args)) {
      aggCall = aggCall.copy(nullableArgs, aggCall.filterArg,
          aggCall.collation);
    }
  }
  RexNode rex = aggCallMapping.get(aggCall);
  if (rex == null) {
    int index = aggCalls.size() + groupCount;
    aggCalls.add(aggCall);
    rex = makeInputRef(aggCall.getType(), index);
    aggCallMapping.put(aggCall, rex);
  }
  return rex;
}
 
Example 2
Source File: SolrAggregate.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings({"fallthrough"})
private Pair<String, String> toSolrMetric(Implementor implementor, AggregateCall aggCall, List<String> inNames) {
  SqlAggFunction aggregation = aggCall.getAggregation();
  List<Integer> args = aggCall.getArgList();
  switch (args.size()) {
    case 0:
      if (aggregation.equals(SqlStdOperatorTable.COUNT)) {
        return new Pair<>(aggregation.getName(), "*");
      }
    case 1:
      String inName = inNames.get(args.get(0));
      String name = implementor.fieldMappings.getOrDefault(inName, inName);
      if(SUPPORTED_AGGREGATIONS.contains(aggregation)) {
        return new Pair<>(aggregation.getName(), name);
      }
    default:
      throw new AssertionError("Invalid aggregation " + aggregation + " with args " + args + " with names" + inNames);
  }
}
 
Example 3
Source File: RelNodeCompiler.java    From streamline with Apache License 2.0 6 votes vote down vote up
private void aggregate(AggregateCall call) {
  SqlAggFunction aggFunction = call.getAggregation();
  String aggregationName = call.getAggregation().getName();
  Type ty = typeFactory.getJavaClass(call.getType());
  if (call.getArgList().size() != 1) {
    if (aggregationName.equals("COUNT")) {
      if (call.getArgList().size() != 0) {
        throw new UnsupportedOperationException("Count with nullable fields");
      }
    }
  }
  if (aggFunction instanceof SqlUserDefinedAggFunction) {
    AggregateFunction aggregateFunction = ((SqlUserDefinedAggFunction) aggFunction).function;
    doAggregate((AggregateFunctionImpl) aggregateFunction, reserveAggVarName(call), ty, call.getArgList());
  } else {
    List<BuiltinAggregateFunctions.TypeClass> typeClasses = BuiltinAggregateFunctions.TABLE.get(aggregationName);
    if (typeClasses == null) {
      throw new UnsupportedOperationException(aggregationName + " Not implemented");
    }
    doAggregate(AggregateFunctionImpl.create(findMatchingClass(aggregationName, typeClasses, ty)),
                reserveAggVarName(call), ty, call.getArgList());
  }
}
 
Example 4
Source File: AggregateUnionTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
private List<AggregateCall> transformAggCalls(RelNode input, int groupCount,
    List<AggregateCall> origCalls) {
  final List<AggregateCall> newCalls = new ArrayList<>();
  for (Ord<AggregateCall> ord : Ord.zip(origCalls)) {
    final AggregateCall origCall = ord.e;
    if (origCall.isDistinct()
        || !SUPPORTED_AGGREGATES.containsKey(origCall.getAggregation()
            .getClass())) {
      return null;
    }
    final SqlAggFunction aggFun;
    final RelDataType aggType;
    if (origCall.getAggregation() == SqlStdOperatorTable.COUNT) {
      aggFun = SqlStdOperatorTable.SUM0;
      // count(any) is always not null, however nullability of sum might
      // depend on the number of columns in GROUP BY.
      // Here we use SUM0 since we are sure we will not face nullable
      // inputs nor we'll face empty set.
      aggType = null;
    } else {
      aggFun = origCall.getAggregation();
      aggType = origCall.getType();
    }
    AggregateCall newCall =
        AggregateCall.create(aggFun, origCall.isDistinct(),
            origCall.isApproximate(),
            ImmutableList.of(groupCount + ord.i), -1,
            origCall.collation,
            groupCount,
            input,
            aggType,
            origCall.getName());
    newCalls.add(newCall);
  }
  return newCalls;
}
 
Example 5
Source File: RelToSqlConverter.java    From Bats with Apache License 2.0 5 votes vote down vote up
/** @see #dispatch */
public Result visit(Aggregate e) {
  // "select a, b, sum(x) from ( ... ) group by a, b"
  final Result x = visitChild(0, e.getInput());
  final Builder builder;
  if (e.getInput() instanceof Project) {
    builder = x.builder(e);
    builder.clauses.add(Clause.GROUP_BY);
  } else {
    builder = x.builder(e, Clause.GROUP_BY);
  }
  List<SqlNode> groupByList = FluentListUtils.list();
  final List<SqlNode> selectList = new ArrayList<>();
  for (int group : e.getGroupSet()) {
    final SqlNode field = builder.context.field(group);
    addSelect(selectList, field, e.getRowType());
    groupByList.add(field);
  }
  for (AggregateCall aggCall : e.getAggCallList()) {
    SqlNode aggCallSqlNode = builder.context.toSql(aggCall);
    if (aggCall.getAggregation() instanceof SqlSingleValueAggFunction) {
      aggCallSqlNode = dialect.
          rewriteSingleValueExpr(aggCallSqlNode);
    }
    addSelect(selectList, aggCallSqlNode, e.getRowType());
  }
  builder.setSelect(new SqlNodeList(selectList, POS));
  if (!groupByList.isEmpty() || e.getAggCallList().isEmpty()) {
    // Some databases don't support "GROUP BY ()". We can omit it as long
    // as there is at least one aggregate function.
    builder.setGroupBy(new SqlNodeList(groupByList, POS));
  }
  return builder.result();
}
 
Example 6
Source File: RelToSqlConverter.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * @see #dispatch
 */
public Result visit(Aggregate e) {
  // "select a, b, sum(x) from ( ... ) group by a, b"
  final Result x = visitChild(0, e.getInput());
  final Builder builder;
  if (e.getInput() instanceof Project) {
    builder = x.builder(e);
    builder.clauses.add(Clause.GROUP_BY);
  } else {
    builder = x.builder(e, Clause.GROUP_BY);
  }
  List<SqlNode> groupByList = Expressions.list();
  final List<SqlNode> selectList = new ArrayList<>();
  for (int group : e.getGroupSet()) {
    final SqlNode field = builder.context.field(group);
    addSelect(selectList, field, e.getRowType());
    groupByList.add(field);
  }
  for (AggregateCall aggCall : e.getAggCallList()) {
    SqlNode aggCallSqlNode = builder.context.toSql(aggCall);
    if (aggCall.getAggregation() instanceof SqlSingleValueAggFunction) {
      aggCallSqlNode = dialect.
        rewriteSingleValueExpr(aggCallSqlNode);
    }
    addSelect(selectList, aggCallSqlNode, e.getRowType());
  }
  builder.setSelect(new SqlNodeList(selectList, POS));
  if (!groupByList.isEmpty() || e.getAggCallList().isEmpty()) {
    // Some databases don't support "GROUP BY ()". We can omit it as long
    // as there is at least one aggregate function.
    builder.setGroupBy(new SqlNodeList(groupByList, POS));
  }
  return builder.result();
}
 
Example 7
Source File: FilterAggStarRule.java    From quark with Apache License 2.0 5 votes vote down vote up
private AggregateCall getMergedAggCall(Aggregate secondAgg, AggregateCall aggCall) {
  final int grouplen = secondAgg.getGroupSet().cardinality();
  final int callLen = secondAgg.getAggCallList().size();
  if (aggCall.getArgList().size() == 1) {
    final Integer arg = aggCall.getArgList().get(0);
    if (arg > (grouplen - 1) && arg < (grouplen + callLen)) {
      AggregateCall call2  = secondAgg.getAggCallList().get(arg - grouplen);
      if (call2.getAggregation() == aggCall.getAggregation()
          && call2.getArgList().size() == 1) {
        return call2.copy(call2.getArgList(), call2.filterArg);
      }
    }
  }
  return null;
}
 
Example 8
Source File: OLAPAggregateRel.java    From kylin with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("deprecation")
private AggregateCall rewriteAggregateCall(AggregateCall aggCall, FunctionDesc func) {
    // rebuild function
    String callName = getSqlFuncName(aggCall);
    RelDataType fieldType = aggCall.getType();
    SqlAggFunction newAgg = aggCall.getAggregation();

    Map<String, Class<?>> udafMap = func.getMeasureType().getRewriteCalciteAggrFunctions();
    if (func.isCount()) {
        newAgg = SqlStdOperatorTable.SUM0;
    } else if (udafMap != null && udafMap.containsKey(callName)) {
        newAgg = createCustomAggFunction(callName, fieldType, udafMap.get(callName));
    }

    // rebuild parameters
    List<Integer> newArgList = Lists.newArrayList(aggCall.getArgList());
    if (udafMap != null && udafMap.containsKey(callName)) {
        newArgList = truncArgList(newArgList, udafMap.get(callName));
    }
    if (func.needRewriteField()) {
        RelDataTypeField field = getInput().getRowType().getField(func.getRewriteFieldName(), true, false);
        if (newArgList.isEmpty()) {
            newArgList.add(field.getIndex());
        } else {
            // TODO: only the first column got overwritten
            newArgList.set(0, field.getIndex());
        }
    }

    // rebuild aggregate call
    AggregateCall newAggCall = new AggregateCall(newAgg, false, newArgList, fieldType, callName);

    return newAggCall;
}
 
Example 9
Source File: OLAPAggregateRule.java    From kylin with Apache License 2.0 5 votes vote down vote up
private boolean containsAvg(LogicalAggregate agg) {
    for (AggregateCall call : agg.getAggCallList()) {
        SqlAggFunction func = call.getAggregation();
        if (func instanceof SqlAvgAggFunction)
            return true;
    }
    return false;
}
 
Example 10
Source File: OLAPAggregateRel.java    From kylin-on-parquet-v2 with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("deprecation")
private AggregateCall rewriteAggregateCall(AggregateCall aggCall, FunctionDesc func) {
    // rebuild function
    String callName = getSqlFuncName(aggCall);
    RelDataType fieldType = aggCall.getType();
    SqlAggFunction newAgg = aggCall.getAggregation();

    Map<String, Class<?>> udafMap = func.getMeasureType().getRewriteCalciteAggrFunctions();
    if (func.isCount()) {
        newAgg = SqlStdOperatorTable.SUM0;
    } else if (udafMap != null && udafMap.containsKey(callName)) {
        newAgg = createCustomAggFunction(callName, fieldType, udafMap.get(callName));
    }

    // rebuild parameters
    List<Integer> newArgList = Lists.newArrayList(aggCall.getArgList());
    if (udafMap != null && udafMap.containsKey(callName)) {
        newArgList = truncArgList(newArgList, udafMap.get(callName));
    }
    if (func.needRewriteField()) {
        RelDataTypeField field = getInput().getRowType().getField(func.getRewriteFieldName(), true, false);
        if (newArgList.isEmpty()) {
            newArgList.add(field.getIndex());
        } else {
            // TODO: only the first column got overwritten
            newArgList.set(0, field.getIndex());
        }
    }

    // rebuild aggregate call
    AggregateCall newAggCall = new AggregateCall(newAgg, false, newArgList, fieldType, callName);

    return newAggCall;
}
 
Example 11
Source File: PreProcessRel.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelNode visit(LogicalAggregate aggregate) {
  for(AggregateCall aggregateCall : aggregate.getAggCallList()) {
    if(aggregateCall.getAggregation() instanceof SqlSingleValueAggFunction) {
      // see DRILL-1937
      unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION,
          "Dremio doesn't currently support non-scalar sub-queries used in an expression");
      throw new UnsupportedOperationException();
    }
  }
  return visitChild(aggregate, 0, aggregate.getInput());
}
 
Example 12
Source File: OLAPAggregateRel.java    From kylin with Apache License 2.0 4 votes vote down vote up
@Override
public void implementRewrite(RewriteImplementor implementor) {
    // only rewrite the innermost aggregation
    if (needRewrite()) {
        translateAggregation();
        buildRewriteFieldsAndMetricsColumns();
    }

    implementor.visitChild(this, getInput());

    this.rewriting = true;

    // only rewrite the innermost aggregation
    if (needRewrite()) {
        // rewrite the aggCalls
        this.rewriteAggCalls = Lists.newArrayListWithExpectedSize(aggCalls.size());
        for (int i = 0; i < this.aggCalls.size(); i++) {
            AggregateCall aggCall = this.hackAggCalls.get(i) != null ? this.hackAggCalls.get(i)
                    : this.aggCalls.get(i);
            if (SqlStdOperatorTable.GROUPING == aggCall.getAggregation()) {
                this.rewriteAggCalls.add(aggCall);
                continue;
            }

            FunctionDesc cubeFunc = this.context.aggregations.get(i);
            // filter needn,t rewrite aggfunc
            // if it's not a cube, then the "needRewriteField func" should not resort to any rewrite fields,
            // which do not exist at all
            if (!(noPrecaculatedFieldsAvailable() && cubeFunc.needRewriteField())) {
                if (cubeFunc.needRewrite()) {
                    aggCall = rewriteAggregateCall(aggCall, cubeFunc);
                }

                //if not dim as measure (using some measure), differentiate it with a new class
                if (cubeFunc.getMeasureType() != null &&
                // DimCountDistinct case
                        cubeFunc.getMeasureType().needRewriteField()) {
                    aggCall = new KylinAggregateCall(aggCall, cubeFunc);
                }
            } else {
                logger.info(aggCall + "skip rewriteAggregateCall because no pre-aggregated field available");
            }

            this.rewriteAggCalls.add(aggCall);
            this.context.aggrSqlCalls.add(toSqlCall(aggCall));
        }
    }

    // rebuild rowType & columnRowType
    this.rowType = this.deriveRowType();
    this.columnRowType = this.buildColumnRowType();

    this.rewriting = false;
}
 
Example 13
Source File: AggregateStarTableRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
private static AggregateCall rollUp(int groupCount, RelBuilder relBuilder,
    AggregateCall aggregateCall, TileKey tileKey) {
  if (aggregateCall.isDistinct()) {
    return null;
  }
  final SqlAggFunction aggregation = aggregateCall.getAggregation();
  final Pair<SqlAggFunction, List<Integer>> seek =
      Pair.of(aggregation, aggregateCall.getArgList());
  final int offset = tileKey.dimensions.cardinality();
  final ImmutableList<Lattice.Measure> measures = tileKey.measures;

  // First, try to satisfy the aggregation by rolling up an aggregate in the
  // materialization.
  final int i = find(measures, seek);
tryRoll:
  if (i >= 0) {
    final SqlAggFunction roll = SubstitutionVisitor.getRollup(aggregation);
    if (roll == null) {
      break tryRoll;
    }
    return AggregateCall.create(roll, false, aggregateCall.isApproximate(),
        aggregateCall.ignoreNulls(), ImmutableList.of(offset + i), -1,
        aggregateCall.collation,
        groupCount, relBuilder.peek(), null, aggregateCall.name);
  }

  // Second, try to satisfy the aggregation based on group set columns.
tryGroup:
  {
    List<Integer> newArgs = new ArrayList<>();
    for (Integer arg : aggregateCall.getArgList()) {
      int z = tileKey.dimensions.indexOf(arg);
      if (z < 0) {
        break tryGroup;
      }
      newArgs.add(z);
    }
    return AggregateCall.create(aggregation, false,
        aggregateCall.isApproximate(), aggregateCall.ignoreNulls(),
        newArgs, -1, aggregateCall.collation,
        groupCount, relBuilder.peek(), null, aggregateCall.name);
  }

  // No roll up possible.
  return null;
}
 
Example 14
Source File: RelDecorrelator.java    From calcite with Apache License 2.0 4 votes vote down vote up
private void onMatch2(
    RelOptRuleCall call,
    Correlate correlate,
    RelNode leftInput,
    Project aggOutputProject,
    Aggregate aggregate) {
  if (generatedCorRels.contains(correlate)) {
    // This Correlate was generated by a previous invocation of
    // this rule. No further work to do.
    return;
  }

  setCurrent(call.getPlanner().getRoot(), correlate);

  // check for this pattern
  // The pattern matching could be simplified if rules can be applied
  // during decorrelation,
  //
  // CorrelateRel(left correlation, condition = true)
  //   leftInput
  //   Project-A (a RexNode)
  //     Aggregate (groupby (0), agg0(), agg1()...)

  // check aggOutputProj projects only one expression
  List<RexNode> aggOutputProjExprs = aggOutputProject.getProjects();
  if (aggOutputProjExprs.size() != 1) {
    return;
  }

  JoinRelType joinType = correlate.getJoinType();
  // corRel.getCondition was here, however Correlate was updated so it
  // never includes a join condition. The code was not modified for brevity.
  RexNode joinCond = relBuilder.literal(true);
  if ((joinType != JoinRelType.LEFT)
      || (joinCond != relBuilder.literal(true))) {
    return;
  }

  // check that the agg is on the entire input
  if (!aggregate.getGroupSet().isEmpty()) {
    return;
  }

  List<AggregateCall> aggCalls = aggregate.getAggCallList();
  Set<Integer> isCount = new HashSet<>();

  // remember the count() positions
  int i = -1;
  for (AggregateCall aggCall : aggCalls) {
    ++i;
    if (aggCall.getAggregation() instanceof SqlCountAggFunction) {
      isCount.add(i);
    }
  }

  // now rewrite the plan to
  //
  // Project-A' (all LHS plus transformed original projections,
  //             replacing references to count() with case statement)
  //   Correlate(left correlation, condition = true)
  //     leftInput
  //     Aggregate(groupby (0), agg0(), agg1()...)
  //
  List<RexNode> requiredNodes =
      correlate.getRequiredColumns().asList().stream()
          .map(ord -> relBuilder.getRexBuilder().makeInputRef(correlate, ord))
          .collect(Collectors.toList());
  Correlate newCorrelate = (Correlate) relBuilder.push(leftInput)
      .push(aggregate).correlate(correlate.getJoinType(),
          correlate.getCorrelationId(),
          requiredNodes).build();


  // remember this rel so we don't fire rule on it again
  // REVIEW jhyde 29-Oct-2007: rules should not save state; rule
  // should recognize patterns where it does or does not need to do
  // work
  generatedCorRels.add(newCorrelate);

  // need to update the mapCorToCorRel Update the output position
  // for the corVars: only pass on the corVars that are not used in
  // the join key.
  if (cm.mapCorToCorRel.get(correlate.getCorrelationId()) == correlate) {
    cm.mapCorToCorRel.put(correlate.getCorrelationId(), newCorrelate);
  }

  RelNode newOutput =
      aggregateCorrelatorOutput(newCorrelate, aggOutputProject, isCount);

  call.transformTo(newOutput);
}
 
Example 15
Source File: ProjectableSqlAggFunctions.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
@Override
public boolean apply(AggregateCall call) {
  return call.getAggregation() instanceof ProjectableSqlAggFunction;
}
 
Example 16
Source File: KylinAggregateCall.java    From kylin with Apache License 2.0 4 votes vote down vote up
public KylinAggregateCall(AggregateCall aggCall, FunctionDesc func) {
    super(aggCall.getAggregation(), aggCall.isDistinct(), aggCall.getArgList(), aggCall.type, aggCall.name);
    this.func = func;
}
 
Example 17
Source File: OLAPAggregateRel.java    From kylin-on-parquet-v2 with Apache License 2.0 4 votes vote down vote up
@Override
public void implementRewrite(RewriteImplementor implementor) {
    // only rewrite the innermost aggregation
    if (needRewrite()) {
        translateAggregation();
        buildRewriteFieldsAndMetricsColumns();
    }

    implementor.visitChild(this, getInput());

    this.rewriting = true;

    // only rewrite the innermost aggregation
    if (needRewrite()) {
        // rewrite the aggCalls
        this.rewriteAggCalls = Lists.newArrayListWithExpectedSize(aggCalls.size());
        for (int i = 0; i < this.aggCalls.size(); i++) {
            AggregateCall aggCall = this.hackAggCalls.get(i) != null ? this.hackAggCalls.get(i)
                    : this.aggCalls.get(i);
            if (SqlStdOperatorTable.GROUPING == aggCall.getAggregation()) {
                this.rewriteAggCalls.add(aggCall);
                continue;
            }

            FunctionDesc cubeFunc = this.context.aggregations.get(i);
            // filter needn,t rewrite aggfunc
            // if it's not a cube, then the "needRewriteField func" should not resort to any rewrite fields,
            // which do not exist at all
            if (!(noPrecaculatedFieldsAvailable() && cubeFunc.needRewriteField())) {
                if (cubeFunc.needRewrite()) {
                    aggCall = rewriteAggregateCall(aggCall, cubeFunc);
                }

                //if not dim as measure (using some measure), differentiate it with a new class
                if (cubeFunc.getMeasureType() != null &&
                // DimCountDistinct case
                        cubeFunc.getMeasureType().needRewriteField()) {
                    aggCall = new KylinAggregateCall(aggCall, cubeFunc);
                }
            } else {
                logger.info(aggCall + "skip rewriteAggregateCall because no pre-aggregated field available");
            }

            this.rewriteAggCalls.add(aggCall);
            this.context.aggrSqlCalls.add(toSqlCall(aggCall));
        }
    }

    // rebuild rowType & columnRowType
    this.rowType = this.deriveRowType();
    this.columnRowType = this.buildColumnRowType();

    this.rewriting = false;
}
 
Example 18
Source File: RelDecorrelator.java    From flink with Apache License 2.0 4 votes vote down vote up
private void onMatch2(
    RelOptRuleCall call,
    LogicalCorrelate correlate,
    RelNode leftInput,
    LogicalProject aggOutputProject,
    LogicalAggregate aggregate) {
  if (generatedCorRels.contains(correlate)) {
    // This Correlate was generated by a previous invocation of
    // this rule. No further work to do.
    return;
  }

  setCurrent(call.getPlanner().getRoot(), correlate);

  // check for this pattern
  // The pattern matching could be simplified if rules can be applied
  // during decorrelation,
  //
  // CorrelateRel(left correlation, condition = true)
  //   leftInput
  //   Project-A (a RexNode)
  //     Aggregate (groupby (0), agg0(), agg1()...)

  // check aggOutputProj projects only one expression
  List<RexNode> aggOutputProjExprs = aggOutputProject.getProjects();
  if (aggOutputProjExprs.size() != 1) {
    return;
  }

  JoinRelType joinType = correlate.getJoinType();
  // corRel.getCondition was here, however Correlate was updated so it
  // never includes a join condition. The code was not modified for brevity.
  RexNode joinCond = relBuilder.literal(true);
  if ((joinType != JoinRelType.LEFT)
      || (joinCond != relBuilder.literal(true))) {
    return;
  }

  // check that the agg is on the entire input
  if (!aggregate.getGroupSet().isEmpty()) {
    return;
  }

  List<AggregateCall> aggCalls = aggregate.getAggCallList();
  Set<Integer> isCount = new HashSet<>();

  // remember the count() positions
  int i = -1;
  for (AggregateCall aggCall : aggCalls) {
    ++i;
    if (aggCall.getAggregation() instanceof SqlCountAggFunction) {
      isCount.add(i);
    }
  }

  // now rewrite the plan to
  //
  // Project-A' (all LHS plus transformed original projections,
  //             replacing references to count() with case statement)
  //   Correlate(left correlation, condition = true)
  //     leftInput
  //     Aggregate(groupby (0), agg0(), agg1()...)
  //
  LogicalCorrelate newCorrelate =
      LogicalCorrelate.create(leftInput, aggregate,
          correlate.getCorrelationId(), correlate.getRequiredColumns(),
          correlate.getJoinType());

  // remember this rel so we don't fire rule on it again
  // REVIEW jhyde 29-Oct-2007: rules should not save state; rule
  // should recognize patterns where it does or does not need to do
  // work
  generatedCorRels.add(newCorrelate);

  // need to update the mapCorToCorRel Update the output position
  // for the corVars: only pass on the corVars that are not used in
  // the join key.
  if (cm.mapCorToCorRel.get(correlate.getCorrelationId()) == correlate) {
    cm.mapCorToCorRel.put(correlate.getCorrelationId(), newCorrelate);
  }

  RelNode newOutput =
      aggregateCorrelatorOutput(newCorrelate, aggOutputProject, isCount);

  call.transformTo(newOutput);
}
 
Example 19
Source File: Lattice.java    From calcite with Apache License 2.0 4 votes vote down vote up
private Measure toMeasure(AggregateCall aggCall) {
  return new Measure(aggCall.getAggregation(), aggCall.isDistinct(),
      aggCall.name, Lists.transform(aggCall.getArgList(), columns::get));
}
 
Example 20
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 4 votes vote down vote up
private void onMatch2(RelOptRuleCall call, LogicalCorrelate correlate, RelNode leftInput,
        LogicalProject aggOutputProject, LogicalAggregate aggregate) {
    if (generatedCorRels.contains(correlate)) {
        // This Correlate was generated by a previous invocation of
        // this rule. No further work to do.
        return;
    }

    setCurrent(call.getPlanner().getRoot(), correlate);

    // check for this pattern
    // The pattern matching could be simplified if rules can be applied
    // during decorrelation,
    //
    // CorrelateRel(left correlation, condition = true)
    // leftInput
    // Project-A (a RexNode)
    // Aggregate (groupby (0), agg0(), agg1()...)

    // check aggOutputProj projects only one expression
    List<RexNode> aggOutputProjExprs = aggOutputProject.getProjects();
    if (aggOutputProjExprs.size() != 1) {
        return;
    }

    JoinRelType joinType = correlate.getJoinType().toJoinType();
    // corRel.getCondition was here, however Correlate was updated so it
    // never includes a join condition. The code was not modified for brevity.
    RexNode joinCond = relBuilder.literal(true);
    if ((joinType != JoinRelType.LEFT) || (joinCond != relBuilder.literal(true))) {
        return;
    }

    // check that the agg is on the entire input
    if (!aggregate.getGroupSet().isEmpty()) {
        return;
    }

    List<AggregateCall> aggCalls = aggregate.getAggCallList();
    Set<Integer> isCount = new HashSet<>();

    // remember the count() positions
    int i = -1;
    for (AggregateCall aggCall : aggCalls) {
        ++i;
        if (aggCall.getAggregation() instanceof SqlCountAggFunction) {
            isCount.add(i);
        }
    }

    // now rewrite the plan to
    //
    // Project-A' (all LHS plus transformed original projections,
    // replacing references to count() with case statement)
    // Correlate(left correlation, condition = true)
    // leftInput
    // Aggregate(groupby (0), agg0(), agg1()...)
    //
    LogicalCorrelate newCorrelate = LogicalCorrelate.create(leftInput, aggregate, correlate.getCorrelationId(),
            correlate.getRequiredColumns(), correlate.getJoinType());

    // remember this rel so we don't fire rule on it again
    // REVIEW jhyde 29-Oct-2007: rules should not save state; rule
    // should recognize patterns where it does or does not need to do
    // work
    generatedCorRels.add(newCorrelate);

    // need to update the mapCorToCorRel Update the output position
    // for the corVars: only pass on the corVars that are not used in
    // the join key.
    if (cm.mapCorToCorRel.get(correlate.getCorrelationId()) == correlate) {
        cm.mapCorToCorRel.put(correlate.getCorrelationId(), newCorrelate);
    }

    RelNode newOutput = aggregateCorrelatorOutput(newCorrelate, aggOutputProject, isCount);

    call.transformTo(newOutput);
}