use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Join in project calcite by apache.
the class SortJoinTransposeRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Sort sort = call.rel(0);
final Join join = call.rel(1);
// We create a new sort operator on the corresponding input
final RelNode newLeftInput;
final RelNode newRightInput;
final RelMetadataQuery mq = call.getMetadataQuery();
if (join.getJoinType() == JoinRelType.LEFT) {
// we bail out
if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getLeft(), sort.getCollation(), sort.offset, sort.fetch)) {
return;
}
newLeftInput = sort.copy(sort.getTraitSet(), join.getLeft(), sort.getCollation(), sort.offset, sort.fetch);
newRightInput = join.getRight();
} else {
final RelCollation rightCollation = RelCollationTraitDef.INSTANCE.canonize(RelCollations.shift(sort.getCollation(), -join.getLeft().getRowType().getFieldCount()));
// we bail out
if (RelMdUtil.checkInputForCollationAndLimit(mq, join.getRight(), rightCollation, sort.offset, sort.fetch)) {
return;
}
newLeftInput = join.getLeft();
newRightInput = sort.copy(sort.getTraitSet().replace(rightCollation), join.getRight(), rightCollation, sort.offset, sort.fetch);
}
// We copy the join and the top sort operator
final RelNode joinCopy = join.copy(join.getTraitSet(), join.getCondition(), newLeftInput, newRightInput, join.getJoinType(), join.isSemiJoinDone());
final RelNode sortCopy = sort.copy(sort.getTraitSet(), joinCopy, sort.getCollation(), sort.offset, sort.fetch);
call.transformTo(sortCopy);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Join in project calcite by apache.
the class JoinCommuteRule method swap.
/**
* 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.go(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();
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Join in project calcite by apache.
the class JoinCommuteRule method onMatch.
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);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Join in project druid by druid-io.
the class DruidJoinRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
final Join join = call.rel(0);
final DruidRel<?> left = call.rel(1);
final DruidRel<?> right = call.rel(2);
// 3) Right has a PartialDruidQuery (i.e., is a real query, not top-level UNION ALL).
return canHandleCondition(join.getCondition(), join.getLeft().getRowType(), right) && left.getPartialDruidQuery() != null && right.getPartialDruidQuery() != null;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Join in project druid by druid-io.
the class FilterJoinExcludePushToChildRule method removeRedundantIsNotNullFilters.
/**
* This tries to find all the 'IS NOT NULL' filters in an inner join whose checking column is also
* a part of an equi-condition between the two tables. It removes such 'IS NOT NULL' filters from join since
* the equi-condition will never return true for null input, thus making the 'IS NOT NULL' filter a no-op.
* @param joinFilters
* @param joinType
* @param isSqlCompatible
*/
static void removeRedundantIsNotNullFilters(List<RexNode> joinFilters, JoinRelType joinType, boolean isSqlCompatible) {
if (joinType != JoinRelType.INNER || !isSqlCompatible) {
// only works for inner joins in SQL mode
return;
}
ImmutableList.Builder<RexNode> isNotNullFiltersBuilder = ImmutableList.builder();
ImmutableList.Builder<Pair<RexNode, RexNode>> equalityFiltersOperandBuilder = ImmutableList.builder();
joinFilters.stream().filter(joinFilter -> joinFilter instanceof RexCall).forEach(joinFilter -> {
if (joinFilter.isA(SqlKind.IS_NOT_NULL)) {
isNotNullFiltersBuilder.add(joinFilter);
} else if (joinFilter.isA(SqlKind.EQUALS)) {
List<RexNode> operands = ((RexCall) joinFilter).getOperands();
if (operands.size() == 2 && operands.stream().noneMatch(Objects::isNull)) {
equalityFiltersOperandBuilder.add(new Pair<>(operands.get(0), operands.get(1)));
}
}
});
List<Pair<RexNode, RexNode>> equalityFilters = equalityFiltersOperandBuilder.build();
ImmutableList.Builder<RexNode> removableFilters = ImmutableList.builder();
for (RexNode isNotNullFilter : isNotNullFiltersBuilder.build()) {
List<RexNode> operands = ((RexCall) isNotNullFilter).getOperands();
boolean canDrop = false;
for (Pair<RexNode, RexNode> equalityFilterOperands : equalityFilters) {
if ((equalityFilterOperands.lhs != null && equalityFilterOperands.lhs.equals(operands.get(0))) || (equalityFilterOperands.rhs != null && equalityFilterOperands.rhs.equals(operands.get(0)))) {
canDrop = true;
break;
}
}
if (canDrop) {
removableFilters.add(isNotNullFilter);
}
}
joinFilters.removeAll(removableFilters.build());
}
Aggregations