org.apache.calcite.plan.RelOptPlanner Java Examples

The following examples show how to use org.apache.calcite.plan.RelOptPlanner. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: FilterRelBase.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery relMetadataQuery) {
  if ((hasContains && !canHaveContains()) || hasFlatten) {
    return planner.getCostFactory().makeInfiniteCost();
  }

  if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner).multiplyBy(.1);
  }

  RelNode child = this.getInput();
  double inputRows = relMetadataQuery.getRowCount(child);
  double cpuCost = estimateCpuCost(relMetadataQuery);
  Factory costFactory = (Factory)planner.getCostFactory();
  return costFactory.makeCost(inputRows, cpuCost, 0, 0);
}
 
Example #2
Source File: Programs.java    From Bats with Apache License 2.0 6 votes vote down vote up
public RelNode run(RelOptPlanner planner, RelNode rel,
    RelTraitSet requiredOutputTraits,
    List<RelOptMaterialization> materializations,
    List<RelOptLattice> lattices) {
  planner.clear();
  for (RelOptRule rule : ruleSet) {
    planner.addRule(rule);
  }
  for (RelOptMaterialization materialization : materializations) {
    planner.addMaterialization(materialization);
  }
  for (RelOptLattice lattice : lattices) {
    planner.addLattice(lattice);
  }
  if (!rel.getTraitSet().equals(requiredOutputTraits)) {
    rel = planner.changeTraits(rel, requiredOutputTraits);
  }
  planner.setRoot(rel);
  return planner.findBestExp();

}
 
Example #3
Source File: ResultProcessor.java    From quark with Apache License 2.0 6 votes vote down vote up
public static String getParsedSql(RelNode relNode, SqlDialect dialect) throws SQLException {
  if (dialect.getDatabaseProduct() == SqlDialect.DatabaseProduct.HIVE) {
    final HepProgram program = new HepProgramBuilder()
        .addRuleInstance(JoinCalcTransposeRule.LEFT_CALC)
        .addRuleInstance(JoinCalcTransposeRule.RIGHT_CALC)
        .addRuleInstance(CalcMergeRule.INSTANCE)
        .build();
    final RelOptPlanner planner = relNode.getCluster().getPlanner();
    final HepPlanner hepPlanner =
        new HepPlanner(program, planner.getContext());
    hepPlanner.setRoot(relNode);
    relNode = hepPlanner.findBestExp();
  }
  RelToSqlConverter relToSqlConverter = new RelToSqlConverter(dialect);
  RelToSqlConverter.Result res = relToSqlConverter.visitChild(0, relNode);
  SqlNode sqlNode = res.asQuery();
  String result = sqlNode.toSqlString(dialect, false).getSql();
  return result.replace("\n", " ");
}
 
Example #4
Source File: DrillAggregateRel.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  for (AggregateCall aggCall : getAggCallList()) {
    String name = aggCall.getAggregation().getName();
    // For avg, stddev_pop, stddev_samp, var_pop and var_samp, the ReduceAggregatesRule is supposed
    // to convert them to use sum and count. Here, we make the cost of the original functions high
    // enough such that the planner does not choose them and instead chooses the rewritten functions.
    // Except when AVG, STDDEV_POP, STDDEV_SAMP, VAR_POP and VAR_SAMP are used with DECIMAL type.
    if ((name.equals(SqlKind.AVG.name())
          || name.equals(SqlKind.STDDEV_POP.name())
          || name.equals(SqlKind.STDDEV_SAMP.name())
          || name.equals(SqlKind.VAR_POP.name())
          || name.equals(SqlKind.VAR_SAMP.name()))
        && aggCall.getType().getSqlTypeName() != SqlTypeName.DECIMAL) {
      return planner.getCostFactory().makeHugeCost();
    }
  }

  return computeLogicalAggCost(planner, mq);
}
 
Example #5
Source File: LocalJobsService.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public void planRelTransform(PlannerPhase phase, RelOptPlanner planner, RelNode before, RelNode after, long millisTaken) {
  planTransformationListener.onPhaseCompletion(phase, before, after, millisTaken);
  switch(phase){
  case LOGICAL:
    builder.addLogicalPlan(before, after);
    // set final pre-accelerated cost
    final RelOptCost cost = after.getCluster().getMetadataQuery().getCumulativeCost(after);
    builder.addCost(cost);
    break;
  case JOIN_PLANNING_MULTI_JOIN:
    // Join planning starts with multi-join analysis phase
    builder.addPreJoinPlan(before);
    break;
  default:
    return;
  }
}
 
