Java Code Examples for org.apache.calcite.rel.core.JoinRelType#FULL

The following examples show how to use org.apache.calcite.rel.core.JoinRelType#FULL . 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: MergeJoinPrel.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner, mq).multiplyBy(.1);
  }
  if (joincategory == JoinCategory.CARTESIAN || joincategory == JoinCategory.INEQUALITY
      || getJoinType() == JoinRelType.FULL) {
    return planner.getCostFactory().makeInfiniteCost();
  }
  double leftRowCount = mq.getRowCount(this.getLeft());
  double rightRowCount = mq.getRowCount(this.getRight());
  // cost of evaluating each leftkey=rightkey join condition
  double joinConditionCost = DrillCostBase.COMPARE_CPU_COST * this.getLeftKeys().size();
  double cpuCost = joinConditionCost * (leftRowCount + rightRowCount);
  DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory();
  return costFactory.makeCost(leftRowCount + rightRowCount, cpuCost, 0, 0);
}
 
Example 2
Source File: HBTQueryConvertor.java    From Mycat2 with GNU General Public License v3.0 6 votes vote down vote up
private JoinRelType joinOp(HBTOp op) {
    switch (op) {
        case INNER_JOIN:
            return JoinRelType.INNER;
        case LEFT_JOIN:
            return JoinRelType.LEFT;
        case RIGHT_JOIN:
            return JoinRelType.RIGHT;
        case FULL_JOIN:
            return JoinRelType.FULL;
        case SEMI_JOIN:
            return JoinRelType.SEMI;
        case ANTI_JOIN:
            return JoinRelType.ANTI;
        case CORRELATE_INNER_JOIN:
            return JoinRelType.INNER;
        case CORRELATE_LEFT_JOIN:
            return JoinRelType.LEFT;
        default:
            throw new UnsupportedOperationException();
    }
}
 
Example 3
Source File: MergeJoinComparatorTemplate.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public boolean finishNonMatching() {
  Preconditions.checkArgument(!leftIterator.hasNext() || !rightIterator.hasNext());

  // allocate new buffer for new batch
  if (outputRecordsCounter == 0) {
    outgoing.allocateNew();
  }

  if (joinType == JoinRelType.RIGHT) {
    return projectRightNonMatching();
  } else if (joinType == JoinRelType.LEFT) {
    return projectLeftNonMatching();
  } else if (joinType == JoinRelType.FULL) {
    if (leftIterator.hasNext()) {
      return projectLeftNonMatching();
    } else {
      return projectRightNonMatching();
    }
  } else {
    throw new IllegalStateException("Reach unexpected state");
  }
}
 
Example 4
Source File: EnumerableTraitsUtils.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * This function can be reused when a Join's traits pass-down shall only
 * pass through collation to left input.
 *
 * @param required required trait set for the join
 * @param joinType the join type
 * @param leftInputFieldCount number of field count of left join input
 * @param joinTraitSet trait set of the join
 */
static Pair<RelTraitSet, List<RelTraitSet>> passThroughTraitsForJoin(
    RelTraitSet required, JoinRelType joinType,
    int leftInputFieldCount, RelTraitSet joinTraitSet) {
  RelCollation collation = required.getCollation();
  if (collation == null
      || collation == RelCollations.EMPTY
      || joinType == JoinRelType.FULL
      || joinType == JoinRelType.RIGHT) {
    return null;
  }

  for (RelFieldCollation fc : collation.getFieldCollations()) {
    // If field collation belongs to right input: cannot push down collation.
    if (fc.getFieldIndex() >= leftInputFieldCount) {
      return null;
    }
  }

  RelTraitSet passthroughTraitSet = joinTraitSet.replace(collation);
  return Pair.of(passthroughTraitSet,
      ImmutableList.of(
          passthroughTraitSet,
          passthroughTraitSet.replace(RelCollations.EMPTY)));
}
 
Example 5
Source File: HashJoinProbeTemplate.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public void changeToFinalProbeState() {
  // We are done with the (left) probe phase.
  // If it's a RIGHT or a FULL join then need to get the unmatched indexes from the build side
  probeState =
    (joinType == JoinRelType.RIGHT || joinType == JoinRelType.FULL) ? ProbeState.PROJECT_RIGHT :
      ProbeState.DONE; // else we're done
}
 
