use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.JoinRelType in project flink by apache.
the class FlinkRelDecorrelator method projectJoinOutputWithNullability.
/**
* Pulls project above the join from its RHS input. Enforces nullability
* for join output.
*
* @param join Join
* @param project Original project as the right-hand input of the join
* @param nullIndicatorPos Position of null indicator
* @return the subtree with the new LogicalProject at the root
*/
private RelNode projectJoinOutputWithNullability(LogicalJoin join, LogicalProject project, int nullIndicatorPos) {
final RelDataTypeFactory typeFactory = join.getCluster().getTypeFactory();
final RelNode left = join.getLeft();
final JoinRelType joinType = join.getJoinType();
RexInputRef nullIndicator = new RexInputRef(nullIndicatorPos, typeFactory.createTypeWithNullability(join.getRowType().getFieldList().get(nullIndicatorPos).getType(), true));
// now create the new project
List<Pair<RexNode, String>> newProjExprs = Lists.newArrayList();
// project everything from the LHS and then those from the original
// projRel
List<RelDataTypeField> leftInputFields = left.getRowType().getFieldList();
for (int i = 0; i < leftInputFields.size(); i++) {
newProjExprs.add(RexInputRef.of2(i, leftInputFields));
}
// Marked where the projected expr is coming from so that the types will
// become nullable for the original projections which are now coming out
// of the nullable side of the OJ.
boolean projectPulledAboveLeftCorrelator = joinType.generatesNullsOnRight();
for (Pair<RexNode, String> pair : project.getNamedProjects()) {
RexNode newProjExpr = removeCorrelationExpr(pair.left, projectPulledAboveLeftCorrelator, nullIndicator);
newProjExprs.add(Pair.of(newProjExpr, pair.right));
}
return RelOptUtil.createProject(join, newProjExprs, false);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.JoinRelType in project drill by apache.
the class HashJoinPrel method getHashJoinPop.
private PhysicalOperator getHashJoinPop(PhysicalPlanCreator creator, RelNode left, RelNode right, List<Integer> leftKeys, List<Integer> rightKeys) throws IOException {
final List<String> fields = getRowType().getFieldNames();
assert isUnique(fields);
final List<String> leftFields = left.getRowType().getFieldNames();
final List<String> rightFields = right.getRowType().getFieldNames();
PhysicalOperator leftPop = ((Prel) left).getPhysicalOperator(creator);
PhysicalOperator rightPop = ((Prel) right).getPhysicalOperator(creator);
JoinRelType jtype = this.getJoinType();
List<JoinCondition> conditions = Lists.newArrayList();
buildJoinConditions(conditions, leftFields, rightFields, leftKeys, rightKeys);
HashJoinPOP hjoin = new HashJoinPOP(leftPop, rightPop, conditions, jtype);
return creator.addMetadata(this, hjoin);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.JoinRelType in project hive by apache.
the class HiveRelDecorrelator method projectJoinOutputWithNullability.
/**
* Pulls project above the join from its RHS input. Enforces nullability
* for join output.
*
* @param join Join
* @param project Original project as the right-hand input of the join
* @param nullIndicatorPos Position of null indicator
* @return the subtree with the new LogicalProject at the root
*/
private RelNode projectJoinOutputWithNullability(LogicalJoin join, LogicalProject project, int nullIndicatorPos) {
final RelDataTypeFactory typeFactory = join.getCluster().getTypeFactory();
final RelNode left = join.getLeft();
final JoinRelType joinType = join.getJoinType();
RexInputRef nullIndicator = new RexInputRef(nullIndicatorPos, typeFactory.createTypeWithNullability(join.getRowType().getFieldList().get(nullIndicatorPos).getType(), true));
// now create the new project
List<Pair<RexNode, String>> newProjExprs = Lists.newArrayList();
// project everything from the LHS and then those from the original
// projRel
List<RelDataTypeField> leftInputFields = left.getRowType().getFieldList();
for (int i = 0; i < leftInputFields.size(); i++) {
newProjExprs.add(RexInputRef.of2(i, leftInputFields));
}
// Marked where the projected expr is coming from so that the types will
// become nullable for the original projections which are now coming out
// of the nullable side of the OJ.
boolean projectPulledAboveLeftCorrelator = joinType.generatesNullsOnRight();
for (Pair<RexNode, String> pair : project.getNamedProjects()) {
RexNode newProjExpr = removeCorrelationExpr(pair.left, projectPulledAboveLeftCorrelator, nullIndicator);
newProjExprs.add(Pair.of(newProjExpr, pair.right));
}
return RelOptUtil.createProject(join, newProjExprs, false);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.JoinRelType in project calcite by apache.
the class LoptOptimizeJoinRule method addToTop.
/**
* Creates a join tree with the new factor added to the top of the tree
*
* @param multiJoin join factors being optimized
* @param semiJoinOpt optimal semijoins for each factor
* @param joinTree current join tree
* @param factorToAdd new factor to be added
* @param filtersToAdd filters remaining to be added; modifies the list to
* remove filters that can be added to the join tree
* @param selfJoin true if the join being created is a self-join that's
* removable
*
* @return new join tree
*/
private LoptJoinTree addToTop(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, int factorToAdd, List<RexNode> filtersToAdd, boolean selfJoin) {
// other self-join factor
if (selfJoin && isJoinTree(joinTree.getJoinTree())) {
return null;
}
// if the factor being added is null-generating, create the join
// as a left outer join since it's being added to the RHS side of
// the join; createJoinSubTree may swap the inputs and therefore
// convert the left outer join to a right outer join; if the original
// MultiJoin was a full outer join, these should be the only
// factors in the join, so create the join as a full outer join
JoinRelType joinType;
if (multiJoin.getMultiJoinRel().isFullOuterJoin()) {
assert multiJoin.getNumJoinFactors() == 2;
joinType = JoinRelType.FULL;
} else if (multiJoin.isNullGenerating(factorToAdd)) {
joinType = JoinRelType.LEFT;
} else {
joinType = JoinRelType.INNER;
}
LoptJoinTree rightTree = new LoptJoinTree(semiJoinOpt.getChosenSemiJoin(factorToAdd), factorToAdd);
// in the case of a left or right outer join, use the specific
// outer join condition
RexNode condition;
if ((joinType == JoinRelType.LEFT) || (joinType == JoinRelType.RIGHT)) {
condition = multiJoin.getOuterJoinCond(factorToAdd);
} else {
condition = addFilters(multiJoin, joinTree, -1, rightTree, filtersToAdd, false);
}
return createJoinSubtree(mq, relBuilder, multiJoin, joinTree, rightTree, condition, joinType, filtersToAdd, true, selfJoin);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.JoinRelType in project calcite by apache.
the class LoptOptimizeJoinRule method pushDownFactor.
/**
* Creates a join tree where the new factor is pushed down one of the
* operands of the current join tree
*
* @param multiJoin join factors being optimized
* @param semiJoinOpt optimal semijoins for each factor
* @param joinTree current join tree
* @param factorToAdd new factor to be added
* @param factorsNeeded factors that must precede the factor to be added
* @param filtersToAdd filters remaining to be added; filters that are added
* to the join tree are removed from the list
* @param selfJoin true if the factor being added is part of a removable
* self-join
*
* @return optimal join tree with the new factor pushed down the current
* join tree if it is possible to do the pushdown; otherwise, null is
* returned
*/
private LoptJoinTree pushDownFactor(RelMetadataQuery mq, RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptSemiJoinOptimizer semiJoinOpt, LoptJoinTree joinTree, int factorToAdd, BitSet factorsNeeded, List<RexNode> filtersToAdd, boolean selfJoin) {
// pushdown option only works if we already have a join tree
if (!isJoinTree(joinTree.getJoinTree())) {
return null;
}
int childNo = -1;
LoptJoinTree left = joinTree.getLeft();
LoptJoinTree right = joinTree.getRight();
Join joinRel = (Join) joinTree.getJoinTree();
JoinRelType joinType = joinRel.getJoinType();
// them, we need to keep the factors together
if (joinTree.isRemovableSelfJoin()) {
return null;
}
// half of the self-join.
if (selfJoin) {
BitSet selfJoinFactor = new BitSet(multiJoin.getNumJoinFactors());
selfJoinFactor.set(multiJoin.getOtherSelfJoinFactor(factorToAdd));
if (multiJoin.hasAllFactors(left, selfJoinFactor)) {
childNo = 0;
} else {
assert multiJoin.hasAllFactors(right, selfJoinFactor);
childNo = 1;
}
} else if ((factorsNeeded.cardinality() == 0) && !joinType.generatesNullsOnLeft()) {
childNo = 0;
} else {
// same check for RHS
if (multiJoin.hasAllFactors(left, factorsNeeded) && !joinType.generatesNullsOnLeft()) {
childNo = 0;
} else if (multiJoin.hasAllFactors(right, factorsNeeded) && !joinType.generatesNullsOnRight()) {
childNo = 1;
}
// if it couldn't be pushed down to either side, then it can
// only be put on top
}
if (childNo == -1) {
return null;
}
// remember the original join order before the pushdown so we can
// appropriately adjust any filters already attached to the join
// node
final List<Integer> origJoinOrder = joinTree.getTreeOrder();
// recursively pushdown the factor
LoptJoinTree subTree = (childNo == 0) ? left : right;
subTree = addFactorToTree(mq, relBuilder, multiJoin, semiJoinOpt, subTree, factorToAdd, factorsNeeded, filtersToAdd, selfJoin);
if (childNo == 0) {
left = subTree;
} else {
right = subTree;
}
// adjust the join condition from the original join tree to reflect
// pushdown of the new factor as well as any swapping that may have
// been done during the pushdown
RexNode newCondition = ((Join) joinTree.getJoinTree()).getCondition();
newCondition = adjustFilter(multiJoin, left, right, newCondition, factorToAdd, origJoinOrder, joinTree.getJoinTree().getRowType().getFieldList());
// join in createJoinSubtree
if ((joinType != JoinRelType.LEFT) && (joinType != JoinRelType.RIGHT)) {
RexNode condition = addFilters(multiJoin, left, -1, right, filtersToAdd, true);
RexBuilder rexBuilder = multiJoin.getMultiJoinRel().getCluster().getRexBuilder();
newCondition = RelOptUtil.andJoinFilters(rexBuilder, newCondition, condition);
}
// create the new join tree with the factor pushed down
return createJoinSubtree(mq, relBuilder, multiJoin, left, right, newCondition, joinType, filtersToAdd, false, false);
}
Aggregations