org.apache.calcite.rel.core.Join Java Examples

The following examples show how to use org.apache.calcite.rel.core.Join. 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: LoptOptimizeJoinRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Determines whether a join is a removable self-join. It is if it's an
 * inner join between identical, simple factors and the equality portion of
 * the join condition consists of the same set of unique keys.
 *
 * @param joinRel the join
 *
 * @return true if the join is removable
 */
public static boolean isRemovableSelfJoin(Join joinRel) {
  final RelNode left = joinRel.getLeft();
  final RelNode right = joinRel.getRight();

  if (joinRel.getJoinType() != JoinRelType.INNER) {
    return false;
  }

  // Make sure the join is between the same simple factor
  final RelMetadataQuery mq = joinRel.getCluster().getMetadataQuery();
  final RelOptTable leftTable = mq.getTableOrigin(left);
  if (leftTable == null) {
    return false;
  }
  final RelOptTable rightTable = mq.getTableOrigin(right);
  if (rightTable == null) {
    return false;
  }
  if (!leftTable.getQualifiedName().equals(rightTable.getQualifiedName())) {
    return false;
  }

  // Determine if the join keys are identical and unique
  return areSelfJoinKeysUnique(mq, left, right, joinRel.getCondition());
}
 
Example #2
Source File: RelMdColumnOrigins.java    From Bats with Apache License 2.0 6 votes vote down vote up
public Set<RelColumnOrigin> getColumnOrigins(Join rel, RelMetadataQuery mq,
    int iOutputColumn) {
  int nLeftColumns = rel.getLeft().getRowType().getFieldList().size();
  Set<RelColumnOrigin> set;
  boolean derived = false;
  if (iOutputColumn < nLeftColumns) {
    set = mq.getColumnOrigins(rel.getLeft(), iOutputColumn);
    if (rel.getJoinType().generatesNullsOnLeft()) {
      derived = true;
    }
  } else {
    set = mq.getColumnOrigins(rel.getRight(), iOutputColumn - nLeftColumns);
    if (rel.getJoinType().generatesNullsOnRight()) {
      derived = true;
    }
  }
  if (derived) {
    // nulls are generated due to outer join; that counts
    // as derivation
    set = createDerivedColumnOrigins(set);
  }
  return set;
}
 
Example #3
Source File: LoptOptimizeJoinRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Determines whether a join is a removable self-join. It is if it's an
 * inner join between identical, simple factors and the equality portion of
 * the join condition consists of the same set of unique keys.
 *
 * @param joinRel the join
 *
 * @return true if the join is removable
 */
public static boolean isRemovableSelfJoin(Join joinRel) {
  final RelNode left = joinRel.getLeft();
  final RelNode right = joinRel.getRight();

  if (joinRel.getJoinType().isOuterJoin()) {
    return false;
  }

  // Make sure the join is between the same simple factor
  final RelMetadataQuery mq = joinRel.getCluster().getMetadataQuery();
  final RelOptTable leftTable = mq.getTableOrigin(left);
  if (leftTable == null) {
    return false;
  }
  final RelOptTable rightTable = mq.getTableOrigin(right);
  if (rightTable == null) {
    return false;
  }
  if (!leftTable.getQualifiedName().equals(rightTable.getQualifiedName())) {
    return false;
  }

  // Determine if the join keys are identical and unique
  return areSelfJoinKeysUnique(mq, left, right, joinRel.getCondition());
}
 
