Java Code Examples for org.apache.calcite.plan.RelOptUtil#createEquiJoinCondition()

The following examples show how to use org.apache.calcite.plan.RelOptUtil#createEquiJoinCondition() . 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: DrillPushRowKeyJoinToScanRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
private void doOnMatch(RelOptRuleCall call, int rowKeyPosition, boolean swapInputs, DrillJoin joinRel,
    DrillProjectRel upperProjectRel, DrillFilterRel filterRel, DrillProjectRel lowerProjectRel, DrillScanRel scanRel) {
  // Swap the inputs, when necessary (i.e. when the primary-key col is on the right-side of the join)
  logger.debug("Transforming: Swapping of join inputs is required!");
  RelNode right = swapInputs ? joinRel.getLeft() : joinRel.getRight();
  // The join condition is primary-key = COL similarly to PK-FK relationship in relational DBs
  // where primary-key is PK and COL is FK
  List<Integer> leftJoinKeys = ImmutableList.of(rowKeyPosition);
  List<Integer> rightJoinKeys = swapInputs ? joinRel.getLeftKeys() : joinRel.getRightKeys();
  // Create restricted group scan for scanRel and reconstruct the left side of the join.
  DbGroupScan restrictedGroupScan = ((DbGroupScan)scanRel.getGroupScan()).getRestrictedScan(
      scanRel.getColumns());
  RelNode leftRel =  new DrillScanRel(scanRel.getCluster(), scanRel.getTraitSet(), scanRel.getTable(),
      restrictedGroupScan, scanRel.getRowType(), scanRel.getColumns(), scanRel.partitionFilterPushdown());
  // Transform the project/filter rels if present
  if (lowerProjectRel != null) {
    leftRel = lowerProjectRel.copy(lowerProjectRel.getTraitSet(), ImmutableList.of(leftRel));
  }
  if (filterRel != null) {
    leftRel = filterRel.copy(filterRel.getTraitSet(), leftRel, filterRel.getCondition());
  }
  if (upperProjectRel != null) {
    leftRel = upperProjectRel.copy(upperProjectRel.getTraitSet(), ImmutableList.of(leftRel));
  }
  // Create the equi-join condition for the rowkey join
  RexNode joinCondition =
      RelOptUtil.createEquiJoinCondition(leftRel, leftJoinKeys,
          right, rightJoinKeys, joinRel.getCluster().getRexBuilder());
  logger.debug("Transforming: LeftKeys={}, LeftRowType={}, RightKeys={}, RightRowType={}",
      leftJoinKeys, leftRel.getRowType(), rightJoinKeys, right.getRowType());
  RowKeyJoinRel rowKeyJoin = new RowKeyJoinRel(joinRel.getCluster(), joinRel.getTraitSet(), leftRel, right,
      joinCondition, joinRel.getJoinType(), joinRel instanceof DrillSemiJoinRel);
  logger.info("Transforming: SUCCESS: Register runtime filter pushdown plan (rowkeyjoin)");
  call.transformTo(rowKeyJoin);
}
 
Example 2
Source File: SemiJoinRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
protected void perform(RelOptRuleCall call, Project project,
    Join join, RelNode left, Aggregate aggregate) {
  final RelOptCluster cluster = join.getCluster();
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  if (project != null) {
    final ImmutableBitSet bits =
        RelOptUtil.InputFinder.bits(project.getProjects(), null);
    final ImmutableBitSet rightBits =
        ImmutableBitSet.range(left.getRowType().getFieldCount(),
            join.getRowType().getFieldCount());
    if (bits.intersects(rightBits)) {
      return;
    }
  }
  final JoinInfo joinInfo = join.analyzeCondition();
  if (!joinInfo.rightSet().equals(
      ImmutableBitSet.range(aggregate.getGroupCount()))) {
    // Rule requires that aggregate key to be the same as the join key.
    // By the way, neither a super-set nor a sub-set would work.
    return;
  }
  if (!joinInfo.isEqui()) {
    return;
  }
  final RelBuilder relBuilder = call.builder();
  relBuilder.push(left);
  switch (join.getJoinType()) {
  case INNER:
    final List<Integer> newRightKeyBuilder = new ArrayList<>();
    final List<Integer> aggregateKeys = aggregate.getGroupSet().asList();
    for (int key : joinInfo.rightKeys) {
      newRightKeyBuilder.add(aggregateKeys.get(key));
    }
    final ImmutableIntList newRightKeys = ImmutableIntList.copyOf(newRightKeyBuilder);
    relBuilder.push(aggregate.getInput());
    final RexNode newCondition =
        RelOptUtil.createEquiJoinCondition(relBuilder.peek(2, 0),
            joinInfo.leftKeys, relBuilder.peek(2, 1), newRightKeys,
            rexBuilder);
    relBuilder.semiJoin(newCondition);
    break;

  case LEFT:
    // The right-hand side produces no more than 1 row (because of the
    // Aggregate) and no fewer than 1 row (because of LEFT), and therefore
    // we can eliminate the semi-join.
    break;

  default:
    throw new AssertionError(join.getJoinType());
  }
  if (project != null) {
    relBuilder.project(project.getProjects(), project.getRowType().getFieldNames());
  }
  call.transformTo(relBuilder.build());
}
 
