Search in sources :

Example 1 with MarkDistinctNode

use of io.prestosql.spi.plan.MarkDistinctNode 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 MarkDistinctNode

use of io.prestosql.spi.plan.MarkDistinctNode in project hetu-core by openlookeng.

the class MarkDistinctMatcher method detailMatches.

@Override
public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    checkState(shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName());
    MarkDistinctNode markDistinctNode = (MarkDistinctNode) node;
    if (!markDistinctNode.getHashSymbol().equals(hashSymbol.map(alias -> alias.toSymbol(symbolAliases)))) {
        return NO_MATCH;
    }
    if (!ImmutableSet.copyOf(markDistinctNode.getDistinctSymbols()).equals(distinctSymbols.stream().map(alias -> alias.toSymbol(symbolAliases)).collect(toImmutableSet()))) {
        return NO_MATCH;
    }
    return match(markerSymbol.toString(), toSymbolReference(markDistinctNode.getMarkerSymbol()));
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) StatsProvider(io.prestosql.cost.StatsProvider) MatchResult.match(io.prestosql.sql.planner.assertions.MatchResult.match) PlanNode(io.prestosql.spi.plan.PlanNode) Metadata(io.prestosql.metadata.Metadata) Preconditions.checkState(com.google.common.base.Preconditions.checkState) SymbolUtils.toSymbolReference(io.prestosql.sql.planner.SymbolUtils.toSymbolReference) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Objects.requireNonNull(java.util.Objects.requireNonNull) Session(io.prestosql.Session) Optional(java.util.Optional) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) NO_MATCH(io.prestosql.sql.planner.assertions.MatchResult.NO_MATCH) MarkDistinctNode(io.prestosql.spi.plan.MarkDistinctNode) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) MarkDistinctNode(io.prestosql.spi.plan.MarkDistinctNode)

Example 3 with MarkDistinctNode

use of io.prestosql.spi.plan.MarkDistinctNode in project hetu-core by openlookeng.

the class MultipleDistinctAggregationToMarkDistinct method apply.

@Override
public Result apply(AggregationNode parent, Captures captures, Context context) {
    if (!SystemSessionProperties.useMarkDistinct(context.getSession())) {
        return Result.empty();
    }
    // the distinct marker for the given set of input columns
    Map<Set<Symbol>, Symbol> markers = new HashMap<>();
    Map<Symbol, Aggregation> newAggregations = new HashMap<>();
    PlanNode subPlan = parent.getSource();
    for (Map.Entry<Symbol, Aggregation> entry : parent.getAggregations().entrySet()) {
        Aggregation aggregation = entry.getValue();
        if (aggregation.isDistinct() && !aggregation.getFilter().isPresent() && !aggregation.getMask().isPresent()) {
            Set<Symbol> inputs = aggregation.getArguments().stream().map(OriginalExpressionUtils::castToExpression).map(SymbolUtils::from).collect(toSet());
            Symbol marker = markers.get(inputs);
            if (marker == null) {
                marker = context.getSymbolAllocator().newSymbol(Iterables.getLast(inputs).getName(), BOOLEAN, "distinct");
                markers.put(inputs, marker);
                ImmutableSet.Builder<Symbol> distinctSymbols = ImmutableSet.<Symbol>builder().addAll(parent.getGroupingKeys()).addAll(inputs);
                parent.getGroupIdSymbol().ifPresent(distinctSymbols::add);
                subPlan = new MarkDistinctNode(context.getIdAllocator().getNextId(), subPlan, marker, ImmutableList.copyOf(distinctSymbols.build()), Optional.empty());
            }
            // remove the distinct flag and set the distinct marker
            newAggregations.put(entry.getKey(), new Aggregation(aggregation.getFunctionCall(), aggregation.getArguments(), false, aggregation.getFilter(), aggregation.getOrderingScheme(), Optional.of(marker)));
        } else {
            newAggregations.put(entry.getKey(), aggregation);
        }
    }
    return Result.ofPlanNode(new AggregationNode(parent.getId(), subPlan, newAggregations, parent.getGroupingSets(), ImmutableList.of(), parent.getStep(), parent.getHashSymbol(), parent.getGroupIdSymbol(), parent.getAggregationType(), parent.getFinalizeSymbol()));
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) Collectors.toSet(java.util.stream.Collectors.toSet) MarkDistinctNode(io.prestosql.spi.plan.MarkDistinctNode) HashMap(java.util.HashMap) Symbol(io.prestosql.spi.plan.Symbol) AggregationNode(io.prestosql.spi.plan.AggregationNode) Aggregation(io.prestosql.spi.plan.AggregationNode.Aggregation) PlanNode(io.prestosql.spi.plan.PlanNode) ImmutableSet(com.google.common.collect.ImmutableSet) OriginalExpressionUtils(io.prestosql.sql.relational.OriginalExpressionUtils) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

MarkDistinctNode (io.prestosql.spi.plan.MarkDistinctNode)3 PlanNode (io.prestosql.spi.plan.PlanNode)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Symbol (io.prestosql.spi.plan.Symbol)2 MoreObjects.toStringHelper (com.google.common.base.MoreObjects.toStringHelper)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)1 Session (io.prestosql.Session)1 StatsProvider (io.prestosql.cost.StatsProvider)1 Metadata (io.prestosql.metadata.Metadata)1 AggregationNode (io.prestosql.spi.plan.AggregationNode)1 Aggregation (io.prestosql.spi.plan.AggregationNode.Aggregation)1 FilterNode (io.prestosql.spi.plan.FilterNode)1 ProjectNode (io.prestosql.spi.plan.ProjectNode)1 FunctionCallBuilder (io.prestosql.sql.planner.FunctionCallBuilder)1 SymbolUtils.toSymbolReference (io.prestosql.sql.planner.SymbolUtils.toSymbolReference)1 NO_MATCH (io.prestosql.sql.planner.assertions.MatchResult.NO_MATCH)1 MatchResult.match (io.prestosql.sql.planner.assertions.MatchResult.match)1 AssignUniqueId (io.prestosql.sql.planner.plan.AssignUniqueId)1