Search in sources :

Example 1 with LateralJoinNode

use of io.prestosql.sql.planner.plan.LateralJoinNode in project hetu-core by openlookeng.

the class TransformCorrelatedLateralJoinToJoin method apply.

@Override
public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) {
    PlanNode subquery = lateralJoinNode.getSubquery();
    PlanNodeDecorrelator planNodeDecorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup());
    Optional<DecorrelatedNode> decorrelatedNodeOptional = planNodeDecorrelator.decorrelateFilters(subquery, lateralJoinNode.getCorrelation());
    return decorrelatedNodeOptional.map(decorrelatedNode -> {
        Expression joinFilter = combineConjuncts(decorrelatedNode.getCorrelatedPredicates().orElse(TRUE_LITERAL), lateralJoinNode.getFilter());
        return Result.ofPlanNode(new JoinNode(context.getIdAllocator().getNextId(), lateralJoinNode.getType().toJoinNodeType(), lateralJoinNode.getInput(), decorrelatedNode.getNode(), ImmutableList.of(), lateralJoinNode.getOutputSymbols(), joinFilter.equals(TRUE_LITERAL) ? Optional.empty() : Optional.of(castToRowExpression(joinFilter)), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of()));
    }).orElseGet(Result::empty);
}
Also used : Patterns.lateralJoin(io.prestosql.sql.planner.plan.Patterns.lateralJoin) LateralJoin.correlation(io.prestosql.sql.planner.plan.Patterns.LateralJoin.correlation) ExpressionUtils.combineConjuncts(io.prestosql.sql.ExpressionUtils.combineConjuncts) ImmutableMap(com.google.common.collect.ImmutableMap) Rule(io.prestosql.sql.planner.iterative.Rule) Pattern.nonEmpty(io.prestosql.matching.Pattern.nonEmpty) PlanNodeDecorrelator(io.prestosql.sql.planner.optimizations.PlanNodeDecorrelator) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) Pattern(io.prestosql.matching.Pattern) PlanNode(io.prestosql.spi.plan.PlanNode) TRUE_LITERAL(io.prestosql.sql.tree.BooleanLiteral.TRUE_LITERAL) Captures(io.prestosql.matching.Captures) ImmutableList(com.google.common.collect.ImmutableList) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) Optional(java.util.Optional) DecorrelatedNode(io.prestosql.sql.planner.optimizations.PlanNodeDecorrelator.DecorrelatedNode) Expression(io.prestosql.sql.tree.Expression) JoinNode(io.prestosql.spi.plan.JoinNode) PlanNodeDecorrelator(io.prestosql.sql.planner.optimizations.PlanNodeDecorrelator) PlanNode(io.prestosql.spi.plan.PlanNode) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) Expression(io.prestosql.sql.tree.Expression) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) JoinNode(io.prestosql.spi.plan.JoinNode) DecorrelatedNode(io.prestosql.sql.planner.optimizations.PlanNodeDecorrelator.DecorrelatedNode)

Example 2 with LateralJoinNode

use of io.prestosql.sql.planner.plan.LateralJoinNode in project hetu-core by openlookeng.

the class TransformCorrelatedScalarAggregationToJoin method apply.

@Override
public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) {
    PlanNode subquery = lateralJoinNode.getSubquery();
    if (!isScalar(subquery, context.getLookup())) {
        return Result.empty();
    }
    Optional<AggregationNode> aggregation = findAggregation(subquery, context.getLookup());
    if (!(aggregation.isPresent() && aggregation.get().getGroupingKeys().isEmpty())) {
        return Result.empty();
    }
    ScalarAggregationToJoinRewriter rewriter = new ScalarAggregationToJoinRewriter(metadata, context.getSymbolAllocator(), context.getIdAllocator(), context.getLookup());
    PlanNode rewrittenNode = rewriter.rewriteScalarAggregation(lateralJoinNode, aggregation.get());
    if (rewrittenNode instanceof LateralJoinNode) {
        return Result.empty();
    }
    return Result.ofPlanNode(rewrittenNode);
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) ScalarAggregationToJoinRewriter(io.prestosql.sql.planner.optimizations.ScalarAggregationToJoinRewriter) AggregationNode(io.prestosql.spi.plan.AggregationNode)

Example 3 with LateralJoinNode

use of io.prestosql.sql.planner.plan.LateralJoinNode in project hetu-core by openlookeng.

the class TransformCorrelatedScalarSubquery method apply.