Example #4
Source File: RelMdSize.java    From calcite with Apache License 2.0 6 votes vote down vote up
private List<Double> averageJoinColumnSizes(Join rel, RelMetadataQuery mq) {
  boolean semiOrAntijoin = !rel.getJoinType().projectsRight();
  final RelNode left = rel.getLeft();
  final RelNode right = rel.getRight();
  final List<Double> lefts = mq.getAverageColumnSizes(left);
  final List<Double> rights =
      semiOrAntijoin ? null : mq.getAverageColumnSizes(right);
  if (lefts == null && rights == null) {
    return null;
  }
  final int fieldCount = rel.getRowType().getFieldCount();
  Double[] sizes = new Double[fieldCount];
  if (lefts != null) {
    lefts.toArray(sizes);
  }
  if (rights != null) {
    final int leftCount = left.getRowType().getFieldCount();
    for (int i = 0; i < rights.size(); i++) {
      sizes[leftCount + i] = rights.get(i);
    }
  }
  return ImmutableNullableList.copyOf(sizes);
}
 
Example #5
Source File: FlinkJoinToMultiJoinRule.java    From flink with Apache License 2.0 6 votes vote down vote up
/**
 * Combines the post-join filters from the left and right inputs (if they
 * are MultiJoinRels) into a single AND'd filter.
 *
 * @param joinRel the original LogicalJoin
 * @param left    left child of the LogicalJoin
 * @param right   right child of the LogicalJoin
 * @return combined post-join filters AND'd together
 */
private List<RexNode> combinePostJoinFilters(
		Join joinRel,
		RelNode left,
		RelNode right) {
	final List<RexNode> filters = new ArrayList<>();
	if (right instanceof MultiJoin) {
		final MultiJoin multiRight = (MultiJoin) right;
		filters.add(
				shiftRightFilter(joinRel, left, multiRight,
						multiRight.getPostJoinFilter()));
	}

	if (left instanceof MultiJoin) {
		filters.add(((MultiJoin) left).getPostJoinFilter());
	}

	return filters;
}
 
Example #6
Source File: JoinPushExpressionsRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@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().equals(newCondition)) {
      return;
    }
  }

  call.transformTo(newJoin);
}
 
Example #7
Source File: RelMdColumnOrigins.java    From calcite with Apache License 2.0 6 votes vote down vote up
public Set<RelColumnOrigin> getColumnOrigins(Join rel, RelMetadataQuery mq,
    int iOutputColumn) {
  int nLeftColumns = rel.getLeft().getRowType().getFieldList().size();
  Set<RelColumnOrigin> set;
  boolean derived = false;
  if (iOutputColumn < nLeftColumns) {
    set = mq.getColumnOrigins(rel.getLeft(), iOutputColumn);
    if (rel.getJoinType().generatesNullsOnLeft()) {
      derived = true;
    }
  } else {
    set = mq.getColumnOrigins(rel.getRight(), iOutputColumn - nLeftColumns);
    if (rel.getJoinType().generatesNullsOnRight()) {
      derived = true;
    }
  }
  if (derived) {
    // nulls are generated due to outer join; that counts
    // as derivation
    set = createDerivedColumnOrigins(set);
  }
  return set;
}
 
Example #8
Source File: AggregateJoinTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Deprecated // to be removed before 2.0
public AggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
    RelFactories.AggregateFactory aggregateFactory,
    Class<? extends Join> joinClass,
    RelFactories.JoinFactory joinFactory) {
  this(aggregateClass, joinClass,
      RelBuilder.proto(aggregateFactory, joinFactory), false);
}
 
Example #9
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Creates projection expressions reflecting the swapping of a join's input.
 *
 * @param newJoin   the RelNode corresponding to the join with its inputs
 *                  swapped
 * @param origJoin  original LogicalJoin
 * @param origOrder if true, create the projection expressions to reflect
 *                  the original (pre-swapped) join projection; otherwise,
 *                  create the projection to reflect the order of the swapped
 *                  projection
 * @return array of expression representing the swapped join inputs
 */
