Search in sources :

Example 11 with PlanNodeIdAllocator

use of com.facebook.presto.spi.plan.PlanNodeIdAllocator in project presto by prestodb.

the class PickTableLayout method pushPredicateIntoTableScan.

/**
 * For RowExpression {@param predicate}
 */
private static PlanNode pushPredicateIntoTableScan(TableScanNode node, RowExpression predicate, boolean pruneWithPredicateExpression, Session session, PlanNodeIdAllocator idAllocator, Metadata metadata, DomainTranslator domainTranslator) {
    // don't include non-deterministic predicates
    LogicalRowExpressions logicalRowExpressions = new LogicalRowExpressions(new RowExpressionDeterminismEvaluator(metadata.getFunctionAndTypeManager()), new FunctionResolution(metadata.getFunctionAndTypeManager()), metadata.getFunctionAndTypeManager());
    RowExpression deterministicPredicate = logicalRowExpressions.filterDeterministicConjuncts(predicate);
    DomainTranslator.ExtractionResult<VariableReferenceExpression> decomposedPredicate = domainTranslator.fromPredicate(session.toConnectorSession(), deterministicPredicate, BASIC_COLUMN_EXTRACTOR);
    TupleDomain<ColumnHandle> newDomain = decomposedPredicate.getTupleDomain().transform(variableName -> node.getAssignments().get(variableName)).intersect(node.getEnforcedConstraint());
    Map<ColumnHandle, VariableReferenceExpression> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
    Constraint<ColumnHandle> constraint;
    if (pruneWithPredicateExpression) {
        LayoutConstraintEvaluatorForRowExpression evaluator = new LayoutConstraintEvaluatorForRowExpression(metadata, session, node.getAssignments(), logicalRowExpressions.combineConjuncts(deterministicPredicate, // which would be expensive to evaluate in the call to isCandidate below.
        domainTranslator.toPredicate(newDomain.simplify().transform(column -> assignments.getOrDefault(column, null)))));
        constraint = new Constraint<>(newDomain, evaluator::isCandidate);
    } else {
        // Currently, invoking the expression interpreter is very expensive.
        // TODO invoke the interpreter unconditionally when the interpreter becomes cheap enough.
        constraint = new Constraint<>(newDomain);
    }
    if (constraint.getSummary().isNone()) {
        return new ValuesNode(node.getSourceLocation(), idAllocator.getNextId(), node.getOutputVariables(), ImmutableList.of());
    }
    // Layouts will be returned in order of the connector's preference
    TableLayoutResult layout = metadata.getLayout(session, node.getTable(), constraint, Optional.of(node.getOutputVariables().stream().map(variable -> node.getAssignments().get(variable)).collect(toImmutableSet())));
    if (layout.getLayout().getPredicate().isNone()) {
        return new ValuesNode(node.getSourceLocation(), idAllocator.getNextId(), node.getOutputVariables(), ImmutableList.of());
    }
    TableScanNode tableScan = new TableScanNode(node.getSourceLocation(), node.getId(), layout.getLayout().getNewTableHandle(), node.getOutputVariables(), node.getAssignments(), layout.getLayout().getPredicate(), computeEnforced(newDomain, layout.getUnenforcedConstraint()));
    // The order of the arguments to combineConjuncts matters:
    // * Unenforced constraints go first because they can only be simple column references,
    // which are not prone to logic errors such as out-of-bound access, div-by-zero, etc.
    // * Conjuncts in non-deterministic expressions and non-TupleDomain-expressible expressions should
    // retain their original (maybe intermixed) order from the input predicate. However, this is not implemented yet.
    // * Short of implementing the previous bullet point, the current order of non-deterministic expressions
    // and non-TupleDomain-expressible expressions should be retained. Changing the order can lead
    // to failures of previously successful queries.
    RowExpression resultingPredicate = logicalRowExpressions.combineConjuncts(domainTranslator.toPredicate(layout.getUnenforcedConstraint().transform(assignments::get)), logicalRowExpressions.filterNonDeterministicConjuncts(predicate), decomposedPredicate.getRemainingExpression());
    if (!TRUE_CONSTANT.equals(resultingPredicate)) {
        return new FilterNode(node.getSourceLocation(), idAllocator.getNextId(), tableScan, resultingPredicate);
    }
    return tableScan;
}
Also used : RowExpressionDomainTranslator(com.facebook.presto.sql.relational.RowExpressionDomainTranslator) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Pattern(com.facebook.presto.matching.Pattern) TryFunction(com.facebook.presto.operator.scalar.TryFunction) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Capture(com.facebook.presto.matching.Capture) Map(java.util.Map) RowExpressionInterpreter(com.facebook.presto.sql.planner.RowExpressionInterpreter) ImmutableSet(com.google.common.collect.ImmutableSet) NullableValue(com.facebook.presto.common.predicate.NullableValue) ImmutableMap(com.google.common.collect.ImmutableMap) TableLayoutResult.computeEnforced(com.facebook.presto.metadata.TableLayoutResult.computeEnforced) DomainTranslator(com.facebook.presto.spi.relation.DomainTranslator) Set(java.util.Set) TRUE_CONSTANT(com.facebook.presto.expressions.LogicalRowExpressions.TRUE_CONSTANT) Objects(java.util.Objects) Capture.newCapture(com.facebook.presto.matching.Capture.newCapture) Optional(java.util.Optional) TableLayoutResult(com.facebook.presto.metadata.TableLayoutResult) Captures(com.facebook.presto.matching.Captures) RowExpressionDeterminismEvaluator(com.facebook.presto.sql.relational.RowExpressionDeterminismEvaluator) ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) Function(java.util.function.Function) Patterns.filter(com.facebook.presto.sql.planner.plan.Patterns.filter) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) FilterNode(com.facebook.presto.spi.plan.FilterNode) SystemSessionProperties.isNewOptimizerEnabled(com.facebook.presto.SystemSessionProperties.isNewOptimizerEnabled) ImmutableList(com.google.common.collect.ImmutableList) LogicalRowExpressions(com.facebook.presto.expressions.LogicalRowExpressions) BASIC_COLUMN_EXTRACTOR(com.facebook.presto.spi.relation.DomainTranslator.BASIC_COLUMN_EXTRACTOR) Objects.requireNonNull(java.util.Objects.requireNonNull) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) TableHandle(com.facebook.presto.spi.TableHandle) FunctionResolution(com.facebook.presto.sql.relational.FunctionResolution) VariablesExtractor(com.facebook.presto.sql.planner.VariablesExtractor) RowExpression(com.facebook.presto.spi.relation.RowExpression) VariableResolver(com.facebook.presto.sql.planner.VariableResolver) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) Session(com.facebook.presto.Session) Rule(com.facebook.presto.sql.planner.iterative.Rule) Constraint(com.facebook.presto.spi.Constraint) TupleDomain(com.facebook.presto.common.predicate.TupleDomain) PreconditionRules.checkRulesAreFiredBeforeAddExchangesRule(com.facebook.presto.sql.planner.iterative.rule.PreconditionRules.checkRulesAreFiredBeforeAddExchangesRule) OPTIMIZED(com.facebook.presto.spi.relation.ExpressionOptimizer.Level.OPTIMIZED) Patterns.source(com.facebook.presto.sql.planner.plan.Patterns.source) PlanNode(com.facebook.presto.spi.plan.PlanNode) ColumnHandle(com.facebook.presto.spi.ColumnHandle) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) Sets.intersection(com.google.common.collect.Sets.intersection) Patterns.tableScan(com.facebook.presto.sql.planner.plan.Patterns.tableScan) Metadata(com.facebook.presto.metadata.Metadata) RowExpressionDeterminismEvaluator(com.facebook.presto.sql.relational.RowExpressionDeterminismEvaluator) ColumnHandle(com.facebook.presto.spi.ColumnHandle) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) LogicalRowExpressions(com.facebook.presto.expressions.LogicalRowExpressions) FilterNode(com.facebook.presto.spi.plan.FilterNode) RowExpression(com.facebook.presto.spi.relation.RowExpression) TableLayoutResult(com.facebook.presto.metadata.TableLayoutResult) FunctionResolution(com.facebook.presto.sql.relational.FunctionResolution) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpressionDomainTranslator(com.facebook.presto.sql.relational.RowExpressionDomainTranslator) DomainTranslator(com.facebook.presto.spi.relation.DomainTranslator)