@Override
public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) {
    PlanNode subquery = context.getLookup().resolve(lateralJoinNode.getSubquery());
    if (!searchFrom(subquery, context.getLookup()).where(EnforceSingleRowNode.class::isInstance).recurseOnlyWhen(ProjectNode.class::isInstance).matches()) {
        return Result.empty();
    }
    PlanNode rewrittenSubquery = searchFrom(subquery, context.getLookup()).where(EnforceSingleRowNode.class::isInstance).recurseOnlyWhen(ProjectNode.class::isInstance).removeFirst();
    Range<Long> subqueryCardinality = extractCardinality(rewrittenSubquery, context.getLookup());
    boolean producesAtMostOneRow = Range.closed(0L, 1L).encloses(subqueryCardinality);
    if (producesAtMostOneRow) {
        boolean producesSingleRow = Range.singleton(1L).encloses(subqueryCardinality);
        return Result.ofPlanNode(new LateralJoinNode(context.getIdAllocator().getNextId(), lateralJoinNode.getInput(), rewrittenSubquery, lateralJoinNode.getCorrelation(), producesSingleRow ? lateralJoinNode.getType() : LEFT, lateralJoinNode.getFilter(), lateralJoinNode.getOriginSubquery()));
    }
    Symbol unique = context.getSymbolAllocator().newSymbol("unique", BigintType.BIGINT);
    LateralJoinNode rewrittenLateralJoinNode = new LateralJoinNode(context.getIdAllocator().getNextId(), new AssignUniqueId(context.getIdAllocator().getNextId(), lateralJoinNode.getInput(), unique), rewrittenSubquery, lateralJoinNode.getCorrelation(), LEFT, lateralJoinNode.getFilter(), lateralJoinNode.getOriginSubquery());
    Symbol isDistinct = context.getSymbolAllocator().newSymbol("is_distinct", BooleanType.BOOLEAN);
    MarkDistinctNode markDistinctNode = new MarkDistinctNode(context.getIdAllocator().getNextId(), rewrittenLateralJoinNode, isDistinct, rewrittenLateralJoinNode.getInput().getOutputSymbols(), Optional.empty());
    FilterNode filterNode = new FilterNode(context.getIdAllocator().getNextId(), markDistinctNode, castToRowExpression(new SimpleCaseExpression(toSymbolReference(isDistinct), ImmutableList.of(new WhenClause(TRUE_LITERAL, TRUE_LITERAL)), Optional.of(new Cast(new FunctionCallBuilder(metadata).setName(QualifiedName.of("fail")).addArgument(INTEGER, new LongLiteral(Integer.toString(SUBQUERY_MULTIPLE_ROWS.toErrorCode().getCode()))).addArgument(VARCHAR, new StringLiteral("Scalar sub-query has returned multiple rows")).build(), BOOLEAN)))));
    return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), filterNode, AssignmentUtils.identityAsSymbolReferences((lateralJoinNode.getOutputSymbols()))));
}
Also used : Cast(io.prestosql.sql.tree.Cast) MarkDistinctNode(io.prestosql.spi.plan.MarkDistinctNode) LongLiteral(io.prestosql.sql.tree.LongLiteral) Symbol(io.prestosql.spi.plan.Symbol) FilterNode(io.prestosql.spi.plan.FilterNode) SimpleCaseExpression(io.prestosql.sql.tree.SimpleCaseExpression) WhenClause(io.prestosql.sql.tree.WhenClause) PlanNode(io.prestosql.spi.plan.PlanNode) AssignUniqueId(io.prestosql.sql.planner.plan.AssignUniqueId) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) StringLiteral(io.prestosql.sql.tree.StringLiteral) EnforceSingleRowNode(io.prestosql.sql.planner.plan.EnforceSingleRowNode) ProjectNode(io.prestosql.spi.plan.ProjectNode) FunctionCallBuilder(io.prestosql.sql.planner.FunctionCallBuilder)

Example 4 with LateralJoinNode

use of io.prestosql.sql.planner.plan.LateralJoinNode in project hetu-core by openlookeng.

the class TransformCorrelatedSingleRowSubqueryToProject method apply.

