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

The following examples show how to use org.apache.calcite.rel.core.JoinRelType#INNER . 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: NestedLoopJoinPrule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
protected boolean checkPreconditions(DrillJoin join, RelNode left, RelNode right,
                                     PlannerSettings settings) {
  JoinRelType type = join.getJoinType();

  if (!(type == JoinRelType.INNER || type == JoinRelType.LEFT)) {
    return false;
  }

  List<Integer> leftKeys = Lists.newArrayList();
  List<Integer> rightKeys = Lists.newArrayList();
  List<Boolean> filterNulls = Lists.newArrayList();
  JoinCategory category = JoinUtils.getJoinCategory(left, right, join.getCondition(), leftKeys, rightKeys, filterNulls);
  if (category == JoinCategory.EQUALITY
      && (settings.isHashJoinEnabled() || settings.isMergeJoinEnabled())) {
    return false;
  }

  if (settings.isNlJoinForScalarOnly()) {
    return JoinUtils.hasScalarSubqueryInput(left, right);
  }

  return true;
}
 
Example 2
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 3
Source File: DrillFilterJoinRules.java    From Bats with Apache License 2.0 6 votes vote down vote up
public boolean apply(Join join, JoinRelType joinType, RexNode exp) {
  if (joinType != JoinRelType.INNER) {
    return true;  // In OUTER join, we could not pull-up the filter.
                  // All we can do is keep the filter with JOIN, and
                  // then decide whether the filter could be pushed down
                  // into LEFT/RIGHT.
  }

  List<RexNode> tmpLeftKeys = new ArrayList<>();
  List<RexNode> tmpRightKeys = new ArrayList<>();
  List<RelDataTypeField> sysFields = new ArrayList<>();
  List<Integer> filterNulls = new ArrayList<>();

  RexNode remaining = RelOptUtil.splitJoinCondition(sysFields, join.getLeft(), join.getRight(),
      exp, tmpLeftKeys, tmpRightKeys, filterNulls, null);

  return remaining.isAlwaysTrue();
}
 
Example 4
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 5
Source File: EnumerableBatchNestedLoopJoinRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public boolean matches(RelOptRuleCall call) {
  Join join = call.rel(0);
  JoinRelType joinType = join.getJoinType();
  return joinType == JoinRelType.INNER
      || joinType == JoinRelType.LEFT
      || joinType == JoinRelType.ANTI
      || joinType == JoinRelType.SEMI;
}
 
Example 6
Source File: JoinPruleBase.java    From Bats with Apache License 2.0 5 votes vote down vote up
protected boolean checkBroadcastConditions(RelOptPlanner planner, DrillJoin join, RelNode left, RelNode right) {

    double estimatedRightRowCount = RelMetadataQuery.instance().getRowCount(right);
    if (estimatedRightRowCount < PrelUtil.getSettings(join.getCluster()).getBroadcastThreshold()
        && ! left.getTraitSet().getTrait(DrillDistributionTraitDef.INSTANCE).equals(DrillDistributionTrait.SINGLETON)
        && (join.getJoinType() == JoinRelType.INNER || join.getJoinType() == JoinRelType.LEFT)
        ) {
      return true;
    }
    return false;
  }
 
Example 7
Source File: CalcPythonCorrelateTransposeRule.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	FlinkLogicalCorrelate correlate = call.rel(0);
	FlinkLogicalCalc right = call.rel(2);
	JoinRelType joinType = correlate.getJoinType();
	FlinkLogicalCalc mergedCalc = StreamExecCorrelateRule.getMergedCalc(right);
	FlinkLogicalTableFunctionScan scan = StreamExecCorrelateRule.getTableScan(mergedCalc);
	return joinType == JoinRelType.INNER &&
		PythonUtil.isPythonCall(scan.getCall(), null) &&
		mergedCalc.getProgram().getCondition() != null;
}
 
Example 8
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 9
Source File: AbstractJoinExtractFilterRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Join join = call.rel(0);

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

  if (join.getCondition().isAlwaysTrue()) {
    return;
  }

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

  final RelBuilder builder = call.builder();

  // NOTE jvs 14-Mar-2006:  See JoinCommuteRule for why we
  // preserve attribute semiJoinDone here.

  final RelNode cartesianJoin =
      join.copy(
          join.getTraitSet(),
          builder.literal(true),
          join.getLeft(),
          join.getRight(),
          join.getJoinType(),
          join.isSemiJoinDone());

  builder.push(cartesianJoin)
      .filter(join.getCondition());

  call.transformTo(builder.build());
}
 