Example 12 with PlanNodeIdAllocator

use of com.facebook.presto.spi.plan.PlanNodeIdAllocator in project presto by prestodb.

the class PushAggregationThroughOuterJoin method createAggregationOverNull.

private Optional<MappedAggregationInfo> createAggregationOverNull(AggregationNode referenceAggregation, PlanVariableAllocator variableAllocator, PlanNodeIdAllocator idAllocator, Lookup lookup) {
    // Create a values node that consists of a single row of nulls.
    // Map the output symbols from the referenceAggregation's source
    // to symbol references for the new values node.
    ImmutableList.Builder<VariableReferenceExpression> nullVariables = ImmutableList.builder();
    ImmutableList.Builder<RowExpression> nullLiterals = ImmutableList.builder();
    ImmutableMap.Builder<VariableReferenceExpression, VariableReferenceExpression> sourcesVariableMappingBuilder = ImmutableMap.builder();
    for (VariableReferenceExpression sourceVariable : referenceAggregation.getSource().getOutputVariables()) {
        RowExpression nullLiteral = constantNull(sourceVariable.getSourceLocation(), sourceVariable.getType());
        nullLiterals.add(nullLiteral);
        VariableReferenceExpression nullVariable = variableAllocator.newVariable(nullLiteral);
        nullVariables.add(nullVariable);
        // TODO The type should be from sourceVariable.getType
        sourcesVariableMappingBuilder.put(sourceVariable, nullVariable);
    }
    ValuesNode nullRow = new ValuesNode(referenceAggregation.getSourceLocation(), idAllocator.getNextId(), nullVariables.build(), ImmutableList.of(nullLiterals.build()));
    Map<VariableReferenceExpression, VariableReferenceExpression> sourcesVariableMapping = sourcesVariableMappingBuilder.build();
    // For each aggregation function in the reference node, create a corresponding aggregation function
    // that points to the nullRow. Map the symbols from the aggregations in referenceAggregation to the
    // symbols in these new aggregations.
    ImmutableMap.Builder<VariableReferenceExpression, VariableReferenceExpression> aggregationsVariableMappingBuilder = ImmutableMap.builder();
    ImmutableMap.Builder<VariableReferenceExpression, AggregationNode.Aggregation> aggregationsOverNullBuilder = ImmutableMap.builder();
    for (Map.Entry<VariableReferenceExpression, AggregationNode.Aggregation> entry : referenceAggregation.getAggregations().entrySet()) {
        VariableReferenceExpression aggregationVariable = entry.getKey();
        AggregationNode.Aggregation aggregation = entry.getValue();
        if (!isUsingVariables(aggregation, sourcesVariableMapping.keySet())) {
            return Optional.empty();
        }
        AggregationNode.Aggregation overNullAggregation = new AggregationNode.Aggregation(new CallExpression(aggregation.getCall().getSourceLocation(), aggregation.getCall().getDisplayName(), aggregation.getCall().getFunctionHandle(), aggregation.getCall().getType(), aggregation.getArguments().stream().map(argument -> inlineVariables(sourcesVariableMapping, argument)).collect(toImmutableList())), aggregation.getFilter().map(filter -> inlineVariables(sourcesVariableMapping, filter)), aggregation.getOrderBy().map(orderBy -> inlineOrderByVariables(sourcesVariableMapping, orderBy)), aggregation.isDistinct(), aggregation.getMask().map(x -> new VariableReferenceExpression(sourcesVariableMapping.get(x).getSourceLocation(), sourcesVariableMapping.get(x).getName(), x.getType())));
        QualifiedObjectName functionName = functionAndTypeManager.getFunctionMetadata(overNullAggregation.getFunctionHandle()).getName();
        VariableReferenceExpression overNull = variableAllocator.newVariable(aggregation.getCall().getSourceLocation(), functionName.getObjectName(), aggregationVariable.getType());
        aggregationsOverNullBuilder.put(overNull, overNullAggregation);
        aggregationsVariableMappingBuilder.put(aggregationVariable, overNull);
    }
    Map<VariableReferenceExpression, VariableReferenceExpression> aggregationsSymbolMapping = aggregationsVariableMappingBuilder.build();
    // create an aggregation node whose source is the null row.
    AggregationNode aggregationOverNullRow = new AggregationNode(referenceAggregation.getSourceLocation(), idAllocator.getNextId(), nullRow, aggregationsOverNullBuilder.build(), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
    return Optional.of(new MappedAggregationInfo(aggregationOverNullRow, aggregationsSymbolMapping));
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) Captures(com.facebook.presto.matching.Captures) Assignments(com.facebook.presto.spi.plan.Assignments) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Patterns.join(com.facebook.presto.sql.planner.plan.Patterns.join) Pattern(com.facebook.presto.matching.Pattern) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) HashSet(java.util.HashSet) Capture(com.facebook.presto.matching.Capture) ImmutableList(com.google.common.collect.ImmutableList) DistinctOutputQueryUtil.isDistinct(com.facebook.presto.sql.planner.optimizations.DistinctOutputQueryUtil.isDistinct) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) AggregationNode.singleGroupingSet(com.facebook.presto.spi.plan.AggregationNode.singleGroupingSet) CallExpression(com.facebook.presto.spi.relation.CallExpression) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) Patterns.aggregation(com.facebook.presto.sql.planner.plan.Patterns.aggregation) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) AggregationNode.globalAggregation(com.facebook.presto.spi.plan.AggregationNode.globalAggregation) SortOrder(com.facebook.presto.common.block.SortOrder) ImmutableMap(com.google.common.collect.ImmutableMap) Session(com.facebook.presto.Session) Ordering(com.facebook.presto.spi.plan.Ordering) Rule(com.facebook.presto.sql.planner.iterative.Rule) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) RowExpressionVariableInliner.inlineVariables(com.facebook.presto.sql.planner.RowExpressionVariableInliner.inlineVariables) Expressions.constantNull(com.facebook.presto.sql.relational.Expressions.constantNull) Lookup(com.facebook.presto.sql.planner.iterative.Lookup) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Patterns.source(com.facebook.presto.sql.planner.plan.Patterns.source) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) SystemSessionProperties.shouldPushAggregationThroughJoin(com.facebook.presto.SystemSessionProperties.shouldPushAggregationThroughJoin) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) Capture.newCapture(com.facebook.presto.matching.Capture.newCapture) PlanVariableAllocator(com.facebook.presto.sql.planner.PlanVariableAllocator) Optional(java.util.Optional) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) RowExpression(com.facebook.presto.spi.relation.RowExpression) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) ImmutableMap(com.google.common.collect.ImmutableMap) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) AggregationNode.globalAggregation(com.facebook.presto.spi.plan.AggregationNode.globalAggregation) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Example 13 with PlanNodeIdAllocator

