Search in sources :

Example 1 with PluralPersistentAttribute

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);
}
Also used : PathException(org.hibernate.query.PathException) PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) HqlParser(org.hibernate.grammars.hql.HqlParser) ParsingException(org.hibernate.query.sqm.ParsingException) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) CollectionPart(org.hibernate.metamodel.mapping.CollectionPart)

Example 2 with PluralPersistentAttribute

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;
}
Also used : PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) HqlParser(org.hibernate.grammars.hql.HqlParser) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) DotIdentifierConsumer(org.hibernate.query.hql.spi.DotIdentifierConsumer) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode)

Example 3 with PluralPersistentAttribute

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);
}
Also used : SqmSelectableNode(org.hibernate.query.sqm.tree.select.SqmSelectableNode) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) SqmPath(org.hibernate.query.sqm.tree.domain.SqmPath) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 4 with PluralPersistentAttribute

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;
}
Also used : VirtualTableGroup(org.hibernate.sql.ast.tree.from.VirtualTableGroup) LazyTableGroup(org.hibernate.sql.ast.tree.from.LazyTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) CorrelatedTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedTableGroup) CorrelatedPluralTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) NavigablePath(org.hibernate.query.spi.NavigablePath) TableGroupJoinProducer(org.hibernate.sql.ast.tree.from.TableGroupJoinProducer) ConvertibleModelPart(org.hibernate.metamodel.mapping.ConvertibleModelPart) ModelPart(org.hibernate.metamodel.mapping.ModelPart) EntityValuedModelPart(org.hibernate.metamodel.mapping.EntityValuedModelPart) BasicValuedModelPart(org.hibernate.metamodel.mapping.BasicValuedModelPart) EmbeddableValuedModelPart(org.hibernate.metamodel.mapping.EmbeddableValuedModelPart) PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) CorrelatedPluralTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) TableGroupJoin(org.hibernate.sql.ast.tree.from.TableGroupJoin) SqmJoinType(org.hibernate.query.sqm.tree.SqmJoinType) PredicateCollector(org.hibernate.sql.ast.tree.predicate.PredicateCollector)

Example 5 with PluralPersistentAttribute

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;
}
Also used : PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) SqmListJoin(org.hibernate.query.sqm.tree.domain.SqmListJoin) SqmMapJoin(org.hibernate.query.sqm.tree.domain.SqmMapJoin) SqmPluralValuedSimplePath(org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath) HqlParser(org.hibernate.grammars.hql.HqlParser) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) DotIdentifierConsumer(org.hibernate.query.hql.spi.DotIdentifierConsumer) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) SemanticException(org.hibernate.query.SemanticException)

Aggregations

PluralPersistentAttribute (org.hibernate.metamodel.model.domain.PluralPersistentAttribute)7 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)3 HqlParser (org.hibernate.grammars.hql.HqlParser)3 StrictJpaComplianceViolation (org.hibernate.query.sqm.StrictJpaComplianceViolation)3 PathException (org.hibernate.query.PathException)2 DotIdentifierConsumer (org.hibernate.query.hql.spi.DotIdentifierConsumer)2 ParsingException (org.hibernate.query.sqm.ParsingException)2 BigInteger (java.math.BigInteger)1 ArrayList (java.util.ArrayList)1 ParseTree (org.antlr.v4.runtime.tree.ParseTree)1 BasicValuedModelPart (org.hibernate.metamodel.mapping.BasicValuedModelPart)1 CollectionPart (org.hibernate.metamodel.mapping.CollectionPart)1 ConvertibleModelPart (org.hibernate.metamodel.mapping.ConvertibleModelPart)1 EmbeddableValuedModelPart (org.hibernate.metamodel.mapping.EmbeddableValuedModelPart)1 EntityValuedModelPart (org.hibernate.metamodel.mapping.EntityValuedModelPart)1 ModelPart (org.hibernate.metamodel.mapping.ModelPart)1 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)1 SemanticException (org.hibernate.query.SemanticException)1 NavigablePath (org.hibernate.query.spi.NavigablePath)1 SqmJoinType (org.hibernate.query.sqm.tree.SqmJoinType)1