use of io.prestosql.sql.planner.plan.SemiJoinNode in project hetu-core by openlookeng.
the class SqlStageExecution method traverseNodesForDynamicFiltering.
private void traverseNodesForDynamicFiltering(List<PlanNode> nodes) {
for (PlanNode node : nodes) {
if (node instanceof JoinNode) {
JoinNode joinNode = (JoinNode) node;
dynamicFilterService.registerTasks(joinNode, allTasks, getScheduledNodes(), stateMachine);
} else if (node instanceof SemiJoinNode) {
SemiJoinNode semiJoinNode = (SemiJoinNode) node;
dynamicFilterService.registerTasks(semiJoinNode, allTasks, getScheduledNodes(), stateMachine);
}
traverseNodesForDynamicFiltering(node.getSources());
}
}
use of io.prestosql.sql.planner.plan.SemiJoinNode in project hetu-core by openlookeng.
the class TransformUncorrelatedInPredicateSubqueryToSemiJoin method apply.
@Override
public Result apply(ApplyNode applyNode, Captures captures, Context context) {
if (applyNode.getSubqueryAssignments().size() != 1) {
return Result.empty();
}
Expression expression = castToExpression(getOnlyElement(applyNode.getSubqueryAssignments().getExpressions()));
if (!(expression instanceof InPredicate)) {
return Result.empty();
}
InPredicate inPredicate = (InPredicate) expression;
Symbol semiJoinSymbol = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols());
SemiJoinNode replacement = new SemiJoinNode(context.getIdAllocator().getNextId(), applyNode.getInput(), applyNode.getSubquery(), SymbolUtils.from(inPredicate.getValue()), SymbolUtils.from(inPredicate.getValueList()), semiJoinSymbol, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
return Result.ofPlanNode(replacement);
}
use of io.prestosql.sql.planner.plan.SemiJoinNode in project hetu-core by openlookeng.
the class DynamicFilterService method registerTasksHelper.
private void registerTasksHelper(PlanNode node, Symbol buildSymbol, Map<String, Symbol> dynamicFiltersMap, Set<TaskId> taskIds, Set<InternalNode> workers, StageStateMachine stateMachine) {
final StateStore stateStore = stateStoreProvider.getStateStore();
String queryId = stateMachine.getSession().getQueryId().toString();
for (Map.Entry<String, Symbol> entry : dynamicFiltersMap.entrySet()) {
Symbol buildSymbolToCheck = buildSymbol != null ? buildSymbol : node.getOutputSymbols().contains(entry.getValue()) ? entry.getValue() : null;
if (buildSymbolToCheck != null && entry.getValue().getName().equals(buildSymbol.getName())) {
String filterId = entry.getKey();
stateStore.createStateCollection(createKey(DynamicFilterUtils.TASKSPREFIX, filterId, queryId), SET);
stateStore.createStateCollection(createKey(DynamicFilterUtils.PARTIALPREFIX, filterId, queryId), SET);
dynamicFilters.putIfAbsent(queryId, new ConcurrentHashMap<>());
Map<String, DynamicFilterRegistryInfo> filters = dynamicFilters.get(queryId);
if (node instanceof JoinNode) {
filters.put(filterId, extractDynamicFilterRegistryInfo((JoinNode) node, stateMachine.getSession(), filterId));
} else if (node instanceof SemiJoinNode) {
filters.put(filterId, extractDynamicFilterRegistryInfo((SemiJoinNode) node, stateMachine.getSession()));
}
dynamicFiltersToTask.putIfAbsent(filterId + "-" + queryId, new CopyOnWriteArraySet<>());
CopyOnWriteArraySet<TaskId> taskSet = dynamicFiltersToTask.get(filterId + "-" + queryId);
taskSet.addAll(taskIds);
log.debug("registerTasks source " + filterId + " filters:" + filters + ", workers: " + workers.stream().map(x -> x.getNodeIdentifier()).collect(Collectors.joining(",")) + ", taskIds: " + taskIds.stream().map(TaskId::toString).collect(Collectors.joining(",")));
}
}
}
use of io.prestosql.sql.planner.plan.SemiJoinNode in project hetu-core by openlookeng.
the class TransformFilteringSemiJoinToInnerJoin method apply.
@Override
public Result apply(FilterNode filterNode, Captures captures, Context context) {
SemiJoinNode semiJoin = captures.get(SEMI_JOIN);
// Do no transform semi-join in context of DELETE
if (PlanNodeSearcher.searchFrom(semiJoin.getSource(), context.getLookup()).where(node -> node instanceof TableScanNode && ((TableScanNode) node).isForDelete()).matches()) {
return Result.empty();
}
Symbol semiJoinSymbol = semiJoin.getSemiJoinOutput();
TypeProvider types = context.getSymbolAllocator().getTypes();
Predicate<RowExpression> isSemiJoinSymbol = expression -> expression.equals(toVariableReference(semiJoinSymbol, types));
LogicalRowExpressions logicalRowExpressions = new LogicalRowExpressions(new RowExpressionDeterminismEvaluator(metadata), new FunctionResolution(metadata.getFunctionAndTypeManager()), metadata.getFunctionAndTypeManager());
List<RowExpression> conjuncts = LogicalRowExpressions.extractConjuncts(filterNode.getPredicate());
if (conjuncts.stream().noneMatch(isSemiJoinSymbol)) {
return Result.empty();
}
RowExpression filteredPredicate = LogicalRowExpressions.and(conjuncts.stream().filter(expression -> !expression.equals(toVariableReference(semiJoinSymbol, types))).collect(toImmutableList()));
RowExpression simplifiedPredicate = inlineVariables(variable -> {
if (variable.equals(toVariableReference(semiJoinSymbol, types))) {
return TRUE_CONSTANT;
}
return variable;
}, filteredPredicate);
Optional<RowExpression> joinFilter = simplifiedPredicate.equals(TRUE_CONSTANT) ? Optional.empty() : Optional.of(simplifiedPredicate);
PlanNode filteringSourceDistinct = new AggregationNode(context.getIdAllocator().getNextId(), semiJoin.getFilteringSource(), ImmutableMap.of(), singleGroupingSet(ImmutableList.of(semiJoin.getFilteringSourceJoinSymbol())), ImmutableList.of(), SINGLE, Optional.empty(), Optional.empty(), AggregationNode.AggregationType.HASH, Optional.empty());
JoinNode innerJoin = new JoinNode(semiJoin.getId(), INNER, semiJoin.getSource(), filteringSourceDistinct, ImmutableList.of(new EquiJoinClause(semiJoin.getSourceJoinSymbol(), semiJoin.getFilteringSourceJoinSymbol())), semiJoin.getSource().getOutputSymbols(), joinFilter.isPresent() ? Optional.of(joinFilter.get()) : Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), // TODO: dynamic filter from SemiJoinNode
ImmutableMap.of());
ProjectNode project = new ProjectNode(context.getIdAllocator().getNextId(), innerJoin, Assignments.builder().putAll(AssignmentUtils.identityAsSymbolReferences(innerJoin.getOutputSymbols())).put(semiJoinSymbol, TRUE_CONSTANT).build());
return Result.ofPlanNode(project);
}
use of io.prestosql.sql.planner.plan.SemiJoinNode in project hetu-core by openlookeng.
the class SemiJoinMatcher 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());
SemiJoinNode semiJoinNode = (SemiJoinNode) node;
if (!(symbolAliases.get(sourceSymbolAlias).equals(toSymbolReference(semiJoinNode.getSourceJoinSymbol())) && symbolAliases.get(filteringSymbolAlias).equals(toSymbolReference(semiJoinNode.getFilteringSourceJoinSymbol())))) {
return NO_MATCH;
}
if (distributionType.isPresent() && !distributionType.equals(semiJoinNode.getDistributionType())) {
return NO_MATCH;
}
if (hasDynamicFilter.isPresent()) {
if (hasDynamicFilter.get()) {
if (!semiJoinNode.getDynamicFilterId().isPresent()) {
return NO_MATCH;
}
String dynamicFilterId = semiJoinNode.getDynamicFilterId().get();
List<DynamicFilters.Descriptor> matchingDescriptors = searchFrom(semiJoinNode.getSource()).where(FilterNode.class::isInstance).findAll().stream().flatMap(filterNode -> extractExpressions(filterNode).stream()).flatMap(expression -> extractDynamicFilters(expression).getDynamicConjuncts().stream()).filter(descriptor -> descriptor.getId().equals(dynamicFilterId)).collect(toImmutableList());
boolean sourceSymbolsMatch = matchingDescriptors.stream().map(descriptor -> new Symbol(((VariableReferenceExpression) descriptor.getInput()).getName())).allMatch(sourceSymbol -> symbolAliases.get(sourceSymbolAlias).equals(toSymbolReference(sourceSymbol)));
if (!matchingDescriptors.isEmpty() && sourceSymbolsMatch) {
return match(outputAlias, toSymbolReference(semiJoinNode.getSemiJoinOutput()));
}
return NO_MATCH;
}
if (semiJoinNode.getDynamicFilterId().isPresent()) {
return NO_MATCH;
}
}
return match(outputAlias, toSymbolReference(semiJoinNode.getSemiJoinOutput()));
}
Aggregations