Search in sources :

Example 1 with AssignUniqueId

use of io.prestosql.sql.planner.plan.AssignUniqueId 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 2 with AssignUniqueId

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

the class TransformCorrelatedInPredicateToJoin method buildInPredicateEquivalent.

private PlanNode buildInPredicateEquivalent(ApplyNode apply, InPredicate inPredicate, Symbol inPredicateOutputSymbol, Decorrelated decorrelated, PlanNodeIdAllocator idAllocator, PlanSymbolAllocator planSymbolAllocator) {
    Expression correlationCondition = and(decorrelated.getCorrelatedPredicates());
    PlanNode decorrelatedBuildSource = decorrelated.getDecorrelatedNode();
    AssignUniqueId probeSide = new AssignUniqueId(idAllocator.getNextId(), apply.getInput(), planSymbolAllocator.newSymbol("unique", BIGINT));
    Symbol buildSideKnownNonNull = planSymbolAllocator.newSymbol("buildSideKnownNonNull", BIGINT);
    ProjectNode buildSide = new ProjectNode(idAllocator.getNextId(), decorrelatedBuildSource, Assignments.builder().putAll(identityAsSymbolReferences(decorrelatedBuildSource.getOutputSymbols())).put(buildSideKnownNonNull, castToRowExpression(bigint(0))).build());
    Symbol probeSideSymbol = SymbolUtils.from(inPredicate.getValue());
    Symbol buildSideSymbol = SymbolUtils.from(inPredicate.getValueList());
    Expression joinExpression = and(or(new IsNullPredicate(toSymbolReference(probeSideSymbol)), new ComparisonExpression(ComparisonExpression.Operator.EQUAL, toSymbolReference(probeSideSymbol), toSymbolReference(buildSideSymbol)), new IsNullPredicate(toSymbolReference(buildSideSymbol))), correlationCondition);
    JoinNode leftOuterJoin = leftOuterJoin(idAllocator, probeSide, buildSide, joinExpression);
    Symbol matchConditionSymbol = planSymbolAllocator.newSymbol("matchConditionSymbol", BOOLEAN);
    Expression matchCondition = and(isNotNull(probeSideSymbol), isNotNull(buildSideSymbol));
    Symbol nullMatchConditionSymbol = planSymbolAllocator.newSymbol("nullMatchConditionSymbol", BOOLEAN);
    Expression nullMatchCondition = and(isNotNull(buildSideKnownNonNull), not(matchCondition));
    ProjectNode preProjection = new ProjectNode(idAllocator.getNextId(), leftOuterJoin, Assignments.builder().putAll(AssignmentUtils.identityAsSymbolReferences(leftOuterJoin.getOutputSymbols())).put(matchConditionSymbol, castToRowExpression(matchCondition)).put(nullMatchConditionSymbol, castToRowExpression(nullMatchCondition)).build());
    Symbol countMatchesSymbol = planSymbolAllocator.newSymbol("countMatches", BIGINT);
    Symbol countNullMatchesSymbol = planSymbolAllocator.newSymbol("countNullMatches", BIGINT);
    AggregationNode aggregation = new AggregationNode(idAllocator.getNextId(), preProjection, ImmutableMap.<Symbol, AggregationNode.Aggregation>builder().put(countMatchesSymbol, countWithFilter(matchConditionSymbol)).put(countNullMatchesSymbol, countWithFilter(nullMatchConditionSymbol)).build(), singleGroupingSet(probeSide.getOutputSymbols()), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty(), AggregationNode.AggregationType.HASH, Optional.empty());
    // TODO since we care only about "some count > 0", we could have specialized node instead of leftOuterJoin that does the job without materializing join results
    SearchedCaseExpression inPredicateEquivalent = new SearchedCaseExpression(ImmutableList.of(new WhenClause(isGreaterThan(countMatchesSymbol, 0), booleanConstant(true)), new WhenClause(isGreaterThan(countNullMatchesSymbol, 0), booleanConstant(null))), Optional.of(booleanConstant(false)));
    return new ProjectNode(idAllocator.getNextId(), aggregation, Assignments.builder().putAll(identityAsSymbolReferences(apply.getInput().getOutputSymbols())).put(inPredicateOutputSymbol, castToRowExpression(inPredicateEquivalent)).build());
}
Also used : ComparisonExpression(io.prestosql.sql.tree.ComparisonExpression) WhenClause(io.prestosql.sql.tree.WhenClause) PlanNode(io.prestosql.spi.plan.PlanNode) AssignUniqueId(io.prestosql.sql.planner.plan.AssignUniqueId) SearchedCaseExpression(io.prestosql.sql.tree.SearchedCaseExpression) CallExpression(io.prestosql.spi.relation.CallExpression) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) OriginalExpressionUtils.castToExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToExpression) SearchedCaseExpression(io.prestosql.sql.tree.SearchedCaseExpression) NotExpression(io.prestosql.sql.tree.NotExpression) ComparisonExpression(io.prestosql.sql.tree.ComparisonExpression) Expression(io.prestosql.sql.tree.Expression) Symbol(io.prestosql.spi.plan.Symbol) JoinNode(io.prestosql.spi.plan.JoinNode) IsNullPredicate(io.prestosql.sql.tree.IsNullPredicate) ProjectNode(io.prestosql.spi.plan.ProjectNode) AggregationNode(io.prestosql.spi.plan.AggregationNode)

Example 3 with AssignUniqueId

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

the class PushRemoteExchangeThroughAssignUniqueId method apply.

