Search in sources :

Example 1 with Lookup

use of io.prestosql.sql.planner.iterative.Lookup in project hetu-core by openlookeng.

the class RuleAssert method applyRule.

private RuleApplication applyRule() {
    PlanSymbolAllocator planSymbolAllocator = new PlanSymbolAllocator(types.allTypes());
    Memo memo = new Memo(idAllocator, plan);
    Lookup lookup = Lookup.from(planNode -> Stream.of(memo.resolve(planNode)));
    PlanNode memoRoot = memo.getNode(memo.getRootGroup());
    return inTransaction(session -> applyRule(rule, memoRoot, ruleContext(statsCalculator, costCalculator, planSymbolAllocator, memo, lookup, session)));
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) Lookup(io.prestosql.sql.planner.iterative.Lookup) PlanSymbolAllocator(io.prestosql.sql.planner.PlanSymbolAllocator) Memo(io.prestosql.sql.planner.iterative.Memo)

Example 2 with Lookup

use of io.prestosql.sql.planner.iterative.Lookup in project hetu-core by openlookeng.

the class TableScanStatsRule method doCalculate.

@Override
protected Optional<PlanNodeStatsEstimate> doCalculate(TableScanNode node, StatsProvider sourceStats, Lookup lookup, Session session, TypeProvider types) {
    // TODO Construct predicate like AddExchanges's LayoutConstraintEvaluator
    TupleDomain<ColumnHandle> predicate = metadata.getTableProperties(session, node.getTable()).getPredicate();
    Constraint constraint = new Constraint(predicate);
    TableStatistics tableStatistics = metadata.getTableStatistics(session, node.getTable(), constraint, true);
    verify(tableStatistics != null, "tableStatistics is null for %s", node);
    Map<Symbol, SymbolStatsEstimate> outputSymbolStats = new HashMap<>();
    Map<ColumnHandle, Symbol> remainingSymbols = new HashMap<>();
    Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
    boolean isPredicatesPushDown = false;
    if ((predicate.isAll() || predicate.getDomains().get().equals(node.getEnforcedConstraint().getDomains().get())) && !(node.getEnforcedConstraint().isAll() || node.getEnforcedConstraint().isNone())) {
        predicate = node.getEnforcedConstraint();
        isPredicatesPushDown = true;
        predicate.getDomains().get().entrySet().stream().forEach(e -> {
            remainingSymbols.put(e.getKey(), new Symbol(e.getKey().getColumnName()));
        });
    }
    for (Map.Entry<Symbol, ColumnHandle> entry : node.getAssignments().entrySet()) {
        Symbol symbol = entry.getKey();
        Optional<ColumnStatistics> columnStatistics = Optional.ofNullable(tableStatistics.getColumnStatistics().get(entry.getValue()));
        SymbolStatsEstimate symbolStatistics = columnStatistics.map(statistics -> toSymbolStatistics(tableStatistics, statistics, types.get(symbol))).orElse(SymbolStatsEstimate.unknown());
        outputSymbolStats.put(symbol, symbolStatistics);
        remainingSymbols.remove(entry.getValue());
    }
    PlanNodeStatsEstimate tableEstimates = PlanNodeStatsEstimate.builder().setOutputRowCount(tableStatistics.getRowCount().getValue()).addSymbolStatistics(outputSymbolStats).build();
    if (isPredicatesPushDown) {
        if (remainingSymbols.size() > 0) {
            ImmutableBiMap.Builder<ColumnHandle, Symbol> assignmentBuilder = ImmutableBiMap.builder();
            assignments = assignmentBuilder.putAll(assignments).putAll(remainingSymbols).build();
            for (Map.Entry<ColumnHandle, Symbol> entry : remainingSymbols.entrySet()) {
                Symbol symbol = entry.getValue();
                Optional<ColumnStatistics> columnStatistics = Optional.ofNullable(tableStatistics.getColumnStatistics().get(entry.getKey()));
                SymbolStatsEstimate symbolStatistics = columnStatistics.map(statistics -> toSymbolStatistics(tableStatistics, statistics, types.get(symbol))).orElse(SymbolStatsEstimate.unknown());
                outputSymbolStats.put(symbol, symbolStatistics);
            }
            /* Refresh TableEstimates for remaining columns */
            tableEstimates = PlanNodeStatsEstimate.builder().setOutputRowCount(tableStatistics.getRowCount().getValue()).addSymbolStatistics(outputSymbolStats).build();
        }
        Expression pushDownExpression = domainTranslator.toPredicate(predicate.transform(assignments::get));
        PlanNodeStatsEstimate estimate = filterStatsCalculator.filterStats(tableEstimates, pushDownExpression, session, types);
        if ((isDefaultFilterFactorEnabled(session) || sourceStats.isEnforceDefaultFilterFactor()) && estimate.isOutputRowCountUnknown()) {
            PlanNodeStatsEstimate finalTableEstimates = tableEstimates;
            estimate = tableEstimates.mapOutputRowCount(sourceRowCount -> finalTableEstimates.getOutputRowCount() * UNKNOWN_FILTER_COEFFICIENT);
        }
        return Optional.of(estimate);
    }
    return Optional.of(tableEstimates);
}
Also used : ColumnStatistics(io.prestosql.spi.statistics.ColumnStatistics) TableStatistics(io.prestosql.spi.statistics.TableStatistics) Lookup(io.prestosql.sql.planner.iterative.Lookup) TypeProvider(io.prestosql.sql.planner.TypeProvider) HashMap(java.util.HashMap) Pattern(io.prestosql.matching.Pattern) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) NaN(java.lang.Double.NaN) ExpressionDomainTranslator(io.prestosql.sql.planner.ExpressionDomainTranslator) Verify.verify(com.google.common.base.Verify.verify) FixedWidthType(io.prestosql.spi.type.FixedWidthType) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) Session(io.prestosql.Session) Type(io.prestosql.spi.type.Type) ColumnStatistics(io.prestosql.spi.statistics.ColumnStatistics) Constraint(io.prestosql.spi.connector.Constraint) Symbol(io.prestosql.spi.plan.Symbol) UNKNOWN_FILTER_COEFFICIENT(io.prestosql.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT) TupleDomain(io.prestosql.spi.predicate.TupleDomain) TableScanNode(io.prestosql.spi.plan.TableScanNode) SystemSessionProperties.isDefaultFilterFactorEnabled(io.prestosql.SystemSessionProperties.isDefaultFilterFactorEnabled) Metadata(io.prestosql.metadata.Metadata) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) LiteralEncoder(io.prestosql.sql.planner.LiteralEncoder) Optional(java.util.Optional) Patterns.tableScan(io.prestosql.sql.planner.plan.Patterns.tableScan) Expression(io.prestosql.sql.tree.Expression) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) Constraint(io.prestosql.spi.connector.Constraint) HashMap(java.util.HashMap) Symbol(io.prestosql.spi.plan.Symbol) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) Expression(io.prestosql.sql.tree.Expression) TableStatistics(io.prestosql.spi.statistics.TableStatistics) HashMap(java.util.HashMap) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) Map(java.util.Map)

