use of org.hibernate.metamodel.mapping.PluralAttributeMapping 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.mapping.PluralAttributeMapping in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitIsEmptyPredicate.
@Override
public Object visitIsEmptyPredicate(SqmEmptinessPredicate predicate) {
prepareReusablePath(predicate.getPluralPath(), () -> null);
final QuerySpec subQuerySpec = new QuerySpec(false, 1);
final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
final SqlAstProcessingStateImpl subQueryState = new SqlAstProcessingStateImpl(getCurrentProcessingState(), this, currentClauseStack::getCurrent);
pushProcessingState(subQueryState);
try {
final SqmPluralValuedSimplePath<?> sqmPluralPath = predicate.getPluralPath();
final NavigablePath pluralPathNavPath = sqmPluralPath.getNavigablePath();
final NavigablePath parentNavPath = pluralPathNavPath.getParent();
assert parentNavPath != null;
final TableGroup parentTableGroup = parentFromClauseAccess.getTableGroup(parentNavPath);
final SqlAliasBase sqlAliasBase = sqlAliasBaseManager.createSqlAliasBase(parentTableGroup.getGroupAlias());
final TableGroup tableGroup = new CorrelatedTableGroup(parentTableGroup, sqlAliasBase, subQuerySpec, subQuerySpec::applyPredicate, creationContext.getSessionFactory());
subQueryState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup(parentNavPath, tableGroup);
registerPluralTableGroupParts(tableGroup);
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) visitPluralValuedPath(sqmPluralPath).getExpressionType();
// The creation of the table group join against the correlated table group
// has the side effect that the from and where clause of the sub-query are set
tableGroup.addTableGroupJoin(pluralAttributeMapping.createTableGroupJoin(pluralPathNavPath, tableGroup, sqmPluralPath.getExplicitAlias(), SqlAstJoinType.INNER, false, false, sqlAliasBaseManager, subQueryState, this, creationContext));
final ForeignKeyDescriptor collectionKeyDescriptor = pluralAttributeMapping.getKeyDescriptor();
final int jdbcTypeCount = collectionKeyDescriptor.getJdbcTypeCount();
assert jdbcTypeCount > 0;
final JdbcLiteral<Integer> jdbcLiteral = new JdbcLiteral<>(1, basicType(Integer.class));
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, jdbcLiteral));
return new ExistsPredicate(subQuerySpec, !predicate.isNegated(), getBooleanType());
} finally {
popProcessingStateStack();
}
}
use of org.hibernate.metamodel.mapping.PluralAttributeMapping in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method pruneTableGroupJoins.
protected void pruneTableGroupJoins() {
for (Map.Entry<TableGroup, Set<String>> entry : tableGroupTreatUsages.entrySet()) {
final TableGroup tableGroup = entry.getKey();
final Set<String> treatedEntityNames = entry.getValue();
final ModelPartContainer modelPart = tableGroup.getModelPart();
final EntityPersister tableGroupPersister;
if (modelPart instanceof PluralAttributeMapping) {
tableGroupPersister = (EntityPersister) ((PluralAttributeMapping) modelPart).getElementDescriptor().getPartMappingType();
} else {
tableGroupPersister = (EntityPersister) modelPart.getPartMappingType();
}
tableGroupPersister.pruneForSubclasses(tableGroup, treatedEntityNames);
}
}
use of org.hibernate.metamodel.mapping.PluralAttributeMapping in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitPluralAttributeSizeFunction.
@Override
public Expression visitPluralAttributeSizeFunction(SqmCollectionSize function) {
final SqmPath<?> pluralPath = function.getPluralPath();
prepareReusablePath(pluralPath, () -> null);
final TableGroup parentTableGroup = getFromClauseAccess().getTableGroup(pluralPath.getNavigablePath().getParent());
assert parentTableGroup != null;
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) parentTableGroup.getModelPart().findSubPart(pluralPath.getNavigablePath().getUnaliasedLocalName(), null);
assert pluralAttributeMapping != null;
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final AbstractSqmSelfRenderingFunctionDescriptor functionDescriptor = (AbstractSqmSelfRenderingFunctionDescriptor) creationContext.getSessionFactory().getQueryEngine().getSqmFunctionRegistry().findFunctionDescriptor("count");
final BasicType<Integer> integerType = creationContext.getMappingMetamodel().getTypeConfiguration().getBasicTypeForJavaType(Integer.class);
final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression(functionDescriptor.getName(), functionDescriptor, Collections.singletonList(new QueryLiteral<>(1, integerType)), null, integerType, integerType);
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, expression));
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentTableGroup, tableGroup, getSqlExpressionResolver(), creationContext));
} finally {
popProcessingStateStack();
}
return subQuerySpec;
}
use of org.hibernate.metamodel.mapping.PluralAttributeMapping in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method createCorrelatedAggregateSubQuery.
protected Expression createCorrelatedAggregateSubQuery(AbstractSqmSpecificPluralPartPath<?> pluralPartPath, boolean index, String function) {
prepareReusablePath(pluralPartPath.getLhs(), () -> null);
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) determineValueMapping(pluralPartPath.getPluralDomainPath());
final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPartPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPartPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final AbstractSqmSelfRenderingFunctionDescriptor functionDescriptor = (AbstractSqmSelfRenderingFunctionDescriptor) creationContext.getSessionFactory().getQueryEngine().getSqmFunctionRegistry().findFunctionDescriptor(function);
final CollectionPart collectionPart = index ? pluralAttributeMapping.getIndexDescriptor() : pluralAttributeMapping.getElementDescriptor();
final ModelPart modelPart;
if (collectionPart instanceof EntityAssociationMapping) {
modelPart = ((EntityAssociationMapping) collectionPart).getKeyTargetMatchPart();
} else {
modelPart = collectionPart;
}
final List<Expression> arguments = new ArrayList<>(1);
final NavigablePath navigablePath = pluralPartPath.getNavigablePath();
final int jdbcTypeCount = modelPart.getJdbcTypeCount();
final List<Expression> tupleElements;
if (jdbcTypeCount == 1) {
tupleElements = arguments;
} else {
tupleElements = new ArrayList<>(jdbcTypeCount);
}
modelPart.forEachSelectable((selectionIndex, selectionMapping) -> tupleElements.add(new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectionMapping.getContainingTableExpression()), selectionMapping, creationContext.getSessionFactory())));
if (jdbcTypeCount != 1) {
arguments.add(new SqlTuple(tupleElements, modelPart));
}
final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression(functionDescriptor.getName(), functionDescriptor, arguments, null, (ReturnableType<?>) functionDescriptor.getReturnTypeResolver().resolveFunctionReturnType(() -> null, arguments).getJdbcMapping(), modelPart);
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, expression));
NavigablePath parent = pluralPartPath.getPluralDomainPath().getNavigablePath().getParent();
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentFromClauseAccess.findTableGroup(parent), tableGroup, getSqlExpressionResolver(), creationContext));
} finally {
popProcessingStateStack();
}
return subQuerySpec;
}
Aggregations