use of org.hibernate.metamodel.model.domain.PluralPersistentAttribute in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitCollectionFunctionMisuse.
@Override
public SqmPath<?> visitCollectionFunctionMisuse(HqlParser.CollectionFunctionMisuseContext ctx) {
if (getCreationOptions().useStrictJpaCompliance()) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION);
}
final SqmPath<?> pluralAttributePath = consumeDomainPath((HqlParser.PathContext) ctx.getChild(2));
final SqmPathSource<?> referencedPathSource = pluralAttributePath.getReferencedPathSource();
final TerminalNode firstNode = (TerminalNode) ctx.getChild(0);
if (!(referencedPathSource instanceof PluralPersistentAttribute<?, ?, ?>)) {
throw new PathException(String.format("Argument of '%s' is not a plural path '%s'", firstNode.getSymbol().getText(), pluralAttributePath.getNavigablePath()));
}
CollectionPart.Nature nature;
switch(firstNode.getSymbol().getType()) {
case ELEMENTS:
nature = CollectionPart.Nature.ELEMENT;
break;
case INDICES:
nature = CollectionPart.Nature.INDEX;
break;
default:
throw new ParsingException("Impossible symbol");
}
return pluralAttributePath.resolvePathPart(nature.getName(), true, this);
}
use of org.hibernate.metamodel.model.domain.PluralPersistentAttribute in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitCollectionValueNavigablePath.
@Override
public SqmPath<?> visitCollectionValueNavigablePath(HqlParser.CollectionValueNavigablePathContext ctx) {
final DotIdentifierConsumer consumer = dotIdentifierConsumerStack.getCurrent();
final boolean madeNested;
if (consumer instanceof QualifiedJoinPathConsumer) {
final QualifiedJoinPathConsumer qualifiedJoinPathConsumer = (QualifiedJoinPathConsumer) consumer;
madeNested = !qualifiedJoinPathConsumer.isNested();
if (madeNested) {
qualifiedJoinPathConsumer.setNested(true);
}
} else {
madeNested = false;
}
final SqmPath<?> sqmPath = consumeDomainPath((HqlParser.PathContext) ctx.getChild(2));
final boolean hasContinuation = ctx.getChildCount() == 5;
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
final TerminalNode firstNode = (TerminalNode) ctx.getChild(0);
checkPluralPath(sqmPath, referencedPathSource, firstNode);
if (getCreationOptions().useStrictJpaCompliance()) {
final PluralPersistentAttribute<?, ?, ?> attribute = (PluralPersistentAttribute<?, ?, ?>) referencedPathSource;
if (attribute.getCollectionClassification() != CollectionClassification.MAP && firstNode.getSymbol().getType() == HqlParser.VALUE) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.VALUE_FUNCTION_ON_NON_MAP);
}
}
SqmPath<?> result;
if (consumer instanceof QualifiedJoinPathConsumer) {
if (madeNested && !hasContinuation) {
// Reset the nested state before consuming the terminal identifier
((QualifiedJoinPathConsumer) consumer).setNested(false);
}
consumer.consumeIdentifier(CollectionPart.Nature.ELEMENT.getName(), false, !hasContinuation);
result = (SqmPath<?>) consumer.getConsumedPart();
} else {
result = sqmPath.resolvePathPart(CollectionPart.Nature.ELEMENT.getName(), true, this);
}
if (hasContinuation) {
if (madeNested) {
// Reset the nested state before consuming the terminal identifier
((QualifiedJoinPathConsumer) consumer).setNested(false);
}
final HqlParser.SimplePathContext identCtx = (HqlParser.SimplePathContext) ctx.getChild(4).getChild(1);
if (consumer instanceof QualifiedJoinPathConsumer) {
result = consumeDomainPath(identCtx);
} else {
dotIdentifierConsumerStack.push(new BasicDotIdentifierConsumer(result, this) {
@Override
protected void reset() {
}
});
try {
result = consumeDomainPath(identCtx);
} finally {
dotIdentifierConsumerStack.pop();
}
}
}
return result;
}
use of org.hibernate.metamodel.model.domain.PluralPersistentAttribute in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitSelectableNode.
private SqmSelectableNode<?> visitSelectableNode(HqlParser.SelectionContext ctx) {
final ParseTree subCtx = ctx.getChild(0).getChild(0);
if (subCtx instanceof HqlParser.ExpressionOrPredicateContext) {
final SqmExpression<?> sqmExpression = (SqmExpression<?>) subCtx.accept(this);
if (sqmExpression instanceof SqmPath) {
final SqmPath<?> sqmPath = (SqmPath<?>) sqmExpression;
if (sqmPath.getReferencedPathSource() instanceof PluralPersistentAttribute) {
// - this is not strictly JPA compliant
if (creationOptions.useStrictJpaCompliance()) {
SqmTreeCreationLogger.LOGGER.debugf("Raw selection of plural attribute not supported by JPA: %s. Use `value(%s)` or `key(%s)` to indicate what part of the collection to select", sqmPath.getAlias(), sqmPath.getAlias(), sqmPath.getAlias());
}
final SqmPath<?> elementPath = sqmPath.resolvePathPart(CollectionPart.Nature.ELEMENT.getName(), true, this);
processingStateStack.getCurrent().getPathRegistry().register(elementPath);
return elementPath;
}
}
return sqmExpression;
}
return (SqmSelectableNode<?>) subCtx.accept(this);
}
use of org.hibernate.metamodel.model.domain.PluralPersistentAttribute in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeAttributeJoin.
private TableGroup consumeAttributeJoin(SqmAttributeJoin<?, ?> sqmJoin, TableGroup lhsTableGroup, TableGroup ownerTableGroup, boolean transitive) {
final SqmPathSource<?> pathSource = sqmJoin.getReferencedPathSource();
final SqmJoinType sqmJoinType = sqmJoin.getSqmJoinType();
final TableGroupJoin joinedTableGroupJoin;
final TableGroup joinedTableGroup;
final NavigablePath sqmJoinNavigablePath = sqmJoin.getNavigablePath();
final ModelPart modelPart = ownerTableGroup.getModelPart().findSubPart(pathSource.getPathName(), SqmMappingModelHelper.resolveExplicitTreatTarget(sqmJoin, this));
if (pathSource instanceof PluralPersistentAttribute) {
assert modelPart instanceof PluralAttributeMapping;
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
if (sqmJoin.isFetched()) {
containsCollectionFetches = true;
}
joinedTableGroupJoin = pluralAttributeMapping.createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
pluralAttributeMapping.applyBaseRestrictions((predicate) -> {
final PredicateCollector existing = collectionFilterPredicates.get(joinedTableGroup.getGroupAlias());
final PredicateCollector collector;
if (existing == null) {
collector = new PredicateCollector(predicate);
collectionFilterPredicates.put(joinedTableGroup.getGroupAlias(), collector);
} else {
collector = existing;
collector.applyPredicate(predicate);
}
}, joinedTableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
} else {
assert modelPart instanceof TableGroupJoinProducer;
joinedTableGroupJoin = ((TableGroupJoinProducer) modelPart).createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
// Left or inner singular attribute joins without a predicate can be safely optimized away
if (sqmJoin.getJoinPredicate() != null || sqmJoinType != SqmJoinType.INNER && sqmJoinType != SqmJoinType.LEFT) {
joinedTableGroup.getPrimaryTableReference();
}
}
lhsTableGroup.addTableGroupJoin(joinedTableGroupJoin);
getFromClauseIndex().register(sqmJoin, joinedTableGroup);
registerPluralTableGroupParts(joinedTableGroup);
// For joins we also need to register the table groups for the treats
if (joinedTableGroup instanceof PluralTableGroup) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) joinedTableGroup;
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
if (pluralTableGroup.getElementTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.ELEMENT.getName()), pluralTableGroup.getElementTableGroup());
}
if (pluralTableGroup.getIndexTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.INDEX.getName()), pluralTableGroup.getIndexTableGroup());
}
}
} else {
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath(), joinedTableGroup);
}
}
// add any additional join restrictions
if (sqmJoin.getJoinPredicate() != null) {
if (sqmJoin.isFetched()) {
QueryLogging.QUERY_MESSAGE_LOGGER.debugf("Join fetch [" + sqmJoinNavigablePath + "] is restricted");
}
final SqmJoin<?, ?> oldJoin = currentlyProcessingJoin;
currentlyProcessingJoin = sqmJoin;
joinedTableGroupJoin.applyPredicate(visitNestedTopLevelPredicate(sqmJoin.getJoinPredicate()));
currentlyProcessingJoin = oldJoin;
}
if (transitive) {
consumeExplicitJoins(sqmJoin, joinedTableGroup);
}
return joinedTableGroup;
}
use of org.hibernate.metamodel.model.domain.PluralPersistentAttribute in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitMapKeyNavigablePath.
@Override
public SqmPath<?> visitMapKeyNavigablePath(HqlParser.MapKeyNavigablePathContext ctx) {
final DotIdentifierConsumer consumer = dotIdentifierConsumerStack.getCurrent();
final boolean madeNested;
if (consumer instanceof QualifiedJoinPathConsumer) {
final QualifiedJoinPathConsumer qualifiedJoinPathConsumer = (QualifiedJoinPathConsumer) consumer;
madeNested = !qualifiedJoinPathConsumer.isNested();
if (madeNested) {
qualifiedJoinPathConsumer.setNested(true);
}
} else {
madeNested = false;
}
final SqmPath<?> sqmPath = consumeDomainPath((HqlParser.PathContext) ctx.getChild(2));
final boolean hasContinuation = ctx.getChildCount() == 5;
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
final TerminalNode firstNode = (TerminalNode) ctx.getChild(0);
checkPluralPath(sqmPath, referencedPathSource, firstNode);
if (getCreationOptions().useStrictJpaCompliance()) {
final PluralPersistentAttribute<?, ?, ?> attribute = (PluralPersistentAttribute<?, ?, ?>) referencedPathSource;
if (attribute.getCollectionClassification() != CollectionClassification.MAP && firstNode.getSymbol().getType() == HqlParser.KEY) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.KEY_FUNCTION_ON_NON_MAP);
}
}
SqmPath<?> result;
if (sqmPath instanceof SqmMapJoin) {
final SqmMapJoin<?, ?, ?> sqmMapJoin = (SqmMapJoin<?, ?, ?>) sqmPath;
if (consumer instanceof QualifiedJoinPathConsumer) {
if (madeNested && !hasContinuation) {
// Reset the nested state before consuming the terminal identifier
((QualifiedJoinPathConsumer) consumer).setNested(false);
}
consumer.consumeIdentifier(CollectionPart.Nature.INDEX.getName(), false, !hasContinuation);
result = (SqmPath<?>) consumer.getConsumedPart();
} else {
result = sqmMapJoin.key();
}
} else if (sqmPath instanceof SqmListJoin) {
if (hasContinuation) {
throw new SemanticException("list index may not be dereferenced");
}
SqmListJoin<?, ?> listJoin = (SqmListJoin<?, ?>) sqmPath;
result = listJoin.resolvePathPart(CollectionPart.Nature.INDEX.getName(), true, this);
} else {
assert sqmPath instanceof SqmPluralValuedSimplePath;
final SqmPluralValuedSimplePath<?> mapPath = (SqmPluralValuedSimplePath<?>) sqmPath;
result = mapPath.resolvePathPart(CollectionPart.Nature.INDEX.getName(), !hasContinuation, this);
}
if (hasContinuation) {
if (madeNested) {
// Reset the nested state before consuming the terminal identifier
((QualifiedJoinPathConsumer) consumer).setNested(false);
}
final HqlParser.SimplePathContext identCtx = (HqlParser.SimplePathContext) ctx.getChild(4).getChild(1);
if (consumer instanceof QualifiedJoinPathConsumer) {
result = consumeDomainPath(identCtx);
} else {
dotIdentifierConsumerStack.push(new BasicDotIdentifierConsumer(result, this) {
@Override
protected void reset() {
}
});
try {
result = consumeDomainPath(identCtx);
} finally {
dotIdentifierConsumerStack.pop();
}
}
}
return result;
}
Aggregations