public JdbcPrel(RelOptCluster cluster, RelTraitSet traitSet, JdbcIntermediatePrel prel) { super(cluster, traitSet); final RelNode input = prel.getInput(); rows = input.estimateRowCount(cluster.getMetadataQuery()); convention = (DrillJdbcConvention) input.getTraitSet().getTrait(ConventionTraitDef.INSTANCE); // generate sql for tree. final SqlDialect dialect = convention.getPlugin().getDialect(); final JdbcImplementor jdbcImplementor = new JdbcImplementor( dialect, (JavaTypeFactory) getCluster().getTypeFactory()); final JdbcImplementor.Result result = jdbcImplementor.visitChild(0, input.accept(new SubsetRemover())); sql = result.asStatement().toSqlString(dialect).getSql(); rowType = input.getRowType(); }
@Override public double estimateRowCount(RelMetadataQuery mq) { return input.estimateRowCount(mq); }
/** Catch-all implementation for * {@link BuiltInMetadata.RowCount#getRowCount()}, * invoked using reflection. * * @see org.apache.calcite.rel.metadata.RelMetadataQuery#getRowCount(RelNode) */ public Double getRowCount(RelNode rel, RelMetadataQuery mq) { return rel.estimateRowCount(mq); }
/** Catch-all implementation for * {@link BuiltInMetadata.RowCount#getRowCount()}, * invoked using reflection. * * @see org.apache.calcite.rel.metadata.RelMetadataQuery#getRowCount(RelNode) */ public Double getRowCount(RelNode rel, RelMetadataQuery mq) { return rel.estimateRowCount(mq); }
@Override public double estimateRowCount(RelMetadataQuery mq) { final double leftRowCount = left.estimateRowCount(mq); final double rightRowCount = right.estimateRowCount(mq); return Math.max(leftRowCount, rightRowCount); }
@Override public double estimateRowCount(RelMetadataQuery mq) { final double leftRowCount = left.estimateRowCount(mq); final double rightRowCount = right.estimateRowCount(mq); return Math.max(leftRowCount, rightRowCount); }
@Override public double estimateRowCount(RelMetadataQuery mq) { return this.getLeft().estimateRowCount(mq) * this.getRight().estimateRowCount(mq); }
@Override public double estimateRowCount(RelMetadataQuery mq) { if (this.condition.isAlwaysTrue()) { return joinRowFactor * this.getLeft().estimateRowCount(mq) * this.getRight().estimateRowCount(mq); } else { return joinRowFactor * Math.max(this.getLeft().estimateRowCount(mq), this.getRight().estimateRowCount(mq)); } }
public Double getRowCount(JdbcRelBase jdbc, RelMetadataQuery mq) { return jdbc.getSubTree().estimateRowCount(mq); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { // We assume that the inputs are sorted. The price of sorting them has // already been paid. The cost of the join is therefore proportional to the // input and output size. final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); final double rowCount = mq.getRowCount(this); final double d = leftRowCount + rightRowCount + rowCount; return planner.getCostFactory().makeCost(d, 0, 0); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { // We assume that the inputs are sorted. The price of sorting them has // already been paid. The cost of the join is therefore proportional to the // input and output size. final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); final double rowCount = mq.getRowCount(this); final double d = leftRowCount + rightRowCount + rowCount; return planner.getCostFactory().makeCost(d, 0, 0); }
private Double getDistinctRowCountFromEstimateRowCount(RelNode rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) { final int groupKeySize = groupKey.cardinality(); return rel.estimateRowCount(mq) * (1.0 - Math.pow(0.9, groupKeySize)) * RelMdUtil.guessSelectivity(predicate); } }
@Override public double estimateRowCount(RelMetadataQuery mq) { int off = offset != null? RexLiteral.intValue(offset): 0; if (fetch == null) { // If estimated rowcount is less than offset return 0 return Math.max(0, getInput().estimateRowCount(mq) - off); } else { int f = RexLiteral.intValue(fetch); return off + f; } }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { double rowCount = mq.getRowCount(this); // Right-hand input is the "build", and hopefully small, input. final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); if (Double.isInfinite(leftRowCount)) { rowCount = leftRowCount; } else { rowCount += Util.nLogN(leftRowCount); } if (Double.isInfinite(rightRowCount)) { rowCount = rightRowCount; } else { rowCount += rightRowCount; } return planner.getCostFactory().makeCost(rowCount, 0, 0).multiplyBy(.01d); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { double rowCount = mq.getRowCount(this); // Right-hand input is the "build", and hopefully small, input. final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); if (Double.isInfinite(leftRowCount)) { rowCount = leftRowCount; } else { rowCount += Util.nLogN(leftRowCount); } if (Double.isInfinite(rightRowCount)) { rowCount = rightRowCount; } else { rowCount += rightRowCount; } return planner.getCostFactory().makeCost(rowCount, 0, 0).multiplyBy(.01d); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { double rowCount = mq.getRowCount(this); // Joins can be flipped, and for many algorithms, both versions are viable // and have the same cost. To make the results stable between versions of // the planner, make one of the versions slightly more expensive. switch (joinType) { case RIGHT: rowCount = addEpsilon(rowCount); break; default: if (left.getId() > right.getId()) { rowCount = addEpsilon(rowCount); } } final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); if (Double.isInfinite(leftRowCount)) { rowCount = leftRowCount; } if (Double.isInfinite(rightRowCount)) { rowCount = rightRowCount; } return planner.getCostFactory().makeCost(rowCount, 0, 0); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { double rowCount = mq.getRowCount(this); final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); if (Double.isInfinite(leftRowCount) || Double.isInfinite(rightRowCount)) { return planner.getCostFactory().makeInfiniteCost(); } Double restartCount = mq.getRowCount(getLeft()); // RelMetadataQuery.getCumulativeCost(getRight()); does not work for // RelSubset, so we ask planner to cost-estimate right relation RelOptCost rightCost = planner.getCost(getRight(), mq); RelOptCost rescanCost = rightCost.multiplyBy(Math.max(1.0, restartCount - 1)); return planner.getCostFactory().makeCost( rowCount /* generate results */ + leftRowCount /* scan left results */, 0, 0).plus(rescanCost); } }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { double rowCount = mq.getRowCount(this); final double rightRowCount = right.estimateRowCount(mq); final double leftRowCount = left.estimateRowCount(mq); if (Double.isInfinite(leftRowCount) || Double.isInfinite(rightRowCount)) { return planner.getCostFactory().makeInfiniteCost(); } Double restartCount = mq.getRowCount(getLeft()); // RelMetadataQuery.getCumulativeCost(getRight()); does not work for // RelSubset, so we ask planner to cost-estimate right relation RelOptCost rightCost = planner.getCost(getRight(), mq); RelOptCost rescanCost = rightCost.multiplyBy(Math.max(1.0, restartCount - 1)); return planner.getCostFactory().makeCost( rowCount /* generate results */ + leftRowCount /* scan left results */, 0, 0).plus(rescanCost); } }
@Override public Prel visitJoin(JoinPrel prel, Double value) throws RuntimeException { JoinPrel newJoin = (JoinPrel) visitPrel(prel, value); if (prel instanceof HashJoinPrel && !((HashJoinPrel) prel).isRowKeyJoin() /* don't swap for rowkey joins */) { // Mark left/right is swapped, when INNER hash join's left row count < ( 1+ margin factor) right row count. RelMetadataQuery mq = newJoin.getCluster().getMetadataQuery(); if (newJoin.getLeft().estimateRowCount(mq) < (1 + value) * newJoin.getRight().estimateRowCount(mq) && newJoin.getJoinType() == JoinRelType.INNER && !newJoin.isSemiJoin()) { ((HashJoinPrel) newJoin).setSwapped(true); } } return newJoin; }
protected boolean create2PhasePlan(RelOptRuleCall call, DrillAggregateRel aggregate) { PlannerSettings settings = PrelUtil.getPlannerSettings(call.getPlanner()); RelNode child = call.rel(0).getInputs().get(0); boolean smallInput = child.estimateRowCount(child.getCluster().getMetadataQuery()) < settings.getSliceTarget(); if (!settings.isMultiPhaseAggEnabled() || settings.isSingleMode() // Can override a small child - e.g., for testing with a small table || (smallInput && !settings.isForce2phaseAggr())) { return false; } for (AggregateCall aggCall : aggregate.getAggCallList()) { String name = aggCall.getAggregation().getName(); if (!(name.equals(SqlKind.SUM.name()) || name.equals(SqlKind.MIN.name()) || name.equals(SqlKind.MAX.name()) || name.equals(SqlKind.COUNT.name()) || name.equals("$SUM0"))) { return false; } } return true; }