public static List<RexNode> createSwappedJoinExprs(RelNode newJoin, Join origJoin, boolean origOrder) {
    final List<RelDataTypeField> newJoinFields = newJoin.getRowType().getFieldList();
    final RexBuilder rexBuilder = newJoin.getCluster().getRexBuilder();
    final List<RexNode> exps = new ArrayList<>();
    final int nFields = origOrder ? origJoin.getRight().getRowType().getFieldCount()
            : origJoin.getLeft().getRowType().getFieldCount();
    for (int i = 0; i < newJoinFields.size(); i++) {
        final int source = (i + nFields) % newJoinFields.size();
        RelDataTypeField field = origOrder ? newJoinFields.get(source) : newJoinFields.get(i);
        exps.add(rexBuilder.makeInputRef(field.getType(), source));
    }
    return exps;
}
 
Example #10
Source File: StreamRules.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a DeltaJoinTransposeRule.
 *
 * @param relBuilderFactory Builder for relational expressions
 */
public DeltaJoinTransposeRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(Delta.class,
          operand(Join.class, any())),
      relBuilderFactory, null);
}
 
Example #11
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testNodeTypeCountJoinEmptyEmpty() {
  final String sql = "select * from (select * from emp limit 0) as emp\n"
      + "inner join (select * from dept limit 0) as dept\n"
      + "on emp.deptno = dept.deptno";
  final Map<Class<? extends RelNode>, Integer> expected = new HashMap<>();
  expected.put(TableScan.class, 2);
  expected.put(Join.class, 1);
  expected.put(Project.class, 3);
  expected.put(Sort.class, 2);
  checkNodeTypeCount(sql, expected);
}
 
Example #12
Source File: JoinToMultiJoinRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Combines the join filters from the left and right inputs (if they are
 * MultiJoinRels) with the join filter in the joinrel into a single AND'd
 * join filter, unless the inputs correspond to null generating inputs in an
 * outer join
 *
 * @param joinRel join rel
 * @param left    left child of the join
 * @param right   right child of the join
 * @return combined join filters AND-ed together
 */
private List<RexNode> combineJoinFilters(
    Join joinRel,
    RelNode left,
    RelNode right) {
  JoinRelType joinType = joinRel.getJoinType();

  // AND the join condition if this isn't a left or right outer join;
  // in those cases, the outer join condition is already tracked
  // separately
  final List<RexNode> filters = new ArrayList<>();
  if ((joinType != JoinRelType.LEFT) && (joinType != JoinRelType.RIGHT)) {
    filters.add(joinRel.getCondition());
  }
  if (canCombine(left, joinType.generatesNullsOnLeft())) {
    filters.add(((MultiJoin) left).getJoinFilter());
  }
  // Need to adjust the RexInputs of the right child, since
  // those need to shift over to the right
  if (canCombine(right, joinType.generatesNullsOnRight())) {
    MultiJoin multiJoin = (MultiJoin) right;
    filters.add(
        shiftRightFilter(joinRel, left, multiJoin,
            multiJoin.getJoinFilter()));
  }

  return filters;
}
 
Example #13
Source File: SemiJoinRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
protected SemiJoinRule(Class<Project> projectClass, Class<Join> joinClass,
    Class<Aggregate> aggregateClass, RelBuilderFactory relBuilderFactory,
    String description) {
  super(
      operand(projectClass,
          some(
              operandJ(joinClass, null, IS_LEFT_OR_INNER,
                  some(operand(RelNode.class, any()),
                      operand(aggregateClass, any()))))),
      relBuilderFactory, description);
}
 
Example #14
Source File: LoptOptimizeJoinRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Computes a cost for a join tree based on the row widths of the inputs
 * into the join. Joins where the inputs have the fewest number of columns
 * lower in the tree are better than equivalent joins where the inputs with
 * the larger number of columns are lower in the tree.
 *
 * @param tree a tree of RelNodes
 *
 * @return the cost associated with the width of the tree
 */