Example #6
Source File: SortPrel.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery relMetadataQuery) {
  if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    //We use multiplier 0.05 for TopN operator, and 0.1 for Sort, to make TopN a preferred choice.
    return super.computeSelfCost(planner).multiplyBy(.1);
  }

  RelNode child = this.getInput();
  double inputRows = relMetadataQuery.getRowCount(child);
  // int  rowWidth = child.getRowType().getPrecision();
  int numSortFields = this.collation.getFieldCollations().size();
  double cpuCost = DremioCost.COMPARE_CPU_COST * numSortFields * inputRows * (Math.log(inputRows)/Math.log(2));
  double diskIOCost = 0; // assume in-memory for now until we enforce operator-level memory constraints

  // TODO: use rowWidth instead of avgFieldWidth * numFields
  // avgFieldWidth * numFields * inputRows
  double numFields = this.getRowType().getFieldCount();
  long fieldWidth = PrelUtil.getPlannerSettings(planner).getOptions()
    .getOption(ExecConstants.AVERAGE_FIELD_WIDTH_KEY).getNumVal();

  double memCost = fieldWidth * numFields * inputRows;

  Factory costFactory = (Factory) planner.getCostFactory();
  return costFactory.makeCost(inputRows, cpuCost, diskIOCost, 0, memCost);
}
 
Example #7
Source File: PlanCaptureAttemptObserver.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
private String getPlanDump(RelOptPlanner planner) {
  if (planner == null) {
    return null;
  }

  // Use VolcanoPlanner#dump to get more detailed information
  if (planner instanceof VolcanoPlanner) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    ((VolcanoPlanner) planner).dump(pw);
    pw.flush();
    return sw.toString();
  }

  // Print the current tree otherwise
  RelNode root = planner.getRoot();
  return RelOptUtil.toString(root);
}
 
Example #8
Source File: RangePartitionExchangePrel.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner).multiplyBy(.1);
  }
  RelNode child = this.getInput();
  double inputRows = (mq == null)? ROWCOUNT_UNKNOWN : mq.getRowCount(child);

  // int  rowWidth = child.getRowType().getFieldCount() * DrillCostBase.AVG_FIELD_WIDTH;

  /* NOTE: the Exchange costing in general has to be examined in a broader context. A RangePartitionExchange
   * may be added for index plans with RowJeyJoin and Calcite compares the cost of this sub-plan with a
   * full table scan (FTS) sub-plan without an exchange.  The RelSubSet would have Filter-Project-TableScan for
   * the FTS and a RowKeyJoin whose right input is a RangePartitionExchange-IndexScan. Although a final UnionExchange
   * is done for both plans, the intermediate costing of index plan with exchange makes it more expensive than the FTS
   * sub-plan, even though the final cost of the overall FTS would have been more expensive.
   */

  // commenting out following based on comments above
  // double rangePartitionCpuCost = DrillCostBase.RANGE_PARTITION_CPU_COST * inputRows;
  // double svrCpuCost = DrillCostBase.SVR_CPU_COST * inputRows;
  // double networkCost = DrillCostBase.BYTE_NETWORK_COST * inputRows * rowWidth;
  DrillCostFactory costFactory = (DrillCostFactory)planner.getCostFactory();
  return costFactory.makeCost(inputRows, 0, 0, 0 /* see comments above */);
}
 
Example #9
Source File: EnumerableCorrelateTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** Test case for
 * <a href="https://issues.apache.org/jira/browse/CALCITE-2605">[CALCITE-2605]
 * NullPointerException when left outer join implemented with EnumerableCorrelate</a> */