Example 6
Source File: PigRelOpVisitor.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Decides the join type from the inner types of both relation.
 *
 * @param leftInner  true if the left requires inner
 * @param rightInner true if the right requires inner
 * @return The join type, either INNER, LEFT, RIGHT, or FULL
 */
private static JoinRelType getJoinType(boolean leftInner, boolean rightInner) {
  if (leftInner && rightInner) {
    return JoinRelType.INNER;
  } else if (leftInner) {
    return JoinRelType.LEFT;
  } else if (rightInner) {
    return JoinRelType.RIGHT;
  } else {
    return JoinRelType.FULL;
  }
}
 
Example 7
Source File: QueryOperationConverter.java    From flink with Apache License 2.0 5 votes vote down vote up
private JoinRelType convertJoinType(JoinType joinType) {
	switch (joinType) {
		case INNER:
			return JoinRelType.INNER;
		case LEFT_OUTER:
			return JoinRelType.LEFT;
		case RIGHT_OUTER:
			return JoinRelType.RIGHT;
		case FULL_OUTER:
			return JoinRelType.FULL;
		default:
			throw new TableException("Unknown join type: " + joinType);
	}
}
 
Example 8
Source File: EnumerableHashJoin.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public DeriveMode getDeriveMode() {
  if (joinType == JoinRelType.FULL || joinType == JoinRelType.RIGHT) {
    return DeriveMode.PROHIBITED;
  }

  return DeriveMode.LEFT_FIRST;
}
 
Example 9
Source File: EnumerableBatchNestedLoopJoin.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public DeriveMode getDeriveMode() {
  if (joinType == JoinRelType.FULL || joinType == JoinRelType.RIGHT) {
    return DeriveMode.PROHIBITED;
  }

  return DeriveMode.LEFT_FIRST;
}
 
Example 10
Source File: VectorizedHashJoinOperator.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void noMoreToConsumeLeft() throws Exception {
  state.is(State.CAN_CONSUME_L);

  finishedProbe = true;
  if(joinType == JoinRelType.FULL || joinType == JoinRelType.RIGHT){
    // if we need to project build records that didn't match, make sure we do so.
    state = State.CAN_PRODUCE;
  } else {
    state = State.DONE;
  }
}
 
Example 11
Source File: ApexRelNode.java    From attic-apex-malhar with Apache License 2.0 5 votes vote down vote up
@Override
public RelInfo visit(RelContext context, RelNode node, List<RelInfo> inputStreams)
{
  Join join = (Join)node;
  if (inputStreams.size() != 2) {
    throw new UnsupportedOperationException("Join is a BiRel");
  }

  if ((join.getJoinType() == JoinRelType.FULL) || (join.getJoinType() == JoinRelType.LEFT) ||
      (join.getJoinType() == JoinRelType.RIGHT)) {
    throw new UnsupportedOperationException("Outer joins are not supported");
  }

  final List<Integer> leftKeys = new ArrayList<>();
  final List<Integer> rightKeys = new ArrayList<>();

  RexNode remaining =
      RelOptUtil.splitJoinCondition(join.getLeft(), join.getRight(), join.getCondition(), leftKeys, rightKeys);

  if (leftKeys.size() != rightKeys.size()) {
    throw new RuntimeException("Unexpected condition reached. Left and right condition count should be same");
  }

  if (leftKeys.size() == 0) {
    throw new UnsupportedOperationException("Theta joins are not supported.");
  }

  RelInfo relInfo = addInnerJoinOperator(join, leftKeys, rightKeys, context);

  if (!remaining.isAlwaysTrue()) {
    relInfo = addJoinFilter(join, remaining, relInfo, context);
  }

  return relInfo;
}
 
Example 12
Source File: HashJoinOperator.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void noMoreToConsumeRight() throws Exception {
  state.is(State.CAN_CONSUME_R);

  if (hashTable.size() == 0 && !(joinType == JoinRelType.LEFT || joinType == JoinRelType.FULL)) {
    // nothing needs to be read on the left side as right side is empty
    state = State.DONE;
    return;
  }
  this.hashJoinProbe = setupHashJoinProbe();
  state = State.CAN_CONSUME_L;
}
 
Example 13
Source File: HashJoinOperator.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void noMoreToConsumeLeft() throws Exception {
  state.is(State.CAN_CONSUME_L);

  finishedProbe = true;
  if(joinType == JoinRelType.FULL || joinType == JoinRelType.RIGHT){
    // if we need to project build records that didn't match, make sure we do so.
    state = State.CAN_PRODUCE;
  } else {
    state = State.DONE;
  }
}
 
