use of io.trino.sql.planner.optimizations.PlanOptimizer in project trino by trinodb.
the class IterativeOptimizer method optimize.
@Override
public PlanNode optimize(PlanNode plan, Session session, TypeProvider types, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator, WarningCollector warningCollector) {
// only disable new rules if we have legacy rules to fall back to
if (useLegacyRules.test(session) && !legacyRules.isEmpty()) {
for (PlanOptimizer optimizer : legacyRules) {
plan = optimizer.optimize(plan, session, symbolAllocator.getTypes(), symbolAllocator, idAllocator, warningCollector);
}
return plan;
}
Memo memo = new Memo(idAllocator, plan);
Lookup lookup = Lookup.from(planNode -> Stream.of(memo.resolve(planNode)));
Duration timeout = SystemSessionProperties.getOptimizerTimeout(session);
Context context = new Context(memo, lookup, idAllocator, symbolAllocator, nanoTime(), timeout.toMillis(), session, warningCollector);
exploreGroup(memo.getRootGroup(), context);
return memo.extract();
}
use of io.trino.sql.planner.optimizations.PlanOptimizer in project trino by trinodb.
the class TestIterativeOptimizer method optimizerTimeoutsOnNonConvergingPlan.
@Test(timeOut = 10_000)
public void optimizerTimeoutsOnNonConvergingPlan() {
PlanOptimizer optimizer = new IterativeOptimizer(queryRunner.getPlannerContext(), new RuleStatsRecorder(), queryRunner.getStatsCalculator(), queryRunner.getCostCalculator(), ImmutableSet.of(new AddIdentityOverTableScan(), new RemoveRedundantIdentityProjections()));
assertTrinoExceptionThrownBy(() -> queryRunner.inTransaction(transactionSession -> queryRunner.createPlan(transactionSession, "SELECT nationkey FROM nation", ImmutableList.of(optimizer), WarningCollector.NOOP))).hasErrorCode(OPTIMIZER_TIMEOUT).hasMessageMatching("The optimizer exhausted the time limit of 1 ms: (no rules invoked|(?s)Top rules:.*(RemoveRedundantIdentityProjections|AddIdentityOverTableScan).*)");
}
use of io.trino.sql.planner.optimizations.PlanOptimizer in project trino by trinodb.
the class BasePlanTest method assertMinimallyOptimizedPlan.
protected void assertMinimallyOptimizedPlan(@Language("SQL") String sql, PlanMatchPattern pattern) {
List<PlanOptimizer> optimizers = ImmutableList.of(new UnaliasSymbolReferences(getQueryRunner().getMetadata()), new IterativeOptimizer(queryRunner.getPlannerContext(), new RuleStatsRecorder(), queryRunner.getStatsCalculator(), queryRunner.getCostCalculator(), ImmutableSet.<Rule<?>>builder().add(new RemoveRedundantIdentityProjections()).addAll(columnPruningRules(getQueryRunner().getMetadata())).build()));
assertPlan(sql, OPTIMIZED, pattern, optimizers);
}
use of io.trino.sql.planner.optimizations.PlanOptimizer in project trino by trinodb.
the class LogicalPlanner method plan.
public Plan plan(Analysis analysis, Stage stage, boolean collectPlanStatistics) {
PlanNode root = planStatement(analysis, analysis.getStatement());
if (LOG.isDebugEnabled()) {
LOG.debug("Initial plan:\n%s", PlanPrinter.textLogicalPlan(root, symbolAllocator.getTypes(), metadata, plannerContext.getFunctionManager(), StatsAndCosts.empty(), session, 0, false));
}
planSanityChecker.validateIntermediatePlan(root, session, plannerContext, typeAnalyzer, symbolAllocator.getTypes(), warningCollector);
if (stage.ordinal() >= OPTIMIZED.ordinal()) {
for (PlanOptimizer optimizer : planOptimizers) {
root = optimizer.optimize(root, session, symbolAllocator.getTypes(), symbolAllocator, idAllocator, warningCollector);
requireNonNull(root, format("%s returned a null plan", optimizer.getClass().getName()));
if (LOG.isDebugEnabled()) {
LOG.debug("%s:\n%s", optimizer.getClass().getName(), PlanPrinter.textLogicalPlan(root, symbolAllocator.getTypes(), metadata, plannerContext.getFunctionManager(), StatsAndCosts.empty(), session, 0, false));
}
}
}
if (stage.ordinal() >= OPTIMIZED_AND_VALIDATED.ordinal()) {
// make sure we produce a valid plan after optimizations run. This is mainly to catch programming errors
planSanityChecker.validateFinalPlan(root, session, plannerContext, typeAnalyzer, symbolAllocator.getTypes(), warningCollector);
}
TypeProvider types = symbolAllocator.getTypes();
StatsAndCosts statsAndCosts = StatsAndCosts.empty();
if (collectPlanStatistics) {
StatsProvider statsProvider = new CachingStatsProvider(statsCalculator, session, types);
CostProvider costProvider = new CachingCostProvider(costCalculator, statsProvider, Optional.empty(), session, types);
statsAndCosts = StatsAndCosts.create(root, statsProvider, costProvider);
}
return new Plan(root, types, statsAndCosts);
}
Aggregations