use of com.facebook.presto.spi.plan.PlanNodeIdAllocator in project presto by prestodb.

the class StatsCalculatorTester method assertStatsFor.

public StatsCalculatorAssertion assertStatsFor(Function<PlanBuilder, PlanNode> planProvider) {
    PlanBuilder planBuilder = new PlanBuilder(session, new PlanNodeIdAllocator(), metadata);
    PlanNode planNode = planProvider.apply(planBuilder);
    return new StatsCalculatorAssertion(statsCalculator, session, planNode, planBuilder.getTypes());
}
Also used : PlanNode(com.facebook.presto.spi.plan.PlanNode) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) PlanBuilder(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder)

Example 14 with PlanNodeIdAllocator

use of com.facebook.presto.spi.plan.PlanNodeIdAllocator in project presto by prestodb.

the class TestVerifyNoOriginalExpression method setup.

@BeforeClass
public void setup() {
    metadata = getQueryRunner().getMetadata();
    builder = new PlanBuilder(TEST_SESSION, new PlanNodeIdAllocator(), metadata);
    valuesNode = builder.values();
    comparisonCallExpression = new CallExpression("LESS_THAN", metadata.getFunctionAndTypeManager().resolveOperator(LESS_THAN, fromTypes(BIGINT, BIGINT)), BooleanType.BOOLEAN, ImmutableList.of(VARIABLE_REFERENCE_EXPRESSION, VARIABLE_REFERENCE_EXPRESSION));
}
Also used : PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) PlanBuilder(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder) CallExpression(com.facebook.presto.spi.relation.CallExpression) BeforeClass(org.testng.annotations.BeforeClass)