Example 14
Source File: RelMdColumnUniqueness.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Boolean areColumnsUnique(Join rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
  if (columns.cardinality() == 0) {
    return false;
  }

  final RelNode left = rel.getLeft();
  final RelNode right = rel.getRight();

  // Semi or anti join should ignore uniqueness of the right input.
  if (!rel.getJoinType().projectsRight()) {
    return mq.areColumnsUnique(left, columns, ignoreNulls);
  }

  // Divide up the input column mask into column masks for the left and
  // right sides of the join
  final Pair<ImmutableBitSet, ImmutableBitSet> leftAndRightColumns =
      splitLeftAndRightColumns(rel.getLeft().getRowType().getFieldCount(),
          columns);
  final ImmutableBitSet leftColumns = leftAndRightColumns.left;
  final ImmutableBitSet rightColumns = leftAndRightColumns.right;

  // for FULL OUTER JOIN if columns contain column from both inputs it is not
  // guaranteed that the result will be unique
  if (!ignoreNulls && rel.getJoinType() == JoinRelType.FULL
      && leftColumns.cardinality() > 0 && rightColumns.cardinality() > 0) {
    return false;
  }

  // If the original column mask contains columns from both the left and
  // right hand side, then the columns are unique if and only if they're
  // unique for their respective join inputs
  Boolean leftUnique = mq.areColumnsUnique(left, leftColumns, ignoreNulls);
  Boolean rightUnique = mq.areColumnsUnique(right, rightColumns, ignoreNulls);
  if ((leftColumns.cardinality() > 0)
      && (rightColumns.cardinality() > 0)) {
    if ((leftUnique == null) || (rightUnique == null)) {
      return null;
    } else {
      return leftUnique && rightUnique;
    }
  }

  // If we're only trying to determine uniqueness for columns that
  // originate from one join input, then determine if the equijoin
  // columns from the other join input are unique.  If they are, then
  // the columns are unique for the entire join if they're unique for
  // the corresponding join input, provided that input is not null
  // generating.
  final JoinInfo joinInfo = rel.analyzeCondition();
  if (leftColumns.cardinality() > 0) {
    if (rel.getJoinType().generatesNullsOnLeft()) {
      return false;
    }
    Boolean rightJoinColsUnique =
        mq.areColumnsUnique(right, joinInfo.rightSet(), ignoreNulls);
    if ((rightJoinColsUnique == null) || (leftUnique == null)) {
      return null;
    }
    return rightJoinColsUnique && leftUnique;
  } else if (rightColumns.cardinality() > 0) {
    if (rel.getJoinType().generatesNullsOnRight()) {
      return false;
    }
    Boolean leftJoinColsUnique =
        mq.areColumnsUnique(left, joinInfo.leftSet(), ignoreNulls);
    if ((leftJoinColsUnique == null) || (rightUnique == null)) {
      return null;
    }
    return leftJoinColsUnique && rightUnique;
  }

  throw new AssertionError();
}
 
Example 15
Source File: JoinToMultiJoinRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
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 = new ArrayList<>();
  final List<int[]> joinFieldRefCountsList = new ArrayList<>();
  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 = new ArrayList<>();
  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),
          origJoin.getRowType(),
          origJoin.getJoinType() == JoinRelType.FULL,
          Pair.right(joinSpecs),
          Pair.left(joinSpecs),
          projFieldsList,
          newJoinFieldRefCountsMap,
          RexUtil.composeConjunction(rexBuilder, newPostJoinFilters, true));

  call.transformTo(multiJoin);
}
 