private int rowWidthCost(RelNode tree) {
  // The width cost is the width of the tree itself plus the widths
  // of its children.  Hence, skinnier rows are better when they're
  // lower in the tree since the width of a RelNode contributes to
  // the cost of each LogicalJoin that appears above that RelNode.
  int width = tree.getRowType().getFieldCount();
  if (isJoinTree(tree)) {
    Join joinRel = (Join) tree;
    width +=
        rowWidthCost(joinRel.getLeft())
            + rowWidthCost(joinRel.getRight());
  }
  return width;
}
 
Example #15
Source File: JoinCommuteRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(final RelOptRuleCall call) {
  Join join = call.rel(0);

  final RelNode swapped = swap(join, this.swapOuter, call.builder());
  if (swapped == null) {
    return;
  }

  // The result is either a Project or, if the project is trivial, a
  // raw Join.
  final Join newJoin =
      swapped instanceof Join
          ? (Join) swapped
          : (Join) swapped.getInput(0);

  call.transformTo(swapped);

  // We have converted join='a join b' into swapped='select
  // a0,a1,a2,b0,b1 from b join a'. Now register that project='select
  // b0,b1,a0,a1,a2 from (select a0,a1,a2,b0,b1 from b join a)' is the
  // same as 'b join a'. If we didn't do this, the swap join rule
  // would fire on the new join, ad infinitum.
  final RelBuilder relBuilder = call.builder();
  final List<RexNode> exps =
      RelOptUtil.createSwappedJoinExprs(newJoin, join, false);
  relBuilder.push(swapped)
      .project(exps, newJoin.getRowType().getFieldNames());

  call.getPlanner().ensureRegistered(relBuilder.build(), newJoin);
}
 
Example #16
Source File: RelMdDistinctRowCount.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
public Double getDistinctRowCount(Join rel, RelMetadataQuery mq,
                                  ImmutableBitSet groupKey, RexNode predicate) {
  if (predicate == null || predicate.isAlwaysTrue()) {
    if (groupKey.isEmpty()) {
      return 1D;
    }
  }
  return getDistinctRowCountFromEstimateRowCount(rel, mq, groupKey, predicate);
}
 
Example #17
Source File: DrillJoinRelBase.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public double estimateRowCount(RelMetadataQuery mq) {
  if (this.condition.isAlwaysTrue()) {
    return joinRowFactor * this.getLeft().estimateRowCount(mq) * this.getRight().estimateRowCount(mq);
  }

  int[] joinFields = new int[2];

  LogicalJoin jr = LogicalJoin.create(this.getLeft(), this.getRight(), this.getCondition(),
          this.getVariablesSet(), this.getJoinType());

  if (!DrillRelOptUtil.guessRows(this)         //Statistics present for left and right side of the join
      && jr.getJoinType() == JoinRelType.INNER
      && DrillRelOptUtil.analyzeSimpleEquiJoin((Join)jr, joinFields)) {
    ImmutableBitSet leq = ImmutableBitSet.of(joinFields[0]);
    ImmutableBitSet req = ImmutableBitSet.of(joinFields[1]);

    Double ldrc = mq.getDistinctRowCount(this.getLeft(), leq, null);
    Double rdrc = mq.getDistinctRowCount(this.getRight(), req, null);

    Double lrc = mq.getRowCount(this.getLeft());
    Double rrc = mq.getRowCount(this.getRight());

    if (ldrc != null && rdrc != null && lrc != null && rrc != null) {
      // Join cardinality = (lrc * rrc) / Math.max(ldrc, rdrc). Avoid overflow by dividing earlier
      return (lrc / Math.max(ldrc, rdrc)) * rrc;
    }
  }

  return joinRowFactor * Math.max(
      mq.getRowCount(this.getLeft()),
      mq.getRowCount(this.getRight()));
}
 
Example #18
Source File: CompositeFilterJoinRule.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
protected RelNode doMatch(RelOptRuleCall call) {
  Filter filter = call.rel(0);
  Join join = call.rel(1);
  TransformCollectingCall c = new TransformCollectingCall(call.getPlanner(), this.getOperand(), new RelNode[] {filter, join}, null);
  perform(c, filter, join);
  if (c.outcome.isEmpty()) {
    return null;
  }

  return c.outcome.get(0);
}
 
