use of org.hibernate.sql.ast.spi.SqlAstQueryPartProcessingState in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitSelection.
@Override
public Void visitSelection(SqmSelection<?> sqmSelection) {
final List<Map.Entry<String, DomainResultProducer<?>>> resultProducers;
final SqmSelectableNode<?> selectionNode = sqmSelection.getSelectableNode();
if (selectionNode instanceof SqmJpaCompoundSelection<?>) {
final SqmJpaCompoundSelection<?> selectableNode = (SqmJpaCompoundSelection<?>) selectionNode;
resultProducers = new ArrayList<>(selectableNode.getSelectionItems().size());
for (SqmSelectableNode<?> selectionItem : selectableNode.getSelectionItems()) {
if (selectionItem instanceof SqmPath<?>) {
prepareForSelection((SqmPath<?>) selectionItem);
}
resultProducers.add(new AbstractMap.SimpleEntry<>(selectionItem.getAlias(), (DomainResultProducer<?>) selectionItem.accept(this)));
}
} else {
if (selectionNode instanceof SqmPath<?>) {
prepareForSelection((SqmPath<?>) selectionNode);
}
resultProducers = Collections.singletonList(new AbstractMap.SimpleEntry<>(sqmSelection.getAlias(), (DomainResultProducer<?>) selectionNode.accept(this)));
}
final Stack<SqlAstProcessingState> processingStateStack = getProcessingStateStack();
final boolean needsDomainResults = domainResults != null && currentClauseContributesToTopLevelSelectClause();
final boolean collectDomainResults;
if (processingStateStack.depth() == 1) {
collectDomainResults = needsDomainResults;
} else {
final SqlAstProcessingState current = processingStateStack.getCurrent();
// Since we only want to create domain results for the first/left-most query spec within query groups,
// we have to check if the current query spec is the left-most.
// This is the case when all upper level in-flight query groups are still empty
collectDomainResults = needsDomainResults && processingStateStack.findCurrentFirst(processingState -> {
if (!(processingState instanceof SqlAstQueryPartProcessingState)) {
return Boolean.FALSE;
}
if (processingState == current) {
return null;
}
final QueryPart part = ((SqlAstQueryPartProcessingState) processingState).getInflightQueryPart();
if (part instanceof QueryGroup) {
if (((QueryGroup) part).getQueryParts().isEmpty()) {
return null;
}
}
return Boolean.FALSE;
}) == null;
}
// arguments
if (collectDomainResults) {
resultProducers.forEach(entry -> {
if (!(entry.getValue() instanceof DynamicInstantiation<?>)) {
currentSqlSelectionCollector().next();
}
domainResults.add(entry.getValue().createDomainResult(entry.getKey(), this));
});
} else if (needsDomainResults) {
// We just create domain results for the purpose of creating selections
// This is necessary for top-level query specs within query groups to avoid cycles
resultProducers.forEach(entry -> {
if (!(entry.getValue() instanceof DynamicInstantiation<?>)) {
currentSqlSelectionCollector().next();
}
entry.getValue().createDomainResult(entry.getKey(), this);
});
} else {
resultProducers.forEach(entry -> {
if (!(entry.getValue() instanceof DynamicInstantiation<?>)) {
currentSqlSelectionCollector().next();
}
entry.getValue().applySqlSelections(this);
});
}
return null;
}
Aggregations