Search in sources :

Example 1 with Rule

use of io.trino.sql.planner.iterative.Rule in project trino by trinodb.

the class InlineProjections method extractInliningTargets.

private static Set<Symbol> extractInliningTargets(PlannerContext plannerContext, ProjectNode parent, ProjectNode child, Session session, TypeAnalyzer typeAnalyzer, TypeProvider types) {
    // candidates for inlining are
    // 1. references to simple constants or symbol references
    // 2. references to complex expressions that
    // a. are not inputs to try() expressions
    // b. appear only once across all expressions
    // c. are not identity projections
    // which come from the child, as opposed to an enclosing scope.
    Set<Symbol> childOutputSet = ImmutableSet.copyOf(child.getOutputSymbols());
    Map<Symbol, Long> dependencies = parent.getAssignments().getExpressions().stream().flatMap(expression -> SymbolsExtractor.extractAll(expression).stream()).filter(childOutputSet::contains).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    // find references to simple constants or symbol references
    Set<Symbol> basicReferences = dependencies.keySet().stream().filter(input -> isEffectivelyLiteral(plannerContext, session, child.getAssignments().get(input)) || child.getAssignments().get(input) instanceof SymbolReference).filter(// skip identities, otherwise, this rule will keep firing forever
    input -> !child.getAssignments().isIdentity(input)).collect(toSet());
    // exclude any complex inputs to TRY expressions. Inlining them would potentially
    // change the semantics of those expressions
    Set<Symbol> tryArguments = parent.getAssignments().getExpressions().stream().flatMap(expression -> extractTryArguments(expression).stream()).collect(toSet());
    Set<Symbol> singletons = dependencies.entrySet().stream().filter(// reference appears just once across all expressions in parent project node
    entry -> entry.getValue() == 1).filter(// they are not inputs to TRY. Otherwise, inlining might change semantics
    entry -> !tryArguments.contains(entry.getKey())).filter(// skip identities, otherwise, this rule will keep firing forever
    entry -> !child.getAssignments().isIdentity(entry.getKey())).filter(entry -> {
        // skip dereferences, otherwise, inlining can cause conflicts with PushdownDereferences
        Expression assignment = child.getAssignments().get(entry.getKey());
        if (assignment instanceof SubscriptExpression) {
            if (typeAnalyzer.getType(session, types, ((SubscriptExpression) assignment).getBase()) instanceof RowType) {
                return false;
            }
        }
        return true;
    }).map(Map.Entry::getKey).collect(toSet());
    return Sets.union(singletons, basicReferences);
}
Also used : Function(java.util.function.Function) Capture.newCapture(io.trino.matching.Capture.newCapture) PlanNode(io.trino.sql.planner.plan.PlanNode) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ExpressionSymbolInliner.inlineSymbols(io.trino.sql.planner.ExpressionSymbolInliner.inlineSymbols) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) Rule(io.trino.sql.planner.iterative.Rule) SymbolsExtractor(io.trino.sql.planner.SymbolsExtractor) TryExpression(io.trino.sql.tree.TryExpression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Collectors.toSet(java.util.stream.Collectors.toSet) Symbol(io.trino.sql.planner.Symbol) RowType(io.trino.spi.type.RowType) ImmutableSet(com.google.common.collect.ImmutableSet) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Capture(io.trino.matching.Capture) ExpressionUtils.isEffectivelyLiteral(io.trino.sql.ExpressionUtils.isEffectivelyLiteral) Pattern(io.trino.matching.Pattern) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) AstUtils(io.trino.sql.util.AstUtils) Patterns.source(io.trino.sql.planner.plan.Patterns.source) SymbolReference(io.trino.sql.tree.SymbolReference) Captures(io.trino.matching.Captures) TypeProvider(io.trino.sql.planner.TypeProvider) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) Patterns.project(io.trino.sql.planner.plan.Patterns.project) Session(io.trino.Session) PlannerContext(io.trino.sql.PlannerContext) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) TryExpression(io.trino.sql.tree.TryExpression) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) SymbolReference(io.trino.sql.tree.SymbolReference) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) RowType(io.trino.spi.type.RowType) Map(java.util.Map)

Example 2 with Rule

use of io.trino.sql.planner.iterative.Rule in project trino by trinodb.

the class TestMergeWindows method assertUnitPlan.

private void assertUnitPlan(@Language("SQL") String sql, PlanMatchPattern pattern) {
    List<PlanOptimizer> optimizers = ImmutableList.of(new UnaliasSymbolReferences(getQueryRunner().getMetadata()), new IterativeOptimizer(getQueryRunner().getPlannerContext(), new RuleStatsRecorder(), getQueryRunner().getStatsCalculator(), getQueryRunner().getEstimatedExchangesCostCalculator(), ImmutableSet.<Rule<?>>builder().add(new RemoveRedundantIdentityProjections()).addAll(GatherAndMergeWindows.rules()).addAll(columnPruningRules(getQueryRunner().getMetadata())).build()));
    assertPlan(sql, pattern, optimizers);
}
Also used : RuleStatsRecorder(io.trino.sql.planner.RuleStatsRecorder) RemoveRedundantIdentityProjections(io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections) IterativeOptimizer(io.trino.sql.planner.iterative.IterativeOptimizer) Rule(io.trino.sql.planner.iterative.Rule)

Example 3 with Rule

use of io.trino.sql.planner.iterative.Rule in project trino by trinodb.

the class TestReorderWindows method assertUnitPlan.