Example #19
Source File: PostOrderRelNodeVisitor.java    From streamline with Apache License 2.0 5 votes vote down vote up
public final T traverse(RelNode n) throws Exception {
  List<T> inputStreams = new ArrayList<>();
  for (RelNode input : n.getInputs()) {
    inputStreams.add(traverse(input));
  }

  if (n instanceof Aggregate) {
    return visitAggregate((Aggregate) n, inputStreams);
  } else if (n instanceof Calc) {
    return visitCalc((Calc) n, inputStreams);
  } else if (n instanceof Collect) {
    return visitCollect((Collect) n, inputStreams);
  } else if (n instanceof Correlate) {
    return visitCorrelate((Correlate) n, inputStreams);
  } else if (n instanceof Delta) {
    return visitDelta((Delta) n, inputStreams);
  } else if (n instanceof Exchange) {
    return visitExchange((Exchange) n, inputStreams);
  } else if (n instanceof Project) {
    return visitProject((Project) n, inputStreams);
  } else if (n instanceof Filter) {
    return visitFilter((Filter) n, inputStreams);
  } else if (n instanceof Sample) {
    return visitSample((Sample) n, inputStreams);
  } else if (n instanceof Sort) {
    return visitSort((Sort) n, inputStreams);
  } else if (n instanceof TableModify) {
    return visitTableModify((TableModify) n, inputStreams);
  } else if (n instanceof TableScan) {
    return visitTableScan((TableScan) n, inputStreams);
  } else if (n instanceof Uncollect) {
    return visitUncollect((Uncollect) n, inputStreams);
  } else if (n instanceof Window) {
    return visitWindow((Window) n, inputStreams);
  } else if (n instanceof Join) {
    return visitJoin((Join) n, inputStreams);
  } else {
    return defaultValue(n, inputStreams);
  }
}
 
Example #20
Source File: AggregateJoinTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
@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,
    boolean allowFunctions) {
  this(aggregateClass, joinClass,
      RelBuilder.proto(aggregateFactory, joinFactory, projectFactory),
      allowFunctions);
}
 
Example #21
Source File: StreamRules.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Delta delta = call.rel(0);
  Util.discard(delta);
  final Join join = call.rel(1);
  final RelNode left = join.getLeft();
  final RelNode right = join.getRight();

  final LogicalDelta rightWithDelta = LogicalDelta.create(right);
  final LogicalJoin joinL = LogicalJoin.create(left,
      rightWithDelta,
      join.getHints(),
      join.getCondition(),
      join.getVariablesSet(),
      join.getJoinType(),
      join.isSemiJoinDone(),
      ImmutableList.copyOf(join.getSystemFieldList()));

  final LogicalDelta leftWithDelta = LogicalDelta.create(left);
  final LogicalJoin joinR = LogicalJoin.create(leftWithDelta,
      right,
      join.getHints(),
      join.getCondition(),
      join.getVariablesSet(),
      join.getJoinType(),
      join.isSemiJoinDone(),
      ImmutableList.copyOf(join.getSystemFieldList()));

  List<RelNode> inputsToUnion = new ArrayList<>();
  inputsToUnion.add(joinL);
  inputsToUnion.add(joinR);

  final LogicalUnion newNode = LogicalUnion.create(inputsToUnion, true);
  call.transformTo(newNode);
}
 
Example #22
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testAllPredicates() {
  final Project rel = (Project) convertSql("select * from emp, dept");
  final Join join = (Join) rel.getInput();
  final RelOptTable empTable = join.getInput(0).getTable();
  final RelOptTable deptTable = join.getInput(1).getTable();
  Frameworks.withPlanner((cluster, relOptSchema, rootSchema) -> {
    checkAllPredicates(cluster, empTable, deptTable);
    return null;
  });
}
 