Example 15 with PlanNodeIdAllocator

use of com.facebook.presto.spi.plan.PlanNodeIdAllocator in project presto by prestodb.

the class LocalQueryRunner method createPlan.

public Plan createPlan(Session session, @Language("SQL") String sql, List<PlanOptimizer> optimizers, LogicalPlanner.Stage stage, WarningCollector warningCollector) {
    Statement wrappedStatement = sqlParser.createStatement(sql, createParsingOptions(session, warningCollector));
    PreparedQuery preparedQuery = new QueryPreparer(sqlParser).prepareQuery(session, wrappedStatement, warningCollector);
    assertFormattedSql(sqlParser, createParsingOptions(session), preparedQuery.getStatement());
    PlanNodeIdAllocator idAllocator = new PlanNodeIdAllocator();
    QueryExplainer queryExplainer = new QueryExplainer(optimizers, planFragmenter, metadata, accessControl, sqlParser, statsCalculator, costCalculator, dataDefinitionTask, distributedPlanChecker);
    Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.of(queryExplainer), preparedQuery.getParameters(), warningCollector);
    LogicalPlanner logicalPlanner = new LogicalPlanner(wrappedStatement instanceof Explain, session, optimizers, singleNodePlanChecker, idAllocator, metadata, sqlParser, statsCalculator, costCalculator, warningCollector);
    Analysis analysis = analyzer.analyze(preparedQuery.getStatement());
    return logicalPlanner.plan(analysis, stage);
}
Also used : QueryPreparer(com.facebook.presto.execution.QueryPreparer) QueryExplainer(com.facebook.presto.sql.analyzer.QueryExplainer) LogicalPlanner(com.facebook.presto.sql.planner.LogicalPlanner) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) Statement(com.facebook.presto.sql.tree.Statement) Analysis(com.facebook.presto.sql.analyzer.Analysis) Explain(com.facebook.presto.sql.tree.Explain) PreparedQuery(com.facebook.presto.execution.QueryPreparer.PreparedQuery) Analyzer(com.facebook.presto.sql.analyzer.Analyzer)