@Override
public Result apply(ExchangeNode node, Captures captures, Context context) {
    checkArgument(!node.getOrderingScheme().isPresent(), "Merge exchange over AssignUniqueId not supported");
    AssignUniqueId assignUniqueId = captures.get(ASSIGN_UNIQUE_ID);
    PartitioningScheme partitioningScheme = node.getPartitioningScheme();
    if (partitioningScheme.getPartitioning().getColumns().contains(assignUniqueId.getIdColumn())) {
        // Hence, AssignUniqueId node has to stay below the exchange node.
        return Result.empty();
    }
    return Result.ofPlanNode(new AssignUniqueId(assignUniqueId.getId(), new ExchangeNode(node.getId(), node.getType(), node.getScope(), new PartitioningScheme(partitioningScheme.getPartitioning(), removeSymbol(partitioningScheme.getOutputLayout(), assignUniqueId.getIdColumn()), partitioningScheme.getHashColumn(), partitioningScheme.isReplicateNullsAndAny(), partitioningScheme.getBucketToPartition()), ImmutableList.of(assignUniqueId.getSource()), ImmutableList.of(removeSymbol(getOnlyElement(node.getInputs()), assignUniqueId.getIdColumn())), Optional.empty(), node.getAggregationType()), assignUniqueId.getIdColumn()));
}
Also used : AssignUniqueId(io.prestosql.sql.planner.plan.AssignUniqueId) ExchangeNode(io.prestosql.sql.planner.plan.ExchangeNode) PartitioningScheme(io.prestosql.sql.planner.PartitioningScheme)

Example 4 with AssignUniqueId

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

the class ScalarAggregationToJoinRewriter method rewriteScalarAggregation.

private PlanNode rewriteScalarAggregation(LateralJoinNode lateralJoinNode, AggregationNode scalarAggregation, PlanNode scalarAggregationSource, Optional<Expression> joinExpression, Symbol nonNull) {
    AssignUniqueId inputWithUniqueColumns = new AssignUniqueId(idAllocator.getNextId(), lateralJoinNode.getInput(), planSymbolAllocator.newSymbol("unique", BIGINT));
    JoinNode leftOuterJoin = new JoinNode(idAllocator.getNextId(), JoinNode.Type.LEFT, inputWithUniqueColumns, scalarAggregationSource, ImmutableList.of(), ImmutableList.<Symbol>builder().addAll(inputWithUniqueColumns.getOutputSymbols()).addAll(scalarAggregationSource.getOutputSymbols()).build(), joinExpression.map(OriginalExpressionUtils::castToRowExpression), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of());
    Optional<AggregationNode> aggregationNode = createAggregationNode(scalarAggregation, leftOuterJoin, nonNull);
    if (!aggregationNode.isPresent()) {
        return lateralJoinNode;
    }
    Optional<ProjectNode> subqueryProjection = searchFrom(lateralJoinNode.getSubquery(), lookup).where(ProjectNode.class::isInstance).recurseOnlyWhen(EnforceSingleRowNode.class::isInstance).findFirst();
    List<Symbol> aggregationOutputSymbols = getTruncatedAggregationSymbols(lateralJoinNode, aggregationNode.get());
    if (subqueryProjection.isPresent()) {
        Assignments assignments = Assignments.builder().putAll(AssignmentUtils.identityAsSymbolReferences(aggregationOutputSymbols)).putAll(subqueryProjection.get().getAssignments()).build();
        return new ProjectNode(idAllocator.getNextId(), aggregationNode.get(), assignments);
    } else {
        return new ProjectNode(idAllocator.getNextId(), aggregationNode.get(), AssignmentUtils.identityAsSymbolReferences(aggregationOutputSymbols));
    }
}
Also used : AssignUniqueId(io.prestosql.sql.planner.plan.AssignUniqueId) LateralJoinNode(io.prestosql.sql.planner.plan.LateralJoinNode) JoinNode(io.prestosql.spi.plan.JoinNode) Symbol(io.prestosql.spi.plan.Symbol) Assignments(io.prestosql.spi.plan.Assignments) AggregationNode(io.prestosql.spi.plan.AggregationNode) ProjectNode(io.prestosql.spi.plan.ProjectNode)

Aggregations

AssignUniqueId (io.prestosql.sql.planner.plan.AssignUniqueId)4 ProjectNode (io.prestosql.spi.plan.ProjectNode)3 Symbol (io.prestosql.spi.plan.Symbol)3 AggregationNode (io.prestosql.spi.plan.AggregationNode)2 JoinNode (io.prestosql.spi.plan.JoinNode)2 PlanNode (io.prestosql.spi.plan.PlanNode)2 LateralJoinNode (io.prestosql.sql.planner.plan.LateralJoinNode)2 WhenClause (io.prestosql.sql.tree.WhenClause)2 Assignments (io.prestosql.spi.plan.Assignments)1 FilterNode (io.prestosql.spi.plan.FilterNode)1 MarkDistinctNode (io.prestosql.spi.plan.MarkDistinctNode)1 CallExpression (io.prestosql.spi.relation.CallExpression)1 FunctionCallBuilder (io.prestosql.sql.planner.FunctionCallBuilder)1 PartitioningScheme (io.prestosql.sql.planner.PartitioningScheme)1 EnforceSingleRowNode (io.prestosql.sql.planner.plan.EnforceSingleRowNode)1 ExchangeNode (io.prestosql.sql.planner.plan.ExchangeNode)1 OriginalExpressionUtils.castToExpression (io.prestosql.sql.relational.OriginalExpressionUtils.castToExpression)1 OriginalExpressionUtils.castToRowExpression (io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression)1 Cast (io.prestosql.sql.tree.Cast)1 ComparisonExpression (io.prestosql.sql.tree.ComparisonExpression)1