@Test void leftOuterJoinCorrelate() {
  tester(false, new JdbcTest.HrSchema())
      .query(
          "select e.empid, e.name, d.name as dept from emps e left outer join depts d on e.deptno=d.deptno")
      .withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
        // force the left outer join to run via EnumerableCorrelate
        // instead of EnumerableHashJoin
        planner.addRule(JoinToCorrelateRule.INSTANCE);
        planner.removeRule(EnumerableRules.ENUMERABLE_JOIN_RULE);
      })
      .explainContains(""
          + "EnumerableCalc(expr#0..4=[{inputs}], empid=[$t0], name=[$t2], dept=[$t4])\n"
          + "  EnumerableCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{1}])\n"
          + "    EnumerableCalc(expr#0..4=[{inputs}], proj#0..2=[{exprs}])\n"
          + "      EnumerableTableScan(table=[[s, emps]])\n"
          + "    EnumerableCalc(expr#0..3=[{inputs}], expr#4=[$cor0], expr#5=[$t4.deptno], expr#6=[=($t5, $t0)], proj#0..1=[{exprs}], $condition=[$t6])\n"
          + "      EnumerableTableScan(table=[[s, depts]])")
      .returnsUnordered(
          "empid=100; name=Bill; dept=Sales",
          "empid=110; name=Theodore; dept=Sales",
          "empid=150; name=Sebastian; dept=Sales",
          "empid=200; name=Eric; dept=null");
}
 
Example #10
Source File: EnumerableBatchNestedLoopJoinTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void simpleInnerBatchJoinTestBuilder() {
  tester(false, new JdbcTest.HrSchema())
      .query("?")
      .withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
        planner.removeRule(EnumerableRules.ENUMERABLE_CORRELATE_RULE);
        planner.addRule(EnumerableRules.ENUMERABLE_BATCH_NESTED_LOOP_JOIN_RULE);
      })
      .withRel(
          builder -> builder
              .scan("s", "depts").as("d")
              .scan("s", "emps").as("e")
              .join(JoinRelType.INNER,
                  builder.equals(
                      builder.field(2, "d", "deptno"),
                      builder.field(2, "e", "deptno")))
              .project(
                  builder.field("deptno"))
              .build())
      .returnsUnordered(
          "deptno=10",
          "deptno=10",
          "deptno=10");
}
 
Example #11
Source File: HashToRandomExchangePrel.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * HashToRandomExchange processes M input rows and hash partitions them
 * based on computing a hash value on the distribution fields.
 * If there are N nodes (endpoints), we can assume for costing purposes
 * on average each sender will send M/N rows to 1 destination endpoint.
 * (See DrillCostBase for symbol notations)
 * Include impact of skewness of distribution : the more keys used, the less likely the distribution will be skewed.
 * The hash cpu cost will be proportional to 1 / #_keys.
 * C =  CPU cost of hashing k fields of M/N rows
 *      + CPU cost of SV remover for M/N rows
 *      + Network cost of sending M/N rows to 1 destination.
 * So, C = (h * 1/k * M/N) + (s * M/N) + (w * M/N)
 * Total cost = N * C
 */
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner, mq).multiplyBy(.1);
  }

  RelNode child = this.getInput();
  double inputRows = mq.getRowCount(child);

  int rowWidth = child.getRowType().getFieldCount() * DrillCostBase.AVG_FIELD_WIDTH;

  double hashCpuCost = DrillCostBase.HASH_CPU_COST * inputRows / fields.size();
  double svrCpuCost = DrillCostBase.SVR_CPU_COST * inputRows;
  double networkCost = DrillCostBase.BYTE_NETWORK_COST * inputRows * rowWidth;
  DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory();
  return costFactory.makeCost(inputRows, hashCpuCost + svrCpuCost, 0, networkCost);
}
 
Example #12
Source File: PrelTransformer.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
private static RelNode doTransform(SqlHandlerConfig config, final PlannerType plannerType, final PlannerPhase phase, final RelOptPlanner planner, final RelNode input, boolean log, Supplier<RelNode> toPlan) {
  final Stopwatch watch = Stopwatch.createStarted();

  try {
    final RelNode output = toPlan.get();

    if (log) {
      log(plannerType, phase, output, logger, watch);
      config.getObserver().planRelTransform(phase, planner, input, output, watch.elapsed(TimeUnit.MILLISECONDS));
    }

    CALCITE_LOGGER.trace("Completed Phase: {}.", phase);

    return output;
  } catch (Throwable t) {
    // log our input state as oput anyway so we can ensure that we have details.
    try {
      log(plannerType, phase, input, logger, watch);
      config.getObserver().planRelTransform(phase, planner, input, input, watch.elapsed(TimeUnit.MILLISECONDS));
    } catch (Throwable unexpected) {
      t.addSuppressed(unexpected);
    }
    throw t;
  }
}
 