Example #23
Source File: RelNodeCompiler.java    From streamline with Apache License 2.0 5 votes vote down vote up
@Override
public Void visitJoin(Join join, List<Void> inputStreams) {
  beginJoinStage(join);
  pw.println("        if (source == left) {");
  pw.println("            leftRows.add(_data);");
  pw.println("        } else if (source == right) {");
  pw.println("            rightRows.add(_data);");
  pw.println("        }");
  endStage();
  return null;
}
 
Example #24
Source File: AggregateJoinTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/** Creates an AggregateJoinTransposeRule. */
public AggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
    Class<? extends Join> joinClass, RelBuilderFactory relBuilderFactory,
    boolean allowFunctions) {
  super(
      operandJ(aggregateClass, null, agg -> isAggregateSupported(agg, allowFunctions),
          operandJ(joinClass, null, join -> join.getJoinType() == JoinRelType.INNER, any())),
      relBuilderFactory, null);
  this.allowFunctions = allowFunctions;
}
 
Example #25
Source File: SemiJoinRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@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);
}
 
Example #26
Source File: LoptJoinTree.java    From calcite with Apache License 2.0 5 votes vote down vote up
public LoptJoinTree getLeft() {
  final Node node = (Node) factorTree;
  return new LoptJoinTree(
      ((Join) joinTree).getLeft(),
      node.getLeft(),
      node.getLeft().getParent().isRemovableSelfJoin());
}
 
Example #27
Source File: MaterializedViewProjectJoinRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public MaterializedViewProjectJoinRule(RelBuilderFactory relBuilderFactory,
    boolean generateUnionRewriting, HepProgram unionRewritingPullProgram,
    boolean fastBailOut) {
  super(
      operand(Project.class,
          operand(Join.class, any())),
      relBuilderFactory,
      "MaterializedViewJoinRule(Project-Join)",
      generateUnionRewriting, unionRewritingPullProgram, fastBailOut);
}
 
Example #28
Source File: AggregateJoinTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Deprecated // to be removed before 2.0
public AggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
    RelFactories.AggregateFactory aggregateFactory,
    Class<? extends Join> joinClass,
    RelFactories.JoinFactory joinFactory,
    boolean allowFunctions) {
  this(aggregateClass, joinClass,
      RelBuilder.proto(aggregateFactory, joinFactory), allowFunctions);
}
 
Example #29
Source File: JoinCommuteRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(final RelOptRuleCall call) {
    Join join = call.rel(0);

    if (!join.getSystemFieldList().isEmpty()) {
        // FIXME Enable this rule for joins with system fields
        return;
    }

    final RelNode swapped = swap(join, this.swapOuter, call.builder());
    if (swapped == null) {
        return;
    }

    // The result is either a Project or, if the project is trivial, a
    // raw Join.
    final Join newJoin = swapped instanceof Join ? (Join) swapped : (Join) swapped.getInput(0);

    call.transformTo(swapped);

    // We have converted join='a join b' into swapped='select
    // a0,a1,a2,b0,b1 from b join a'. Now register that project='select
    // b0,b1,a0,a1,a2 from (select a0,a1,a2,b0,b1 from b join a)' is the
    // same as 'b join a'. If we didn't do this, the swap join rule
    // would fire on the new join, ad infinitum.
    final RelBuilder relBuilder = call.builder();
    final List<RexNode> exps = RelOptUtil.createSwappedJoinExprs(newJoin, join, false);
    relBuilder.push(swapped).project(exps, newJoin.getRowType().getFieldNames());

    call.getPlanner().ensureRegistered(relBuilder.build(), newJoin);
}
 
Example #30
Source File: JoinNormalizationRule.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  final Join join = call.rel(0);

  final RelNode newJoin = normalize(join);

  if (newJoin != join) {
    call.transformTo(newJoin);
  }
}