public class LoptOptimizeJoinRule extends RelOptRule
It is triggered by the pattern
LogicalProject
(MultiJoin).
| Modifier and Type | Field and Description |
|---|---|
static LoptOptimizeJoinRule |
INSTANCE |
description, operands, relBuilderFactory| Constructor and Description |
|---|
LoptOptimizeJoinRule(RelBuilderFactory relBuilderFactory)
Creates a LoptOptimizeJoinRule.
|
LoptOptimizeJoinRule(RelFactories.JoinFactory joinFactory,
RelFactories.ProjectFactory projectFactory,
RelFactories.FilterFactory filterFactory)
Deprecated.
|
| Modifier and Type | Method and Description |
|---|---|
private void |
addAdditionalFilters(RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptJoinTree left,
LoptJoinTree right,
List<RexNode> filtersToAdd)
Determines whether any additional filters are applicable to a join tree.
|
private LoptJoinTree |
addFactorToTree(RelMetadataQuery mq,
RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree joinTree,
int factorToAdd,
BitSet factorsNeeded,
List<RexNode> filtersToAdd,
boolean selfJoin)
Adds a new factor into the current join tree.
|
private RexNode |
addFilters(LoptMultiJoin multiJoin,
LoptJoinTree leftTree,
int leftIdx,
LoptJoinTree rightTree,
List<RexNode> filtersToAdd,
boolean adjust)
Determines which join filters can be added to the current join tree.
|
private LoptJoinTree |
addToTop(RelMetadataQuery mq,
RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree joinTree,
int factorToAdd,
List<RexNode> filtersToAdd,
boolean selfJoin)
Creates a join tree with the new factor added to the top of the tree
|
private RexNode |
adjustFilter(LoptMultiJoin multiJoin,
LoptJoinTree left,
LoptJoinTree right,
RexNode condition,
int factorAdded,
List<Integer> origJoinOrder,
List<RelDataTypeField> origFields)
Adjusts a filter to reflect a newly added factor in the middle of an
existing join tree
|
private static boolean |
areSelfJoinKeysUnique(RelMetadataQuery mq,
RelNode leftRel,
RelNode rightRel,
RexNode joinFilters)
Determines if the equality portion of a self-join condition is between
identical keys that are unique.
|
private Double |
computeJoinCardinality(RelMetadataQuery mq,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree joinTree,
List<RexNode> filters,
int factor)
Computes the cardinality of the join columns from a particular factor,
when that factor is joined with another join tree.
|
private LoptJoinTree |
createJoinSubtree(RelMetadataQuery mq,
RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptJoinTree left,
LoptJoinTree right,
RexNode condition,
JoinRelType joinType,
List<RexNode> filtersToAdd,
boolean fullAdjust,
boolean selfJoin)
Creates a LogicalJoin given left and right operands and a join condition.
|
private LoptJoinTree |
createOrdering(RelMetadataQuery mq,
RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
int firstFactor)
Generates a join tree with a specific factor as the first factor in the
join tree
|
private LoptJoinTree |
createReplacementJoin(RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree currJoinTree,
int leftIdx,
int factorToAdd,
ImmutableIntList newKeys,
Integer[] replacementKeys,
List<RexNode> filtersToAdd)
Creates a replacement join, projecting either dummy columns or
replacement keys from the factor that doesn't actually need to be joined.
|
private LoptJoinTree |
createReplacementSemiJoin(RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree factTree,
int dimIdx,
List<RexNode> filtersToAdd)
In the event that a dimension table does not need to be joined because of
a semijoin, this method creates a join tree that consists of a projection
on top of an existing join tree.
|
private RelNode |
createTopProject(RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptJoinTree joinTree,
List<String> fieldNames)
Creates the topmost projection that will sit on top of the selected join
ordering.
|
private void |
findBestOrderings(RelMetadataQuery mq,
RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
RelOptRuleCall call)
Generates N optimal join orderings.
|
private void |
findRemovableOuterJoins(RelMetadataQuery mq,
LoptMultiJoin multiJoin)
Locates all null generating factors whose outer join can be removed.
|
private void |
findRemovableSelfJoins(RelMetadataQuery mq,
LoptMultiJoin multiJoin)
Locates pairs of joins that are self-joins where the join can be removed
because the join condition between the two factors is an equality join on
unique keys.
|
private int |
getBestNextFactor(RelMetadataQuery mq,
LoptMultiJoin multiJoin,
BitSet factorsToAdd,
BitSet factorsAdded,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree joinTree,
List<RexNode> filtersToAdd)
Determines the best factor to be added next into a join tree.
|
private Map<Integer,RelOptTable> |
getSimpleFactors(RelMetadataQuery mq,
LoptMultiJoin multiJoin)
Retrieves join factors that correspond to simple table references.
|
private boolean |
isJoinTree(RelNode rel)
Returns whether a RelNode corresponds to a Join that wasn't one of the
original MultiJoin input factors.
|
static boolean |
isRemovableSelfJoin(Join joinRel)
Determines whether a join is a removable self-join.
|
private boolean |
isSelfJoinFilterUnique(RelMetadataQuery mq,
LoptMultiJoin multiJoin,
int leftFactor,
int rightFactor,
List<RexNode> joinFilterList)
Determines if the equality join filters between two factors that map to
the same table consist of unique, identical keys.
|
private boolean |
needsAdjustment(LoptMultiJoin multiJoin,
int[] adjustments,
LoptJoinTree joinTree,
LoptJoinTree otherTree,
boolean selfJoin)
Sets an array indicating how much each factor in a join tree needs to be
adjusted to reflect the tree's join ordering
|
void |
onMatch(RelOptRuleCall call)
Receives notification about a rule match.
|
private LoptJoinTree |
pushDownFactor(RelMetadataQuery mq,
RelBuilder relBuilder,
LoptMultiJoin multiJoin,
LoptSemiJoinOptimizer semiJoinOpt,
LoptJoinTree joinTree,
int factorToAdd,
BitSet factorsNeeded,
List<RexNode> filtersToAdd,
boolean selfJoin)
Creates a join tree where the new factor is pushed down one of the
operands of the current join tree
|
private boolean |
remapJoinReferences(LoptMultiJoin multiJoin,
int factor,
List<Integer> newJoinOrder,
int newPos,
int[] adjustments,
int offset,
int newOffset,
boolean alwaysUseDefault)
Sets an adjustment array based on where column references for a
particular factor end up as a result of a new join ordering.
|
private int |
rowWidthCost(RelNode tree)
Computes a cost for a join tree based on the row widths of the inputs
into the join.
|
private void |
setFactorJoinKeys(LoptMultiJoin multiJoin,
List<RexNode> filters,
ImmutableBitSet joinFactors,
int factorStart,
int nFields,
ImmutableBitSet.Builder joinKeys)
Locates from a list of filters those that correspond to a particular join
tree.
|
private void |
setJoinKey(ImmutableBitSet.Builder joinKeys,
ImmutableBitSet.Builder otherJoinKeys,
int ref1,
int ref2,
int firstFieldNum,
int lastFieldNum,
boolean swap)
Sets a join key if only one of the specified input references corresponds
to a specified factor as determined by its field numbers.
|
private RexNode |
swapFilter(RexBuilder rexBuilder,
LoptMultiJoin multiJoin,
LoptJoinTree origLeft,
LoptJoinTree origRight,
RexNode condition)
Adjusts a filter to reflect swapping of join inputs
|
private boolean |
swapInputs(RelMetadataQuery mq,
LoptMultiJoin multiJoin,
LoptJoinTree left,
LoptJoinTree right,
boolean selfJoin)
Swaps the operands to a join, so the smaller input is on the right.
|
any, convert, convert, convertList, convertOperand, equals, equals, getOperand, getOperands, getOutConvention, getOutTrait, hashCode, matches, none, operand, operand, operand, operand, operand, some, toString, unorderedpublic static final LoptOptimizeJoinRule INSTANCE
public LoptOptimizeJoinRule(RelBuilderFactory relBuilderFactory)
@Deprecated public LoptOptimizeJoinRule(RelFactories.JoinFactory joinFactory, RelFactories.ProjectFactory projectFactory, RelFactories.FilterFactory filterFactory)
public void onMatch(RelOptRuleCall call)
RelOptRulecall.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.
onMatch in class RelOptRulecall - Rule callRelOptRule.matches(RelOptRuleCall)private void findRemovableOuterJoins(RelMetadataQuery mq, LoptMultiJoin multiJoin)
multiJoin - join factors being optimizedprivate void setJoinKey(ImmutableBitSet.Builder joinKeys, ImmutableBitSet.Builder otherJoinKeys, int ref1, int ref2, int firstFieldNum, int lastFieldNum, boolean swap)
joinKeys - join keys to be set if a key is foundotherJoinKeys - join keys for the other join factorref1 - first input referenceref2 - second input referencefirstFieldNum - first field number of the factorlastFieldNum - last field number + 1 of the factorswap - if true, check for the desired input reference in the second
input reference parameter if the first input reference isn't the correct
oneprivate void findRemovableSelfJoins(RelMetadataQuery mq, LoptMultiJoin multiJoin)
multiJoin - join factors being optimizedprivate Map<Integer,RelOptTable> getSimpleFactors(RelMetadataQuery mq, LoptMultiJoin multiJoin)
multiJoin - join factors being optimizedprivate boolean isSelfJoinFilterUnique(RelMetadataQuery mq, LoptMultiJoin multiJoin, int leftFactor, int rightFactor, List<RexNode> joinFilterList)
multiJoin - join factors being optimizedleftFactor - left factor in the joinrightFactor - right factor in the joinjoinFilterList - list of join filters between the two factorsprivate void findBestOrderings(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, RelOptRuleCall call)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorcall - RelOptRuleCall associated with this ruleprivate RelNode createTopProject(RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptJoinTree joinTree, List<String> fieldNames)
multiJoin - join factors being optimizedjoinTree - selected join orderingfieldNames - field names corresponding to the projection expressionsprivate Double computeJoinCardinality(RelMetadataQuery mq, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, List<RexNode> filters, int factor)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins chosen for each factorjoinTree - the join tree that the factor is being joined withfilters - possible join filters to select fromfactor - the factor being addedprivate void setFactorJoinKeys(LoptMultiJoin multiJoin, List<RexNode> filters, ImmutableBitSet joinFactors, int factorStart, int nFields, ImmutableBitSet.Builder joinKeys)
multiJoin - join factors being optimizedfilters - list of join filtersjoinFactors - bitmap containing the factors in a particular join
treefactorStart - the initial offset of the factor whose join keys will
be extractednFields - the number of fields in the factor whose join keys will be
extractedjoinKeys - the bitmap that will be set with the join keysprivate LoptJoinTree createOrdering(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, int firstFactor)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorfirstFactor - first factor in the treeprivate int getBestNextFactor(RelMetadataQuery mq, LoptMultiJoin multiJoin, BitSet factorsToAdd, BitSet factorsAdded, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, List<RexNode> filtersToAdd)
multiJoin - join factors being optimizedfactorsToAdd - factors to choose from to add nextfactorsAdded - factors that have already been added to the join treesemiJoinOpt - optimal semijoins for each factorjoinTree - join tree constructed thus farfiltersToAdd - remaining filters that need to be addedprivate boolean isJoinTree(RelNode rel)
private LoptJoinTree addFactorToTree(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, int factorToAdd, BitSet factorsNeeded, List<RexNode> filtersToAdd, boolean selfJoin)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorjoinTree - current join treefactorToAdd - new factor to be addedfactorsNeeded - factors that must precede the factor to be addedfiltersToAdd - filters remaining to be added; filters added to the
new join tree are removed from the listselfJoin - true if the join being created is a self-join that's
removableprivate int rowWidthCost(RelNode tree)
tree - a tree of RelNodesprivate LoptJoinTree pushDownFactor(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, int factorToAdd, BitSet factorsNeeded, List<RexNode> filtersToAdd, boolean selfJoin)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorjoinTree - current join treefactorToAdd - new factor to be addedfactorsNeeded - factors that must precede the factor to be addedfiltersToAdd - filters remaining to be added; filters that are added
to the join tree are removed from the listselfJoin - true if the factor being added is part of a removable
self-joinprivate LoptJoinTree addToTop(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, int factorToAdd, List<RexNode> filtersToAdd, boolean selfJoin)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorjoinTree - current join treefactorToAdd - new factor to be addedfiltersToAdd - filters remaining to be added; modifies the list to
remove filters that can be added to the join treeselfJoin - true if the join being created is a self-join that's
removableprivate RexNode addFilters(LoptMultiJoin multiJoin, LoptJoinTree leftTree, int leftIdx, LoptJoinTree rightTree, List<RexNode> filtersToAdd, boolean adjust)
multiJoin - join factors being optimizedleftTree - left subtree of the join treeleftIdx - if ≥ 0, only consider filters that reference leftIdx in
leftTree; otherwise, consider all filters that reference any factor in
leftTreerightTree - right subtree of the join treefiltersToAdd - remaining join filters that need to be added; those
that are added are removed from the listadjust - if true, adjust filter to reflect new join orderingprivate RexNode adjustFilter(LoptMultiJoin multiJoin, LoptJoinTree left, LoptJoinTree right, RexNode condition, int factorAdded, List<Integer> origJoinOrder, List<RelDataTypeField> origFields)
multiJoin - join factors being optimizedleft - left subtree of the joinright - right subtree of the joincondition - current join conditionfactorAdded - index corresponding to the newly added factororigJoinOrder - original join order, before factor was pushed into
the treeorigFields - fields from the original join before the factor was
addedprivate boolean remapJoinReferences(LoptMultiJoin multiJoin, int factor, List<Integer> newJoinOrder, int newPos, int[] adjustments, int offset, int newOffset, boolean alwaysUseDefault)
If the factor is not the right factor in a removable self-join, then it needs to be adjusted as follows:
If the factor is the right factor in a removable self-join and its column reference can be mapped to the left factor in the self-join, then:
Note that this only applies if both factors in the self-join are in the join ordering. If they are, then the left factor always precedes the right factor in the join ordering.
multiJoin - join factors being optimizedfactor - the factor whose references are being adjustednewJoinOrder - the new join ordering containing the factornewPos - the position of the factor in the new join orderingadjustments - the adjustments array that will be setoffset - the starting offset within the original join ordering for
the columns of the factor being adjustednewOffset - the new starting offset in the new join ordering for the
columns of the factor being adjustedalwaysUseDefault - always use the default adjustment value
regardless of whether the factor is the right factor in a removable
self-joinprivate LoptJoinTree createReplacementSemiJoin(RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree factTree, int dimIdx, List<RexNode> filtersToAdd)
The projection created on top of the join tree mimics a join of the fact and dimension tables. In order for the dimension table to have been removed, the only fields referenced from the dimension table are its dimension keys. Therefore, we can replace these dimension fields with the fields corresponding to the semijoin keys from the fact table in the projection.
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorfactTree - existing join tree containing the fact tabledimIdx - dimension table factor idfiltersToAdd - filters remaining to be added; filters added to the
new join tree are removed from the listprivate LoptJoinTree createReplacementJoin(RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree currJoinTree, int leftIdx, int factorToAdd, ImmutableIntList newKeys, Integer[] replacementKeys, List<RexNode> filtersToAdd)
multiJoin - join factors being optimizedsemiJoinOpt - optimal semijoins for each factorcurrJoinTree - current join tree being added toleftIdx - if ≥ 0, when creating the replacement join, only consider
filters that reference leftIdx in currJoinTree; otherwise, consider all
filters that reference any factor in currJoinTreefactorToAdd - new factor whose join can be removednewKeys - join keys that need to be replacedreplacementKeys - the keys that replace the join keys; null if we're
removing the null generating factor in an outer joinfiltersToAdd - filters remaining to be added; filters added to the
new join tree are removed from the listprivate LoptJoinTree createJoinSubtree(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptJoinTree left, LoptJoinTree right, RexNode condition, JoinRelType joinType, List<RexNode> filtersToAdd, boolean fullAdjust, boolean selfJoin)
multiJoin - join factors being optimizedleft - left operandright - right operandcondition - join conditionjoinType - the join typefullAdjust - true if the join condition reflects the original join
ordering and therefore has not gone through any type of adjustment yet;
otherwise, the condition has already been partially adjusted and only
needs to be further adjusted if swapping is donefiltersToAdd - additional filters that may be added on top of the
resulting LogicalJoin, if the join is a left or right outer joinselfJoin - true if the join being created is a self-join that's
removableprivate void addAdditionalFilters(RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptJoinTree left, LoptJoinTree right, List<RexNode> filtersToAdd)
relBuilder - Builder holding current join treemultiJoin - join factors being optimizedleft - left side of join treeright - right side of join treefiltersToAdd - remaining filtersprivate boolean swapInputs(RelMetadataQuery mq, LoptMultiJoin multiJoin, LoptJoinTree left, LoptJoinTree right, boolean selfJoin)
multiJoin - join factors being optimizedleft - left side of join treeright - right hand side of join treeselfJoin - true if the join is a removable self-joinprivate RexNode swapFilter(RexBuilder rexBuilder, LoptMultiJoin multiJoin, LoptJoinTree origLeft, LoptJoinTree origRight, RexNode condition)
rexBuilder - rexBuildermultiJoin - join factors being optimizedorigLeft - original LHS of the join tree (before swap)origRight - original RHS of the join tree (before swap)condition - original join conditionprivate boolean needsAdjustment(LoptMultiJoin multiJoin, int[] adjustments, LoptJoinTree joinTree, LoptJoinTree otherTree, boolean selfJoin)
multiJoin - join factors being optimizedadjustments - array to be filled outjoinTree - join treeotherTree - null unless joinTree only represents the left side of
the join treeselfJoin - true if no adjustments need to be made for self-joinspublic static boolean isRemovableSelfJoin(Join joinRel)
joinRel - the joinprivate static boolean areSelfJoinKeysUnique(RelMetadataQuery mq, RelNode leftRel, RelNode rightRel, RexNode joinFilters)
mq - Metadata queryleftRel - left side of the joinrightRel - right side of the joinjoinFilters - the join conditionCopyright © 2012–2018 The Apache Software Foundation. All rights reserved.