use of org.hibernate.query.sqm.tree.domain.AbstractSqmFrom in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method createCollectionReferenceSubQuery.
private <X> SqmSubQuery<X> createCollectionReferenceSubQuery(HqlParser.SimplePathContext pathCtx, TerminalNode collectionReferenceCtx) {
final SqmPath<?> pluralAttributePath = consumeDomainPath(pathCtx);
final SqmPathSource<?> referencedPathSource = pluralAttributePath.getReferencedPathSource();
if (!(referencedPathSource instanceof PluralPersistentAttribute)) {
throw new PathException("Path is not a plural path '" + pluralAttributePath.getNavigablePath() + "'");
}
final SqmSubQuery<?> subQuery = new SqmSubQuery<>(processingStateStack.getCurrent().getProcessingQuery(), creationContext.getNodeBuilder());
final SqmSelectClause selectClause = new SqmSelectClause(false, 1, creationContext.getNodeBuilder());
final SqmFromClause fromClause = new SqmFromClause(1);
SqmPath<?> lhs = pluralAttributePath.getLhs();
final List<String> implicitJoinPaths = new ArrayList<>();
while (!(lhs instanceof AbstractSqmFrom<?, ?>)) {
implicitJoinPaths.add(lhs.getNavigablePath().getUnaliasedLocalName());
lhs = lhs.getLhs();
}
final AbstractSqmFrom<?, ?> correlationBase = (AbstractSqmFrom<?, ?>) lhs;
final SqmCorrelation<?, ?> correlation = correlationBase.createCorrelation();
SqmFrom<?, ?> joinBase = correlation;
for (int i = implicitJoinPaths.size() - 1; i >= 0; i--) {
joinBase = joinBase.join(implicitJoinPaths.get(i));
}
final SqmAttributeJoin<?, ?> collectionJoin = joinBase.join(pluralAttributePath.getNavigablePath().getUnaliasedLocalName());
fromClause.addRoot(correlation.getCorrelatedRoot());
if (collectionReferenceCtx == null) {
final SqmLiteral<Integer> literal = new SqmLiteral<>(1, creationContext.getNodeBuilder().getIntegerType(), creationContext.getNodeBuilder());
subQuery.applyInferableType(literal.getNodeType());
selectClause.setSelection(literal);
} else {
final String partName;
switch(collectionReferenceCtx.getSymbol().getType()) {
case HqlParser.ELEMENTS:
partName = CollectionPart.Nature.ELEMENT.getName();
break;
case HqlParser.INDICES:
partName = CollectionPart.Nature.INDEX.getName();
break;
default:
throw new ParsingException("Unexpected collection reference : " + collectionReferenceCtx.getText());
}
final SqmPath<?> path = collectionJoin.resolvePathPart(partName, true, this);
subQuery.applyInferableType(path.getNodeType());
selectClause.setSelection(path);
}
final SqmQuerySpec<?> querySpec = subQuery.getQuerySpec();
querySpec.setFromClause(fromClause);
querySpec.setSelectClause(selectClause);
// noinspection unchecked
return (SqmSubQuery<X>) subQuery;
}
Aggregations