Example #13
Source File: EnumerableMergeJoin.java    From calcite with Apache License 2.0 5 votes vote down vote up
@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);
}
 
Example #14
Source File: TableScan.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public RelOptCost computeSelfCost(RelOptPlanner planner,
    RelMetadataQuery mq) {
  double dRows = table.getRowCount();
  double dCpu = dRows + 1; // ensure non-zero cost
  double dIo = 0;
  return planner.getCostFactory().makeCost(dRows, dCpu, dIo);
}
 
Example #15
Source File: CalcitePrepareImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
<T> CalciteSignature<T> prepare_(
    Context context,
    Query<T> query,
    Type elementType,
    long maxRowCount) {
  if (SIMPLE_SQLS.contains(query.sql)) {
    return simplePrepare(context, query.sql);
  }
  final JavaTypeFactory typeFactory = context.getTypeFactory();
  CalciteCatalogReader catalogReader =
      new CalciteCatalogReader(
          context.getRootSchema(),
          context.getDefaultSchemaPath(),
          typeFactory,
          context.config());
  final List<Function1<Context, RelOptPlanner>> plannerFactories =
      createPlannerFactories();
  if (plannerFactories.isEmpty()) {
    throw new AssertionError("no planner factories");
  }
  RuntimeException exception = Util.FoundOne.NULL;
  for (Function1<Context, RelOptPlanner> plannerFactory : plannerFactories) {
    final RelOptPlanner planner = plannerFactory.apply(context);
    if (planner == null) {
      throw new AssertionError("factory returned null planner");
    }
    try {
      return prepare2_(context, query, elementType, maxRowCount,
          catalogReader, planner);
    } catch (RelOptPlanner.CannotPlanException e) {
      exception = e;
    }
  }
  throw exception;
}
 
Example #16
Source File: DrillLimitRelBase.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner, mq).multiplyBy(.1);
  }

  double numRows = estimateRowCount(mq);
  double cpuCost = DrillCostBase.COMPARE_CPU_COST * numRows;
  DrillCostFactory costFactory = (DrillCostFactory)planner.getCostFactory();
  return costFactory.makeCost(numRows, cpuCost, 0, 0);
}
 
Example #17
Source File: LimitRelBase.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner).multiplyBy(.1);
  }

  double numRows = mq.getRowCount(this);
  double cpuCost = DremioCost.COMPARE_CPU_COST * numRows;
  Factory costFactory = (Factory)planner.getCostFactory();
  return costFactory.makeCost(numRows, cpuCost, 0, 0);
}
 
Example #18
Source File: DrillAggregateRelBase.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Estimate cost of hash agg. Called by DrillAggregateRel.computeSelfCost() and HashAggPrel.computeSelfCost()
*/
protected RelOptCost computeHashAggCost(RelOptPlanner planner, RelMetadataQuery mq) {
  if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    return super.computeSelfCost(planner, mq).multiplyBy(.1);
  }
  RelNode child = this.getInput();
  double inputRows = mq.getRowCount(child);

  int numGroupByFields = this.getGroupCount();
  int numAggrFields = this.aggCalls.size();
  // cpu cost of hashing each grouping key
  double cpuCost = DrillCostBase.HASH_CPU_COST * numGroupByFields * inputRows;
  // add cpu cost for computing the aggregate functions
  cpuCost += DrillCostBase.FUNC_CPU_COST * numAggrFields * inputRows;
  double diskIOCost = 0; // assume in-memory for now until we enforce operator-level memory constraints

  // TODO: use distinct row count
  // + hash table template stuff
  double factor = PrelUtil.getPlannerSettings(planner).getOptions()
      .getOption(ExecConstants.HASH_AGG_TABLE_FACTOR_KEY).float_val;
  long fieldWidth = PrelUtil.getPlannerSettings(planner).getOptions()
      .getOption(ExecConstants.AVERAGE_FIELD_WIDTH_KEY).num_val;

  // table + hashValues + links
  double memCost =
      (
          (fieldWidth * numGroupByFields) +
              IntHolder.WIDTH +
              IntHolder.WIDTH
      ) * inputRows * factor;

  DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory();
  return costFactory.makeCost(inputRows, cpuCost, diskIOCost, 0 /* network cost */, memCost);

}
 