Example 16
Source File: HashJoinProbeTemplate.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
@Override
public void setupHashJoinProbe(
    FunctionContext functionContext,
    VectorAccessible buildBatch,
    VectorAccessible probeBatch,
    VectorAccessible outgoing,
    HashTable hashTable,
    JoinRelType joinRelType,
    List<BuildInfo> buildInfos,
    List<ArrowBuf> startIndices,
    List<BitSet> keyMatchBitVectors,
    int maxHashTableIndex,
    int targetRecordsPerBatch) {

  links = new ArrowBuf[buildInfos.size()];

  for (int i =0; i < links.length; i++) {
    links[i] = buildInfos.get(i).getLinks();
  }

  starts = new ArrowBuf[startIndices.size()];
  this.keyMatches = new BitSet[keyMatchBitVectors.size()];

  if (startIndices.size() > 0) {
    this.maxOffsetForLastBatch = maxHashTableIndex - (startIndices.size() - 1) * HashTable.BATCH_SIZE;
  } else {
    this.maxOffsetForLastBatch = -1;
  }
  for (int i = 0; i < starts.length; i++) {
    starts[i] = startIndices.get(i);
    keyMatches[i] = keyMatchBitVectors.get(i);
  }

  this.probeBatch = probeBatch;
  this.projectUnmatchedProbe = joinRelType == JoinRelType.LEFT || joinRelType == JoinRelType.FULL;
  this.projectUnmatchedBuild = joinRelType == JoinRelType.RIGHT || joinRelType == JoinRelType.FULL;
  this.hashTable = hashTable;
  this.targetRecordsPerBatch = targetRecordsPerBatch;

  doSetup(functionContext, buildBatch, probeBatch, outgoing);
}
 
Example 17
Source File: VectorizedProbe.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
public void setup(
    BufferAllocator allocator,
    final ExpandableHyperContainer buildBatch,
    final VectorAccessible probeBatch,
    // Contains all vectors in probe side output
    final List<FieldVector> probeOutputs,
    /* Contains only carry over vectors in build side output for VECTORIZED_GENERIC
     * Contains all field vectors in build side output for VECTORIZED_BIGINT
     */
    final List<FieldVector> buildOutputs,
    /* Contains the key field vectors in incoming probe side batch for VECTORIZED_GENERIC
     * Only for VECTORIZED_GENERIC
     */
    final List<FieldVector> probeIncomingKeys,
    /* Contains the key field vectors in build side output for VECTORIZED_GENERIC
     * Only for VECTORIZED_GENERIC
     */
    final List<FieldVector> buildOutputKeys,
    VectorizedHashJoinOperator.Mode mode,
    JoinRelType joinRelType,
    List<BuildInfo> buildInfos,
    List<ArrowBuf> startIndices,
    List<MatchBitSet> keyMatchBitVectors,
    int maxHashTableIndex,
    JoinTable table,
    // Used to pivot the keys in incoming build batch into hash table
    PivotDef pivot,
    // Used to unpivot the keys in hash table to build side output
    PivotDef buildUnpivot,
    int targetRecordsPerBatch,
    final NullComparator nullMask){

  this.nullMask = nullMask;
  this.pivot = pivot;
  this.buildUnpivot = buildUnpivot;
  this.allocator = allocator;
  this.table = table;
  this.links = new ArrowBuf[buildInfos.size()];

  for (int i =0; i < links.length; i++) {
    links[i] = buildInfos.get(i).getLinks();
  }

  this.starts = new ArrowBuf[startIndices.size()];
  this.keyMatches = new MatchBitSet[keyMatchBitVectors.size()];

  if (startIndices.size() > 0) {
    this.maxOffsetForLastBatch = maxHashTableIndex - (startIndices.size() - 1) * HashTable.BATCH_SIZE;
  } else {
    this.maxOffsetForLastBatch = -1;
  }
  this.maxHashTableIndex = maxHashTableIndex;
  for (int i = 0; i < starts.length; i++) {
    starts[i] = startIndices.get(i);
    keyMatches[i] = keyMatchBitVectors.get(i);
  }

  this.projectUnmatchedBuild = joinRelType == JoinRelType.RIGHT || joinRelType == JoinRelType.FULL;
  this.projectUnmatchedProbe = joinRelType == JoinRelType.LEFT || joinRelType == JoinRelType.FULL;
  this.targetRecordsPerBatch = targetRecordsPerBatch;
  this.projectProbeSv2 = allocator.buffer(targetRecordsPerBatch * BATCH_OFFSET_SIZE);
  this.probeSv2Addr = projectProbeSv2.memoryAddress();
  // first 4 bytes (int) are for batch index and rest 2 bytes are offset within the batch
  this.projectBuildOffsetBuf = allocator.buffer(targetRecordsPerBatch * BUILD_RECORD_LINK_SIZE);
  this.projectBuildOffsetAddr = projectBuildOffsetBuf.memoryAddress();
  this.projectBuildKeyOffsetBuf = allocator.buffer(targetRecordsPerBatch * ORDINAL_SIZE);
  this.projectBuildKeyOffsetAddr = projectBuildKeyOffsetBuf.memoryAddress();

  this.mode = mode;

  this.buildOutputs = buildOutputs;
  if (table.size() > 0) {
    this.buildCopiers = projectUnmatchedProbe  ?
      ConditionalFieldBufferCopier6.getFourByteCopiers(VectorContainer.getHyperFieldVectors(buildBatch), buildOutputs) :
      FieldBufferCopier6.getFourByteCopiers(VectorContainer.getHyperFieldVectors(buildBatch), buildOutputs);
  } else {
    this.buildCopiers = Collections.emptyList();
  }

  /* For VECTORIZED_GENERIC, we don't keep the key vectors in hyper container,
   * and then we need to copy keys from probe batch to build side in output for matched and non matched records,
   * otherwise eight byte hash table is used, we keep the key vector in hyper container,
   * and then we don't need to copy keys from probe batch to build side in output for matched and non matched records.
   */
  if (this.mode == VectorizedHashJoinOperator.Mode.VECTORIZED_GENERIC) {
    // create copier for copying keys from probe batch to build side output
    if (probeIncomingKeys.size() > 0) {
      this.keysCopiers = FieldBufferCopier.getCopiers(probeIncomingKeys, buildOutputKeys);
    } else {
      this.keysCopiers = Collections.emptyList();
    }

    this.projectNullKeyOffset = allocator.buffer(targetRecordsPerBatch * BATCH_OFFSET_SIZE);
    this.projectNullKeyOffsetAddr = projectNullKeyOffset.memoryAddress();
  } else {
    this.projectNullKeyOffsetAddr = 0;
    this.keysCopiers = null;
  }

  this.probeCopiers = FieldBufferCopier.getCopiers(VectorContainer.getFieldVectors(probeBatch), probeOutputs);
}
 