Example 10
Source File: NLJEOperator.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
@Override
public void noMoreToConsumeRight() throws Exception {
  if(buildRecords == 0 && (joinType == JoinRelType.INNER || joinType == JoinRelType.RIGHT)) {
    state = State.DONE;
    return;
  }

  if(buildRecords == 0) {
    this.joinMatcher = new StraightThroughMatcher(output, probeOutputTransfers);
  } else {
    Stopwatch watch = Stopwatch.createStarted();
    Pointer<Integer> ind = new Pointer<Integer>(-1);
    List<FieldVector[]> buildInputVectorsUsed = (List<FieldVector[]>) (Object) StreamSupport.stream(build.spliterator(), false).map(w -> {
      ind.value++;
      return w.getValueVectors();
    }).filter(v -> config.getBuildProjected().contains(ind.value)).collect(Collectors.toList());
    final int targetGenerateAtOnce = (int) context.getOptions().getOption(NestedLoopJoinPrel.OUTPUT_COUNT);
    this.joinMatcher = new EvaluatingJoinMatcher(context, probeIncoming, build,
        targetGenerateAtOnce,
        getInitialMatchState(),
        FieldBufferCopier.getCopiers(probeInputVectorsUsed, probeOutputVectors),
        FieldBufferCopier4.getFourByteCopiers(buildInputVectorsUsed, buildOutputVectors),
        joinType
        );
    context.getStats().setLongStat(Metric.COMPILE_NANOS, watch.elapsed(TimeUnit.NANOSECONDS));

  }

  joinMatcher.setup(config.getCondition(), context.getClassProducer(), probeIncoming, build);
  state = State.CAN_CONSUME_L;
}
 
Example 11
Source File: AbstractJoinExtractFilterRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Join join = call.rel(0);

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

  if (join.getCondition().isAlwaysTrue()) {
    return;
  }

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

  final RelBuilder builder = call.builder();

  // NOTE jvs 14-Mar-2006:  See JoinCommuteRule for why we
  // preserve attribute semiJoinDone here.

  final RelNode cartesianJoin =
      join.copy(
          join.getTraitSet(),
          builder.literal(true),
          join.getLeft(),
          join.getRight(),
          join.getJoinType(),
          join.isSemiJoinDone());

  builder.push(cartesianJoin)
      .filter(join.getCondition());

  call.transformTo(builder.build());
}
 
Example 12
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 13
Source File: RelToSqlConverter.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * @see #dispatch
 */
public Result visit(Join e) {
  final Result leftResult = visitChild(0, e.getLeft()).resetAlias();
  final Result rightResult = visitChild(1, e.getRight()).resetAlias();
  final Context leftContext = leftResult.qualifiedContext();
  final Context rightContext = rightResult.qualifiedContext();
  SqlNode sqlCondition = null;
  SqlLiteral condType = JoinConditionType.ON.symbol(POS);
  JoinType joinType = joinType(e.getJoinType());
  if (e.getJoinType() == JoinRelType.INNER && e.getCondition().isAlwaysTrue()) {
    joinType = JoinType.COMMA;
    condType = JoinConditionType.NONE.symbol(POS);
  } else {
    final RexNode condition = e.getCondition() != null
      ? simplifyDatetimePlus(e.getCondition(), e.getCluster().getRexBuilder())
      : null;
    sqlCondition = convertConditionToSqlNode(
      condition,
      leftContext,
      rightContext,
      e.getLeft().getRowType().getFieldCount());
  }
  SqlNode join =
    new SqlJoin(POS,
      leftResult.asFrom(),
      SqlLiteral.createBoolean(false, POS),
      joinType.symbol(POS),
      rightResult.asFrom(),
      condType,
      sqlCondition);
  return result(join, leftResult, rightResult);
}
 
Example 14
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 15
Source File: JoinCommuteRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a relational expression with the inputs switched round. Does not
 * modify <code>join</code>. Returns null if the join cannot be swapped (for
 * example, because it is an outer join).
 *
 * @param join              join to be swapped
 * @param swapOuterJoins    whether outer joins should be swapped
 * @param relBuilder        Builder for relational expressions
 * @return swapped join if swapping possible; else null
 */
