Search in sources :

Example 81 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class AggregateProjectMergeRule method apply.

public static RelNode apply(RelOptRuleCall call, Aggregate aggregate, Project 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.getGroupType() != Group.SIMPLE) {
        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.
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(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);
        }
        relBuilder.project(relBuilder.fields(posList));
    }
    return relBuilder.build();
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RexInputRef(org.apache.calcite.rex.RexInputRef) Aggregate(org.apache.calcite.rel.core.Aggregate) RexNode(org.apache.calcite.rex.RexNode)

Example 82 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class AggregateReduceFunctionsRule method reduceSum.

private RexNode reduceSum(Aggregate oldAggRel, AggregateCall oldCall, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping) {
    final int nGroups = oldAggRel.getGroupCount();
    RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
    int arg = oldCall.getArgList().get(0);
    RelDataType argType = getFieldType(oldAggRel.getInput(), arg);
    final AggregateCall sumZeroCall = AggregateCall.create(SqlStdOperatorTable.SUM0, oldCall.isDistinct(), oldCall.isApproximate(), oldCall.getArgList(), oldCall.filterArg, oldAggRel.getGroupCount(), oldAggRel.getInput(), null, oldCall.name);
    final AggregateCall countCall = AggregateCall.create(SqlStdOperatorTable.COUNT, oldCall.isDistinct(), oldCall.isApproximate(), oldCall.getArgList(), oldCall.filterArg, oldAggRel.getGroupCount(), oldAggRel, null, null);
    // NOTE:  these references are with respect to the output
    // of newAggRel
    RexNode sumZeroRef = rexBuilder.addAggCall(sumZeroCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(argType));
    if (!oldCall.getType().isNullable()) {
        // null). Therefore we translate to SUM0(x).
        return sumZeroRef;
    }
    RexNode countRef = rexBuilder.addAggCall(countCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(argType));
    return rexBuilder.makeCall(SqlStdOperatorTable.CASE, rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countRef, rexBuilder.makeExactLiteral(BigDecimal.ZERO)), rexBuilder.makeCast(sumZeroRef.getType(), rexBuilder.constantNull()), sumZeroRef);
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 83 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class AggregateReduceFunctionsRule method reduceStddev.

private RexNode reduceStddev(Aggregate oldAggRel, AggregateCall oldCall, boolean biased, boolean sqrt, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping, List<RexNode> inputExprs) {
    // stddev_pop(x) ==>
    // power(
    // (sum(x * x) - sum(x) * sum(x) / count(x))
    // / count(x),
    // .5)
    // 
    // stddev_samp(x) ==>
    // power(
    // (sum(x * x) - sum(x) * sum(x) / count(x))
    // / nullif(count(x) - 1, 0),
    // .5)
    final int nGroups = oldAggRel.getGroupCount();
    final RelOptCluster cluster = oldAggRel.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
    assert oldCall.getArgList().size() == 1 : oldCall.getArgList();
    final int argOrdinal = oldCall.getArgList().get(0);
    final RelDataType argOrdinalType = getFieldType(oldAggRel.getInput(), argOrdinal);
    final RelDataType oldCallType = typeFactory.createTypeWithNullability(oldCall.getType(), argOrdinalType.isNullable());
    final RexNode argRef = rexBuilder.ensureType(oldCallType, inputExprs.get(argOrdinal), true);
    final int argRefOrdinal = lookupOrAdd(inputExprs, argRef);
    final RexNode argSquared = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argRef, argRef);
    final int argSquaredOrdinal = lookupOrAdd(inputExprs, argSquared);
    final AggregateCall sumArgSquaredAggCall = createAggregateCallWithBinding(typeFactory, SqlStdOperatorTable.SUM, argSquared.getType(), oldAggRel, oldCall, argSquaredOrdinal);
    final RexNode sumArgSquared = rexBuilder.addAggCall(sumArgSquaredAggCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(sumArgSquaredAggCall.getType()));
    final AggregateCall sumArgAggCall = AggregateCall.create(SqlStdOperatorTable.SUM, oldCall.isDistinct(), oldCall.isApproximate(), ImmutableIntList.of(argOrdinal), oldCall.filterArg, oldAggRel.getGroupCount(), oldAggRel.getInput(), null, null);
    final RexNode sumArg = rexBuilder.addAggCall(sumArgAggCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(sumArgAggCall.getType()));
    final RexNode sumArgCast = rexBuilder.ensureType(oldCallType, sumArg, true);
    final RexNode sumSquaredArg = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, sumArgCast, sumArgCast);
    final AggregateCall countArgAggCall = AggregateCall.create(SqlStdOperatorTable.COUNT, oldCall.isDistinct(), oldCall.isApproximate(), oldCall.getArgList(), oldCall.filterArg, oldAggRel.getGroupCount(), oldAggRel, null, null);
    final RexNode countArg = rexBuilder.addAggCall(countArgAggCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, ImmutableList.of(argOrdinalType));
    final RexNode avgSumSquaredArg = rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, sumSquaredArg, countArg);
    final RexNode diff = rexBuilder.makeCall(SqlStdOperatorTable.MINUS, sumArgSquared, avgSumSquaredArg);
    final RexNode denominator;
    if (biased) {
        denominator = countArg;
    } else {
        final RexLiteral one = rexBuilder.makeExactLiteral(BigDecimal.ONE);
        final RexNode nul = rexBuilder.makeCast(countArg.getType(), rexBuilder.constantNull());
        final RexNode countMinusOne = rexBuilder.makeCall(SqlStdOperatorTable.MINUS, countArg, one);
        final RexNode countEqOne = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countArg, one);
        denominator = rexBuilder.makeCall(SqlStdOperatorTable.CASE, countEqOne, nul, countMinusOne);
    }
    final RexNode div = rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, diff, denominator);
    RexNode result = div;
    if (sqrt) {
        final RexNode half = rexBuilder.makeExactLiteral(new BigDecimal("0.5"));
        result = rexBuilder.makeCall(SqlStdOperatorTable.POWER, div, half);
    }
    return rexBuilder.makeCast(oldCall.getType(), result);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RexLiteral(org.apache.calcite.rex.RexLiteral) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) BigDecimal(java.math.BigDecimal) RexNode(org.apache.calcite.rex.RexNode)