@Override
public Result apply(LateralJoinNode parent, Captures captures, Context context) {
    List<ValuesNode> values = searchFrom(parent.getSubquery(), context.getLookup()).recurseOnlyWhen(ProjectNode.class::isInstance).where(ValuesNode.class::isInstance).findAll();
    if (values.size() != 1 || !isSingleRowValuesWithNoColumns(values.get(0))) {
        return Result.empty();
    }
    List<ProjectNode> subqueryProjections = searchFrom(parent.getSubquery(), context.getLookup()).where(node -> node instanceof ProjectNode && !node.getOutputSymbols().equals(parent.getCorrelation())).findAll();
    if (subqueryProjections.size() == 0) {
        return Result.ofPlanNode(parent.getInput());
    }
    if (subqueryProjections.size() == 1) {
        Assignments assignments = Assignments.builder().putAll(AssignmentUtils.identityAsSymbolReferences(parent.getInput().getOutputSymbols())).putAll(subqueryProjections.get(0).getAssignments()).build();
        return Result.ofPlanNode(projectNode(parent.getInput(), assignments, context));
    }
    return Result.empty();
}
Also used : AssignmentUtils(io.prestosql.sql.planner.plan.AssignmentUtils) Patterns.lateralJoin(io.prestosql.sql.planner.plan.Patterns.lateralJoin) LateralJoin.filter(io.prestosql.sql.planner.plan.Patterns.LateralJoin.filter) Assignments(io.prestosql.spi.plan.Assignments) Rule(io.prestosql.sql.planner.iterative.Rule) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) Pattern(io.prestosql.matching.Pattern) PlanNode(io.prestosql.spi.plan.PlanNode) ProjectNode(io.prestosql.spi.plan.ProjectNode) TRUE_LITERAL(io.prestosql.sql.tree.BooleanLiteral.TRUE_LITERAL) PlanNodeSearcher.searchFrom(io.prestosql.sql.planner.optimizations.PlanNodeSearcher.searchFrom) Captures(io.prestosql.matching.Captures) ValuesNode(io.prestosql.spi.plan.ValuesNode) List(java.util.List) ValuesNode(io.prestosql.spi.plan.ValuesNode) Assignments(io.prestosql.spi.plan.Assignments) ProjectNode(io.prestosql.spi.plan.ProjectNode)

Example 5 with LateralJoinNode

use of io.prestosql.sql.planner.plan.LateralJoinNode in project hetu-core by openlookeng.

the class TransformExistsApplyToLateralNode method rewriteToNonDefaultAggregation.

private Optional<PlanNode> rewriteToNonDefaultAggregation(ApplyNode applyNode, Context context) {
    checkState(applyNode.getSubquery().getOutputSymbols().isEmpty(), "Expected subquery output symbols to be pruned");
    Symbol exists = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols());
    Symbol subqueryTrue = context.getSymbolAllocator().newSymbol("subqueryTrue", BOOLEAN);
    Assignments.Builder assignments = Assignments.builder();
    assignments.putAll(AssignmentUtils.identityAsSymbolReferences(applyNode.getInput().getOutputSymbols()));
    assignments.put(exists, castToRowExpression(new CoalesceExpression(ImmutableList.of(toSymbolReference(subqueryTrue), BooleanLiteral.FALSE_LITERAL))));
    PlanNode subquery = new ProjectNode(context.getIdAllocator().getNextId(), new LimitNode(context.getIdAllocator().getNextId(), applyNode.getSubquery(), 1L, false), Assignments.of(subqueryTrue, castToRowExpression(TRUE_LITERAL)));
    PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup());
    if (!decorrelator.decorrelateFilters(subquery, applyNode.getCorrelation()).isPresent()) {
        return Optional.empty();
    }
    return Optional.of(new ProjectNode(context.getIdAllocator().getNextId(), new LateralJoinNode(applyNode.getId(), applyNode.getInput(), subquery, applyNode.getCorrelation(), LEFT, TRUE_LITERAL, applyNode.getOriginSubquery()), assignments.build()));
}
Also used : PlanNodeDecorrelator(io.prestosql.sql.planner.optimizations.PlanNodeDecorrelator) PlanNode(io.prestosql.spi.plan.PlanNode) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) LimitNode(io.prestosql.spi.plan.LimitNode) Symbol(io.prestosql.spi.plan.Symbol) Assignments(io.prestosql.spi.plan.Assignments) ProjectNode(io.prestosql.spi.plan.ProjectNode) CoalesceExpression(io.prestosql.sql.tree.CoalesceExpression)

Aggregations

LateralJoinNode (io.prestosql.sql.planner.plan.LateralJoinNode)9 PlanNode (io.prestosql.spi.plan.PlanNode)6 ProjectNode (io.prestosql.spi.plan.ProjectNode)5 Symbol (io.prestosql.spi.plan.Symbol)4 AggregationNode (io.prestosql.spi.plan.AggregationNode)3 Assignments (io.prestosql.spi.plan.Assignments)3 Captures (io.prestosql.matching.Captures)2 Pattern (io.prestosql.matching.Pattern)2 JoinNode (io.prestosql.spi.plan.JoinNode)2 Rule (io.prestosql.sql.planner.iterative.Rule)2 PlanNodeDecorrelator (io.prestosql.sql.planner.optimizations.PlanNodeDecorrelator)2 AssignUniqueId (io.prestosql.sql.planner.plan.AssignUniqueId)2 Patterns.lateralJoin (io.prestosql.sql.planner.plan.Patterns.lateralJoin)2 OriginalExpressionUtils.castToRowExpression (io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression)2 TRUE_LITERAL (io.prestosql.sql.tree.BooleanLiteral.TRUE_LITERAL)2 Cast (io.prestosql.sql.tree.Cast)2 Expression (io.prestosql.sql.tree.Expression)2 LongLiteral (io.prestosql.sql.tree.LongLiteral)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1