Example 3 with Lookup

use of io.prestosql.sql.planner.iterative.Lookup in project hetu-core by openlookeng.

the class TopNStatsRule method doCalculate.

@Override
protected Optional<PlanNodeStatsEstimate> doCalculate(TopNNode node, StatsProvider statsProvider, Lookup lookup, Session session, TypeProvider types) {
    PlanNodeStatsEstimate sourceStats = statsProvider.getStats(node.getSource());
    double rowCount = sourceStats.getOutputRowCount();
    if (rowCount <= node.getCount()) {
        return Optional.of(sourceStats);
    }
    long limitCount = node.getCount();
    PlanNodeStatsEstimate resultStats = PlanNodeStatsEstimate.buildFrom(sourceStats).setOutputRowCount(limitCount).build();
    if (limitCount == 0) {
        return Optional.of(resultStats);
    }
    // augment null fraction estimation for first ORDER BY symbol
    // Assuming not empty list
    Symbol firstOrderSymbol = node.getOrderingScheme().getOrderBy().get(0);
    SortOrder sortOrder = node.getOrderingScheme().getOrdering(firstOrderSymbol);
    resultStats = resultStats.mapSymbolColumnStatistics(firstOrderSymbol, symbolStats -> {
        SymbolStatsEstimate.Builder newStats = SymbolStatsEstimate.buildFrom(symbolStats);
        double nullCount = rowCount * symbolStats.getNullsFraction();
        if (sortOrder.isNullsFirst()) {
            if (nullCount > limitCount) {
                newStats.setNullsFraction(1.0);
            } else {
                newStats.setNullsFraction(nullCount / limitCount);
            }
        } else {
            double nonNullCount = (rowCount - nullCount);
            if (nonNullCount > limitCount) {
                newStats.setNullsFraction(0.0);
            } else {
                newStats.setNullsFraction((limitCount - nonNullCount) / limitCount);
            }
        }
        return newStats.build();
    });
    // TopN actually limits (or when there was no row count estimated for source)
    return Optional.of(resultStats);
}
Also used : Symbol(io.prestosql.spi.plan.Symbol) Patterns.topN(io.prestosql.sql.planner.plan.Patterns.topN) Lookup(io.prestosql.sql.planner.iterative.Lookup) TopNNode(io.prestosql.spi.plan.TopNNode) Session(io.prestosql.Session) TypeProvider(io.prestosql.sql.planner.TypeProvider) Optional(java.util.Optional) Pattern(io.prestosql.matching.Pattern) SortOrder(io.prestosql.spi.block.SortOrder) Symbol(io.prestosql.spi.plan.Symbol) SortOrder(io.prestosql.spi.block.SortOrder)

