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()))));
}
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());
}
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()));
}
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));
}
}
Aggregations