Example 84 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class JoinToCorrelateRule method onMatch.

public void onMatch(RelOptRuleCall call) {
    assert matches(call);
    final LogicalJoin join = call.rel(0);
    RelNode right = join.getRight();
    final RelNode left = join.getLeft();
    final int leftFieldCount = left.getRowType().getFieldCount();
    final RelOptCluster cluster = join.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RelBuilder relBuilder = call.builder();
    final CorrelationId correlationId = cluster.createCorrel();
    final RexNode corrVar = rexBuilder.makeCorrel(left.getRowType(), correlationId);
    final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
    // Replace all references of left input with FieldAccess(corrVar, field)
    final RexNode joinCondition = join.getCondition().accept(new RexShuttle() {

        @Override
        public RexNode visitInputRef(RexInputRef input) {
            int field = input.getIndex();
            if (field >= leftFieldCount) {
                return rexBuilder.makeInputRef(input.getType(), input.getIndex() - leftFieldCount);
            }
            requiredColumns.set(field);
            return rexBuilder.makeFieldAccess(corrVar, field);
        }
    });
    relBuilder.push(right).filter(joinCondition);
    RelNode newRel = LogicalCorrelate.create(left, relBuilder.build(), correlationId, requiredColumns.build(), SemiJoinType.of(join.getJoinType()));
    call.transformTo(newRel);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelBuilder(org.apache.calcite.tools.RelBuilder) RexShuttle(org.apache.calcite.rex.RexShuttle) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelNode(org.apache.calcite.rel.RelNode) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexNode(org.apache.calcite.rex.RexNode)

Example 85 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class JoinToMultiJoinRule method onMatch.

// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
    final Join origJoin = call.rel(0);
    final RelNode left = call.rel(1);
    final RelNode right = call.rel(2);
    // combine the children MultiJoin inputs into an array of inputs
    // for the new MultiJoin
    final List<ImmutableBitSet> projFieldsList = Lists.newArrayList();
    final List<int[]> joinFieldRefCountsList = Lists.newArrayList();
    final List<RelNode> newInputs = combineInputs(origJoin, left, right, projFieldsList, joinFieldRefCountsList);
    // combine the outer join information from the left and right
    // inputs, and include the outer join information from the current
    // join, if it's a left/right outer join
    final List<Pair<JoinRelType, RexNode>> joinSpecs = Lists.newArrayList();
    combineOuterJoins(origJoin, newInputs, left, right, joinSpecs);
    // pull up the join filters from the children MultiJoinRels and
    // combine them with the join filter associated with this LogicalJoin to
    // form the join filter for the new MultiJoin
    List<RexNode> newJoinFilters = combineJoinFilters(origJoin, left, right);
    // add on the join field reference counts for the join condition
    // associated with this LogicalJoin
    final ImmutableMap<Integer, ImmutableIntList> newJoinFieldRefCountsMap = addOnJoinFieldRefCounts(newInputs, origJoin.getRowType().getFieldCount(), origJoin.getCondition(), joinFieldRefCountsList);
    List<RexNode> newPostJoinFilters = combinePostJoinFilters(origJoin, left, right);
    final RexBuilder rexBuilder = origJoin.getCluster().getRexBuilder();
    RelNode multiJoin = new MultiJoin(origJoin.getCluster(), newInputs, RexUtil.composeConjunction(rexBuilder, newJoinFilters, false), origJoin.getRowType(), origJoin.getJoinType() == JoinRelType.FULL, Pair.right(joinSpecs), Pair.left(joinSpecs), projFieldsList, newJoinFieldRefCountsMap, RexUtil.composeConjunction(rexBuilder, newPostJoinFilters, true));
    call.transformTo(multiJoin);
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) Pair(org.apache.calcite.util.Pair) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexNode (org.apache.calcite.rex.RexNode)1167 ArrayList (java.util.ArrayList)423 RelNode (org.apache.calcite.rel.RelNode)363 RelDataType (org.apache.calcite.rel.type.RelDataType)289 RexBuilder (org.apache.calcite.rex.RexBuilder)262 RexInputRef (org.apache.calcite.rex.RexInputRef)207 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)198 RexCall (org.apache.calcite.rex.RexCall)185 Test (org.junit.Test)138 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)136 RexLiteral (org.apache.calcite.rex.RexLiteral)104 HashMap (java.util.HashMap)102 List (java.util.List)97 AggregateCall (org.apache.calcite.rel.core.AggregateCall)83 Pair (org.apache.calcite.util.Pair)79 Project (org.apache.calcite.rel.core.Project)77 RelBuilder (org.apache.calcite.tools.RelBuilder)77 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)66 ImmutableList (com.google.common.collect.ImmutableList)64 Map (java.util.Map)63