Example 3
Source File: JoinInfo.java    From Bats with Apache License 2.0 4 votes vote down vote up
public RexNode getEquiCondition(RelNode left, RelNode right,
    RexBuilder rexBuilder) {
  return RelOptUtil.createEquiJoinCondition(left, leftKeys, right, rightKeys,
      rexBuilder);
}
 
Example 4
Source File: SemiJoinRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
protected void perform(RelOptRuleCall call, Project project,
    Join join, RelNode left, Aggregate aggregate) {
  final RelOptCluster cluster = join.getCluster();
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  if (project != null) {
    final ImmutableBitSet bits =
        RelOptUtil.InputFinder.bits(project.getProjects(), null);
    final ImmutableBitSet rightBits =
        ImmutableBitSet.range(left.getRowType().getFieldCount(),
            join.getRowType().getFieldCount());
    if (bits.intersects(rightBits)) {
      return;
    }
  } else {
    if (join.getJoinType().projectsRight()
        && !IS_EMPTY_AGGREGATE.test(aggregate)) {
      return;
    }
  }
  final JoinInfo joinInfo = join.analyzeCondition();
  if (!joinInfo.rightSet().equals(
      ImmutableBitSet.range(aggregate.getGroupCount()))) {
    // Rule requires that aggregate key to be the same as the join key.
    // By the way, neither a super-set nor a sub-set would work.
    return;
  }
  if (!joinInfo.isEqui()) {
    return;
  }
  final RelBuilder relBuilder = call.builder();
  relBuilder.push(left);
  switch (join.getJoinType()) {
  case SEMI:
  case INNER:
    final List<Integer> newRightKeyBuilder = new ArrayList<>();
    final List<Integer> aggregateKeys = aggregate.getGroupSet().asList();
    for (int key : joinInfo.rightKeys) {
      newRightKeyBuilder.add(aggregateKeys.get(key));
    }
    final ImmutableIntList newRightKeys = ImmutableIntList.copyOf(newRightKeyBuilder);
    relBuilder.push(aggregate.getInput());
    final RexNode newCondition =
        RelOptUtil.createEquiJoinCondition(relBuilder.peek(2, 0),
            joinInfo.leftKeys, relBuilder.peek(2, 1), newRightKeys,
            rexBuilder);
    relBuilder.semiJoin(newCondition);
    break;

  case LEFT:
    // The right-hand side produces no more than 1 row (because of the
    // Aggregate) and no fewer than 1 row (because of LEFT), and therefore
    // we can eliminate the semi-join.
    break;

  default:
    throw new AssertionError(join.getJoinType());
  }
  if (project != null) {
    relBuilder.project(project.getProjects(), project.getRowType().getFieldNames());
  }
  final RelNode relNode = relBuilder.build();
  call.transformTo(relNode);
}
 
Example 5
Source File: JoinInfo.java    From calcite with Apache License 2.0 4 votes vote down vote up
public RexNode getEquiCondition(RelNode left, RelNode right,
    RexBuilder rexBuilder) {
  return RelOptUtil.createEquiJoinCondition(left, leftKeys, right, rightKeys,
      rexBuilder);
}