Class JoinToMultiJoinRule
- java.lang.Object
-
- org.apache.calcite.plan.RelOptRule
-
- org.apache.calcite.rel.rules.JoinToMultiJoinRule
-
public class JoinToMultiJoinRule extends RelOptRule
Planner rule to flatten a tree ofLogicalJoin
s into a singleMultiJoin
with N inputs.An input is not flattened if the input is a null generating input in an outer join, i.e., either input in a full outer join, the right hand side of a left outer join, or the left hand side of a right outer join.
Join conditions are also pulled up from the inputs into the topmost
MultiJoin
, unless the input corresponds to a null generating input in an outer join,Outer join information is also stored in the
MultiJoin
. A boolean flag indicates if the join is a full outer join, and in the case of left and right outer joins, the join type and outer join conditions are stored in arrays in theMultiJoin
. This outer join information is associated with the null generating input in the outer join. So, in the case of a a left outer join between A and B, the information is associated with B, not A.Here are examples of the
MultiJoin
s constructed after this rule has been applied on following join trees.- A JOIN B → MJ(A, B)
- A JOIN B JOIN C → MJ(A, B, C)
- A LEFT JOIN B → MJ(A, B), left outer join on input#1
- A RIGHT JOIN B → MJ(A, B), right outer join on input#0
- A FULL JOIN B → MJ[full](A, B)
- A LEFT JOIN (B JOIN C) → MJ(A, MJ(B, C))), left outer join on input#1 in the outermost MultiJoin
- (A JOIN B) LEFT JOIN C → MJ(A, B, C), left outer join on input#2
- (A LEFT JOIN B) JOIN C → MJ(MJ(A, B), C), left outer join on input#1 of the inner MultiJoin TODO
- A LEFT JOIN (B FULL JOIN C) → MJ(A, MJ[full](B, C)), left outer join on input#1 in the outermost MultiJoin
- (A LEFT JOIN B) FULL JOIN (C RIGHT JOIN D) → MJ[full](MJ(A, B), MJ(C, D)), left outer join on input #1 in the first inner MultiJoin and right outer join on input#0 in the second inner MultiJoin
The constructor is parameterized to allow any sub-class of
Join
, not justLogicalJoin
.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private class
JoinToMultiJoinRule.InputReferenceCounter
Visitor that keeps a reference count of the inputs used by an expression.
-
Field Summary
Fields Modifier and Type Field Description static JoinToMultiJoinRule
INSTANCE
-
Fields inherited from class org.apache.calcite.plan.RelOptRule
description, operands, relBuilderFactory
-
-
Constructor Summary
Constructors Constructor Description JoinToMultiJoinRule(java.lang.Class<? extends Join> clazz)
Deprecated.JoinToMultiJoinRule(java.lang.Class<? extends Join> clazz, RelBuilderFactory relBuilderFactory)
Creates a JoinToMultiJoinRule.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private com.google.common.collect.ImmutableMap<java.lang.Integer,ImmutableIntList>
addOnJoinFieldRefCounts(java.util.List<RelNode> multiJoinInputs, int nTotalFields, RexNode joinCondition, java.util.List<int[]> origJoinFieldRefCounts)
Adds on to the existing join condition reference counts the references from the new join condition.private boolean
canCombine(RelNode input, boolean nullGenerating)
Returns whether an input can be merged into a given relational expression without changing semantics.private java.util.List<RelNode>
combineInputs(Join join, RelNode left, RelNode right, java.util.List<ImmutableBitSet> projFieldsList, java.util.List<int[]> joinFieldRefCountsList)
Combines the inputs into a LogicalJoin into an array of inputs.private java.util.List<RexNode>
combineJoinFilters(Join joinRel, RelNode left, RelNode right)
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 joinprivate void
combineOuterJoins(Join joinRel, java.util.List<RelNode> combinedInputs, RelNode left, RelNode right, java.util.List<Pair<JoinRelType,RexNode>> joinSpecs)
Combines the outer join conditions and join types from the left and right join inputs.private java.util.List<RexNode>
combinePostJoinFilters(Join joinRel, RelNode left, RelNode right)
Combines the post-join filters from the left and right inputs (if they are MultiJoinRels) into a single AND'd filter.private void
copyOuterJoinInfo(MultiJoin multiJoin, java.util.List<Pair<JoinRelType,RexNode>> destJoinSpecs, int adjustmentAmount, java.util.List<RelDataTypeField> srcFields, java.util.List<RelDataTypeField> destFields)
Copies outer join data from a source MultiJoin to a new set of arrays.void
onMatch(RelOptRuleCall call)
Receives notification about a rule match.private RexNode
shiftRightFilter(Join joinRel, RelNode left, MultiJoin right, RexNode rightFilter)
Shifts a filter originating from the right child of the LogicalJoin to the right, to reflect the filter now being applied on the resulting MultiJoin.-
Methods inherited from class org.apache.calcite.plan.RelOptRule
any, convert, convert, convertList, convertOperand, convertOperand, equals, equals, getOperand, getOperands, getOutConvention, getOutTrait, hashCode, matches, none, operand, operand, operand, operand, operand, operandJ, operandJ, some, toString, unordered
-
-
-
-
Field Detail
-
INSTANCE
public static final JoinToMultiJoinRule INSTANCE
-
-
Constructor Detail
-
JoinToMultiJoinRule
@Deprecated public JoinToMultiJoinRule(java.lang.Class<? extends Join> clazz)
Deprecated.
-
JoinToMultiJoinRule
public JoinToMultiJoinRule(java.lang.Class<? extends Join> clazz, RelBuilderFactory relBuilderFactory)
Creates a JoinToMultiJoinRule.
-
-
Method Detail
-
onMatch
public void onMatch(RelOptRuleCall call)
Description copied from class:RelOptRule
Receives notification about a rule match. At the time that this method is called,call.rels
holds the set of relational expressions which match the operands to the rule;call.rels[0]
is the root expression.Typically a rule would check that the nodes are valid matches, creates a new expression, then calls back
RelOptRuleCall.transformTo(org.apache.calcite.rel.RelNode, java.util.Map<org.apache.calcite.rel.RelNode, org.apache.calcite.rel.RelNode>)
to register the expression.- Specified by:
onMatch
in classRelOptRule
- Parameters:
call
- Rule call- See Also:
RelOptRule.matches(RelOptRuleCall)
-
combineInputs
private java.util.List<RelNode> combineInputs(Join join, RelNode left, RelNode right, java.util.List<ImmutableBitSet> projFieldsList, java.util.List<int[]> joinFieldRefCountsList)
Combines the inputs into a LogicalJoin into an array of inputs.- Parameters:
join
- original joinleft
- left input into joinright
- right input into joinprojFieldsList
- returns a list of the new combined projection fieldsjoinFieldRefCountsList
- returns a list of the new combined join field reference counts- Returns:
- combined left and right inputs in an array
-
combineOuterJoins
private void combineOuterJoins(Join joinRel, java.util.List<RelNode> combinedInputs, RelNode left, RelNode right, java.util.List<Pair<JoinRelType,RexNode>> joinSpecs)
Combines the outer join conditions and join types from the left and right join inputs. If the join itself is either a left or right outer join, then the join condition corresponding to the join is also set in the position corresponding to the null-generating input into the join. The join type is also set.- Parameters:
joinRel
- join relcombinedInputs
- the combined inputs to the joinleft
- left child of the joinrelright
- right child of the joinreljoinSpecs
- the list where the join types and conditions will be copied
-
copyOuterJoinInfo
private void copyOuterJoinInfo(MultiJoin multiJoin, java.util.List<Pair<JoinRelType,RexNode>> destJoinSpecs, int adjustmentAmount, java.util.List<RelDataTypeField> srcFields, java.util.List<RelDataTypeField> destFields)
Copies outer join data from a source MultiJoin to a new set of arrays. Also adjusts the conditions to reflect the new position of an input if that input ends up being shifted to the right.- Parameters:
multiJoin
- the source MultiJoindestJoinSpecs
- the list where the join types and conditions will be copiedadjustmentAmount
- if > 0, the amount the RexInputRefs in the join conditions need to be adjusted bysrcFields
- the source fields that the original join conditions are referencingdestFields
- the destination fields that the new join conditions
-
combineJoinFilters
private java.util.List<RexNode> combineJoinFilters(Join joinRel, RelNode left, RelNode right)
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- Parameters:
joinRel
- join relleft
- left child of the joinright
- right child of the join- Returns:
- combined join filters AND-ed together
-
canCombine
private boolean canCombine(RelNode input, boolean nullGenerating)
Returns whether an input can be merged into a given relational expression without changing semantics.- Parameters:
input
- input into a joinnullGenerating
- true if the input is null generating- Returns:
- true if the input can be combined into a parent MultiJoin
-
shiftRightFilter
private RexNode shiftRightFilter(Join joinRel, RelNode left, MultiJoin right, RexNode rightFilter)
Shifts a filter originating from the right child of the LogicalJoin to the right, to reflect the filter now being applied on the resulting MultiJoin.- Parameters:
joinRel
- the original LogicalJoinleft
- the left child of the LogicalJoinright
- the right child of the LogicalJoinrightFilter
- the filter originating from the right child- Returns:
- the adjusted right filter
-
addOnJoinFieldRefCounts
private com.google.common.collect.ImmutableMap<java.lang.Integer,ImmutableIntList> addOnJoinFieldRefCounts(java.util.List<RelNode> multiJoinInputs, int nTotalFields, RexNode joinCondition, java.util.List<int[]> origJoinFieldRefCounts)
Adds on to the existing join condition reference counts the references from the new join condition.- Parameters:
multiJoinInputs
- inputs into the new MultiJoinnTotalFields
- total number of fields in the MultiJoinjoinCondition
- the new join conditionorigJoinFieldRefCounts
- existing join condition reference counts- Returns:
- Map containing the new join condition
-
combinePostJoinFilters
private java.util.List<RexNode> combinePostJoinFilters(Join joinRel, RelNode left, RelNode right)
Combines the post-join filters from the left and right inputs (if they are MultiJoinRels) into a single AND'd filter.- Parameters:
joinRel
- the original LogicalJoinleft
- left child of the LogicalJoinright
- right child of the LogicalJoin- Returns:
- combined post-join filters AND'd together
-
-