Aggregations

PlanNodeIdAllocator (com.facebook.presto.spi.plan.PlanNodeIdAllocator)22 PlanBuilder (com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder)14 Test (org.testng.annotations.Test)9 PlanVariableAllocator (com.facebook.presto.sql.planner.PlanVariableAllocator)7 PlanNode (com.facebook.presto.spi.plan.PlanNode)5 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)5 TableScanNode (com.facebook.presto.spi.plan.TableScanNode)4 ProjectionContext (com.facebook.presto.sql.planner.iterative.rule.PlanRemotePojections.ProjectionContext)4 Session (com.facebook.presto.Session)3 LogicalRowExpressions (com.facebook.presto.expressions.LogicalRowExpressions)3 ConnectorId (com.facebook.presto.spi.ConnectorId)3 TableHandle (com.facebook.presto.spi.TableHandle)3 PlanNodeId (com.facebook.presto.spi.plan.PlanNodeId)3 TpchColumnHandle (com.facebook.presto.tpch.TpchColumnHandle)3 TpchTableHandle (com.facebook.presto.tpch.TpchTableHandle)3 BeforeClass (org.testng.annotations.BeforeClass)3 Capture (com.facebook.presto.matching.Capture)2 Capture.newCapture (com.facebook.presto.matching.Capture.newCapture)2 Captures (com.facebook.presto.matching.Captures)2 Pattern (com.facebook.presto.matching.Pattern)2