@Override public void onMatch(RelOptRuleCall call) { final Join join = call.rel(0); final RexBuilder rexBuilder = join.getCluster().getRexBuilder(); final RexNode condition = RexUtil.pullFactors(rexBuilder, join.getCondition()); RexNode newCondition = analyzeRexNode(rexBuilder, condition); // If we could not transform anything, we bail out if (newCondition.toString().equals(condition.toString())) { return; } RelNode newNode = join.copy(join.getTraitSet(), newCondition, join.getLeft(), join.getRight(), join.getJoinType(), join.isSemiJoinDone()); call.transformTo(newNode); } }
private Project swapInputs(Join join, Project topProject, RelBuilder builder) { RexBuilder rexBuilder = join.getCluster().getRexBuilder(); int rightInputSize = join.getRight().getRowType().getFieldCount(); int leftInputSize = join.getLeft().getRowType().getFieldCount(); List<RelDataTypeField> joinFields = join.getRowType().getFieldList(); RexNode newJoinCond = join.getCondition().accept(new RelOptUtil.RexInputConverter(rexBuilder, joinFields, joinFields, condAdjustments)); Join swappedJoin = (Join)builder.push(join.getRight()).push(join.getLeft()).join(join.getJoinType(), newJoinCond).build(); List<RelDataTypeField> swappedJoinFeilds = swappedJoin.getRowType().getFieldList(); for(RexNode project:topProject.getProjects()) { RexNode newProject = project.accept(new RelOptUtil.RexInputConverter(rexBuilder, swappedJoinFeilds,
private static boolean validJoinParent(RelNode joinNode, RelNode parent) { boolean validParent = true; if (parent instanceof Join) { // In Hive AST, right child of join cannot be another join, // thus we need to introduce a project on top of it. // But we only need the additional project if the left child // is another join too; if it is not, ASTConverter will swap // the join inputs, leaving the join operator on the left. // we also do it if parent is HiveSemiJoin since ASTConverter won't // swap inputs then // This will help triggering multijoin recognition methods that // are embedded in SemanticAnalyzer. if (((Join) parent).getRight() == joinNode && (((Join) parent).getLeft() instanceof Join || parent instanceof HiveSemiJoin) ) { validParent = false; } } else if (parent instanceof SetOp) { validParent = false; } return validParent; }
/** * * @param j * @param additionalPredicate * @return if predicate is the join condition return (true, joinCond) * else return (false, minusPred) */ private Pair<Boolean,RexNode> getCombinedPredicateForJoin(Join j, RexNode additionalPredicate) { RexNode minusPred = RelMdUtil.minusPreds(j.getCluster().getRexBuilder(), additionalPredicate, j.getCondition()); if (minusPred != null) { List<RexNode> minusList = new ArrayList<RexNode>(); minusList.add(j.getCondition()); minusList.add(minusPred); return new Pair<Boolean,RexNode>(false, minusPred); } return new Pair<Boolean,RexNode>(true,j.getCondition()); }
} else if (call.rel(0) instanceof Join) { Join join = call.rel(0); newOp = join.copy(join.getTraitSet(), join.getCondition(), newInputs.get(0), newInputs.get(1), join.getJoinType(), join.isSemiJoinDone()); } else { return;
public void onMatch(RelOptRuleCall call) { final Delta delta = call.rel(0); Util.discard(delta); final Join join = call.rel(1); final RelNode left = join.getLeft(); final RelNode right = join.getRight(); final LogicalDelta rightWithDelta = LogicalDelta.create(right); final LogicalJoin joinL = LogicalJoin.create(left, rightWithDelta, join.getCondition(), join.getVariablesSet(), join.getJoinType(), join.isSemiJoinDone(), ImmutableList.copyOf(join.getSystemFieldList())); final LogicalDelta leftWithDelta = LogicalDelta.create(left); final LogicalJoin joinR = LogicalJoin.create(leftWithDelta, right, join.getCondition(), join.getVariablesSet(), join.getJoinType(), join.isSemiJoinDone(), ImmutableList.copyOf(join.getSystemFieldList())); List<RelNode> inputsToUnion = new ArrayList<>(); inputsToUnion.add(joinL); inputsToUnion.add(joinR); final LogicalUnion newNode = LogicalUnion.create(inputsToUnion, true); call.transformTo(newNode); } }
Join join, List<RexNode> joinFilters, boolean leftInputPotentialFK, RelMetadataQuery mq) { final List<RexNode> residualPreds = new ArrayList<>(); final JoinRelType joinType = join.getJoinType(); final RelNode fkInput = leftInputPotentialFK ? join.getLeft() : join.getRight(); final PKFKJoinInfo cannotExtract = PKFKJoinInfo.of(false, null, null); join = join.copy(join.getTraitSet(), join.getCluster().getRexBuilder().makeLiteral(true), join.getLeft(), join.getRight(), JoinRelType.INNER, false); final Set<RelTableRef> leftTables = mq.getTableReferences(join.getLeft()); final Set<RelTableRef> rightTables = Sets.difference(mq.getTableReferences(join), mq.getTableReferences(join.getLeft())); final Set<RelTableRef> fkTables = join.getLeft() == fkInput ? leftTables : rightTables; final Set<RelTableRef> nonFkTables = join.getLeft() == fkInput ? rightTables : leftTables; int nFieldsLeft = join.getLeft().getRowType().getFieldList().size(); int nFieldsRight = join.getRight().getRowType().getFieldList().size(); int nSysFields = join.getSystemFieldList().size(); ImmutableBitSet rightFieldsBitSet = ImmutableBitSet.range(nSysFields + nFieldsLeft, nSysFields + nFieldsLeft + nFieldsRight);
public Set<ImmutableBitSet> getUniqueKeys(Join rel, RelMetadataQuery mq, boolean ignoreNulls) { final RelNode left = rel.getLeft(); final RelNode right = rel.getRight(); final JoinInfo joinInfo = rel.analyzeCondition(); && rightUnique && (leftSet != null) && !(rel.getJoinType().generatesNullsOnLeft())) { retSet.addAll(leftSet); && leftUnique && (rightSet != null) && !(rel.getJoinType().generatesNullsOnRight())) { retSet.addAll(rightSet);
if (join.getJoinType() != JoinRelType.INNER) { return; mq.getPulledUpPredicates(join).pulledUpPredicates); final ImmutableBitSet joinColumns = RelOptUtil.InputFinder.bits(join.getCondition()); final boolean allColumnsInAggregate = keyColumns.contains(joinColumns); final List<Boolean> filterNulls = Lists.newArrayList(); RexNode nonEquiConj = RelOptUtil.splitJoinCondition(join.getLeft(), join.getRight(), join.getCondition(), leftKeys, rightKeys, filterNulls); for (int s = 0; s < 2; s++) { final Side side = new Side(); final RelNode joinInput = join.getInput(s); int fieldCount = joinInput.getRowType().getFieldCount(); final ImmutableBitSet fieldSet = join.getRowType().getFieldCount(), belowOffset); final RexNode newCondition = RexUtil.apply(mapping, join.getCondition()); sides.get(1).newInput, newCondition, join.getJoinType(), join.getVariablesStopped(), join.isSemiJoinDone());
this.joinRel = joinRel; this.isSemiJoin = isSemiJoin; nFieldsLeft = joinRel.getLeft().getRowType().getFieldList().size(); nFieldsRight = joinRel.getRight().getRowType().getFieldList().size(); nSysFields = joinRel.getSystemFieldList().size(); leftFieldsBitSet = ImmutableBitSet.range(nSysFields, nSysFields + nFieldsLeft); nSysFields + nFieldsLeft, nSysFields, 0, nFieldsLeft); leftChildPredicates = lPreds.accept( new RexPermuteInputsShuttle(leftMapping, joinRel.getInput(0))); nSysFields + nFieldsLeft, 0, nFieldsRight); rightChildPredicates = rPreds.accept( new RexPermuteInputsShuttle(rightMapping, joinRel.getInput(1))); RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder(); List<RexNode> exprs = RelOptUtil.conjunctions( compose(rexBuilder, ImmutableList.of(joinRel.getCondition())));
protected void perform(RelOptRuleCall call, ImmutableBitSet topRefs, RelNode topOperator, Join join, RelNode left, Aggregate aggregate) { LOG.debug("Matched HiveSemiJoinRule"); final RelOptCluster cluster = join.getCluster(); final RexBuilder rexBuilder = cluster.getRexBuilder(); final ImmutableBitSet rightBits = ImmutableBitSet.range(left.getRowType().getFieldCount(), join.getRowType().getFieldCount()); if (topRefs.intersects(rightBits)) { return; final JoinInfo joinInfo = join.analyzeCondition(); if (!joinInfo.rightSet().equals( ImmutableBitSet.range(aggregate.getGroupCount()))) { if(join.getJoinType() == JoinRelType.LEFT) { if (join.getJoinType() != JoinRelType.INNER) { return; Join rightJoin = (Join)(((HepRelVertex)aggregate.getInput()).getCurrentRel()); List<RexNode> projects = new ArrayList<>(); for(int i=0; i<rightJoin.getRowType().getFieldCount(); i++){ projects.add(rexBuilder.makeInputRef(rightJoin, i)); RelNode topProject = call.builder().push(rightJoin).project(projects, rightJoin.getRowType().getFieldNames(), true).build(); semi = call.builder().push(left).push(topProject).semiJoin(newCondition).build();
final RelNode oldLeft = rel.getInput(0); final RelNode oldRight = rel.getInput(1); final RelNode newJoin = HiveJoin.getJoin(rel.getCluster(), leftFrame.r, rightFrame.r, decorrelateExpr(rel.getCondition()), rel.getJoinType()); assert rel.getRowType().getFieldCount() == oldLeftFieldCount + oldRightFieldCount;
private List<Double> averageJoinColumnSizes(Join rel, RelMetadataQuery mq, boolean semijoin) { final RelNode left = rel.getLeft(); final RelNode right = rel.getRight(); final List<Double> lefts = mq.getAverageColumnSizes(left); final List<Double> rights = semijoin ? null : mq.getAverageColumnSizes(right); if (lefts == null && rights == null) { return null; } final int fieldCount = rel.getRowType().getFieldCount(); Double[] sizes = new Double[fieldCount]; if (lefts != null) { lefts.toArray(sizes); } if (rights != null) { final int leftCount = left.getRowType().getFieldCount(); for (int i = 0; i < rights.size(); i++) { sizes[leftCount + i] = rights.get(i); } } return ImmutableNullableList.copyOf(sizes); }
Project project, int nullIndicatorPos) { final RelDataTypeFactory typeFactory = join.getCluster().getTypeFactory(); final RelNode left = join.getLeft(); final JoinRelType joinType = join.getJoinType(); nullIndicatorPos, typeFactory.createTypeWithNullability( join.getRowType().getFieldList().get(nullIndicatorPos) .getType(), true));
final RelNode left = join.getInputs().get(0); final RelNode right = join.getInputs().get(1); join.getCondition()); final List<RexNode> leftFilters = new ArrayList<>(); final List<RexNode> rightFilters = new ArrayList<>(); RelOptUtil.classifyFilters(join, joinFilters, join.getJoinType(),false, !join.getJoinType().generatesNullsOnRight(), !join.getJoinType().generatesNullsOnLeft(), joinFilters, leftFilters, rightFilters); boolean leftIsKey = (join.getJoinType() == JoinRelType.INNER || join.getJoinType() == JoinRelType.RIGHT) && leftInputResult.isPkFkJoin; boolean rightIsKey = (join.getJoinType() == JoinRelType.INNER || join.getJoinType() == JoinRelType.LEFT) && rightInputResult.isPkFkJoin; if (!leftIsKey && !rightIsKey) { boolean isPKSideSimpleTree = simpleTree.left; boolean isNoFilteringPKSideTree = simpleTree.right; RexBuilder rexBuilder = join.getCluster().getRexBuilder(); RexNode leftPred = RexUtil.composeConjunction( rexBuilder, leftFilters, true); PKSideInfo pkInfo = new PKSideInfo(leftRowCount, leftNDV, join.getJoinType().generatesNullsOnRight() ? 1.0 : pkSelectivity); double ndvScalingFactor = isPKSideSimpleTree ? leftNDV/rightNDV : 1.0;
public Double getSelectivity(Join j, RelMetadataQuery mq, RexNode predicate) { if (j.getJoinType().equals(JoinRelType.INNER)) { return computeInnerJoinSelectivity(j, mq, predicate); } else if (j.getJoinType().equals(JoinRelType.LEFT) || j.getJoinType().equals(JoinRelType.RIGHT)) { double left = mq.getRowCount(j.getLeft()); double right = mq.getRowCount(j.getRight()); double product = left * right; double innerJoinSelectivity = computeInnerJoinSelectivity(j, mq, predicate); if (j.getJoinType().equals(JoinRelType.LEFT)) { return Math.max(innerJoinSelectivity, left/product); } return Math.max(innerJoinSelectivity, right/product); } return 1.0; }
for (RelNode input : join.getInputs()) { if (convertInputTraits && input.getConvention() != getOutTrait()) { input = if (convertInputTraits && !canJoinOnCondition(join.getCondition())) { return null; join.getCluster(), join.getTraitSet().replace(out), newInputs.get(0), newInputs.get(1), join.getCondition(), join.getVariablesSet(), join.getJoinType()); } catch (InvalidRelException e) { LOGGER.debug(e.toString());
final JoinInfo joinInfo = join.analyzeCondition(); if(!joinInfo.isEqui()) { return; ImmutableBitSet.range(0, join.getLeft().getRowType().getFieldCount());
int rightOffSet = j.getLeft().getRowType().getFieldCount(); HiveRelMdDistinctRowCount.getDistinctRowCount(j.getLeft(), mq, ljk)); HiveRelMdDistinctRowCount.getDistinctRowCount(j.getRight(), mq, rjk)); double ndvEstimate = 1; if (noOfPE > 0) { boolean isCorrelatedColumns = j.getCluster().getPlanner().getContext(). unwrap(HiveConfPlannerContext.class).getIsCorrelatedColumns(); if (noOfPE > 1 && isCorrelatedColumns ){ ndvEstimate = Math.min(mq.getRowCount(j.getLeft()), ndvEstimate); }else if (j instanceof HiveJoin){ ndvEstimate = Math.min(mq.getRowCount(j.getLeft()) * mq.getRowCount(j.getRight()), ndvEstimate); } else { throw new RuntimeException("Unexpected Join type: " + j.getClass().getName());
int nFieldsLeft = joinRel.getLeft().getRowType().getFieldList().size(); int nFieldsRight = joinRel.getRight().getRowType().getFieldList().size(); int nSysFields = joinRel.getSystemFieldList().size(); ImmutableBitSet rightFieldsBitSet = ImmutableBitSet.range(nSysFields + nFieldsLeft, nSysFields + nFieldsLeft + nFieldsRight);