public static RelNode swap(Join join, boolean swapOuterJoins,
    RelBuilder relBuilder) {
  final JoinRelType joinType = join.getJoinType();
  if (!swapOuterJoins && joinType != JoinRelType.INNER) {
    return null;
  }
  final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
  final RelDataType leftRowType = join.getLeft().getRowType();
  final RelDataType rightRowType = join.getRight().getRowType();
  final VariableReplacer variableReplacer =
      new VariableReplacer(rexBuilder, leftRowType, rightRowType);
  final RexNode oldCondition = join.getCondition();
  RexNode condition = variableReplacer.apply(oldCondition);

  // NOTE jvs 14-Mar-2006: We preserve attribute semiJoinDone after the
  // swap.  This way, we will generate one semijoin for the original
  // join, and one for the swapped join, and no more.  This
  // doesn't prevent us from seeing any new combinations assuming
  // that the planner tries the desired order (semijoins after swaps).
  Join newJoin =
      join.copy(join.getTraitSet(), condition, join.getRight(),
          join.getLeft(), joinType.swap(), join.isSemiJoinDone());
  final List<RexNode> exps =
      RelOptUtil.createSwappedJoinExprs(newJoin, join, true);
  return relBuilder.push(newJoin)
      .project(exps, join.getRowType().getFieldNames())
      .build();
}
 
Example 16
Source File: CalcPythonCorrelateTransposeRule.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	FlinkLogicalCorrelate correlate = call.rel(0);
	FlinkLogicalCalc right = call.rel(2);
	JoinRelType joinType = correlate.getJoinType();
	FlinkLogicalCalc mergedCalc = CorrelateUtil.getMergedCalc(right);
	Option<FlinkLogicalTableFunctionScan> scan = CorrelateUtil.getTableFunctionScan(mergedCalc);
	return joinType == JoinRelType.INNER &&
		scan.isDefined() &&
		PythonUtil.isPythonCall(scan.get().getCall(), null) &&
		mergedCalc.getProgram().getCondition() != null;
}
 
Example 17
Source File: SubstitutionVisitor.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Override protected UnifyResult apply(UnifyRuleCall call) {
  final MutableJoin query = (MutableJoin) call.query;
  final MutableRel qInput0 = query.getLeft();
  final MutableCalc qInput1 = (MutableCalc) query.getRight();
  final Pair<RexNode, List<RexNode>> qInput1Explained = explainCalc(qInput1);
  final RexNode qInput1Cond = qInput1Explained.left;
  final List<RexNode> qInput1Projs = qInput1Explained.right;

  final MutableJoin target = (MutableJoin) call.target;

  final RexBuilder rexBuilder = call.getCluster().getRexBuilder();

  // Try pulling up MutableCalc only when:
  // 1. it's inner join.
  // 2. it's outer join but no filtering condition from MutableCalc.
  final JoinRelType joinRelType = sameJoinType(query.joinType, target.joinType);
  if (joinRelType == null) {
    return null;
  }
  if (joinRelType != JoinRelType.INNER
      && !(joinRelType.isOuterJoin() && qInput1Cond.isAlwaysTrue())) {
    return null;
  }
  // Try pulling up MutableCalc only when Join condition references mapping.
  final List<RexNode> identityProjects =
      (List<RexNode>) rexBuilder.identityProjects(qInput0.rowType);
  if (!referenceByMapping(query.condition, identityProjects, qInput1Projs)) {
    return null;
  }

  final RexNode newQueryJoinCond = new RexShuttle() {
    @Override public RexNode visitInputRef(RexInputRef inputRef) {
      final int idx = inputRef.getIndex();
      if (idx < fieldCnt(qInput0)) {
        return inputRef;
      } else {
        final int newIdx = ((RexInputRef) qInput1Projs.get(idx - fieldCnt(qInput0)))
            .getIndex() + fieldCnt(qInput0);
        return new RexInputRef(newIdx, inputRef.getType());
      }
    }
  }.apply(query.condition);

  final RexNode splitted =
      splitFilter(call.getSimplify(), newQueryJoinCond, target.condition);
  // MutableJoin matches only when the conditions are analyzed to be same.
  if (splitted != null && splitted.isAlwaysTrue()) {
    final RexNode compenCond =
        RexUtil.shift(qInput1Cond, qInput0.rowType.getFieldCount());
    final List<RexNode> compenProjs = new ArrayList<>();
    for (int i = 0; i < query.rowType.getFieldCount(); i++) {
      if (i < fieldCnt(qInput0)) {
        compenProjs.add(
            new RexInputRef(i, query.rowType.getFieldList().get(i).getType()));
      } else {
        final RexNode shifted = RexUtil.shift(qInput1Projs.get(i - fieldCnt(qInput0)),
            qInput0.rowType.getFieldCount());
        compenProjs.add(shifted);
      }
    }
    final RexProgram compensatingRexProgram = RexProgram.create(
        target.rowType, compenProjs, compenCond,
        query.rowType, rexBuilder);
    final MutableCalc compenCalc = MutableCalc.of(target, compensatingRexProgram);
    return tryMergeParentCalcAndGenResult(call, compenCalc);
  }
  return null;
}
 
