@Override public Prel visitJoin(JoinPrel prel, Double value) throws RuntimeException { JoinPrel newJoin = (JoinPrel) visitPrel(prel, value); RelMetadataQuery mq = prel.getCluster().getMetadataQuery(); if (prel instanceof HashJoinPrel) { // Mark left/right is swapped, when INNER hash join's left row count < ( 1+ margin factor) right row count. if ( (mq.getRowCount(newJoin.getLeft()) < (1 + value.doubleValue() ) * mq.getRowCount(newJoin.getRight()) ) && newJoin.getJoinType() == JoinRelType.INNER) { ( (HashJoinPrel) newJoin).setSwapped(true); } } return newJoin; }
@Override public Prel visitJoin(JoinPrel prel, Void value) throws RuntimeException { List<RelNode> children = Lists.newArrayList(); for(Prel child : prel){ child = child.accept(this, null); children.add(child); } final int leftCount = children.get(0).getRowType().getFieldCount(); List<RelNode> reNamedChildren = Lists.newArrayList(); RelNode left = prel.getJoinInput(0, children.get(0)); RelNode right = prel.getJoinInput(leftCount, children.get(1)); reNamedChildren.add(left); reNamedChildren.add(right); return (Prel) prel.copy(prel.getTraitSet(), reNamedChildren); }
@Override public RelWriter explainTerms(RelWriter pw) { return super.explainTerms(pw) .itemIf("swapped", swapped, swapped); }
@Override public PrelWithDictionaryInfo visitJoin(JoinPrel joinPrel, Void value) throws RuntimeException { assert joinPrel.getInputs().size() == 2; PrelWithDictionaryInfo leftInput = ((Prel)joinPrel.getLeft()).accept(this, value); PrelWithDictionaryInfo rightInput = ((Prel)joinPrel.getRight()).accept(this, value); if ((joinPrel.getLeft() == leftInput.getPrel()) && (joinPrel.getRight() == rightInput.getPrel())) { return new PrelWithDictionaryInfo(joinPrel); final int leftFieldCount = leftInput.getFields().length; final int rightFieldCount = rightInput.getFields().length; final int systemFieldCount = joinPrel.getSystemFieldList().size(); final GlobalDictionaryFieldInfo[] reorderedFields = new GlobalDictionaryFieldInfo[systemFieldCount + leftFieldCount + rightFieldCount]; joinPrel.getCondition().accept(visitor); reorderedFields[leftFieldCount + i] = rightInput.getGlobalDictionaryFieldInfo(i); return new PrelWithDictionaryInfo((Prel)joinPrel.copy(joinPrel.getTraitSet(), Lists.<RelNode>newArrayList(leftInput.getPrel(), rightInput.getPrel())), reorderedFields);
.setJoinType(toJoinType(joinPrel.getJoinType())) .setUnmatchedBuildCount(unmatchedBuildKeyCount) .setUnmatchedProbeCount(unmatchedProbeCount) .setOutputRecords(outputRecords); final RelMetadataQuery relMetadataQuery = joinPrel.getCluster().getMetadataQuery(); final JoinInfo joinInfo = joinPrel.analyzeCondition();
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) { return super.computeSelfCost(planner).multiplyBy(.1); } if (joincategory == JoinCategory.CARTESIAN || joincategory == JoinCategory.INEQUALITY) { return planner.getCostFactory().makeInfiniteCost(); } return computeHashJoinCost(planner, mq); }
List<Integer> leftKeys, List<Integer> rightKeys) { List<RexNode> conjuncts = RelOptUtil.conjunctions(this.getCondition()); short i=0;
@Override public JoinCondition apply(Pair<Integer, Integer> pair) { final RelColumnOrigin leftColumnOrigin = Iterables.getOnlyElement(relMetadataQuery.getColumnOrigins(joinPrel.getLeft(), pair.left)); final RelColumnOrigin rightColumnOrigin = Iterables.getOnlyElement(relMetadataQuery.getColumnOrigins(joinPrel.getRight(), pair.right)); final RelOptTable leftTable = leftColumnOrigin.getOriginTable(); final RelOptTable rightTable = rightColumnOrigin.getOriginTable(); int leftOrdinal = leftColumnOrigin.getOriginColumnOrdinal(); int rightOrdinal = rightColumnOrigin.getOriginColumnOrdinal(); return new JoinCondition() .setBuildSideColumn(rightTable.getRowType().getFieldList().get(rightOrdinal).getName()) .setProbeSideColumn(leftTable.getRowType().getFieldList().get(leftOrdinal).getName()) .setBuildSideTableId(tables.get(rightTable.getQualifiedName())) .setProbeSideTableId(tables.get(leftTable.getQualifiedName())); } })
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) { return super.computeSelfCost(planner).multiplyBy(.1); } if (joincategory == JoinCategory.CARTESIAN || joincategory == JoinCategory.INEQUALITY) { return ((Factory)planner.getCostFactory()).makeInfiniteCost(); } double leftRowCount = mq.getRowCount(this.getLeft()); double rightRowCount = mq.getRowCount(this.getRight()); // cost of evaluating each leftkey=rightkey join condition double joinConditionCost = DremioCost.COMPARE_CPU_COST * this.getLeftKeys().size(); double cpuCost = joinConditionCost * (leftRowCount + rightRowCount); Factory costFactory = (Factory)planner.getCostFactory(); return costFactory.makeCost(leftRowCount + rightRowCount, cpuCost, 0, 0); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) { return super.computeSelfCost(planner).multiplyBy(.1); } double leftRowCount = mq.getRowCount(this.getLeft()); double rightRowCount = mq.getRowCount(this.getRight()); double nljFactor = PrelUtil.getSettings(getCluster()).getNestedLoopJoinFactor(); // cpu cost of evaluating each leftkey=rightkey join condition double joinConditionCost = DremioCost.COMPARE_CPU_COST * this.getLeftKeys().size(); double cpuCost = joinConditionCost * (leftRowCount * rightRowCount) * nljFactor; Factory costFactory = (Factory) planner.getCostFactory(); return costFactory.makeCost(leftRowCount * rightRowCount, cpuCost, 0, 0, 0); }