Example 4 with Lookup

use of io.prestosql.sql.planner.iterative.Lookup in project hetu-core by openlookeng.

the class FilterStatsRule method doCalculate.

@Override
public Optional<PlanNodeStatsEstimate> doCalculate(FilterNode node, StatsProvider statsProvider, Lookup lookup, Session session, TypeProvider types) {
    PlanNodeStatsEstimate sourceStats = statsProvider.getStats(node.getSource());
    PlanNodeStatsEstimate estimate;
    if (isExpression(node.getPredicate())) {
        estimate = filterStatsCalculator.filterStats(sourceStats, castToExpression(node.getPredicate()), session, types);
    } else {
        Map<Integer, Symbol> layout = new HashMap<>();
        int channel = 0;
        for (Symbol symbol : node.getSource().getOutputSymbols()) {
            layout.put(channel++, symbol);
        }
        estimate = filterStatsCalculator.filterStats(sourceStats, node.getPredicate(), session, types, layout);
    }
    if ((isDefaultFilterFactorEnabled(session) || statsProvider.isEnforceDefaultFilterFactor()) && estimate.isOutputRowCountUnknown()) {
        estimate = sourceStats.mapOutputRowCount(sourceRowCount -> sourceStats.getOutputRowCount() * UNKNOWN_FILTER_COEFFICIENT);
    }
    return Optional.of(estimate);
}
Also used : Symbol(io.prestosql.spi.plan.Symbol) UNKNOWN_FILTER_COEFFICIENT(io.prestosql.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT) Lookup(io.prestosql.sql.planner.iterative.Lookup) Patterns.filter(io.prestosql.sql.planner.plan.Patterns.filter) TypeProvider(io.prestosql.sql.planner.TypeProvider) HashMap(java.util.HashMap) Pattern(io.prestosql.matching.Pattern) SystemSessionProperties.isDefaultFilterFactorEnabled(io.prestosql.SystemSessionProperties.isDefaultFilterFactorEnabled) OriginalExpressionUtils.isExpression(io.prestosql.sql.relational.OriginalExpressionUtils.isExpression) FilterNode(io.prestosql.spi.plan.FilterNode) Map(java.util.Map) Session(io.prestosql.Session) Optional(java.util.Optional) OriginalExpressionUtils.castToExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToExpression) HashMap(java.util.HashMap) Symbol(io.prestosql.spi.plan.Symbol)

Example 5 with Lookup

use of io.prestosql.sql.planner.iterative.Lookup in project hetu-core by openlookeng.

the class TablePushdown method apply.

@Override
public Result apply(JoinNode node, Captures captures, Context context) {
    uniqueColumnsPerTable = getUniqueColumnTableMap();
    ruleContext = context;
    Lookup lookup = ruleContext.getLookup();
    if (verifyJoinConditions(node, lookup)) {
        LOG.info("Table Pushdown preconditions satisfied.");
        PlanNode rewrittenNode = planRewriter(node, lookup);
        clearAllDataStructures();
        return Result.ofPlanNode(rewrittenNode);
    }
    return Result.empty();
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) Lookup(io.prestosql.sql.planner.iterative.Lookup)

Aggregations

Lookup (io.prestosql.sql.planner.iterative.Lookup)8 Session (io.prestosql.Session)5 PlanNode (io.prestosql.spi.plan.PlanNode)5 Pattern (io.prestosql.matching.Pattern)4 Symbol (io.prestosql.spi.plan.Symbol)4 TypeProvider (io.prestosql.sql.planner.TypeProvider)3 Optional (java.util.Optional)3 SystemSessionProperties.isDefaultFilterFactorEnabled (io.prestosql.SystemSessionProperties.isDefaultFilterFactorEnabled)2 UNKNOWN_FILTER_COEFFICIENT (io.prestosql.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT)2 AggregationNode (io.prestosql.spi.plan.AggregationNode)2 PlanNodeIdAllocator (io.prestosql.spi.plan.PlanNodeIdAllocator)2 PlanSymbolAllocator (io.prestosql.sql.planner.PlanSymbolAllocator)2 Memo (io.prestosql.sql.planner.iterative.Memo)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Verify.verify (com.google.common.base.Verify.verify)1 ImmutableBiMap (com.google.common.collect.ImmutableBiMap)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1