Example #19
Source File: PlannerContext.java    From flink with Apache License 2.0 5 votes vote down vote up
public PlannerContext(
		TableConfig tableConfig,
		FunctionCatalog functionCatalog,
		CatalogManager catalogManager,
		CalciteSchema rootSchema,
		List<RelTraitDef> traitDefs) {
	this.tableConfig = tableConfig;

	this.context = new FlinkContextImpl(
			tableConfig,
			functionCatalog,
			catalogManager,
			this::createSqlExprToRexConverter);

	this.rootSchema = rootSchema;
	this.traitDefs = traitDefs;
	// Make a framework config to initialize the RelOptCluster instance,
	// caution that we can only use the attributes that can not be overwrite/configured
	// by user.
	this.frameworkConfig = createFrameworkConfig();

	RelOptPlanner planner = new VolcanoPlanner(frameworkConfig.getCostFactory(), frameworkConfig.getContext());
	planner.setExecutor(frameworkConfig.getExecutor());
	for (RelTraitDef traitDef : frameworkConfig.getTraitDefs()) {
		planner.addRelTraitDef(traitDef);
	}
	this.cluster = FlinkRelOptClusterFactory.create(planner, new RexBuilder(typeFactory));
}
 
Example #20
Source File: DrillUnnestRelBase.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {

  double rowCount = mq.getRowCount(this);
  // Attribute small cost for projecting simple fields. In reality projecting simple columns in not free and
  // this allows projection pushdown/project-merge rules to kick-in thereby eliminating unneeded columns from
  // the projection.
  double cpuCost = DrillCostBase.BASE_CPU_COST * rowCount * this.getRowType().getFieldCount();

  DrillCostBase.DrillCostFactory costFactory = (DrillCostBase.DrillCostFactory) planner.getCostFactory();
  return costFactory.makeCost(rowCount, cpuCost, 0, 0);
}
 
Example #21
Source File: Programs.java    From calcite with Apache License 2.0 5 votes vote down vote up
public RelNode run(RelOptPlanner planner, RelNode rel,
    RelTraitSet requiredOutputTraits,
    List<RelOptMaterialization> materializations,
    List<RelOptLattice> lattices) {
  final RelBuilder relBuilder =
      RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null);
  return new RelFieldTrimmer(null, relBuilder).trim(rel);
}
 
Example #22
Source File: Programs.java    From Bats with Apache License 2.0 5 votes vote down vote up
public RelNode run(RelOptPlanner planner, RelNode rel,
    RelTraitSet requiredOutputTraits,
    List<RelOptMaterialization> materializations,
    List<RelOptLattice> lattices) {
  final CalciteConnectionConfig config =
      planner.getContext().unwrap(CalciteConnectionConfig.class);
  if (config != null && config.forceDecorrelate()) {
    final RelBuilder relBuilder =
        RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null);
    return RelDecorrelator.decorrelateQuery(rel, relBuilder);
  }
  return rel;
}
 
Example #23
Source File: Values.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public RelOptCost computeSelfCost(RelOptPlanner planner,
    RelMetadataQuery mq) {
  double dRows = mq.getRowCount(this);

  // Assume CPU is negligible since values are precomputed.
  double dCpu = 1;
  double dIo = 0;
  return planner.getCostFactory().makeCost(dRows, dCpu, dIo);
}
 
Example #24
Source File: GeodeSort.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public RelOptCost computeSelfCost(RelOptPlanner planner,
    RelMetadataQuery mq) {

  RelOptCost cost = super.computeSelfCost(planner, mq);

  if (fetch != null) {
    return cost.multiplyBy(0.05);
  } else {
    return cost.multiplyBy(0.9);
  }
}
 
Example #25
Source File: MongoTableScan.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public RelOptCost computeSelfCost(RelOptPlanner planner,
    RelMetadataQuery mq) {
  // scans with a small project list are cheaper
  final float f = projectRowType == null ? 1f
      : (float) projectRowType.getFieldCount() / 100f;
  return super.computeSelfCost(planner, mq).multiplyBy(.1 * f);
}
 