Example 18
Source File: FilterNLJMergeRule.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
  NestedLoopJoinPrel join = call.rel(1);
  return join.getJoinType() == JoinRelType.INNER &&
      PrelUtil.getPlannerSettings(call.getPlanner()).getOptions().getOption(NestedLoopJoinPrel.VECTORIZED);
}
 
Example 19
Source File: RelToSqlConverter.java    From Bats with Apache License 2.0 4 votes vote down vote up
private boolean isCrossJoin(final Join e) {
  return e.getJoinType() == JoinRelType.INNER && e.getCondition().isAlwaysTrue();
}
 
Example 20
Source File: RelMdAllPredicates.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Add the Join condition to the list obtained from the input.
 */
public RelOptPredicateList getAllPredicates(Join join, RelMetadataQuery mq) {
  if (join.getJoinType() != JoinRelType.INNER) {
    // We cannot map origin of this expression.
    return null;
  }

  final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
  final RexNode pred = join.getCondition();

  final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
  RelOptPredicateList newPreds = RelOptPredicateList.EMPTY;
  for (RelNode input : join.getInputs()) {
    final RelOptPredicateList inputPreds = mq.getAllPredicates(input);
    if (inputPreds == null) {
      // Bail out
      return null;
    }
    // Gather table references
    final Set<RelTableRef> tableRefs = mq.getTableReferences(input);
    if (input == join.getLeft()) {
      // Left input references remain unchanged
      for (RelTableRef leftRef : tableRefs) {
        qualifiedNamesToRefs.put(leftRef.getQualifiedName(), leftRef);
      }
      newPreds = newPreds.union(rexBuilder, inputPreds);
    } else {
      // Right input references might need to be updated if there are table name
      // clashes with left input
      final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
      for (RelTableRef rightRef : tableRefs) {
        int shift = 0;
        Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get(
            rightRef.getQualifiedName());
        if (lRefs != null) {
          shift = lRefs.size();
        }
        currentTablesMapping.put(rightRef,
            RelTableRef.of(rightRef.getTable(), shift + rightRef.getEntityNumber()));
      }
      final List<RexNode> updatedPreds = Lists.newArrayList(
          Iterables.transform(inputPreds.pulledUpPredicates,
              e -> RexUtil.swapTableReferences(rexBuilder, e,
                  currentTablesMapping)));
      newPreds = newPreds.union(rexBuilder,
          RelOptPredicateList.of(rexBuilder, updatedPreds));
    }
  }

  // Extract input fields referenced by Join condition
  final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
  final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
  pred.accept(inputFinder);
  final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();

  // Infer column origin expressions for given references
  final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
  for (int idx : inputFieldsUsed) {
    final RexInputRef inputRef = RexInputRef.of(idx, join.getRowType().getFieldList());
    final Set<RexNode> originalExprs = mq.getExpressionLineage(join, inputRef);
    if (originalExprs == null) {
      // Bail out
      return null;
    }
    final RexInputRef ref = RexInputRef.of(idx, join.getRowType().getFieldList());
    mapping.put(ref, originalExprs);
  }

  // Replace with new expressions and return union of predicates
  final Set<RexNode> allExprs =
      RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping);
  if (allExprs == null) {
    return null;
  }
  return newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, allExprs));
}