HHH-17667 Fix pruning of root table with discriminator predicate

This commit is contained in:
Marco Belladelli 2024-01-23 15:00:17 +01:00 committed by Christian Beikov
parent ce0217df46
commit 236e3e2228
1 changed files with 50 additions and 56 deletions

View File

@ -93,7 +93,6 @@ import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.EntityNameUse; import org.hibernate.persister.entity.EntityNameUse;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.query.BindableType; import org.hibernate.query.BindableType;
import org.hibernate.query.QueryLogging; import org.hibernate.query.QueryLogging;
import org.hibernate.query.ReturnableType; import org.hibernate.query.ReturnableType;
@ -3167,9 +3166,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
registerEntityNameUsage( tableGroup, EntityNameUse.PROJECTION, persister.getEntityName(), true ); registerEntityNameUsage( tableGroup, EntityNameUse.PROJECTION, persister.getEntityName(), true );
} }
else { else {
// Avoid doing this for single table entity persisters, as the table span includes secondary tables, // Avoid resolving subclass tables for persisters with physical discriminators as we won't need them
// which we don't want to resolve, though we know that there is only a single table anyway if ( persister.getDiscriminatorMapping().hasPhysicalColumn() ) {
if ( persister instanceof SingleTableEntityPersister ) {
return; return;
} }
final int subclassTableSpan = persister.getSubclassTableSpan(); final int subclassTableSpan = persister.getSubclassTableSpan();
@ -7557,46 +7555,56 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
else { else {
return; return;
} }
if ( literalExpression == null ) { handleTypeComparison(
typeExpression,
literalExpression != null ? singletonList( literalExpression ) : null,
inclusive
);
}
private void handleTypeComparison(
DiscriminatorPathInterpretation<?> typeExpression,
List<EntityTypeLiteral> literalExpressions,
boolean inclusive) {
final TableGroup tableGroup = getFromClauseIndex().getTableGroup( typeExpression.getNavigablePath().getParent() );
final EntityMappingType entityMappingType = (EntityMappingType) tableGroup.getModelPart().getPartMappingType();
if ( entityMappingType.getDiscriminatorMapping().hasPhysicalColumn() ) {
// Prevent pruning of the root type's table reference containing the physical discriminator column
registerEntityNameUsage(
tableGroup,
EntityNameUse.EXPRESSION,
entityMappingType.getRootEntityDescriptor().getEntityName()
);
}
if ( literalExpressions == null ) {
// We have to assume all types are possible and can't do optimizations // We have to assume all types are possible and can't do optimizations
final TableGroup tableGroup = getFromClauseIndex().getTableGroup( typeExpression.getNavigablePath().getParent() );
final EntityMappingType entityMappingType = (EntityMappingType) tableGroup.getModelPart().getPartMappingType();
registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, entityMappingType.getEntityName() ); registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, entityMappingType.getEntityName() );
for ( EntityMappingType subMappingType : entityMappingType.getSubMappingTypes() ) { for ( EntityMappingType subMappingType : entityMappingType.getSubMappingTypes() ) {
registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, subMappingType.getEntityName() ); registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, subMappingType.getEntityName() );
} }
} }
else { else {
handleTypeComparison( typeExpression, Collections.singletonList( literalExpression ), inclusive ); if ( inclusive ) {
} for ( EntityTypeLiteral literalExpr : literalExpressions ) {
} registerEntityNameUsage(
tableGroup,
private void handleTypeComparison( EntityNameUse.FILTER,
DiscriminatorPathInterpretation typeExpression, literalExpr.getEntityTypeDescriptor().getEntityName()
List<EntityTypeLiteral> literalExpressions, );
boolean inclusive) { }
final TableGroup tableGroup = getFromClauseIndex().getTableGroup( typeExpression.getNavigablePath().getParent() );
if ( inclusive ) {
for ( EntityTypeLiteral literalExpr : literalExpressions ) {
registerEntityNameUsage(
tableGroup,
EntityNameUse.FILTER,
literalExpr.getEntityTypeDescriptor().getEntityName()
);
} }
} else {
else { final Set<String> excludedEntityNames = new HashSet<>( entityMappingType.getSubMappingTypes().size() );
final EntityMappingType entityMappingType = (EntityMappingType) tableGroup.getModelPart().getPartMappingType(); for ( EntityTypeLiteral literalExpr : literalExpressions ) {
final Set<String> excludedEntityNames = new HashSet<>(entityMappingType.getSubMappingTypes().size()); excludedEntityNames.add( literalExpr.getEntityTypeDescriptor().getEntityName() );
for ( EntityTypeLiteral literalExpr : literalExpressions ) { }
excludedEntityNames.add( literalExpr.getEntityTypeDescriptor().getEntityName() ); if ( !excludedEntityNames.contains( entityMappingType.getEntityName() ) ) {
} registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, entityMappingType.getEntityName() );
if ( !excludedEntityNames.contains( entityMappingType.getEntityName() ) ) { }
registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, entityMappingType.getEntityName() ); for ( EntityMappingType subMappingType : entityMappingType.getSubMappingTypes() ) {
} if ( !excludedEntityNames.contains( subMappingType.getEntityName() ) ) {
for ( EntityMappingType subMappingType : entityMappingType.getSubMappingTypes() ) { registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, subMappingType.getEntityName() );
if ( !excludedEntityNames.contains( subMappingType.getEntityName() ) ) { }
registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, subMappingType.getEntityName() );
} }
} }
} }
@ -7852,26 +7860,12 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
break; break;
} }
} }
if ( containsNonLiteral ) { //noinspection unchecked
// We have to assume all types are possible and can't do optimizations handleTypeComparison(
final TableGroup tableGroup = getFromClauseIndex().getTableGroup( typeExpression,
typeExpression.getNavigablePath().getParent() containsNonLiteral ? null : (List<EntityTypeLiteral>) (List<?>) inPredicate.getListExpressions(),
); !inPredicate.isNegated()
final EntityMappingType entityMappingType = (EntityMappingType) tableGroup.getModelPart() );
.getPartMappingType();
registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, entityMappingType.getEntityName() );
for ( EntityMappingType subMappingType : entityMappingType.getSubMappingTypes() ) {
registerEntityNameUsage( tableGroup, EntityNameUse.FILTER, subMappingType.getEntityName() );
}
}
else {
//noinspection unchecked
handleTypeComparison(
typeExpression,
(List<EntityTypeLiteral>) (List<?>) inPredicate.getListExpressions(),
!inPredicate.isNegated()
);
}
} }
} }