Example #26
Source File: TopNPrel.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Cost of doing Top-N is proportional to M log N where M is the total number of
 * input rows and N is the limit for Top-N.  This makes Top-N preferable to Sort
 * since cost of full Sort is proportional to M log M .
 */
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery relMetadataQuery) {
  if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
    //We use multiplier 0.05 for TopN operator, and 0.1 for Sort, to make TopN a preferred choice.
    return super.computeSelfCost(planner).multiplyBy(0.05);
  }
  RelNode child = this.getInput();
  double inputRows = relMetadataQuery.getRowCount(child);
  int numSortFields = this.collation.getFieldCollations().size();
  double cpuCost = DremioCost.COMPARE_CPU_COST * numSortFields * inputRows * (Math.log(limit)/Math.log(2));
  double diskIOCost = 0; // assume in-memory for now until we enforce operator-level memory constraints
  Factory costFactory = (Factory)planner.getCostFactory();
  return costFactory.makeCost(inputRows, cpuCost, diskIOCost, 0);
}
 
Example #27
Source File: MockRelOptPlanner.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a MockRuleCall.
 *
 * @param planner Planner
 * @param operand Operand
 * @param rels    List of matched relational expressions
 */
MockRuleCall(
    RelOptPlanner planner,
    RelOptRuleOperand operand,
    RelNode[] rels) {
  super(
      planner,
      operand,
      rels,
      Collections.emptyMap());
}
 
Example #28
Source File: SparkHandlerImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
public RelNode flattenTypes(RelOptPlanner planner, RelNode rootRel,
    boolean restructure) {
  RelNode root2 =
      planner.changeTraits(rootRel,
          rootRel.getTraitSet().plus(SparkRel.CONVENTION).simplify());
  return planner.changeTraits(root2, rootRel.getTraitSet().simplify());
}
 
Example #29
Source File: DrillJoinRelBase.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
  JoinCategory category = JoinUtils.getJoinCategory(left, right, condition, leftKeys, rightKeys, filterNulls);
  if (category == JoinCategory.CARTESIAN || category == JoinCategory.INEQUALITY) {
    if (PrelUtil.getPlannerSettings(planner).isNestedLoopJoinEnabled()) {
      if (PrelUtil.getPlannerSettings(planner).isNlJoinForScalarOnly()) {
        if (JoinUtils.hasScalarSubqueryInput(left, right)) {
          return computeLogicalJoinCost(planner, mq);
        } else {
          /*
           *  Why do we return non-infinite cost for CartsianJoin with non-scalar subquery, when LOPT planner is enabled?
           *   - We do not want to turn on the two Join permutation rule : PushJoinPastThroughJoin.LEFT, RIGHT.
           *   - As such, we may end up with filter on top of join, which will cause CanNotPlan in LogicalPlanning, if we
           *   return infinite cost.
           *   - Such filter on top of join might be pushed into JOIN, when LOPT planner is called.
           *   - Return non-infinite cost will give LOPT planner a chance to try to push the filters.
           */
          if (PrelUtil.getPlannerSettings(planner).isHepOptEnabled()) {
           return computeCartesianJoinCost(planner, mq);
          } else {
            return planner.getCostFactory().makeInfiniteCost();
          }
        }
      } else {
        return computeLogicalJoinCost(planner, mq);
      }
    }
    return planner.getCostFactory().makeInfiniteCost();
  }

  return computeLogicalJoinCost(planner, mq);
}
 
Example #30
Source File: EnumerableBatchNestedLoopJoinTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void simpleInnerBatchJoinTestSQL() {
  tester(false, new JdbcTest.HrSchema())
      .query(
          "select e.name from emps e join depts d on d.deptno = e.deptno")
      .withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
        planner.removeRule(EnumerableRules.ENUMERABLE_CORRELATE_RULE);
        planner.addRule(EnumerableRules.ENUMERABLE_BATCH_NESTED_LOOP_JOIN_RULE);
      })
      .returnsUnordered("name=Bill",
          "name=Sebastian",
          "name=Theodore");
}