Example 18
Source File: FlinkJoinToMultiJoinRule.java    From flink with Apache License 2.0 4 votes vote down vote up
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 = new ArrayList<>();
	final List<int[]> joinFieldRefCountsList = new ArrayList<>();
	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 = new ArrayList<>();
	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 com.google.common.collect.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),
					origJoin.getRowType(),
					origJoin.getJoinType() == JoinRelType.FULL,
					Pair.right(joinSpecs),
					Pair.left(joinSpecs),
					projFieldsList,
					newJoinFieldRefCountsMap,
					RexUtil.composeConjunction(rexBuilder, newPostJoinFilters, true));

	call.transformTo(multiJoin);
}
 
Example 19
Source File: JoinToMultiJoinRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
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 = new ArrayList<>();
  final List<int[]> joinFieldRefCountsList = new ArrayList<>();
  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 = new ArrayList<>();
  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),
          origJoin.getRowType(),
          origJoin.getJoinType() == JoinRelType.FULL,
          Pair.right(joinSpecs),
          Pair.left(joinSpecs),
          projFieldsList,
          newJoinFieldRefCountsMap,
          RexUtil.composeConjunction(rexBuilder, newPostJoinFilters, true));

  call.transformTo(multiJoin);
}
 
Example 20
Source File: JoinNode.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void run() throws InterruptedException {

    final int fieldCount = rel.getLeft().getRowType().getFieldCount()
        + rel.getRight().getRowType().getFieldCount();
    context.values = new Object[fieldCount];

    // source for the outer relation of nested loop
    Source outerSource = leftSource;
    // source for the inner relation of nested loop
    Source innerSource = rightSource;
    if (rel.getJoinType() == JoinRelType.RIGHT) {
      outerSource = rightSource;
      innerSource = leftSource;
    }

    // row from outer source
    Row outerRow = null;
    // rows from inner source
    List<Row> innerRows = null;
    Set<Row> matchRowSet = new HashSet<>();
    while ((outerRow = outerSource.receive()) != null) {
      if (innerRows == null) {
        innerRows = new ArrayList<Row>();
        Row innerRow = null;
        while ((innerRow = innerSource.receive()) != null) {
          innerRows.add(innerRow);
        }
      }
      matchRowSet.addAll(doJoin(outerRow, innerRows, rel.getJoinType()));
    }
    if (rel.getJoinType() == JoinRelType.FULL) {
      // send un-match rows for full join on right source
      List<Row> empty = new ArrayList<>();
      for (Row row: innerRows) {
        if (matchRowSet.contains(row)) {
          continue;
        }
        doSend(row, empty, JoinRelType.RIGHT);
      }
    }
  }