Search in sources :

Example 1 with PlanOptimizer

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();
}
Also used : PlannerContext(io.trino.sql.PlannerContext) PlanOptimizer(io.trino.sql.planner.optimizations.PlanOptimizer) Duration(io.airlift.units.Duration)

Example 2 with PlanOptimizer

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).*)");
}
Also used : AfterClass(org.testng.annotations.AfterClass) ImmutableSet(com.google.common.collect.ImmutableSet) RemoveRedundantIdentityProjections(io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeClass(org.testng.annotations.BeforeClass) Assignments(io.trino.sql.planner.plan.Assignments) Test(org.testng.annotations.Test) Patterns.tableScan(io.trino.sql.planner.plan.Patterns.tableScan) TrinoExceptionAssert.assertTrinoExceptionThrownBy(io.trino.testing.assertions.TrinoExceptionAssert.assertTrinoExceptionThrownBy) RuleStatsRecorder(io.trino.sql.planner.RuleStatsRecorder) TestingSession.testSessionBuilder(io.trino.testing.TestingSession.testSessionBuilder) Pattern(io.trino.matching.Pattern) ImmutableList(com.google.common.collect.ImmutableList) Captures(io.trino.matching.Captures) TpchConnectorFactory(io.trino.plugin.tpch.TpchConnectorFactory) PlanOptimizer(io.trino.sql.planner.optimizations.PlanOptimizer) LocalQueryRunner(io.trino.testing.LocalQueryRunner) WarningCollector(io.trino.execution.warnings.WarningCollector) ProjectNode(io.trino.sql.planner.plan.ProjectNode) TableScanNode(io.trino.sql.planner.plan.TableScanNode) OPTIMIZER_TIMEOUT(io.trino.spi.StandardErrorCode.OPTIMIZER_TIMEOUT) Session(io.trino.Session) PlanOptimizer(io.trino.sql.planner.optimizations.PlanOptimizer) RuleStatsRecorder(io.trino.sql.planner.RuleStatsRecorder) RemoveRedundantIdentityProjections(io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections) Test(org.testng.annotations.Test)

Example 3 with PlanOptimizer

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);
}
Also used : PlanOptimizer(io.trino.sql.planner.optimizations.PlanOptimizer) RuleStatsRecorder(io.trino.sql.planner.RuleStatsRecorder) RemoveRedundantIdentityProjections(io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections) IterativeOptimizer(io.trino.sql.planner.iterative.IterativeOptimizer) UnaliasSymbolReferences(io.trino.sql.planner.optimizations.UnaliasSymbolReferences)

Example 4 with PlanOptimizer

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);
}
Also used : PlanOptimizer(io.trino.sql.planner.optimizations.PlanOptimizer) CachingStatsProvider(io.trino.cost.CachingStatsProvider) PlanNode(io.trino.sql.planner.plan.PlanNode) CachingStatsProvider(io.trino.cost.CachingStatsProvider) StatsProvider(io.trino.cost.StatsProvider) StatsAndCosts(io.trino.cost.StatsAndCosts) CachingCostProvider(io.trino.cost.CachingCostProvider) CostProvider(io.trino.cost.CostProvider) CachingCostProvider(io.trino.cost.CachingCostProvider)

Aggregations

PlanOptimizer (io.trino.sql.planner.optimizations.PlanOptimizer)4 RuleStatsRecorder (io.trino.sql.planner.RuleStatsRecorder)2 RemoveRedundantIdentityProjections (io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Duration (io.airlift.units.Duration)1 Session (io.trino.Session)1 CachingCostProvider (io.trino.cost.CachingCostProvider)1 CachingStatsProvider (io.trino.cost.CachingStatsProvider)1 CostProvider (io.trino.cost.CostProvider)1 StatsAndCosts (io.trino.cost.StatsAndCosts)1 StatsProvider (io.trino.cost.StatsProvider)1 WarningCollector (io.trino.execution.warnings.WarningCollector)1 Captures (io.trino.matching.Captures)1 Pattern (io.trino.matching.Pattern)1 TpchConnectorFactory (io.trino.plugin.tpch.TpchConnectorFactory)1 OPTIMIZER_TIMEOUT (io.trino.spi.StandardErrorCode.OPTIMIZER_TIMEOUT)1 PlannerContext (io.trino.sql.PlannerContext)1 IterativeOptimizer (io.trino.sql.planner.iterative.IterativeOptimizer)1