Search in sources :

Example 96 with RexNode

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

the class FilterTableScanRule method apply.

// ~ Methods ----------------------------------------------------------------
protected void apply(RelOptRuleCall call, Filter filter, TableScan scan) {
    final ImmutableIntList projects;
    final ImmutableList.Builder<RexNode> filters = ImmutableList.builder();
    if (scan instanceof Bindables.BindableTableScan) {
        final Bindables.BindableTableScan bindableScan = (Bindables.BindableTableScan) scan;
        filters.addAll(bindableScan.filters);
        projects = bindableScan.projects;
    } else {
        projects = scan.identity();
    }
    final Mapping mapping = Mappings.target(projects, scan.getTable().getRowType().getFieldCount());
    filters.add(RexUtil.apply(mapping, filter.getCondition()));
    call.transformTo(Bindables.BindableTableScan.create(scan.getCluster(), scan.getTable(), filters.build(), projects));
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) Mapping(org.apache.calcite.util.mapping.Mapping) Bindables(org.apache.calcite.interpreter.Bindables) RexNode(org.apache.calcite.rex.RexNode)

Example 97 with RexNode

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

the class JoinAssociateRule method onMatch.

// ~ Methods ----------------------------------------------------------------
public void onMatch(final RelOptRuleCall call) {
    final Join topJoin = call.rel(0);
    final Join bottomJoin = call.rel(1);
    final RelNode relA = bottomJoin.getLeft();
    final RelNode relB = bottomJoin.getRight();
    final RelSubset relC = call.rel(2);
    final RelOptCluster cluster = topJoin.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    if (relC.getConvention() != relA.getConvention()) {
        // EnumerableConvention, we're only interested in enumerable subsets.
        return;
    }
    // topJoin
    // /     \
    // bottomJoin  C
    // /    \
    // A      B
    final int aCount = relA.getRowType().getFieldCount();
    final int bCount = relB.getRowType().getFieldCount();
    final int cCount = relC.getRowType().getFieldCount();
    final ImmutableBitSet aBitSet = ImmutableBitSet.range(0, aCount);
    final ImmutableBitSet bBitSet = ImmutableBitSet.range(aCount, aCount + bCount);
    if (!topJoin.getSystemFieldList().isEmpty()) {
        // FIXME Enable this rule for joins with system fields
        return;
    }
    // (Is this too strict?)
    if (topJoin.getJoinType() != JoinRelType.INNER || bottomJoin.getJoinType() != JoinRelType.INNER) {
        return;
    }
    // Goal is to transform to
    // 
    // newTopJoin
    // /     \
    // A   newBottomJoin
    // /    \
    // B      C
    // Split the condition of topJoin and bottomJoin into a conjunctions. A
    // condition can be pushed down if it does not use columns from A.
    final List<RexNode> top = Lists.newArrayList();
    final List<RexNode> bottom = Lists.newArrayList();
    JoinPushThroughJoinRule.split(topJoin.getCondition(), aBitSet, top, bottom);
    JoinPushThroughJoinRule.split(bottomJoin.getCondition(), aBitSet, top, bottom);
    // Mapping for moving conditions from topJoin or bottomJoin to
    // newBottomJoin.
    // target: | B | C      |
    // source: | A       | B | C      |
    final Mappings.TargetMapping bottomMapping = Mappings.createShiftMapping(aCount + bCount + cCount, 0, aCount, bCount, bCount, aCount + bCount, cCount);
    final List<RexNode> newBottomList = Lists.newArrayList();
    new RexPermuteInputsShuttle(bottomMapping, relB, relC).visitList(bottom, newBottomList);
    RexNode newBottomCondition = RexUtil.composeConjunction(rexBuilder, newBottomList, false);
    final Join newBottomJoin = bottomJoin.copy(bottomJoin.getTraitSet(), newBottomCondition, relB, relC, JoinRelType.INNER, false);
    // Condition for newTopJoin consists of pieces from bottomJoin and topJoin.
    // Field ordinals do not need to be changed.
    RexNode newTopCondition = RexUtil.composeConjunction(rexBuilder, top, false);
    final Join newTopJoin = topJoin.copy(topJoin.getTraitSet(), newTopCondition, relA, newBottomJoin, JoinRelType.INNER, false);
    call.transformTo(newTopJoin);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelNode(org.apache.calcite.rel.RelNode) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Mappings(org.apache.calcite.util.mapping.Mappings) Join(org.apache.calcite.rel.core.Join) RexBuilder(org.apache.calcite.rex.RexBuilder) RexPermuteInputsShuttle(org.apache.calcite.rex.RexPermuteInputsShuttle) RelSubset(org.apache.calcite.plan.volcano.RelSubset) RexNode(org.apache.calcite.rex.RexNode)

Example 98 with RexNode

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

the class JoinProjectTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Join joinRel = call.rel(0);
    JoinRelType joinType = joinRel.getJoinType();
    Project leftProj;
    Project rightProj;
    RelNode leftJoinChild;
    RelNode rightJoinChild;
    // 2) input's projection doesn't generate nulls
    if (hasLeftChild(call) && (includeOuter || !joinType.generatesNullsOnLeft())) {
        leftProj = call.rel(1);
        leftJoinChild = getProjectChild(call, leftProj, true);
    } else {
        leftProj = null;
        leftJoinChild = call.rel(1);
    }
    if (hasRightChild(call) && (includeOuter || !joinType.generatesNullsOnRight())) {
        rightProj = getRightChild(call);
        rightJoinChild = getProjectChild(call, rightProj, false);
    } else {
        rightProj = null;
        rightJoinChild = joinRel.getRight();
    }
    if ((leftProj == null) && (rightProj == null)) {
        return;
    }
    // Construct two RexPrograms and combine them.  The bottom program
    // is a join of the projection expressions from the left and/or
    // right projects that feed into the join.  The top program contains
    // the join condition.
    // Create a row type representing a concatenation of the inputs
    // underneath the projects that feed into the join.  This is the input
    // into the bottom RexProgram.  Note that the join type is an inner
    // join because the inputs haven't actually been joined yet.
    RelDataType joinChildrenRowType = SqlValidatorUtil.deriveJoinRowType(leftJoinChild.getRowType(), rightJoinChild.getRowType(), JoinRelType.INNER, joinRel.getCluster().getTypeFactory(), null, Collections.<RelDataTypeField>emptyList());
    // Create projection expressions, combining the projection expressions
    // from the projects that feed into the join.  For the RHS projection
    // expressions, shift them to the right by the number of fields on
    // the LHS.  If the join input was not a projection, simply create
    // references to the inputs.
    int nProjExprs = joinRel.getRowType().getFieldCount();
    final List<Pair<RexNode, String>> projects = new ArrayList<>();
    final RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder();
    createProjectExprs(leftProj, leftJoinChild, 0, rexBuilder, joinChildrenRowType.getFieldList(), projects);
    List<RelDataTypeField> leftFields = leftJoinChild.getRowType().getFieldList();
    int nFieldsLeft = leftFields.size();
    createProjectExprs(rightProj, rightJoinChild, nFieldsLeft, rexBuilder, joinChildrenRowType.getFieldList(), projects);
    final List<RelDataType> projTypes = new ArrayList<>();
    for (int i = 0; i < nProjExprs; i++) {
        projTypes.add(projects.get(i).left.getType());
    }
    RelDataType projRowType = rexBuilder.getTypeFactory().createStructType(projTypes, Pair.right(projects));
    // create the RexPrograms and merge them
    RexProgram bottomProgram = RexProgram.create(joinChildrenRowType, Pair.left(projects), null, projRowType, rexBuilder);
    RexProgramBuilder topProgramBuilder = new RexProgramBuilder(projRowType, rexBuilder);
    topProgramBuilder.addIdentity();
    topProgramBuilder.addCondition(joinRel.getCondition());
    RexProgram topProgram = topProgramBuilder.getProgram();
    RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
    // expand out the join condition and construct a new LogicalJoin that
    // directly references the join children without the intervening
    // ProjectRels
    RexNode newCondition = mergedProgram.expandLocalRef(mergedProgram.getCondition());
    Join newJoinRel = joinRel.copy(joinRel.getTraitSet(), newCondition, leftJoinChild, rightJoinChild, joinRel.getJoinType(), joinRel.isSemiJoinDone());
    // expand out the new projection expressions; if the join is an
    // outer join, modify the expressions to reference the join output
    final List<RexNode> newProjExprs = new ArrayList<>();
    List<RexLocalRef> projList = mergedProgram.getProjectList();
    List<RelDataTypeField> newJoinFields = newJoinRel.getRowType().getFieldList();
    int nJoinFields = newJoinFields.size();
    int[] adjustments = new int[nJoinFields];
    for (int i = 0; i < nProjExprs; i++) {
        RexNode newExpr = mergedProgram.expandLocalRef(projList.get(i));
        if (joinType != JoinRelType.INNER) {
            newExpr = newExpr.accept(new RelOptUtil.RexInputConverter(rexBuilder, joinChildrenRowType.getFieldList(), newJoinFields, adjustments));
        }
        newProjExprs.add(newExpr);
    }
    // finally, create the projection on top of the join
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(newJoinRel);
    relBuilder.project(newProjExprs, joinRel.getRowType().getFieldNames());
    // projection to fix differences wrt nullability of fields
    if (joinType != JoinRelType.INNER) {
        relBuilder.convert(joinRel.getRowType(), false);
    }
    call.transformTo(relBuilder.build());
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) RexProgram(org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RelDataType(org.apache.calcite.rel.type.RelDataType) JoinRelType(org.apache.calcite.rel.core.JoinRelType) Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) Pair(org.apache.calcite.util.Pair) RexNode(org.apache.calcite.rex.RexNode)