private void assertUnitPlan(@Language("SQL") String sql, PlanMatchPattern pattern) {
    List<PlanOptimizer> optimizers = ImmutableList.of(new UnaliasSymbolReferences(getQueryRunner().getMetadata()), new PredicatePushDown(getQueryRunner().getPlannerContext(), createTestingTypeAnalyzer(getQueryRunner().getPlannerContext()), false, false), new IterativeOptimizer(getQueryRunner().getPlannerContext(), new RuleStatsRecorder(), getQueryRunner().getStatsCalculator(), getQueryRunner().getEstimatedExchangesCostCalculator(), ImmutableSet.<Rule<?>>builder().add(new RemoveRedundantIdentityProjections()).add(new GatherAndMergeWindows.SwapAdjacentWindowsBySpecifications(0)).add(new GatherAndMergeWindows.SwapAdjacentWindowsBySpecifications(1)).add(new GatherAndMergeWindows.SwapAdjacentWindowsBySpecifications(2)).addAll(columnPruningRules(getQueryRunner().getMetadata())).build()));
    assertPlan(sql, pattern, optimizers);
}
Also used : GatherAndMergeWindows(io.trino.sql.planner.iterative.rule.GatherAndMergeWindows) RuleStatsRecorder(io.trino.sql.planner.RuleStatsRecorder) RemoveRedundantIdentityProjections(io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections) IterativeOptimizer(io.trino.sql.planner.iterative.IterativeOptimizer) Rule(io.trino.sql.planner.iterative.Rule)

Example 4 with Rule

use of io.trino.sql.planner.iterative.Rule in project trino by trinodb.

the class TestRemoveEmptyDeleteRuleSet method testDoesNotFire.

@Test(dataProvider = "rules")
public void testDoesNotFire(Rule<?> rule) {
    tester().assertThat(rule).on(p -> p.tableDelete(new SchemaTableName("sch", "tab"), p.tableScan(new TableHandle(CONNECTOR_ID, new TpchTableHandle("sf1", "nation", 1.0), TpchTransactionHandle.INSTANCE), ImmutableList.of(), ImmutableMap.of()), p.symbol("a", BigintType.BIGINT))).doesNotFire();
    tester().assertThat(rule).on(p -> p.tableWithExchangeDelete(new SchemaTableName("sch", "tab"), p.tableScan(new TableHandle(CONNECTOR_ID, new TpchTableHandle("sf1", "nation", 1.0), TpchTransactionHandle.INSTANCE), ImmutableList.of(), ImmutableMap.of()), p.symbol("a", BigintType.BIGINT))).doesNotFire();
}
Also used : DataProvider(org.testng.annotations.DataProvider) ImmutableMap(com.google.common.collect.ImmutableMap) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) CONNECTOR_ID(io.trino.sql.planner.iterative.rule.test.RuleTester.CONNECTOR_ID) PlanMatchPattern(io.trino.sql.planner.assertions.PlanMatchPattern) Test(org.testng.annotations.Test) SchemaTableName(io.trino.spi.connector.SchemaTableName) RemoveEmptyDeleteRuleSet.removeEmptyDeleteWithExchangeRule(io.trino.sql.planner.iterative.rule.RemoveEmptyDeleteRuleSet.removeEmptyDeleteWithExchangeRule) TpchTransactionHandle(io.trino.plugin.tpch.TpchTransactionHandle) BigintType(io.trino.spi.type.BigintType) TableHandle(io.trino.metadata.TableHandle) DataProviders.toDataProvider(io.trino.testing.DataProviders.toDataProvider) ImmutableList(com.google.common.collect.ImmutableList) TpchTableHandle(io.trino.plugin.tpch.TpchTableHandle) Rule(io.trino.sql.planner.iterative.Rule) RemoveEmptyDeleteRuleSet.remoteEmptyDeleteRule(io.trino.sql.planner.iterative.rule.RemoveEmptyDeleteRuleSet.remoteEmptyDeleteRule) TableHandle(io.trino.metadata.TableHandle) TpchTableHandle(io.trino.plugin.tpch.TpchTableHandle) SchemaTableName(io.trino.spi.connector.SchemaTableName) TpchTableHandle(io.trino.plugin.tpch.TpchTableHandle) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test)

Aggregations

Rule (io.trino.sql.planner.iterative.Rule)4 ImmutableList (com.google.common.collect.ImmutableList)2 RuleStatsRecorder (io.trino.sql.planner.RuleStatsRecorder)2 IterativeOptimizer (io.trino.sql.planner.iterative.IterativeOptimizer)2 RemoveRedundantIdentityProjections (io.trino.sql.planner.iterative.rule.RemoveRedundantIdentityProjections)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Sets (com.google.common.collect.Sets)1 Session (io.trino.Session)1 Capture (io.trino.matching.Capture)1 Capture.newCapture (io.trino.matching.Capture.newCapture)1 Captures (io.trino.matching.Captures)1 Pattern (io.trino.matching.Pattern)1 TableHandle (io.trino.metadata.TableHandle)1 TpchTableHandle (io.trino.plugin.tpch.TpchTableHandle)1 TpchTransactionHandle (io.trino.plugin.tpch.TpchTransactionHandle)1 SchemaTableName (io.trino.spi.connector.SchemaTableName)1 BigintType (io.trino.spi.type.BigintType)1 RowType (io.trino.spi.type.RowType)1 ExpressionUtils.isEffectivelyLiteral (io.trino.sql.ExpressionUtils.isEffectivelyLiteral)1