Example 99 with RexNode

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

the class JoinPushExpressionsRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    Join join = call.rel(0);
    // Push expression in join condition into Project below Join.
    RelNode newJoin = RelOptUtil.pushDownJoinConditions(join, call.builder());
    // If the join is the same, we bail out
    if (newJoin instanceof Join) {
        final RexNode newCondition = ((Join) newJoin).getCondition();
        if (join.getCondition().toString().equals(newCondition.toString())) {
            return;
        }
    }
    call.transformTo(newJoin);
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Join(org.apache.calcite.rel.core.Join) RexNode(org.apache.calcite.rex.RexNode)

Example 100 with RexNode

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

the class LoptSemiJoinOptimizer method findSemiJoinIndexByCost.

/**
 * Given a list of possible filters on a fact table, determine if there is
 * an index that can be used, provided all the fact table keys originate
 * from the same underlying table.
 *
 * @param multiJoin join factors being optimized
 * @param joinFilters filters to be used on the fact table
 * @param factIdx index in join factors corresponding to the fact table
 * @param dimIdx index in join factors corresponding to the dimension table
 *
 * @return SemiJoin containing information regarding the semijoin that
 * can be used to filter the fact table
 */
private SemiJoin findSemiJoinIndexByCost(LoptMultiJoin multiJoin, List<RexNode> joinFilters, int factIdx, int dimIdx) {
    // create a SemiJoin with the semi-join condition and keys
    RexNode semiJoinCondition = RexUtil.composeConjunction(rexBuilder, joinFilters, true);
    int leftAdjustment = 0;
    for (int i = 0; i < factIdx; i++) {
        leftAdjustment -= multiJoin.getNumFieldsInJoinFactor(i);
    }
    semiJoinCondition = adjustSemiJoinCondition(multiJoin, leftAdjustment, semiJoinCondition, factIdx, dimIdx);
    RelNode factRel = multiJoin.getJoinFactor(factIdx);
    RelNode dimRel = multiJoin.getJoinFactor(dimIdx);
    final JoinInfo joinInfo = JoinInfo.of(factRel, dimRel, semiJoinCondition);
    assert joinInfo.leftKeys.size() > 0;
    // mutable copies
    final List<Integer> leftKeys = Lists.newArrayList(joinInfo.leftKeys);
    final List<Integer> rightKeys = Lists.newArrayList(joinInfo.rightKeys);
    // make sure all the fact table keys originate from the same table
    // and are simple column references
    final List<Integer> actualLeftKeys = new ArrayList<>();
    LcsTable factTable = validateKeys(factRel, leftKeys, rightKeys, actualLeftKeys);
    if (factTable == null) {
        return null;
    }
    // find the best index
    final List<Integer> bestKeyOrder = new ArrayList<>();
    LcsTableScan tmpFactRel = (LcsTableScan) factTable.toRel(RelOptUtil.getContext(factRel.getCluster()));
    LcsIndexOptimizer indexOptimizer = new LcsIndexOptimizer(tmpFactRel);
    FemLocalIndex bestIndex = indexOptimizer.findSemiJoinIndexByCost(dimRel, actualLeftKeys, rightKeys, bestKeyOrder);
    if (bestIndex == null) {
        return null;
    }
    // if necessary, truncate the keys to reflect the ones that match
    // the index and remove the corresponding, unnecessary filters from
    // the condition; note that we don't save the actual keys here because
    // later when the semijoin is pushed past other RelNodes, the keys will
    // be converted
    final List<Integer> truncatedLeftKeys;
    final List<Integer> truncatedRightKeys;
    if (actualLeftKeys.size() == bestKeyOrder.size()) {
        truncatedLeftKeys = leftKeys;
        truncatedRightKeys = rightKeys;
    } else {
        truncatedLeftKeys = new ArrayList<>();
        truncatedRightKeys = new ArrayList<>();
        for (int key : bestKeyOrder) {
            truncatedLeftKeys.add(leftKeys.get(key));
            truncatedRightKeys.add(rightKeys.get(key));
        }
        semiJoinCondition = removeExtraFilters(truncatedLeftKeys, multiJoin.getNumFieldsInJoinFactor(factIdx), semiJoinCondition);
    }
    return SemiJoin.create(factRel, dimRel, semiJoinCondition, ImmutableIntList.copyOf(truncatedLeftKeys), ImmutableIntList.copyOf(truncatedRightKeys));
}
Also used : JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) 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