diff --git a/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java b/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java index 04ca27773d64..1b261825371e 100644 --- a/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/binder/internal/TenantIdBinder.java @@ -6,6 +6,7 @@ import java.util.Collections; +import org.hibernate.AssertionFailure; import org.hibernate.MappingException; import org.hibernate.annotations.TenantId; import org.hibernate.binder.AttributeBinder; @@ -17,9 +18,9 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; +import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.java.JavaType; -import org.hibernate.type.spi.TypeConfiguration; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; @@ -41,12 +42,11 @@ public void bind( PersistentClass persistentClass, Property property) { final InFlightMetadataCollector collector = buildingContext.getMetadataCollector(); - final TypeConfiguration typeConfiguration = collector.getTypeConfiguration(); final String returnedClassName = property.getReturnedClassName(); - final BasicType tenantIdType = typeConfiguration - .getBasicTypeRegistry() - .getRegisteredType( returnedClassName ); + final BasicType tenantIdType = + collector.getTypeConfiguration().getBasicTypeRegistry() + .getRegisteredType( returnedClassName ); final FilterDefinition filterDefinition = collector.getFilterDefinition( FILTER_NAME ); if ( filterDefinition == null ) { @@ -63,13 +63,13 @@ public void bind( } else { final JavaType tenantIdTypeJtd = tenantIdType.getJavaTypeDescriptor(); - final JavaType parameterJtd = filterDefinition - .getParameterJdbcMapping( PARAMETER_NAME ) - .getJavaTypeDescriptor(); - if ( !parameterJtd.getJavaTypeClass().equals( tenantIdTypeJtd.getJavaTypeClass() ) ) { + final JdbcMapping jdbcMapping = filterDefinition.getParameterJdbcMapping( PARAMETER_NAME ); + assert jdbcMapping != null; + final JavaType parameterJavaType = jdbcMapping.getJavaTypeDescriptor(); + if ( !parameterJavaType.getJavaTypeClass().equals( tenantIdTypeJtd.getJavaTypeClass() ) ) { throw new MappingException( "all @TenantId fields must have the same type: " - + parameterJtd.getTypeName() + + parameterJavaType.getTypeName() + " differs from " + tenantIdTypeJtd.getTypeName() ); @@ -93,10 +93,16 @@ private String columnNameOrFormula(Property property) { if ( property.getColumnSpan() != 1 ) { throw new MappingException( "@TenantId attribute must be mapped to a single column or formula" ); } - Selectable selectable = property.getSelectables().get( 0 ); - return selectable.isFormula() - ? ( (Formula) selectable ).getFormula() - : ( (Column) selectable ).getName(); + final Selectable selectable = property.getSelectables().get( 0 ); + if ( selectable instanceof Formula formula ) { + return formula.getFormula(); + } + else if ( selectable instanceof Column column ) { + return column.getName(); + } + else { + throw new AssertionFailure( "@TenantId attribute must be mapped to a column or formula" ); + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/AggregateWindowEmulationQueryTransformer.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/AggregateWindowEmulationQueryTransformer.java index 2decb90df319..46fec75ff6e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/AggregateWindowEmulationQueryTransformer.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/AggregateWindowEmulationQueryTransformer.java @@ -125,7 +125,7 @@ public QuerySpec transform( final Expression expression = subSelections.get( i ).getExpression(); final Expression finalExpression; if ( expression == windowFunction ) { - finalExpression = new SelfRenderingAggregateFunctionSqlAstExpression( + finalExpression = new SelfRenderingAggregateFunctionSqlAstExpression<>( "min", (sqlAppender, sqlAstArguments, returnType, walker1) -> { sqlAppender.appendSql( "min(" ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/CastFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/CastFunction.java index db8aa9ca3e1a..b820eb0ec6ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/CastFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/CastFunction.java @@ -105,7 +105,7 @@ public static void renderCastArrayToString( sqlAppender, List.of( new QueryLiteral<>( "[", stringType ), - new SelfRenderingFunctionSqlAstExpression( + new SelfRenderingFunctionSqlAstExpression<>( "array_to_string", arrayToStringDescriptor, List.of( diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/HypotheticalSetWindowEmulation.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/HypotheticalSetWindowEmulation.java index 5a6a784e4ad6..56da7a7c778b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/HypotheticalSetWindowEmulation.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/HypotheticalSetWindowEmulation.java @@ -5,7 +5,6 @@ package org.hibernate.dialect.function; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import org.hibernate.metamodel.model.domain.ReturnableType; @@ -28,6 +27,8 @@ import org.hibernate.type.BasicTypeReference; import org.hibernate.type.spi.TypeConfiguration; +import static java.util.Collections.emptyList; + /** * @author Christian Beikov */ @@ -79,7 +80,7 @@ else if ( currentClause != Clause.SELECT ) { } List withinGroup; if ( this.getWithinGroup() == null ) { - withinGroup = Collections.emptyList(); + withinGroup = emptyList(); } else { walker.getCurrentClauseStack().push( Clause.ORDER ); @@ -97,15 +98,16 @@ else if ( currentClause != Clause.SELECT ) { walker.getCurrentClauseStack().pop(); } } - final SelfRenderingFunctionSqlAstExpression function = new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression( - getFunctionName(), - getFunctionRenderer(), - Collections.emptyList(), - getFilter() == null ? null : (Predicate) getFilter().accept( walker ), - Collections.emptyList(), - resultType, - getMappingModelExpressible( walker, resultType, arguments ) - ); + final SelfRenderingFunctionSqlAstExpression function = + new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression<>( + getFunctionName(), + getFunctionRenderer(), + emptyList(), + getFilter() == null ? null : (Predicate) getFilter().accept( walker ), + emptyList(), + resultType, + getMappingModelExpressible( walker, resultType, arguments ) + ); final Over windowFunction = new Over<>( function, new ArrayList<>(), withinGroup ); walker.registerQueryTransformer( new AggregateWindowEmulationQueryTransformer( windowFunction, withinGroup, arguments ) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionWindowEmulation.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionWindowEmulation.java index a823d2b569f3..f383b7ab8f38 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionWindowEmulation.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionWindowEmulation.java @@ -67,12 +67,12 @@ else if ( currentClause != Clause.SELECT ) { } final ReturnableType resultType = resolveResultType( walker ); - List arguments = resolveSqlAstArguments( getArguments(), walker ); - ArgumentsValidator argumentsValidator = getArgumentsValidator(); + final List arguments = resolveSqlAstArguments( getArguments(), walker ); + final ArgumentsValidator argumentsValidator = getArgumentsValidator(); if ( argumentsValidator != null ) { argumentsValidator.validateSqlTypes( arguments, getFunctionName() ); } - List withinGroup; + final List withinGroup; if ( this.getWithinGroup() == null ) { withinGroup = Collections.emptyList(); } @@ -92,15 +92,16 @@ else if ( currentClause != Clause.SELECT ) { walker.getCurrentClauseStack().pop(); } } - final SelfRenderingFunctionSqlAstExpression function = new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression( - getFunctionName(), - getFunctionRenderer(), - arguments, - getFilter() == null ? null : (Predicate) getFilter().accept( walker ), - withinGroup, - resultType, - getMappingModelExpressible( walker, resultType, arguments ) - ); + final SelfRenderingFunctionSqlAstExpression function = + new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression<>( + getFunctionName(), + getFunctionRenderer(), + arguments, + getFilter() == null ? null : (Predicate) getFilter().accept( walker ), + withinGroup, + resultType, + getMappingModelExpressible( walker, resultType, arguments ) + ); final Over windowFunction = new Over<>( function, new ArrayList<>(), Collections.emptyList() ); walker.registerQueryTransformer( new AggregateWindowEmulationQueryTransformer( windowFunction, withinGroup, null ) diff --git a/hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java b/hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java index 0c0f9b22e64f..a6e26b0ed04d 100644 --- a/hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java @@ -34,9 +34,12 @@ * @author Steve Ebersole * @author Gavin King */ -public abstract class AttributeNodeImpl +public abstract sealed class AttributeNodeImpl extends AbstractGraphNode - implements AttributeNodeImplementor { + implements AttributeNodeImplementor + permits AttributeNodeImpl.SingularAttributeNodeImpl, + AttributeNodeImpl.PluralAttributeNodeImpl, + AttributeNodeImpl.MapAttributeNodeImpl { protected final PersistentAttribute attribute; protected final DomainType valueGraphType; @@ -100,7 +103,7 @@ private AttributeNodeImpl(AttributeNodeImpl that, boolean mutable) { keySubgraph = that.keySubgraph == null ? null : that.keySubgraph.makeCopy( mutable ); } - private static class SingularAttributeNodeImpl extends AttributeNodeImpl { + static final class SingularAttributeNodeImpl extends AttributeNodeImpl { private SingularAttributeNodeImpl( SingularPersistentAttribute attribute, boolean mutable, @@ -128,7 +131,7 @@ public AttributeNodeImplementor makeCopy(boolean mutable) { } } - private static class PluralAttributeNodeImpl extends AttributeNodeImpl { + static final class PluralAttributeNodeImpl extends AttributeNodeImpl { private PluralAttributeNodeImpl( PluralPersistentAttribute attribute, boolean mutable, @@ -156,7 +159,7 @@ public AttributeNodeImplementor makeCopy(boolean mutable) { } } - static class MapAttributeNodeImpl extends AttributeNodeImpl { + static final class MapAttributeNodeImpl extends AttributeNodeImpl { private MapAttributeNodeImpl( PluralPersistentAttribute pluralAttribute, @SuppressWarnings("unused") // a "witness" that this is really a Map diff --git a/hibernate-core/src/main/java/org/hibernate/id/ExportableColumn.java b/hibernate-core/src/main/java/org/hibernate/id/ExportableColumn.java deleted file mode 100644 index 5eee974a37fc..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/id/ExportableColumn.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-or-later - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.id; - -import java.util.List; - -import org.hibernate.FetchMode; -import org.hibernate.MappingException; -import org.hibernate.boot.model.relational.Database; -import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.internal.util.collections.ArrayHelper; -import org.hibernate.mapping.Column; -import org.hibernate.mapping.Selectable; -import org.hibernate.mapping.Table; -import org.hibernate.mapping.Value; -import org.hibernate.mapping.ValueVisitor; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.type.BasicType; -import org.hibernate.type.Type; -import org.hibernate.type.MappingContext; - -/** - * @author Steve Ebersole - */ -public class ExportableColumn extends Column { - - public ExportableColumn(Database database, Table table, String name, BasicType type) { - this( - database, - table, - name, - type, - database.getTypeConfiguration() - .getDdlTypeRegistry() - .getTypeName( type.getJdbcType().getDdlTypeCode(), database.getDialect() ) - ); - } - - public ExportableColumn( - Database database, - Table table, - String name, - BasicType type, - String dbTypeDeclaration) { - super( name ); - setValue( new ValueImpl( this, table, type, database ) ); - setSqlType( dbTypeDeclaration ); - } - - public static class ValueImpl implements Value { - private final ExportableColumn column; - private final Table table; - private final BasicType type; - private final Database database; - - public ValueImpl(ExportableColumn column, Table table, BasicType type, Database database) { - this.column = column; - this.table = table; - this.type = type; - this.database = database; - } - - @Override - public Value copy() { - return new ValueImpl( column, table, type, database ); - } - - @Override - public int getColumnSpan() { - return 1; - } - - @Override - public List getSelectables() { - return List.of( column ); - } - - @Override - public List getColumns() { - return List.of( column ); - } - - @Override - public Type getType() { - return type; - } - - @Override - public FetchMode getFetchMode() { - return null; - } - - @Override - public Table getTable() { - return table; - } - - @Override - public boolean hasFormula() { - return false; - } - - @Override - public boolean isAlternateUniqueKey() { - return false; - } - - @Override - public boolean isNullable() { - return false; - } - - @Override - public boolean[] getColumnInsertability() { - return ArrayHelper.TRUE; - } - - @Override - public boolean hasAnyInsertableColumns() { - return true; - } - - @Override - public boolean[] getColumnUpdateability() { - return ArrayHelper.TRUE; - } - - @Override - public boolean hasAnyUpdatableColumns() { - return true; - } - - @Override - public void createForeignKey() { - } - - @Override - public void createUniqueKey(MetadataBuildingContext context) { - } - - @Override - public boolean isSimpleValue() { - return true; - } - - @Override - public boolean isValid(MappingContext mappingContext) throws MappingException { - return false; - } - - @Override - public void setTypeUsingReflection(String className, String propertyName) throws MappingException { - } - - @Override - public Object accept(ValueVisitor visitor) { - return null; - } - - @Override - public boolean isSame(Value value) { - return false; - } - - @Override - public ServiceRegistry getServiceRegistry() { - return database.getServiceRegistry(); - } - - @Override - public boolean isColumnInsertable(int index) { - return true; - } - - @Override - public boolean isColumnUpdateable(int index) { - return true; - } - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java new file mode 100644 index 000000000000..70a195a8549b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java @@ -0,0 +1,149 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.id.enhanced; + +import org.hibernate.FetchMode; +import org.hibernate.MappingException; +import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.Selectable; +import org.hibernate.mapping.Table; +import org.hibernate.mapping.Value; +import org.hibernate.mapping.ValueVisitor; +import org.hibernate.service.ServiceRegistry; +import org.hibernate.type.BasicType; +import org.hibernate.type.MappingContext; +import org.hibernate.type.Type; + +import java.util.List; + +class ExportableColumnHelper { + + static Column column(Database database, Table table, String segmentColumnName, BasicType type, String typeName) { + final Column column = new Column( segmentColumnName ); + column.setSqlType( typeName ); + column.setValue( new Value() { + @Override + public Value copy() { + return this; + } + + @Override + public int getColumnSpan() { + return 1; + } + + @Override + public List getSelectables() { + return List.of( column ); + } + + @Override + public List getColumns() { + return List.of( column ); + } + + @Override + public Type getType() { + return type; + } + + @Override + public FetchMode getFetchMode() { + return null; + } + + @Override + public Table getTable() { + return table; + } + + @Override + public boolean hasFormula() { + return false; + } + + @Override + public boolean isAlternateUniqueKey() { + return false; + } + + @Override + public boolean isNullable() { + return false; + } + + @Override + public boolean[] getColumnInsertability() { + return ArrayHelper.TRUE; + } + + @Override + public boolean hasAnyInsertableColumns() { + return true; + } + + @Override + public boolean[] getColumnUpdateability() { + return ArrayHelper.TRUE; + } + + @Override + public boolean hasAnyUpdatableColumns() { + return true; + } + + @Override + public void createForeignKey() { + } + + @Override + public void createUniqueKey(MetadataBuildingContext context) { + } + + @Override + public boolean isSimpleValue() { + return true; + } + + @Override + public boolean isValid(MappingContext mappingContext) throws MappingException { + return false; + } + + @Override + public void setTypeUsingReflection(String className, String propertyName) { + } + + @Override + public Object accept(ValueVisitor visitor) { + return null; + } + + @Override + public boolean isSame(Value value) { + return this == value; + } + + @Override + public ServiceRegistry getServiceRegistry() { + return database.getServiceRegistry(); + } + + @Override + public boolean isColumnInsertable(int index) { + return true; + } + + @Override + public boolean isColumnUpdateable(int index) { + return true; + } + } ); + return column; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java index fe4eb6e2fcae..272bf5cd211c 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java @@ -37,7 +37,6 @@ import org.hibernate.event.monitor.spi.EventMonitor; import org.hibernate.event.monitor.spi.DiagnosticEvent; import org.hibernate.generator.GeneratorCreationContext; -import org.hibernate.id.ExportableColumn; import org.hibernate.id.IdentifierGeneratorHelper; import org.hibernate.id.IntegralDataTypeHolder; import org.hibernate.id.PersistentIdentifierGenerator; @@ -48,10 +47,12 @@ import org.hibernate.mapping.Table; import org.hibernate.service.ServiceRegistry; import org.hibernate.stat.spi.StatisticsImplementor; +import org.hibernate.type.BasicType; import org.hibernate.type.BasicTypeRegistry; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; +import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry; import org.jboss.logging.Logger; import static java.util.Collections.singletonMap; @@ -695,14 +696,13 @@ public void registerExportables(Database database) { final BasicTypeRegistry basicTypeRegistry = database.getTypeConfiguration().getBasicTypeRegistry(); // todo : not sure the best solution here. do we add the columns if missing? other? - final Column segmentColumn = new ExportableColumn( + final DdlTypeRegistry ddlTypeRegistry = database.getTypeConfiguration().getDdlTypeRegistry(); + final Column segmentColumn = ExportableColumnHelper.column( database, table, segmentColumnName, basicTypeRegistry.resolve( StandardBasicTypes.STRING ), - database.getTypeConfiguration() - .getDdlTypeRegistry() - .getTypeName( Types.VARCHAR, Size.length( segmentValueLength ) ) + ddlTypeRegistry.getTypeName( Types.VARCHAR, Size.length( segmentValueLength ) ) ); segmentColumn.setNullable( false ); table.addColumn( segmentColumn ); @@ -711,11 +711,13 @@ public void registerExportables(Database database) { table.setPrimaryKey( new PrimaryKey( table ) ); table.getPrimaryKey().addColumn( segmentColumn ); - final Column valueColumn = new ExportableColumn( + final BasicType type = basicTypeRegistry.resolve( StandardBasicTypes.LONG ); + final Column valueColumn = ExportableColumnHelper.column( database, table, valueColumnName, - basicTypeRegistry.resolve( StandardBasicTypes.LONG ) + type, + ddlTypeRegistry.getTypeName( type.getJdbcType().getDdlTypeCode(), database.getDialect() ) ); table.addColumn( valueColumn ); } diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java index 782b5786083a..aa42dc0a760b 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java @@ -25,15 +25,17 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.event.monitor.spi.EventMonitor; import org.hibernate.event.monitor.spi.DiagnosticEvent; -import org.hibernate.id.ExportableColumn; +import org.hibernate.mapping.Column; import org.hibernate.id.IdentifierGenerationException; import org.hibernate.id.IntegralDataTypeHolder; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.mapping.Table; import org.hibernate.stat.spi.StatisticsImplementor; +import org.hibernate.type.BasicType; import org.hibernate.type.StandardBasicTypes; +import org.hibernate.type.spi.TypeConfiguration; import org.jboss.logging.Logger; import static org.hibernate.LockMode.PESSIMISTIC_WRITE; @@ -320,11 +322,15 @@ public void registerExportables(Database database) { valueColumnNameText = logicalValueColumnNameIdentifier.render( database.getJdbcEnvironment().getDialect() ); if ( tableCreated ) { - final ExportableColumn valueColumn = new ExportableColumn( + final TypeConfiguration typeConfiguration = database.getTypeConfiguration(); + final BasicType type = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG ); + final Column valueColumn = ExportableColumnHelper.column( database, table, valueColumnNameText, - database.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.LONG ) + type, + typeConfiguration.getDdlTypeRegistry() + .getTypeName( type.getJdbcType().getDdlTypeCode(), database.getDialect() ) ); table.addColumn( valueColumn ); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/AggregateColumn.java b/hibernate-core/src/main/java/org/hibernate/mapping/AggregateColumn.java index 789215ded9f9..121c69f502cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/AggregateColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/AggregateColumn.java @@ -18,7 +18,7 @@ * {@link org.hibernate.type.SqlTypes#JSON} or {@link org.hibernate.type.SqlTypes#SQLXML} * that aggregates a component into a single column. */ -public class AggregateColumn extends Column { +public final class AggregateColumn extends Column { private final Component component; @@ -59,14 +59,11 @@ public SelectablePath getSelectablePath() { private static SelectablePath getSelectablePath(Component component) { final AggregateColumn aggregateColumn = component.getAggregateColumn(); - final AggregateColumn parentAggregateColumn = component.getParentAggregateColumn(); + final AggregateColumn parent = component.getParentAggregateColumn(); final String simpleAggregateName = aggregateColumn.getQuotedName(); - if ( parentAggregateColumn == null ) { - return new SelectablePath( simpleAggregateName ); - } - else { - return getSelectablePath( parentAggregateColumn.getComponent() ).append( simpleAggregateName ); - } + return parent == null + ? new SelectablePath( simpleAggregateName ) + : getSelectablePath( parent.getComponent() ).append( simpleAggregateName ); } public String getAggregateReadExpressionTemplate(Dialect dialect) { @@ -75,49 +72,32 @@ public String getAggregateReadExpressionTemplate(Dialect dialect) { private static String getAggregateReadExpressionTemplate(Dialect dialect, Component component) { final AggregateColumn aggregateColumn = component.getAggregateColumn(); - final AggregateColumn parentAggregateColumn = component.getParentAggregateColumn(); + final AggregateColumn parent = component.getParentAggregateColumn(); final String simpleAggregateName = aggregateColumn.getQuotedName( dialect ); - final String aggregateSelectableExpression; // If the aggregate column is an array, drop the parent read expression, because this is a NestedColumnReference // and will require special rendering - if ( parentAggregateColumn == null || isArray( aggregateColumn ) ) { - aggregateSelectableExpression = getRootAggregateSelectableExpression( aggregateColumn, simpleAggregateName ); - } - else { - aggregateSelectableExpression = dialect.getAggregateSupport().aggregateComponentCustomReadExpression( - "", - "", - getAggregateReadExpressionTemplate( - dialect, - parentAggregateColumn.getComponent() - ), - simpleAggregateName, - parentAggregateColumn, - aggregateColumn - ); - } - return aggregateSelectableExpression; + return parent == null || isArray( aggregateColumn ) + ? getRootAggregateSelectableExpression( aggregateColumn, simpleAggregateName ) + : dialect.getAggregateSupport() + .aggregateComponentCustomReadExpression( + "", + "", + getAggregateReadExpressionTemplate( dialect, parent.getComponent() ), + simpleAggregateName, + parent, + aggregateColumn + ); } private static String getRootAggregateSelectableExpression(AggregateColumn aggregateColumn, String simpleAggregateName) { - if ( isArray( aggregateColumn ) ) { - return Template.TEMPLATE; - } - else { - return Template.TEMPLATE + "." + simpleAggregateName; - } + return isArray( aggregateColumn ) ? Template.TEMPLATE : Template.TEMPLATE + "." + simpleAggregateName; } private static boolean isArray(AggregateColumn aggregateColumn) { - switch ( aggregateColumn.getTypeCode() ) { - case JSON_ARRAY: - case XML_ARRAY: - case STRUCT_ARRAY: - case STRUCT_TABLE: - return true; - default: - return false; - } + return switch ( aggregateColumn.getTypeCode() ) { + case JSON_ARRAY, XML_ARRAY, STRUCT_ARRAY, STRUCT_TABLE -> true; + default -> false; + }; } public String getAggregateAssignmentExpressionTemplate(Dialect dialect) { @@ -126,24 +106,17 @@ public String getAggregateAssignmentExpressionTemplate(Dialect dialect) { private static String getAggregateAssignmentExpressionTemplate(Dialect dialect, Component component) { final AggregateColumn aggregateColumn = component.getAggregateColumn(); - final AggregateColumn parentAggregateColumn = component.getParentAggregateColumn(); + final AggregateColumn parent = component.getParentAggregateColumn(); final String simpleAggregateName = aggregateColumn.getQuotedName( dialect ); - final String aggregateSelectableExpression; - if ( parentAggregateColumn == null ) { - aggregateSelectableExpression = Template.TEMPLATE + "." + simpleAggregateName; - } - else { - aggregateSelectableExpression = dialect.getAggregateSupport().aggregateComponentAssignmentExpression( - getAggregateAssignmentExpressionTemplate( - dialect, - parentAggregateColumn.getComponent() - ), - simpleAggregateName, - parentAggregateColumn, - aggregateColumn - ); - } - return aggregateSelectableExpression; + return parent == null + ? Template.TEMPLATE + "." + simpleAggregateName + : dialect.getAggregateSupport() + .aggregateComponentAssignmentExpression( + getAggregateAssignmentExpressionTemplate( dialect, parent.getComponent() ), + simpleAggregateName, + parent, + aggregateColumn + ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Bag.java b/hibernate-core/src/main/java/org/hibernate/mapping/Bag.java index 43ba6fbecdeb..ad4d556e02d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Bag.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Bag.java @@ -18,7 +18,7 @@ * * @author Gavin King */ -public class Bag extends Collection { +public non-sealed class Bag extends Collection { /** * hbm.xml binding */ diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java index 9e31f966ec05..859095091d97 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java @@ -44,7 +44,11 @@ * * @author Gavin King */ -public abstract class Collection implements Fetchable, Value, Filterable, SoftDeletable { +public abstract sealed class Collection + implements Fetchable, Value, Filterable, SoftDeletable + permits Set, Bag, + IndexedCollection, // List, Map + IdentifierCollection { // IdentifierBag only built-in implementation public static final String DEFAULT_ELEMENT_COLUMN_NAME = "elt"; public static final String DEFAULT_KEY_COLUMN_NAME = "id"; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java index ca1dcba9cd6e..6d75ebfdf843 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java @@ -51,7 +51,9 @@ * * @author Gavin King */ -public class Column implements Selectable, Serializable, Cloneable, ColumnTypeInformation { +public sealed class Column + implements Selectable, Serializable, Cloneable, ColumnTypeInformation + permits AggregateColumn { private Long length; private Integer precision; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Formula.java b/hibernate-core/src/main/java/org/hibernate/mapping/Formula.java index bd4718eb330a..0a911152ae26 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Formula.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Formula.java @@ -23,7 +23,7 @@ * * @author Gavin King */ -public class Formula implements Selectable, Serializable { +public final class Formula implements Selectable, Serializable { private static final AtomicInteger formulaUniqueInteger = new AtomicInteger(); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierBag.java b/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierBag.java index a9ff967389aa..87d2b4451028 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierBag.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierBag.java @@ -27,7 +27,9 @@ public IdentifierBag(MetadataBuildingContext buildingContext, PersistentClass ow /** * annotation binding */ - public IdentifierBag(Supplier> customTypeBeanResolver, PersistentClass owner, MetadataBuildingContext buildingContext) { + public IdentifierBag( + Supplier> customTypeBeanResolver, PersistentClass owner, + MetadataBuildingContext buildingContext) { super( customTypeBeanResolver, owner, buildingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierCollection.java b/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierCollection.java index 2c66c0559d72..500e646b963e 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/IdentifierCollection.java @@ -17,7 +17,7 @@ * A mapping model object representing a collection with a synthetic "identifier" column, * that is, a surrogate key. */ -public abstract class IdentifierCollection extends Collection { +public non-sealed abstract class IdentifierCollection extends Collection { public static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id"; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/IndexedCollection.java b/hibernate-core/src/main/java/org/hibernate/mapping/IndexedCollection.java index ff8878f8693c..1523c28f2ca8 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/IndexedCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/IndexedCollection.java @@ -18,7 +18,7 @@ * primitive arrays. * @author Gavin King */ -public abstract class IndexedCollection extends Collection { +public sealed abstract class IndexedCollection extends Collection permits Map, List { public static final String DEFAULT_INDEX_COLUMN_NAME = "idx"; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/JoinedSubclass.java b/hibernate-core/src/main/java/org/hibernate/mapping/JoinedSubclass.java index 02b508d3a6f9..c1bf29f3fb4e 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/JoinedSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/JoinedSubclass.java @@ -17,7 +17,7 @@ * * @author Gavin King */ -public class JoinedSubclass extends Subclass implements TableOwner { +public final class JoinedSubclass extends Subclass implements TableOwner { private Table table; private KeyValue key; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/List.java b/hibernate-core/src/main/java/org/hibernate/mapping/List.java index 91493247ae97..5f8e352d7896 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/List.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/List.java @@ -18,7 +18,7 @@ * * @author Gavin King */ -public class List extends IndexedCollection { +public non-sealed class List extends IndexedCollection { private int baseIndex; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java b/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java index 339bf2e22e6e..a4c5b50c6352 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java @@ -17,7 +17,7 @@ * * @author Gavin King */ -public class ManyToOne extends ToOne { +public final class ManyToOne extends ToOne { private boolean isLogicalOneToOne; private NotFoundAction notFoundAction; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Map.java b/hibernate-core/src/main/java/org/hibernate/mapping/Map.java index db9ad2241f8b..c2180b9e0114 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Map.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Map.java @@ -19,7 +19,7 @@ * A mapping model object representing a collection of type {@link java.util.Map}. * A map has a primary key consisting of the key columns + index columns. */ -public class Map extends IndexedCollection { +public non-sealed class Map extends IndexedCollection { private String mapKeyPropertyName; private boolean hasMapKeyProperty; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/OneToOne.java b/hibernate-core/src/main/java/org/hibernate/mapping/OneToOne.java index 3f660b538a06..159aa6efcd37 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/OneToOne.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/OneToOne.java @@ -18,7 +18,7 @@ * * @author Gavin King */ -public class OneToOne extends ToOne { +public final class OneToOne extends ToOne { private boolean constrained; private ForeignKeyDirection foreignKeyType; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java b/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java index e3e370881e22..d7df9c7d5cad 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java @@ -50,7 +50,9 @@ * * @author Gavin King */ -public abstract class PersistentClass implements IdentifiableTypeClass, AttributeContainer, Filterable, MetaAttributable, Contributable, Serializable { +public abstract sealed class PersistentClass + implements IdentifiableTypeClass, AttributeContainer, Filterable, MetaAttributable, Contributable, Serializable + permits RootClass, Subclass { private static final Alias PK_ALIAS = new Alias( 15, "PK" ); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/RootClass.java b/hibernate-core/src/main/java/org/hibernate/mapping/RootClass.java index 574a808e960d..dec04b6ab4b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/RootClass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/RootClass.java @@ -24,7 +24,7 @@ * * @author Gavin King */ -public class RootClass extends PersistentClass implements TableOwner, SoftDeletable { +public final class RootClass extends PersistentClass implements TableOwner, SoftDeletable { private static final CoreMessageLogger LOG = CoreLogging.messageLogger( RootClass.class ); private Property identifierProperty; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java b/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java index 19e45955bafd..a48867bda2f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java @@ -13,7 +13,7 @@ /** * Models the commonality between a {@link Column} and a {@link Formula} (computed value). */ -public interface Selectable { +public sealed interface Selectable permits Column, Formula { /** * The selectable's "canonical" text representation */ diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Set.java b/hibernate-core/src/main/java/org/hibernate/mapping/Set.java index c8f0e1a96cad..e2377d786343 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Set.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Set.java @@ -24,7 +24,7 @@ * * @author Gavin King */ -public class Set extends Collection { +public non-sealed class Set extends Collection { /** * Used by hbm.xml binding */ diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java b/hibernate-core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java index a4054b902261..837290ea61f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java @@ -18,7 +18,7 @@ * * @author Gavin King */ -public class SingleTableSubclass extends Subclass { +public final class SingleTableSubclass extends Subclass { public SingleTableSubclass(PersistentClass superclass, MetadataBuildingContext buildingContext) { super( superclass, buildingContext ); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Subclass.java b/hibernate-core/src/main/java/org/hibernate/mapping/Subclass.java index b0346a357f0b..e9401065e5fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Subclass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Subclass.java @@ -19,7 +19,8 @@ * * @author Gavin King */ -public class Subclass extends PersistentClass { +public sealed class Subclass extends PersistentClass + permits SingleTableSubclass, JoinedSubclass, UnionSubclass { private PersistentClass superclass; private final int subclassId; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java b/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java index 317031a8a3e5..0ce5f90a1443 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java @@ -23,7 +23,10 @@ * * @author Gavin King */ -public abstract class ToOne extends SimpleValue implements Fetchable, SortableValue { +public abstract sealed class ToOne + extends SimpleValue implements Fetchable, SortableValue + permits OneToOne, ManyToOne { + private FetchMode fetchMode; protected String referencedPropertyName; private String referencedEntityName; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/UnionSubclass.java b/hibernate-core/src/main/java/org/hibernate/mapping/UnionSubclass.java index c720e34277dd..39ddd6124bcd 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/UnionSubclass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/UnionSubclass.java @@ -15,7 +15,7 @@ * * @author Gavin King */ -public class UnionSubclass extends Subclass implements TableOwner { +public final class UnionSubclass extends Subclass implements TableOwner { private Table table; public UnionSubclass(PersistentClass superclass, MetadataBuildingContext buildingContext) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingAggregateFunctionSqlAstExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingAggregateFunctionSqlAstExpression.java index 8ae818c54b5c..d7bc5a9efa7c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingAggregateFunctionSqlAstExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingAggregateFunctionSqlAstExpression.java @@ -21,7 +21,7 @@ * * @author Christian Beikov */ -public class SelfRenderingAggregateFunctionSqlAstExpression extends SelfRenderingFunctionSqlAstExpression +public class SelfRenderingAggregateFunctionSqlAstExpression extends SelfRenderingFunctionSqlAstExpression implements AggregateFunctionExpression { private final Predicate filter; @@ -31,7 +31,7 @@ public SelfRenderingAggregateFunctionSqlAstExpression( FunctionRenderer renderer, List sqlAstArguments, Predicate filter, - ReturnableType type, + ReturnableType type, JdbcMappingContainer expressible) { super( functionName, renderer, sqlAstArguments, type, expressible ); this.filter = filter; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java index 7ae8234ed80d..bd0443976de3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java @@ -6,20 +6,17 @@ import java.util.List; -import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.IndexedConsumer; -import org.hibernate.mapping.Selectable; -import org.hibernate.mapping.Table; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.metamodel.mapping.SqlExpressible; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.metamodel.model.domain.ReturnableType; import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.spi.SqlAppender; -import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.expression.FunctionExpression; @@ -39,19 +36,19 @@ * * @author Steve Ebersole */ -public class SelfRenderingFunctionSqlAstExpression - implements SelfRenderingExpression, Selectable, SqlExpressible, DomainResultProducer, FunctionExpression { +public class SelfRenderingFunctionSqlAstExpression + implements SelfRenderingExpression, SqlExpressible, DomainResultProducer, FunctionExpression { private final String functionName; private final FunctionRenderer renderer; private final List sqlAstArguments; - private final @Nullable ReturnableType type; + private final @Nullable ReturnableType type; private final @Nullable JdbcMappingContainer expressible; public SelfRenderingFunctionSqlAstExpression( String functionName, FunctionRenderer renderer, List sqlAstArguments, - @Nullable ReturnableType type, + @Nullable ReturnableType type, @Nullable JdbcMappingContainer expressible) { this.functionName = functionName; this.renderer = renderer; @@ -78,11 +75,11 @@ public JdbcMappingContainer getExpressionType() { : expressible; } - protected FunctionRenderer getFunctionRenderer() { + FunctionRenderer getFunctionRenderer() { return renderer; } - protected @Nullable ReturnableType getType() { + @Nullable ReturnableType getType() { return type; } @@ -93,23 +90,18 @@ public SqlSelection createSqlSelection( JavaType javaType, boolean virtual, TypeConfiguration typeConfiguration) { - return new SqlSelectionImpl( - jdbcPosition, - valuesArrayPosition, - this, - virtual - ); + return new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, this, virtual ); } @Override - public DomainResult createDomainResult( + public DomainResult createDomainResult( String resultVariable, DomainResultCreationState creationState) { final JdbcMapping jdbcMapping = getJdbcMapping(); - final JavaType jdbcJavaType; - final BasicValueConverter converter; + final JavaType jdbcJavaType; + final BasicValueConverter converter; if ( jdbcMapping != null ) { - jdbcJavaType = jdbcMapping.getJdbcJavaType(); + jdbcJavaType = (JavaType) jdbcMapping.getJdbcJavaType(); converter = jdbcMapping.getValueConverter(); } else if ( type != null ) { @@ -120,17 +112,8 @@ else if ( type != null ) { jdbcJavaType = null; converter = null; } - final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); - return new BasicResult( - sqlAstCreationState.getSqlExpressionResolver() - .resolveSqlSelection( - this, - jdbcJavaType, - null, - sqlAstCreationState.getCreationContext() - .getMappingMetamodel().getTypeConfiguration() - ) - .getValuesArrayPosition(), + return new BasicResult<>( + resolveSqlSelection( creationState, jdbcJavaType ).getValuesArrayPosition(), resultVariable, type == null ? null : type.getExpressibleJavaType(), converter, @@ -148,53 +131,13 @@ public void renderToSql( renderer.render( sqlAppender, sqlAstArguments, type, walker ); } - @Override - public String getAlias(Dialect dialect) { - return null; - } - - @Override - public String getAlias(Dialect dialect, Table table) { - return null; - } - - @Override - public boolean isFormula() { - return false; - } - - @Override - public String getTemplate(Dialect dialect, TypeConfiguration typeConfiguration, SqmFunctionRegistry registry) { - return null; - } - - @Override - public String getText(Dialect dialect) { - return null; - } - - @Override - public String getText() { - return null; - } - - @Override - public String getCustomReadExpression() { - return null; - } - - @Override - public String getCustomWriteExpression() { - return null; - } - @Override public JdbcMapping getJdbcMapping() { - if ( type instanceof SqlExpressible ) { - return ( (SqlExpressible) type ).getJdbcMapping(); + if ( type instanceof SqlExpressible sqlExpressible ) { + return sqlExpressible.getJdbcMapping(); } - else if ( expressible instanceof SqlExpressible ) { - return ( (SqlExpressible) expressible ).getJdbcMapping(); + else if ( expressible instanceof SqlExpressible sqlExpressible ) { + return sqlExpressible.getJdbcMapping(); } else { return null; @@ -203,18 +146,17 @@ else if ( expressible instanceof SqlExpressible ) { @Override public void applySqlSelections(DomainResultCreationState creationState) { - final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); final JdbcMapping jdbcMapping = getJdbcMapping(); - sqlAstCreationState.getSqlExpressionResolver() - .resolveSqlSelection( - this, - jdbcMapping != null - ? jdbcMapping.getJdbcJavaType() - : type.getExpressibleJavaType(), - null, - sqlAstCreationState.getCreationContext() - .getMappingMetamodel().getTypeConfiguration() - ); + resolveSqlSelection( creationState, + jdbcMapping == null ? type.getExpressibleJavaType() : jdbcMapping.getJdbcJavaType() ); + } + + private SqlSelection resolveSqlSelection(DomainResultCreationState creationState, JavaType javaType) { + final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); + final TypeConfiguration typeConfiguration = + sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration(); + return sqlAstCreationState.getSqlExpressionResolver() + .resolveSqlSelection( this, javaType, null, typeConfiguration ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingOrderedSetAggregateFunctionSqlAstExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingOrderedSetAggregateFunctionSqlAstExpression.java index 5e416033f9e3..036b18169857 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingOrderedSetAggregateFunctionSqlAstExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingOrderedSetAggregateFunctionSqlAstExpression.java @@ -22,7 +22,8 @@ * * @author Christian Beikov */ -public class SelfRenderingOrderedSetAggregateFunctionSqlAstExpression extends SelfRenderingAggregateFunctionSqlAstExpression +public class SelfRenderingOrderedSetAggregateFunctionSqlAstExpression + extends SelfRenderingAggregateFunctionSqlAstExpression implements OrderedSetAggregateFunctionExpression { private final List withinGroup; @@ -33,7 +34,7 @@ public SelfRenderingOrderedSetAggregateFunctionSqlAstExpression( List sqlAstArguments, Predicate filter, List withinGroup, - ReturnableType type, + ReturnableType type, JdbcMappingContainer expressible) { super( functionName, renderer, sqlAstArguments, filter, type, expressible ); this.withinGroup = withinGroup; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java index 1d325714ed49..358b3c78f528 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java @@ -48,26 +48,28 @@ public SelfRenderingSqmAggregateFunction copy(SqmCopyContext context) { if ( existing != null ) { return existing; } - final List> arguments = new ArrayList<>( getArguments().size() ); - for ( SqmTypedNode argument : getArguments() ) { - arguments.add( argument.copy( context ) ); + else { + final List> arguments = new ArrayList<>( getArguments().size() ); + for ( SqmTypedNode argument : getArguments() ) { + arguments.add( argument.copy( context ) ); + } + final SelfRenderingSqmAggregateFunction expression = context.registerCopy( + this, + new SelfRenderingSqmAggregateFunction<>( + getFunctionDescriptor(), + getFunctionRenderer(), + arguments, + filter == null ? null : filter.copy( context ), + getImpliedResultType(), + getArgumentsValidator(), + getReturnTypeResolver(), + nodeBuilder(), + getFunctionName() + ) + ); + copyTo( expression, context ); + return expression; } - final SelfRenderingSqmAggregateFunction expression = context.registerCopy( - this, - new SelfRenderingSqmAggregateFunction<>( - getFunctionDescriptor(), - getFunctionRenderer(), - arguments, - filter == null ? null : filter.copy( context ), - getImpliedResultType(), - getArgumentsValidator(), - getReturnTypeResolver(), - nodeBuilder(), - getFunctionName() - ) - ); - copyTo( expression, context ); - return expression; } @Override @@ -79,7 +81,7 @@ public Expression convertToSqlAst(SqmToSqlAstConverter walker) { if ( argumentsValidator != null ) { argumentsValidator.validateSqlTypes( arguments, getFunctionName() ); } - return new SelfRenderingAggregateFunctionSqlAstExpression( + return new SelfRenderingAggregateFunctionSqlAstExpression<>( getFunctionName(), getFunctionRenderer(), arguments, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java index 732f78e1078e..9751507f85c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java @@ -87,7 +87,7 @@ public Expression convertToSqlAst(SqmToSqlAstConverter walker) { if ( argumentsValidator != null ) { argumentsValidator.validateSqlTypes( arguments, getFunctionName() ); } - return new SelfRenderingWindowFunctionSqlAstExpression( + return new SelfRenderingWindowFunctionSqlAstExpression<>( getFunctionName(), getFunctionRenderer(), arguments, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingWindowFunctionSqlAstExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingWindowFunctionSqlAstExpression.java index 29a19565e1b8..7f8b7448ab2b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingWindowFunctionSqlAstExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingWindowFunctionSqlAstExpression.java @@ -21,7 +21,7 @@ * * @author Christian Beikov */ -public class SelfRenderingWindowFunctionSqlAstExpression extends SelfRenderingFunctionSqlAstExpression +public class SelfRenderingWindowFunctionSqlAstExpression extends SelfRenderingFunctionSqlAstExpression implements WindowFunctionExpression { private final Predicate filter; @@ -35,7 +35,7 @@ public SelfRenderingWindowFunctionSqlAstExpression( Predicate filter, Boolean respectNulls, Boolean fromFirst, - ReturnableType type, + ReturnableType type, JdbcMappingContainer expressible) { super( functionName, renderer, sqlAstArguments, type, expressible ); this.filter = filter; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmInsertStrategyHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmInsertStrategyHelper.java index ca60c81bb219..00522cb0dac0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmInsertStrategyHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmInsertStrategyHelper.java @@ -5,7 +5,6 @@ package org.hibernate.query.sqm.mutation.internal; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -19,6 +18,8 @@ import org.hibernate.sql.ast.tree.select.SortSpecification; import org.hibernate.type.BasicType; +import static java.util.Collections.emptyList; + /** * @author Christian Beikov */ @@ -39,11 +40,10 @@ public static Expression createRowNumberingExpression( final List orderList; if ( querySpec.getSelectClause().isDistinct() ) { assert sessionFactory.getJdbcServices().getDialect().supportsWindowFunctions(); - - functionExpression = new SelfRenderingWindowFunctionSqlAstExpression( + functionExpression = new SelfRenderingWindowFunctionSqlAstExpression<>( "dense_rank", (appender, args, returnType, walker) -> appender.appendSql( "dense_rank()" ), - Collections.emptyList(), + emptyList(), null, null, null, @@ -67,27 +67,28 @@ public static Expression createRowNumberingExpression( } } else { - functionExpression = new SelfRenderingWindowFunctionSqlAstExpression( + functionExpression = new SelfRenderingWindowFunctionSqlAstExpression<>( "row_number", (appender, args, returnType, walker) -> appender.appendSql( "row_number()" ), - Collections.emptyList(), + emptyList(), null, null, null, resultType, resultType ); - orderList = Collections.emptyList(); + orderList = emptyList(); } - return new Over<>( functionExpression, Collections.emptyList(), orderList ); + return new Over<>( functionExpression, emptyList(), orderList ); } private static boolean containsSelectionExpression(List orderList, SqlSelection sqlSelection) { final Expression expression = sqlSelection.getExpression(); for ( SortSpecification sortSpecification : orderList ) { final Expression sortExpression = sortSpecification.getSortExpression(); - if ( sortExpression == expression || sortExpression instanceof SqlSelectionExpression - && ( (SqlSelectionExpression) sortExpression ).getSelection() == sqlSelection ) { + if ( sortExpression == expression + || sortExpression instanceof SqlSelectionExpression sqlSelectionExpression + && sqlSelectionExpression.getSelection() == sqlSelection ) { return true; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index e9c4c4f1058d..b28b0d0080be 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -139,7 +139,6 @@ import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression; import org.hibernate.query.sqm.function.SelfRenderingSqmFunction; import org.hibernate.query.sqm.internal.DomainParameterXref; -import org.hibernate.query.sqm.internal.SqmMappingModelHelper; import org.hibernate.query.sqm.mutation.internal.SqmInsertStrategyHelper; import org.hibernate.query.sqm.produce.function.internal.PatternRenderer; import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker; @@ -295,7 +294,6 @@ import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.SqlTreeCreationException; import org.hibernate.sql.ast.SqlTreeCreationLogger; -import org.hibernate.sql.ast.internal.TableGroupJoinHelper; import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBaseConstant; @@ -428,7 +426,6 @@ import org.hibernate.type.internal.BasicTypeImpl; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.UserVersionType; -import org.hibernate.usertype.internal.AbstractTimeZoneStorageCompositeUserType; import org.jboss.logging.Logger; @@ -439,6 +436,8 @@ import static jakarta.persistence.metamodel.Type.PersistenceType.ENTITY; import static java.util.Collections.emptyList; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.hibernate.boot.model.internal.SoftDeleteHelper.createNonSoftDeletedRestriction; import static org.hibernate.boot.model.process.internal.InferredBasicValueResolver.resolveSqlTypeIndicators; @@ -452,12 +451,15 @@ import static org.hibernate.query.common.TemporalUnit.NATIVE; import static org.hibernate.query.common.TemporalUnit.SECOND; import static org.hibernate.query.sqm.UnaryArithmeticOperator.UNARY_MINUS; +import static org.hibernate.query.sqm.internal.SqmMappingModelHelper.resolveExplicitTreatTarget; import static org.hibernate.query.sqm.internal.SqmMappingModelHelper.resolveMappingModelExpressible; import static org.hibernate.query.sqm.internal.SqmUtil.isFkOptimizationAllowed; import static org.hibernate.query.sqm.sql.AggregateColumnAssignmentHandler.forEntityDescriptor; +import static org.hibernate.sql.ast.internal.TableGroupJoinHelper.determineJoinForPredicateApply; import static org.hibernate.sql.ast.spi.SqlAstTreeHelper.combinePredicates; import static org.hibernate.type.spi.TypeConfiguration.getSqlTemporalType; import static org.hibernate.type.spi.TypeConfiguration.isDuration; +import static org.hibernate.usertype.internal.AbstractTimeZoneStorageCompositeUserType.ZONE_OFFSET_NAME; /** * @author Steve Ebersole @@ -973,9 +975,9 @@ public List visitSetClause(SqmSetClause setClause) { final SqmExpression assignmentValue = sqmAssignment.getValue(); final SqmParameter assignmentValueParameter = getSqmParameter( assignmentValue ); final Expression pathSqlExpression = assignedPathInterpretation.getSqlExpression(); - final List targetColumnReferences = + final List targetColumnReferences = pathSqlExpression instanceof SqlTuple sqlTuple - ? (List) sqlTuple.getExpressions() + ? sqlTuple.getExpressions() : pathSqlExpression.getColumnReference().getColumnReferences(); if ( assignmentValueParameter != null ) { consumeSqmParameter( @@ -990,7 +992,7 @@ public List visitSetClause(SqmSetClause setClause) { ); } else if ( assignmentValue instanceof SqmLiteralNull ) { - for ( ColumnReference columnReference : targetColumnReferences ) { + for ( Expression columnReference : targetColumnReferences ) { addAssignment( assignments, aggregateColumnAssignmentHandler, @@ -1025,34 +1027,36 @@ else if ( assignmentValue instanceof SqmLiteralNull ) { private void addAssignments( Expression valueExpression, ModelPart assignedPathType, - List targetColumnReferences, + List targetColumnReferences, ArrayList assignments, - AggregateColumnAssignmentHandler aggregateColumnAssignmentHandler) { + AggregateColumnAssignmentHandler assignmentHandler) { checkAssignment( valueExpression, assignedPathType ); - if ( valueExpression instanceof SqlTuple sqlTuple ) { - final List expressions = sqlTuple.getExpressions(); - assert targetColumnReferences.size() == expressions.size(); - for ( int i = 0; i < targetColumnReferences.size(); i++ ) { - final ColumnReference columnReference = targetColumnReferences.get( i ); - addAssignment( assignments, aggregateColumnAssignmentHandler, columnReference, expressions.get( i ) ); - } + addTupleAssignments( targetColumnReferences, assignments, assignmentHandler, sqlTuple ); } else if ( valueExpression instanceof EmbeddableValuedPathInterpretation embeddable ) { - final List expressions = embeddable.getSqlTuple().getExpressions(); - assert targetColumnReferences.size() == expressions.size(); - for ( int i = 0; i < targetColumnReferences.size(); i++ ) { - final ColumnReference columnReference = targetColumnReferences.get( i ); - addAssignment( assignments, aggregateColumnAssignmentHandler, columnReference, expressions.get( i ) ); - } + addTupleAssignments( targetColumnReferences, assignments, assignmentHandler, embeddable.getSqlTuple() ); } else { - for ( ColumnReference columnReference : targetColumnReferences ) { - addAssignment( assignments, aggregateColumnAssignmentHandler, columnReference, valueExpression ); + for ( Expression columnReference : targetColumnReferences ) { + addAssignment( assignments, assignmentHandler, columnReference, valueExpression ); } } } + private void addTupleAssignments( + List targetColumnReferences, + ArrayList assignments, + AggregateColumnAssignmentHandler aggregateColumnAssignmentHandler, + SqlTuple sqlTuple) { + final List expressions = sqlTuple.getExpressions(); + assert targetColumnReferences.size() == expressions.size(); + for ( int i = 0; i < targetColumnReferences.size(); i++ ) { + final ColumnReference columnReference = (ColumnReference) targetColumnReferences.get( i ); + addAssignment( assignments, aggregateColumnAssignmentHandler, columnReference, expressions.get( i ) ); + } + } + private void checkAssignment(Expression valueExpression, ModelPart assignedPathType) { final int valueExprJdbcCount = getKeyExpressible( valueExpression.getExpressionType() ).getJdbcTypeCount(); final int assignedPathJdbcCount = getKeyExpressible( assignedPathType ).getJdbcTypeCount(); @@ -1071,12 +1075,12 @@ private void checkAssignment(Expression valueExpression, ModelPart assignedPathT private void addAssignment( List assignments, AggregateColumnAssignmentHandler aggregateColumnAssignmentHandler, - ColumnReference columnReference, + Expression columnReference, Expression valueExpression) { if ( aggregateColumnAssignmentHandler != null ) { - aggregateColumnAssignmentHandler.addAssignment( assignments.size(), columnReference ); + aggregateColumnAssignmentHandler.addAssignment( assignments.size(), (ColumnReference) columnReference ); } - assignments.add( new Assignment( columnReference, valueExpression ) ); + assignments.add( new Assignment( (ColumnReference) columnReference, valueExpression ) ); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2771,7 +2775,8 @@ protected void consumeFromClauseRoot(SqmRoot sqmRoot) { final SelectStatement statement = (SelectStatement) derivedRoot.getQueryPart().accept( this ); fromClauseIndexStack.pop(); final AnonymousTupleType tupleType = (AnonymousTupleType) sqmRoot.getNodeType(); - final List sqlSelections = statement.getQueryPart().getFirstQuerySpec().getSelectClause().getSqlSelections(); + final List sqlSelections = + statement.getQueryPart().getFirstQuerySpec().getSelectClause().getSqlSelections(); final AnonymousTupleTableGroupProducer tableGroupProducer = tupleType.resolveTableGroupProducer( derivedRoot.getExplicitAlias(), sqlSelections, @@ -2945,40 +2950,37 @@ private void consumeJoins(SqmRoot sqmRoot, FromClauseIndex fromClauseIndex, T } private EntityPersister resolveEntityPersister(EntityDomainType entityDomainType) { - return creationContext.getSessionFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() + return creationContext.getSessionFactory().getMappingMetamodel() .getEntityDescriptor( entityDomainType.getHibernateEntityName() ); } + private SqlAstQueryPartProcessingState getSqlAstQueryPartProcessingState() { + return (SqlAstQueryPartProcessingState) getCurrentProcessingState(); + } + /** * Registers {@link EntityNameUse#PROJECTION} entity name uses for all entity valued path subtypes. * If the path is a treat, registers {@link EntityNameUse#TREAT} for all treated subtypes instead. */ private void registerEntityNameProjectionUsage(SqmPath projectedPath, TableGroup tableGroup) { final ManagedDomainType treatedType; - if ( projectedPath instanceof SqmTreatedPath ) { - treatedType = ( (SqmTreatedPath) projectedPath ).getTreatTarget(); + if ( projectedPath instanceof SqmTreatedPath sqmTreatedPath ) { + treatedType = sqmTreatedPath.getTreatTarget(); registerEntityNameUsage( tableGroup, EntityNameUse.TREAT, treatedType.getTypeName(), true ); - if ( projectedPath instanceof SqmFrom ) { // Register that the TREAT uses for the SqmFrom node may not be downgraded - ( (SqlAstQueryPartProcessingState) getCurrentProcessingState() ).registerFromUsage( + getSqlAstQueryPartProcessingState().registerFromUsage( (SqmFrom) ( (SqmTreatedPath) projectedPath ).getWrappedPath(), false ); } } - else if ( projectedPath.getNodeType().getSqmPathType() instanceof EntityDomainType ) { - treatedType = (EntityDomainType) projectedPath.getNodeType().getSqmPathType(); + else if ( projectedPath.getNodeType().getSqmPathType() instanceof EntityDomainType entityDomainType ) { + treatedType = entityDomainType; registerEntityNameUsage( tableGroup, EntityNameUse.PROJECTION, treatedType.getTypeName(), true ); - - if ( projectedPath instanceof SqmFrom ) { + if ( projectedPath instanceof SqmFrom sqmFrom ) { // Register that the TREAT uses for the SqmFrom node may not be downgraded - ( (SqlAstQueryPartProcessingState) getCurrentProcessingState() ).registerFromUsage( - (SqmFrom) projectedPath, - true - ); + getSqlAstQueryPartProcessingState().registerFromUsage( sqmFrom, true ); } } } @@ -2992,25 +2994,18 @@ else if ( projectedPath.getNodeType().getSqmPathType() instanceof EntityDomainTy private void registerPathAttributeEntityNameUsage(SqmPath sqmPath, TableGroup tableGroup) { final SqmPath parentPath = sqmPath.getLhs(); final SqlAstProcessingState processingState = getCurrentProcessingState(); - if ( processingState instanceof SqlAstQueryPartProcessingState ) { - if ( parentPath instanceof SqmFrom ) { - ( (SqlAstQueryPartProcessingState) processingState ).registerFromUsage( - (SqmFrom) parentPath, - true - ); + if ( processingState instanceof SqlAstQueryPartProcessingState sqlAstQueryPartProcessingState ) { + if ( parentPath instanceof SqmFrom sqmFrom ) { + sqlAstQueryPartProcessingState.registerFromUsage( sqmFrom, true ); } if ( sqmPath instanceof SqmFrom ) { - ( (SqlAstQueryPartProcessingState) processingState ).registerFromUsage( - (SqmFrom) sqmPath, - true - ); + sqlAstQueryPartProcessingState.registerFromUsage( (SqmFrom) sqmPath, true ); } } - final SqmPathSource resolvedModel; if ( !( sqmPath instanceof SqmTreatedPath ) && tableGroup.getModelPart().getPartMappingType() instanceof EntityMappingType entityType - && ( resolvedModel = sqmPath.getResolvedModel() ) instanceof PersistentAttribute ) { - final String attributeName = resolvedModel.getPathName(); + && sqmPath.getResolvedModel() instanceof PersistentAttribute ) { + final String attributeName = sqmPath.getResolvedModel().getPathName(); final EntityMappingType parentType; if ( parentPath instanceof SqmTreatedPath treatedPath ) { // A treated attribute usage i.e. `treat(alias as Subtype).attribute = 1` @@ -3024,19 +3019,12 @@ private void registerPathAttributeEntityNameUsage(SqmPath sqmPath, TableGroup // and hence we can safely skip adding the `type(alias) = Subtype and ...` condition to the SQL. final ModelPart subPart = parentType.findSubPart( attributeName ); - final EntityNameUse entityNameUse; - // We only apply this optimization for basic valued model parts for now - if ( subPart.asBasicValuedModelPart() != null ) { - entityNameUse = EntityNameUse.OPTIONAL_TREAT; - } - else { - entityNameUse = EntityNameUse.BASE_TREAT; - } - registerEntityNameUsage( - tableGroup, - entityNameUse, - treatTarget.getTypeName() - ); + final EntityNameUse entityNameUse = + subPart.asBasicValuedModelPart() != null + // We only apply this optimization for basic valued model parts for now + ? EntityNameUse.OPTIONAL_TREAT + : EntityNameUse.BASE_TREAT; + registerEntityNameUsage( tableGroup, entityNameUse, treatTarget.getTypeName() ); } else { parentType = entityType; @@ -3051,11 +3039,8 @@ private void registerPathAttributeEntityNameUsage(SqmPath sqmPath, TableGroup if ( attributeName.equals( parentType.getIdentifierMapping().getAttributeName() ) ) { if ( parentType.getIdentifierMapping() instanceof EmbeddableValuedModelPart ) { // Until HHH-16571 is fixed, we must also register an entity name use for the root entity descriptor name - registerEntityNameUsage( - tableGroup, - EntityNameUse.EXPRESSION, - parentType.getRootEntityDescriptor().getEntityName() - ); + registerEntityNameUsage( tableGroup, EntityNameUse.EXPRESSION, + parentType.getRootEntityDescriptor().getEntityName() ); } final EntityDiscriminatorMapping discriminator = parentType.getDiscriminatorMapping(); final String entityName; @@ -3067,11 +3052,7 @@ private void registerPathAttributeEntityNameUsage(SqmPath sqmPath, TableGroup else { entityName = parentType.getEntityName(); } - registerEntityNameUsage( - tableGroup, - EntityNameUse.EXPRESSION, - entityName - ); + registerEntityNameUsage( tableGroup, EntityNameUse.EXPRESSION, entityName ); } else { // If the attribute mapping can't be found on the declaring type and it is not the identifier, @@ -3085,11 +3066,8 @@ private void registerPathAttributeEntityNameUsage(SqmPath sqmPath, TableGroup } } else { - registerEntityNameUsage( - tableGroup, - EntityNameUse.EXPRESSION, - attributeMapping.findContainingEntityMapping().getEntityName() - ); + registerEntityNameUsage( tableGroup, EntityNameUse.EXPRESSION, + attributeMapping.findContainingEntityMapping().getEntityName() ); } } } @@ -3117,20 +3095,18 @@ private void registerEntityNameUsage( EntityNameUse entityNameUse, String treatTargetTypeName, boolean projection) { + final SessionFactoryImplementor factory = creationContext.getSessionFactory(); final EntityPersister persister; if ( tableGroup.getModelPart() instanceof EmbeddableValuedModelPart ) { persister = null; - final EmbeddableDomainType embeddableDomainType = creationContext.getSessionFactory() - .getJpaMetamodel() - .findEmbeddableType( treatTargetTypeName ); + final EmbeddableDomainType embeddableDomainType = + factory.getJpaMetamodel().findEmbeddableType( treatTargetTypeName ); if ( embeddableDomainType == null || !embeddableDomainType.isPolymorphic() ) { return; } } else { - persister = creationContext.getSessionFactory() - .getMappingMetamodel() - .findEntityDescriptor( treatTargetTypeName ); + persister = factory.getMappingMetamodel().findEntityDescriptor( treatTargetTypeName ); if ( persister == null || !persister.getEntityMetamodel().isPolymorphic() ) { return; } @@ -3156,14 +3132,11 @@ private void registerEntityNameUsage( ? entityNameUse : EntityNameUse.EXPRESSION; } - final Map entityNameUses = tableGroupEntityNameUses.computeIfAbsent( - actualTableGroup, - tg -> new HashMap<>( 1 ) - ); - entityNameUses.compute( - treatTargetTypeName, - (s, existingUse) -> finalEntityNameUse.stronger( existingUse ) - ); + final Map entityNameUses = + tableGroupEntityNameUses.computeIfAbsent( actualTableGroup, + group -> new HashMap<>( 1 ) ); + entityNameUses.compute( treatTargetTypeName, + (s, existingUse) -> finalEntityNameUse.stronger( existingUse ) ); if ( persister == null ) { // No need to do anything else for embeddables @@ -3173,8 +3146,11 @@ private void registerEntityNameUsage( // Resolve the table reference for all types which we register an entity name use for. // Also, force table group initialization for treats when needed to ensure correct cardinality final EntityNameUse.UseKind useKind = finalEntityNameUse.getKind(); - if ( actualTableGroup.isInitialized() || ( useKind == EntityNameUse.UseKind.TREAT && actualTableGroup.canUseInnerJoins() - && !( (EntityMappingType) actualTableGroup.getModelPart().getPartMappingType() ).isTypeOrSuperType( persister ) ) ) { + if ( actualTableGroup.isInitialized() + || useKind == EntityNameUse.UseKind.TREAT + && actualTableGroup.canUseInnerJoins() + && !( (EntityMappingType) actualTableGroup.getModelPart().getPartMappingType() ) + .isTypeOrSuperType( persister ) ) { actualTableGroup.resolveTableReference( null, persister.getTableName() ); } @@ -3182,7 +3158,8 @@ private void registerEntityNameUsage( EntityMappingType superMappingType = persister; while ( ( superMappingType = superMappingType.getSuperMappingType() ) != null ) { entityNameUses.putIfAbsent( superMappingType.getEntityName(), EntityNameUse.PROJECTION ); - actualTableGroup.resolveTableReference( null, superMappingType.getEntityPersister().getTableName() ); + actualTableGroup.resolveTableReference( null, + superMappingType.getEntityPersister().getTableName() ); } } @@ -3190,22 +3167,16 @@ private void registerEntityNameUsage( // We do this here to not have to expand entity name uses during pruning later on if ( useKind == EntityNameUse.UseKind.TREAT ) { for ( EntityMappingType subType : persister.getSubMappingTypes() ) { - entityNameUses.compute( - subType.getEntityName(), - (s, existingUse) -> finalEntityNameUse.stronger( existingUse ) - ); + entityNameUses.compute( subType.getEntityName(), + (s, existingUse) -> finalEntityNameUse.stronger( existingUse ) ); } } else if ( useKind == EntityNameUse.UseKind.PROJECTION ) { for ( EntityMappingType subType : persister.getSubMappingTypes() ) { - entityNameUses.compute( - subType.getEntityName(), - (s, existingUse) -> finalEntityNameUse.stronger( existingUse ) - ); - actualTableGroup.resolveTableReference( - null, - subType.getEntityPersister().getMappedTableDetails().getTableName() - ); + entityNameUses.compute( subType.getEntityName(), + (s, existingUse) -> finalEntityNameUse.stronger( existingUse ) ); + actualTableGroup.resolveTableReference( null, + subType.getEntityPersister().getMappedTableDetails().getTableName() ); } } } @@ -3235,21 +3206,20 @@ protected void registerTypeUsage(TableGroup tableGroup) { // but for `a = 1 and type(..) = A or type(..) = B` we can infer `A, B` // The OR junction allows to create a union of entity name lists of all sub-predicates // The AND junction allows to create an intersection of entity name lists of all sub-predicates - final MappingType partMappingType = tableGroup.getModelPart().getPartMappingType(); - if ( partMappingType instanceof EntityMappingType mappingType ) { + if ( tableGroup.getModelPart().getPartMappingType() instanceof EntityMappingType mappingType ) { final EntityPersister persister = mappingType.getEntityPersister(); // Avoid resolving subclass tables for persisters with physical discriminators as we won't need them - if ( persister.getDiscriminatorMapping().hasPhysicalColumn() ) { - return; - } - if ( getCurrentClauseStack().getCurrent() != Clause.WHERE && getCurrentClauseStack().getCurrent() != Clause.HAVING ) { - // Where and having clauses are handled specially with EntityNameUse.FILTER and pruning - registerEntityNameUsage( tableGroup, EntityNameUse.PROJECTION, persister.getEntityName(), true ); - } - else { - final int subclassTableSpan = persister.getSubclassTableSpan(); - for ( int i = 0; i < subclassTableSpan; i++ ) { - tableGroup.resolveTableReference( null, persister.getSubclassTableName( i ) ); + if ( !persister.getDiscriminatorMapping().hasPhysicalColumn() ) { + if ( getCurrentClauseStack().getCurrent() != Clause.WHERE + && getCurrentClauseStack().getCurrent() != Clause.HAVING ) { + // Where and having clauses are handled specially with EntityNameUse.FILTER and pruning + registerEntityNameUsage( tableGroup, EntityNameUse.PROJECTION, persister.getEntityName(), true ); + } + else { + final int subclassTableSpan = persister.getSubclassTableSpan(); + for ( int i = 0; i < subclassTableSpan; i++ ) { + tableGroup.resolveTableReference( null, persister.getSubclassTableName( i ) ); + } } } } @@ -3261,18 +3231,13 @@ protected void pruneTableGroupJoins() { if ( tableGroup.isInitialized() ) { final Map entityNameUses = entry.getValue(); final ModelPartContainer modelPart = tableGroup.getModelPart(); - final MappingType partMappingType; - if ( modelPart instanceof PluralAttributeMapping ) { - partMappingType = ( (PluralAttributeMapping) modelPart ) - .getElementDescriptor() - .getPartMappingType(); - } - else { - partMappingType = modelPart.getPartMappingType(); - } + final MappingType partMappingType = + modelPart instanceof PluralAttributeMapping pluralAttributeMapping + ? pluralAttributeMapping.getElementDescriptor().getPartMappingType() + : modelPart.getPartMappingType(); - if ( partMappingType instanceof EntityPersister ) { - ( (EntityPersister) partMappingType ).pruneForSubclasses( tableGroup, entityNameUses ); + if ( partMappingType instanceof EntityPersister entityPersister ) { + entityPersister.pruneForSubclasses( tableGroup, entityNameUses ); } } } @@ -3291,7 +3256,7 @@ protected void consumeExplicitJoins(SqmFrom sqmFrom, TableGroup lhsTableGr ); final List> sqmTreats = sqmFrom.getSqmTreats(); if ( !sqmTreats.isEmpty() ) { - final SqlAstQueryPartProcessingState queryPartProcessingState = (SqlAstQueryPartProcessingState) getCurrentProcessingState(); + final SqlAstQueryPartProcessingState queryPartProcessingState = getSqlAstQueryPartProcessingState(); queryPartProcessingState.registerTreatedFrom( sqmFrom ); // If a SqmFrom is used anywhere even though treats exists, // the treats are context dependent and hence we need to downgrade TREAT entity uses to EXPRESSION. @@ -3303,7 +3268,8 @@ protected void consumeExplicitJoins(SqmFrom sqmFrom, TableGroup lhsTableGr for ( SqmFrom sqmTreat : sqmTreats ) { final TableGroup actualTableGroup = getActualTableGroup( lhsTableGroup, sqmTreat ); // We don't know the context yet in which a treat is used, so we have to register base treats and track the usage - registerEntityNameUsage( actualTableGroup, EntityNameUse.BASE_TREAT, ( (SqmTreatedPath) sqmTreat ).getTreatTarget().getTypeName() ); + registerEntityNameUsage( actualTableGroup, EntityNameUse.BASE_TREAT, + ( (SqmTreatedPath) sqmTreat ).getTreatTarget().getTypeName() ); consumeExplicitJoins( sqmTreat, actualTableGroup ); } } @@ -3371,14 +3337,13 @@ private TableGroup consumeAttributeJoin( final NavigablePath sqmJoinNavigablePath = sqmJoin.getNavigablePath(); - final ModelPart modelPart = ownerTableGroup.getModelPart().findSubPart( - pathSource.getPathName(), - SqmMappingModelHelper.resolveExplicitTreatTarget( sqmJoin, this ) - ); + final ModelPart modelPart = + ownerTableGroup.getModelPart() + .findSubPart( pathSource.getPathName(), + resolveExplicitTreatTarget( sqmJoin, this ) ); if ( pathSource instanceof PluralPersistentAttribute ) { assert modelPart instanceof PluralAttributeMapping; - final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart; if ( sqmJoin.isFetched() ) { @@ -3417,7 +3382,8 @@ private TableGroup consumeAttributeJoin( // Since this is an explicit join, we force the initialization of a possible lazy table group // to retain the cardinality, but only if this is a non-trivial attribute join. // Left or inner singular attribute joins without a predicate can be safely optimized away - if ( sqmJoin.getJoinPredicate() != null || sqmJoinType != SqmJoinType.INNER && sqmJoinType != SqmJoinType.LEFT ) { + if ( sqmJoin.getJoinPredicate() != null + || sqmJoinType != SqmJoinType.INNER && sqmJoinType != SqmJoinType.LEFT ) { joinedTableGroup.getPrimaryTableReference(); } } @@ -3442,11 +3408,8 @@ private TableGroup consumeAttributeJoin( if ( entityDescriptor.getSuperMappingType() != null ) { // This is a non-treated join with an entity which is an inheritance subtype, // register a TREAT entity name use to filter only the entities of the correct type. - registerEntityNameUsage( - elementTableGroup, - EntityNameUse.TREAT, - entityDomainType.getHibernateEntityName() - ); + registerEntityNameUsage( elementTableGroup, EntityNameUse.TREAT, + entityDomainType.getHibernateEntityName() ); } } @@ -3463,7 +3426,7 @@ private TableGroup consumeAttributeJoin( final SqmJoin oldJoin = currentlyProcessingJoin; currentlyProcessingJoin = sqmJoin; final Predicate predicate = visitNestedTopLevelPredicate( sqmJoin.getJoinPredicate() ); - joinForPredicate = TableGroupJoinHelper.determineJoinForPredicateApply( joinedTableGroupJoin ); + joinForPredicate = determineJoinForPredicateApply( joinedTableGroupJoin ); // If translating the join predicate didn't initialize the table group, // we can safely apply it on the collection table group instead if ( joinForPredicate.getJoinedGroup().isInitialized() ) { @@ -3475,7 +3438,7 @@ private TableGroup consumeAttributeJoin( currentlyProcessingJoin = oldJoin; } else { - joinForPredicate = TableGroupJoinHelper.determineJoinForPredicateApply( joinedTableGroupJoin ); + joinForPredicate = determineJoinForPredicateApply( joinedTableGroupJoin ); } // Since joins on treated paths will never cause table pruning, we need to add a join condition for the treat if ( sqmJoin.getLhs() instanceof SqmTreatedPath treatedPath ) { @@ -3599,7 +3562,8 @@ private TableGroup consumeDerivedJoin(SqmDerivedJoin sqmJoin, TableGroup pare fromClauseIndexStack.pop(); } final AnonymousTupleType tupleType = (AnonymousTupleType) sqmJoin.getNodeType(); - final List sqlSelections = statement.getQueryPart().getFirstQuerySpec().getSelectClause().getSqlSelections(); + final List sqlSelections = + statement.getQueryPart().getFirstQuerySpec().getSelectClause().getSqlSelections(); final AnonymousTupleTableGroupProducer tableGroupProducer = tupleType.resolveTableGroupProducer( sqmJoin.getExplicitAlias(), sqlSelections, @@ -4539,7 +4503,7 @@ private Expression extractEpoch(Expression intervalExpression) { .getDialect() .extractPattern( EPOCH ) ); - return new SelfRenderingFunctionSqlAstExpression( + return new SelfRenderingFunctionSqlAstExpression<>( "extract", (sqlAppender, sqlAstArguments, returnType, walker) -> patternRenderer.render( sqlAppender, sqlAstArguments, walker ), @@ -4688,13 +4652,11 @@ public Expression visitFunctionPath(SqmFunctionPath functionPath) { TableGroup tableGroup = getFromClauseAccess().findTableGroup( navigablePath ); if ( tableGroup == null ) { final Expression functionExpression = (Expression) functionPath.getFunction().accept( this ); - final JdbcType jdbcType = functionExpression.getExpressionType() - .getSingleJdbcMapping() - .getJdbcType(); - if ( jdbcType instanceof AggregateJdbcType ) { + final JdbcType jdbcType = functionExpression.getExpressionType().getSingleJdbcMapping().getJdbcType(); + if ( jdbcType instanceof AggregateJdbcType aggregateJdbcType ) { tableGroup = new EmbeddableFunctionTableGroup( navigablePath, - ( (AggregateJdbcType) jdbcType ).getEmbeddableMappingType(), + aggregateJdbcType.getEmbeddableMappingType(), functionExpression ); getFromClauseAccess().registerTableGroup( navigablePath, tableGroup ); @@ -4781,7 +4743,7 @@ public Expression visitPluralAttributeSizeFunction(SqmCollectionSize function) { final BasicType integerType = creationContext.getMappingMetamodel() .getTypeConfiguration() .getBasicTypeForJavaType( Integer.class ); - final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression( + final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression<>( functionDescriptor.getName(), functionDescriptor, singletonList( Star.INSTANCE ), @@ -4971,15 +4933,14 @@ else if ( collectionPart instanceof ManyToManyCollectionPart ) { if ( jdbcTypeCount != 1 ) { arguments.add( new SqlTuple( tupleElements, modelPart ) ); } - final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression( + final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression<>( functionDescriptor.getName(), functionDescriptor, arguments, null, - (ReturnableType) functionDescriptor.getReturnTypeResolver().resolveFunctionReturnType( - () -> null, - arguments - ).getJdbcMapping(), + (ReturnableType) functionDescriptor.getReturnTypeResolver() + .resolveFunctionReturnType( () -> null, arguments ) + .getJdbcMapping(), modelPart ); subQuerySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( expression ) ); @@ -5143,21 +5104,18 @@ else if ( collectionPart instanceof ManyToManyCollectionPart ) { else { arguments = singletonList( new SqlTuple( subQueryColumns, modelPart ) ); } - final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression( + final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression<>( functionDescriptor.getName(), functionDescriptor, arguments, null, - (ReturnableType) functionDescriptor.getReturnTypeResolver().resolveFunctionReturnType( - () -> null, - arguments - ).getJdbcMapping(), + (ReturnableType) functionDescriptor.getReturnTypeResolver() + .resolveFunctionReturnType( () -> null, arguments ) + .getJdbcMapping(), modelPart ); - subQuerySpec.getSelectClause().addSqlSelection( - new SqlSelectionImpl( expression ) - ); + subQuerySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( expression ) ); resultColumnReferences.add( new ColumnReference( identifierVariable, @@ -5177,24 +5135,13 @@ else if ( collectionPart instanceof ManyToManyCollectionPart ) { this ) ); - final Set compatibleTableExpressions; - final BasicValuedModelPart basicPart = modelPart.asBasicValuedModelPart(); - if ( basicPart != null ) { - compatibleTableExpressions = Collections.singleton( basicPart.getContainingTableExpression() ); - } - else if ( modelPart instanceof EmbeddableValuedModelPart ) { - compatibleTableExpressions = Collections.singleton( ( (EmbeddableValuedModelPart) modelPart ).getContainingTableExpression() ); - } - else { - compatibleTableExpressions = Collections.emptySet(); - } lateralTableGroup = new QueryPartTableGroup( queryPath, null, new SelectStatement( subQuerySpec ), identifierVariable, columnNames, - compatibleTableExpressions, + getCompatibleTableExpressions( modelPart ), true, false, creationContext.getSessionFactory() @@ -5235,7 +5182,7 @@ else if ( modelPart instanceof EmbeddableValuedModelPart ) { } parentFromClauseAccess.registerTableGroup( lateralTableGroup.getNavigablePath(), lateralTableGroup ); if ( jdbcTypeCount == 1 ) { - return new SelfRenderingFunctionSqlAstExpression( + return new SelfRenderingFunctionSqlAstExpression<>( pathName, (sqlAppender, sqlAstArguments, returnType, walker) -> sqlAstArguments.get( 0 ).accept( walker ), resultColumnReferences, @@ -5257,7 +5204,7 @@ else if ( modelPart instanceof EmbeddableValuedModelPart ) { .getFirstQuerySpec() .getSelectClause() .getSqlSelections(); - return new SelfRenderingFunctionSqlAstExpression( + return new SelfRenderingFunctionSqlAstExpression<>( pathName, (sqlAppender, sqlAstArguments, returnType, walker) -> sqlAstArguments.get( 0 ).accept( walker ), singletonList( @@ -5290,6 +5237,19 @@ else if ( modelPart instanceof EmbeddableValuedModelPart ) { } } + private static Set getCompatibleTableExpressions(ModelPart modelPart) { + final BasicValuedModelPart basicPart = modelPart.asBasicValuedModelPart(); + if ( basicPart != null ) { + return singleton( basicPart.getContainingTableExpression() ); + } + else if ( modelPart instanceof EmbeddableValuedModelPart embeddableValuedModelPart ) { + return singleton( embeddableValuedModelPart.getContainingTableExpression() ); + } + else { + return emptySet(); + } + } + private Expression withTreatRestriction(Expression expression, SqmPath path) { final SqmPath lhs; if ( path instanceof SqmTreatedPath ) { @@ -5467,11 +5427,11 @@ private Set determineEntityNamesForTreatTypeRestriction( if ( entityNameUsesSet.containsAll( partMappingType.getSubclassEntityNames() ) ) { // No need to create a restriction if all subclasses are used - return Collections.emptySet(); + return emptySet(); } if ( entityNameUses.containsValue( EntityNameUse.FILTER ) ) { // If the conjunct contains FILTER uses we can omit the treat type restriction - return Collections.emptySet(); + return emptySet(); } final String baseEntityNameToAdd; if ( entityNameUsesSet.contains( partMappingType.getEntityName() ) ) { @@ -5482,7 +5442,7 @@ private Set determineEntityNamesForTreatTypeRestriction( baseEntityNameToAdd = null; } if ( entityNameUses.size() == 1 ) { - return Collections.emptySet(); + return emptySet(); } } else { @@ -5587,14 +5547,11 @@ private Expression getTypeLiteral(SqmPathInterpretation typeExpression, Strin return new EntityTypeLiteral( domainModel.findEntityDescriptor( typeName ) ); } else { - final EmbeddableDomainType embeddable = creationContext.getSessionFactory() - .getRuntimeMetamodels() - .getJpaMetamodel() - .embeddable( typeName ); - return new EmbeddableTypeLiteral( - embeddable, - (BasicType) typeExpression.getExpressionType().getSingleJdbcMapping() - ); + final EmbeddableDomainType embeddable = + creationContext.getSessionFactory().getJpaMetamodel() + .embeddable( typeName ); + return new EmbeddableTypeLiteral( embeddable, + (BasicType) typeExpression.getExpressionType().getSingleJdbcMapping() ); } } @@ -5603,10 +5560,12 @@ private MappingModelExpressible resolveInferredType() { if ( inTypeInference || inferableTypeAccess == null ) { return null; } - inTypeInference = true; - final MappingModelExpressible inferredType = inferableTypeAccess.get(); - inTypeInference = false; - return inferredType; + else { + inTypeInference = true; + final MappingModelExpressible inferredType = inferableTypeAccess.get(); + inTypeInference = false; + return inferredType; + } } @Override @@ -6623,11 +6582,7 @@ public Object visitCoalesce(SqmCoalesce sqmCoalesce) { final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory(); final QueryEngine queryEngine = sessionFactory.getQueryEngine(); return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "coalesce" ) - .generateSqmExpression( - sqmCoalesce.getArguments(), - null, - queryEngine - ) + .generateSqmExpression( sqmCoalesce.getArguments(), null, queryEngine ) .accept( this ); } @@ -6795,21 +6750,18 @@ else if (type instanceof ValueMapping valueMapping ) { if ( lhs != expression.getLeftHandOperand() ) { final SqmPath temporalPath = (SqmPath) expression.getLeftHandOperand(); baseNavigablePath = temporalPath.getNavigablePath().getParent(); - offset = (temporalPath).get( - AbstractTimeZoneStorageCompositeUserType.ZONE_OFFSET_NAME - ).accept( this ); + offset = temporalPath.get( ZONE_OFFSET_NAME ).accept( this ); } else if ( rhs != expression.getRightHandOperand() ) { final SqmPath temporalPath = (SqmPath) expression.getRightHandOperand(); baseNavigablePath = temporalPath.getNavigablePath().getParent(); - offset = ( temporalPath ).get( - AbstractTimeZoneStorageCompositeUserType.ZONE_OFFSET_NAME - ).accept( this ); + offset = temporalPath.get( ZONE_OFFSET_NAME ).accept( this ); } else { return result; } - final EmbeddableValuedModelPart valueMapping = (EmbeddableValuedModelPart) determineValueMapping( expression ); + final EmbeddableValuedModelPart valueMapping = + (EmbeddableValuedModelPart) determineValueMapping( expression ); return new EmbeddableValuedExpression<>( baseNavigablePath, valueMapping, @@ -7346,11 +7298,9 @@ private Summarization.Kind getSummarizationKind(SqmSummarization.Kind kind) { @Override public Expression visitEntityTypeLiteralExpression(SqmLiteralEntityType sqmExpression) { - final EntityDomainType nodeType = sqmExpression.getNodeType(); - final EntityPersister mappingDescriptor = creationContext.getSessionFactory() - .getMappingMetamodel() - .getEntityDescriptor( nodeType.getHibernateEntityName() ); - + final EntityPersister mappingDescriptor = + creationContext.getSessionFactory().getMappingMetamodel() + .getEntityDescriptor( sqmExpression.getNodeType().getHibernateEntityName() ); return new EntityTypeLiteral( mappingDescriptor ); } @@ -7506,14 +7456,16 @@ public Junction visitJunctionPredicate(SqmJunctionPredicate predicate) { } if ( i == 0 ) { // Collect the table groups for which filters are registered - for ( Map.Entry> entry : tableGroupEntityNameUses.entrySet() ) { - if ( entry.getValue().containsValue( EntityNameUse.TREAT ) || entry.getValue().containsValue( EntityNameUse.OPTIONAL_TREAT ) ) { + for ( var entry : tableGroupEntityNameUses.entrySet() ) { + final Map value = entry.getValue(); + if ( value.containsValue( EntityNameUse.TREAT ) + || value.containsValue( EntityNameUse.OPTIONAL_TREAT ) ) { if ( treatedTableGroups == null ) { treatedTableGroups = new ArrayList<>( 1 ); } treatedTableGroups.add( entry.getKey() ); } - if ( entry.getValue().containsValue( EntityNameUse.FILTER ) ) { + if ( value.containsValue( EntityNameUse.FILTER ) ) { if ( filteredTableGroups == null ) { filteredTableGroups = new ArrayList<>( 1 ); } @@ -7540,7 +7492,7 @@ public Junction visitJunctionPredicate(SqmJunctionPredicate predicate) { // If every disjunct contains a FILTER, we can merge the filters // If every disjunct contains a TREAT, we can merge the treats // Otherwise, we downgrade the entity name uses to expression uses - final Iterator>> iterator = tableGroupEntityNameUses.entrySet().iterator(); + final var iterator = tableGroupEntityNameUses.entrySet().iterator(); while ( iterator.hasNext() ) { final Map.Entry> entry = iterator.next(); final TableGroup tableGroup = entry.getKey(); @@ -8194,30 +8146,24 @@ private InListPredicate processInListWithSingleParameter( SqmInListPredicate sqmPredicate, SqmParameter sqmParameter) { assert sqmParameter.allowMultiValuedBinding(); + return sqmParameter instanceof JpaCriteriaParameter parameter + ? processInSingleCriteriaParameter( sqmPredicate, parameter ) + : processInSingleHqlParameter( sqmPredicate, sqmParameter ); - if ( sqmParameter instanceof JpaCriteriaParameter parameter ) { - return processInSingleCriteriaParameter( sqmPredicate, parameter ); - } - - return processInSingleHqlParameter( sqmPredicate, sqmParameter ); } private InListPredicate processInSingleHqlParameter(SqmInListPredicate sqmPredicate, SqmParameter sqmParameter) { final QueryParameterImplementor domainParam = domainParameterXref.getQueryParameter( sqmParameter ); final QueryParameterBinding domainParamBinding = domainParameterBindings.getBinding( domainParam ); - if ( !domainParamBinding.isMultiValued() ) { - // triggers normal processing - return null; - } - - return processInSingleParameter( sqmPredicate, sqmParameter, domainParam, domainParamBinding ); + return !domainParamBinding.isMultiValued() + ? null // triggers normal processing + : processInSingleParameter( sqmPredicate, sqmParameter, domainParam, domainParamBinding ); } private InListPredicate processInSingleCriteriaParameter( SqmInListPredicate sqmPredicate, JpaCriteriaParameter jpaCriteriaParameter) { assert jpaCriteriaParameter.allowsMultiValuedBinding(); - final QueryParameterBinding domainParamBinding = domainParameterBindings.getBinding( jpaCriteriaParameter ); if ( domainParamBinding.isMultiValued() ) { final SqmJpaCriteriaParameterWrapper sqmWrapper = jpaCriteriaParamResolutions.get( jpaCriteriaParameter ); @@ -8245,7 +8191,9 @@ private InListPredicate processInSingleParameter( final FromClauseIndex fromClauseIndex = fromClauseIndexStack.getCurrent(); if ( !iterator.hasNext() ) { - domainParamBinding.setType( (MappingModelExpressible) determineValueMapping( sqmPredicate.getTestExpression(), fromClauseIndex ) ); + final MappingModelExpressible expressible = + determineValueMapping( sqmPredicate.getTestExpression(), fromClauseIndex ); + domainParamBinding.setType( (MappingModelExpressible) expressible ); return inListPredicate; } @@ -8299,8 +8247,8 @@ public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate pred } inferrableTypeAccessStack.pop(); - if ( booleanExpression instanceof SelfRenderingExpression ) { - final Predicate sqlPredicate = new SelfRenderingPredicate( (SelfRenderingExpression) booleanExpression ); + if ( booleanExpression instanceof SelfRenderingExpression selfRenderingExpression ) { + final Predicate sqlPredicate = new SelfRenderingPredicate( selfRenderingExpression ); return predicate.isNegated() ? new NegatedPredicate( sqlPredicate ) : sqlPredicate; } else { @@ -8314,11 +8262,7 @@ public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate pred ); } - return new BooleanExpressionPredicate( - booleanExpression, - predicate.isNegated(), - getBooleanType() - ); + return new BooleanExpressionPredicate( booleanExpression, predicate.isNegated(), getBooleanType() ); } } @@ -8371,8 +8315,8 @@ public Object visitNamedExpression(SqmNamedExpression expression) { @Override public Fetch visitIdentifierFetch(EntityResultGraphNode fetchParent) { - final EntityIdentifierMapping identifierMapping = fetchParent.getReferencedMappingContainer() - .getIdentifierMapping(); + final EntityIdentifierMapping identifierMapping = + fetchParent.getReferencedMappingContainer().getIdentifierMapping(); return createFetch( fetchParent, identifierMapping, false ); } @@ -8381,15 +8325,12 @@ private Fetch createFetch(FetchParent fetchParent, Fetchable fetchable, Boolean return null; } final NavigablePath resolvedNavigablePath = fetchParent.resolveNavigablePath( fetchable ); - final Map.Entry> sqlSelectionsToTrack = trackedFetchSelectionsForGroup.get( resolvedNavigablePath ); - final int sqlSelectionStartIndexForFetch; - if ( sqlSelectionsToTrack != null ) { - final List selections = currentSqlSelectionCollector().getSelections( sqlSelectionsToTrack.getKey() ); - sqlSelectionStartIndexForFetch = selections.size(); - } - else { - sqlSelectionStartIndexForFetch = -1; - } + final var sqlSelectionsToTrack = trackedFetchSelectionsForGroup.get( resolvedNavigablePath ); + final int sqlSelectionStartIndexForFetch = + sqlSelectionsToTrack == null ? -1 + : currentSqlSelectionCollector() + .getSelections( sqlSelectionsToTrack.getKey() ) + .size(); final String alias; FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming(); @@ -8448,9 +8389,9 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { for ( String enabledFetchProfileName : getLoadQueryInfluencers().getEnabledFetchProfileNames() ) { - final FetchProfile enabledFetchProfile = getCreationContext() - .getSessionFactory() - .getFetchProfile( enabledFetchProfileName ); + final FetchProfile enabledFetchProfile = + getCreationContext().getSessionFactory() + .getFetchProfile( enabledFetchProfileName ); final org.hibernate.engine.profile.Fetch profileFetch = enabledFetchProfile.getFetchByRole( fetchableRole ); @@ -8461,9 +8402,10 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { explicitFetch = true; } - if ( currentBagRole != null && fetchable instanceof PluralAttributeMapping ) { + if ( currentBagRole != null + && fetchable instanceof PluralAttributeMapping pluralAttributeMapping ) { final CollectionClassification collectionClassification = - ( (PluralAttributeMapping) fetchable ).getMappedType() + pluralAttributeMapping.getMappedType() .getCollectionSemantics() .getCollectionClassification(); if ( collectionClassification == CollectionClassification.BAG ) { @@ -8500,7 +8442,8 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { final SqmQueryPart queryPart = getCurrentSqmQueryPart(); if ( compatibleTableGroup == null // If the compatible table group is used in the where clause it cannot be reused for fetching - || ( queryPart != null && queryPart.getFirstQuerySpec().whereClauseContains( compatibleTableGroup.getNavigablePath(), this ) ) ) { + || ( queryPart != null && queryPart.getFirstQuerySpec() + .whereClauseContains( compatibleTableGroup.getNavigablePath(), this ) ) ) { final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin( fetchablePath, lhs, @@ -8532,25 +8475,13 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { } // There is no need to check for circular fetches if this is an explicit fetch if ( !explicitFetch && !isResolvingCircularFetch() ) { - final Fetch biDirectionalFetch = fetchable.resolveCircularFetch( - fetchablePath, - fetchParent, - fetchTiming, - this - ); - + final Fetch biDirectionalFetch = + fetchable.resolveCircularFetch( fetchablePath, fetchParent, fetchTiming, this ); if ( biDirectionalFetch != null ) { return biDirectionalFetch; } } - final Fetch fetch = buildFetch( - fetchablePath, - fetchParent, - fetchable, - fetchTiming, - joined, - alias - ); + final Fetch fetch = buildFetch( fetchablePath, fetchParent, fetchable, fetchTiming, joined, alias ); if ( sqlSelectionsToTrack != null ) { final List selections = currentSqlSelectionCollector().getSelections( sqlSelectionsToTrack.getKey() ); @@ -8584,16 +8515,15 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { } } if ( fetchable instanceof PluralAttributeMapping pluralAttributeMapping ) { - final CollectionClassification collectionClassification = pluralAttributeMapping.getMappedType() - .getCollectionSemantics() - .getCollectionClassification(); + final CollectionClassification collectionClassification = + pluralAttributeMapping.getMappedType() + .getCollectionSemantics() + .getCollectionClassification(); if ( collectionClassification == CollectionClassification.BAG ) { if ( currentBagRole != null ) { throw new MultipleBagFetchException( - Arrays.asList( - currentBagRole, - fetchable.getNavigableRole().getNavigableName() - ) + Arrays.asList( currentBagRole, + fetchable.getNavigableRole().getNavigableName() ) ); } currentBagRole = fetchable.getNavigableRole().getNavigableName(); @@ -8615,7 +8545,8 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { @Override public R withNestedFetchParent(FetchParent fetchParent, Function action) { - final SqlAstQueryPartProcessingStateImpl processingState = (SqlAstQueryPartProcessingStateImpl) getCurrentProcessingState(); + final SqlAstQueryPartProcessingStateImpl processingState = + (SqlAstQueryPartProcessingStateImpl) getCurrentProcessingState(); final FetchParent nestingFetchParent = processingState.getNestingFetchParent(); processingState.setNestingFetchParent( fetchParent ); final R result = action.apply( fetchParent ); @@ -8739,12 +8670,16 @@ public boolean equals(Object o) { if ( this == o ) { return true; } - if ( o == null || getClass() != o.getClass() ) { + else if ( o == null ) { return false; } - - final MetadataKey that = (MetadataKey) o; - return source.equals( that.source ) && producer.equals( that.producer ); + else if ( !(o instanceof MetadataKey that) ) { + return false; + } + else { + return source.equals( that.source ) + && producer.equals( that.producer ); + } } @Override @@ -8834,13 +8769,13 @@ private static int countIndividualSelections(List> s int offset = 0; for ( int i = 0; i < selections.size(); i++ ) { final SqmSelectableNode selectableNode = selections.get( i ).getSelectableNode(); - if ( selectableNode instanceof SqmDynamicInstantiation ) { - offset += countIndividualSelections( ( (SqmDynamicInstantiation) selectableNode ).getArguments() ); + if ( selectableNode instanceof SqmDynamicInstantiation dynamicInstantiation ) { + offset += countIndividualSelections( dynamicInstantiation.getArguments() ); } - else if ( selectableNode instanceof SqmJpaCompoundSelection ) { - for ( SqmSelectableNode node : ( (SqmJpaCompoundSelection) selectableNode ).getSelectionItems() ) { - if ( node instanceof SqmDynamicInstantiation ) { - offset += countIndividualSelections( ( (SqmDynamicInstantiation) node ).getArguments() ); + else if ( selectableNode instanceof SqmJpaCompoundSelection compoundSelection ) { + for ( SqmSelectableNode node : compoundSelection.getSelectionItems() ) { + if ( node instanceof SqmDynamicInstantiation dynamicInstantiation ) { + offset += countIndividualSelections( dynamicInstantiation.getArguments() ); } else { offset += 1; @@ -8875,7 +8810,8 @@ public SqlSelection resolveSqlSelection( JavaType javaType, FetchParent fetchParent, TypeConfiguration typeConfiguration) { - SqlSelection selection = delegate.resolveSqlSelection( expression, javaType, fetchParent, typeConfiguration ); + final SqlSelection selection = + delegate.resolveSqlSelection( expression, javaType, fetchParent, typeConfiguration ); List sqlSelectionList = sqlSelectionsForSqmSelection[index]; if ( sqlSelectionList == null ) { sqlSelectionsForSqmSelection[index] = sqlSelectionList = new ArrayList<>(); @@ -8964,8 +8900,9 @@ public CteStatement getCteStatement(String cteLabel) { @Override public void addCteStatement(CteStatement cteStatement) { - if ( cteStatements.putIfAbsent( cteStatement.getCteTable().getTableExpression(), cteStatement ) != null ) { - throw new IllegalArgumentException( "A CTE with the label " + cteStatement.getCteTable().getTableExpression() + " already exists" ); + final String tableExpression = cteStatement.getCteTable().getTableExpression(); + if ( cteStatements.putIfAbsent( tableExpression, cteStatement ) != null ) { + throw new IllegalArgumentException( "A CTE with the label " + tableExpression + " already exists" ); } } @@ -8977,10 +8914,7 @@ public Map getCteObjects() { @Override public CteObject getCteObject(String cteObjectName) { final CteObject cteObject = cteObjects.get( cteObjectName ); - if ( cteObject == null && parent != null ) { - return parent.getCteObject( cteObjectName ); - } - return cteObject; + return cteObject == null && parent != null ? parent.getCteObject( cteObjectName ) : cteObject; } @Override @@ -9033,7 +8967,7 @@ class Sample { */ return creationContext.getMaximumFetchDepth() == null - && ( entityGraphTraversalState != null || getLoadQueryInfluencers().hasEnabledFetchProfiles() ); + && ( entityGraphTraversalState != null || getLoadQueryInfluencers().hasEnabledFetchProfiles() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index c8d11bf23a92..9d1e31d0a30e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -229,6 +229,7 @@ import jakarta.persistence.criteria.Nulls; +import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.persister.entity.DiscriminatorHelper.jdbcLiteral; import static org.hibernate.query.sqm.BinaryArithmeticOperator.DIVIDE_PORTABLE; import static org.hibernate.query.common.TemporalUnit.DAY; @@ -6667,7 +6668,7 @@ && supportsRowValueConstructorDistinctFromSyntax() ) { countQuery.setHavingClauseRestrictions( querySpec.getHavingClauseRestrictions() ); countQuery.getSelectClause().addSqlSelection( new SqlSelectionImpl( - new SelfRenderingAggregateFunctionSqlAstExpression( + new SelfRenderingAggregateFunctionSqlAstExpression<>( "count", (sqlAppender, sqlAstArguments, returnType, walker) -> sqlAppender.append( "count(*)" ), List.of( Star.INSTANCE ), @@ -7305,9 +7306,7 @@ public void visitDuration(Duration duration) { else { duration.getMagnitude().accept( this ); // Convert to NANOSECOND because DurationJavaType requires values in that unit - appendSql( - duration.getUnit().conversionFactor( NANOSECOND, dialect ) - ); + appendSql( duration.getUnit().conversionFactor( NANOSECOND, dialect ) ); } } @@ -7352,11 +7351,7 @@ protected void renderIntervalLiteral(Literal literal, TemporalUnit unit) { public void visitConversion(Conversion conversion) { final Duration duration = conversion.getDuration(); duration.getMagnitude().accept( this ); - appendSql( - duration.getUnit().conversionFactor( - conversion.getUnit(), dialect - ) - ); + appendSql( duration.getUnit().conversionFactor( conversion.getUnit(), dialect ) ); } @Override @@ -7379,7 +7374,8 @@ protected void visitAnsiCaseSearchedExpression( appendSql( "case" ); final SqlAstNodeRenderingMode original = this.parameterRenderingMode; for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) { - if ( original != SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS && original != SqlAstNodeRenderingMode.WRAP_ALL_PARAMETERS ) { + if ( original != SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS + && original != SqlAstNodeRenderingMode.WRAP_ALL_PARAMETERS ) { this.parameterRenderingMode = SqlAstNodeRenderingMode.DEFAULT; } appendSql( " when " ); @@ -7407,7 +7403,8 @@ protected void visitDecodeCaseSearchedExpression(CaseSearchedExpression caseSear for ( int i = 0; i < caseNumber; i++ ) { final CaseSearchedExpression.WhenFragment whenFragment = whenFragments.get( i ); Predicate predicate = whenFragment.getPredicate(); - if ( original != SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS && original != SqlAstNodeRenderingMode.WRAP_ALL_PARAMETERS ) { + if ( original != SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS + && original != SqlAstNodeRenderingMode.WRAP_ALL_PARAMETERS ) { this.parameterRenderingMode = SqlAstNodeRenderingMode.DEFAULT; } if ( i != 0 ) { @@ -7568,12 +7565,7 @@ protected void renderAsLiteral(JdbcParameter jdbcParameter, Object literalValue) throw new IllegalArgumentException( "Can't render parameter as literal, no literal formatter found" ); } else { - literalFormatter.appendJdbcLiteral( - this, - literalValue, - dialect, - getWrapperOptions() - ); + literalFormatter.appendJdbcLiteral( this, literalValue, dialect, getWrapperOptions() ); } } } @@ -7657,20 +7649,18 @@ public void visitFilterPredicate(FilterPredicate filterPredicate) { public void visitFilterFragmentPredicate(FilterFragmentPredicate filter) { // process a specific filter final String sqlFragment = filter.getSqlFragment(); - if ( filter.getParameters() == null ) { sqlBuffer.append( sqlFragment ); - return; - } - - int lastEnd = 0; - for ( int p = 0; p < filter.getParameters().size(); p++ ) { - final FilterFragmentParameter parameter = filter.getParameters().get( p ); - lastEnd = processFilterParameter( parameter, sqlFragment, lastEnd ); } - - if ( lastEnd < sqlFragment.length() ) { - appendSql( sqlFragment.substring( lastEnd ) ); + else { + int lastEnd = 0; + for ( int p = 0; p < filter.getParameters().size(); p++ ) { + final FilterFragmentParameter parameter = filter.getParameters().get( p ); + lastEnd = processFilterParameter( parameter, sqlFragment, lastEnd ); + } + if ( lastEnd < sqlFragment.length() ) { + appendSql( sqlFragment.substring( lastEnd ) ); + } } } @@ -7683,9 +7673,9 @@ private int processFilterParameter(FilterFragmentParameter parameter, String sql final Object value = parameter.getValue(); final JdbcMapping valueMapping = parameter.getValueMapping(); - if ( value instanceof Iterable + if ( value instanceof Iterable iterable && !valueMapping.getJavaTypeDescriptor().isInstance( value ) ) { - processIterableFilterParameterValue( valueMapping, ( (Iterable) value ).iterator() ); + processIterableFilterParameterValue( valueMapping, iterable.iterator() ); } else { processSingularFilterParameterValue( valueMapping, value ); @@ -7700,8 +7690,7 @@ private void processSingularFilterParameterValue(JdbcMapping valueMapping, Objec private void processIterableFilterParameterValue(JdbcMapping valueMapping, Iterator iterator) { while ( iterator.hasNext() ) { - final Object element = iterator.next(); - processSingularFilterParameterValue( valueMapping, element ); + processSingularFilterParameterValue( valueMapping, iterator.next() ); if ( iterator.hasNext() ) { appendSql( "," ); } @@ -7710,19 +7699,17 @@ private void processIterableFilterParameterValue(JdbcMapping valueMapping, Itera @Override public void visitSqlFragmentPredicate(SqlFragmentPredicate predicate) { - assert StringHelper.isNotEmpty( predicate.getSqlFragment() ); + assert isNotEmpty( predicate.getSqlFragment() ); appendSql( predicate.getSqlFragment() ); } @Override public void visitGroupedPredicate(GroupedPredicate groupedPredicate) { - if ( groupedPredicate.isEmpty() ) { - return; + if ( !groupedPredicate.isEmpty() ) { + appendSql( OPEN_PARENTHESIS ); + groupedPredicate.getSubPredicate().accept( this ); + appendSql( CLOSE_PARENTHESIS ); } - - appendSql( OPEN_PARENTHESIS ); - groupedPredicate.getSubPredicate().accept( this ); - appendSql( CLOSE_PARENTHESIS ); } @Override @@ -7732,6 +7719,7 @@ public void visitInListPredicate(InListPredicate inListPredicate) { appendSql( "1=" + ( inListPredicate.isNegated() ? "1" : "0" ) ); return; } + Function itemAccessor = Function.identity(); final SqlTuple lhsTuple; if ( ( lhsTuple = SqlTupleContainer.getSqlTuple( inListPredicate.getTestExpression() ) ) != null ) { @@ -7848,14 +7836,15 @@ private void appendInClauseSeparator(InListPredicate inListPredicate) { } private static int addPadding(int bindValueCount, int inExprLimit) { - int ceilingPowerOfTwo = MathHelper.ceilingPowerOfTwo( bindValueCount ); + final int ceilingPowerOfTwo = MathHelper.ceilingPowerOfTwo( bindValueCount ); if ( inExprLimit <= 0 || ceilingPowerOfTwo <= inExprLimit ) { return ceilingPowerOfTwo; } - - int numberOfInClauses = MathHelper.divideRoundingUp( bindValueCount, inExprLimit ); - int numberOfInClausesWithPadding = MathHelper.ceilingPowerOfTwo( numberOfInClauses ); - return numberOfInClausesWithPadding * inExprLimit; + else { + int numberOfInClauses = MathHelper.divideRoundingUp( bindValueCount, inExprLimit ); + int numberOfInClausesWithPadding = MathHelper.ceilingPowerOfTwo( numberOfInClauses ); + return numberOfInClausesWithPadding * inExprLimit; + } } @Override @@ -7918,9 +7907,10 @@ protected void emulateSubQueryRelationalRestrictionPredic ComparisonOperator tupleComparisonOperator) { final QueryPart queryPart = selectStatement.getQueryPart(); final QuerySpec subQuery; - if ( queryPart instanceof QuerySpec && queryPart.getFetchClauseExpression() == null + if ( queryPart instanceof QuerySpec querySpec + && queryPart.getFetchClauseExpression() == null && queryPart.getOffsetClauseExpression() == null ) { - subQuery = (QuerySpec) queryPart; + subQuery = querySpec; // We can only emulate the tuple subquery predicate as exists predicate when there are no limit/offsets if ( negated ) { appendSql( "not " ); @@ -8017,8 +8007,10 @@ protected void emulateQuantifiedTupleSubQueryPredicate( ComparisonOperator tupleComparisonOperator) { final QueryPart queryPart = selectStatement.getQueryPart(); final QuerySpec subQuery; - if ( queryPart instanceof QuerySpec && queryPart.getFetchClauseExpression() == null && queryPart.getOffsetClauseExpression() == null ) { - subQuery = (QuerySpec) queryPart; + if ( queryPart instanceof QuerySpec querySpec + && queryPart.getFetchClauseExpression() == null + && queryPart.getOffsetClauseExpression() == null ) { + subQuery = querySpec; // We can only emulate the tuple subquery predicate comparing against the top element when there are no limit/offsets lhsTuple.accept( this ); appendSql( tupleComparisonOperator.sqlText() ); @@ -8041,7 +8033,8 @@ protected void emulateQuantifiedTupleSubQueryPredicate( appendSql( " order by " ); final List sqlSelections = subQuery.getSelectClause().getSqlSelections(); final String order; - if ( tupleComparisonOperator == ComparisonOperator.LESS_THAN || tupleComparisonOperator == ComparisonOperator.LESS_THAN_OR_EQUAL ) { + if ( tupleComparisonOperator == ComparisonOperator.LESS_THAN + || tupleComparisonOperator == ComparisonOperator.LESS_THAN_OR_EQUAL ) { // Default order is asc so we don't need to specify the order explicitly order = ""; } @@ -8091,9 +8084,7 @@ public void visitJunction(Junction junction) { } final Junction.Nature nature = junction.getNature(); - final String separator = nature == Junction.Nature.CONJUNCTION - ? " and " - : " or "; + final String separator = nature == Junction.Nature.CONJUNCTION ? " and " : " or "; final List predicates = junction.getPredicates(); visitJunctionPredicate( nature, predicates.get( 0 ) ); for ( int i = 1; i < predicates.size(); i++ ) { @@ -8183,7 +8174,7 @@ protected void renderBackslashEscapedLikePattern( // Note: this does not cover cases where it's set via parameter binding boolean isExplicitEscape = false; if ( escapeCharacter instanceof Literal literal ) { - Object literalValue = literal.getLiteralValue(); + final Object literalValue = literal.getLiteralValue(); isExplicitEscape = literalValue != null && !literalValue.toString().equals( "" ); } if ( isExplicitEscape ) { @@ -8192,8 +8183,8 @@ protected void renderBackslashEscapedLikePattern( else { // Since escape with empty or null character is ignored we need // four backslashes to render a single one in a like pattern - if ( pattern instanceof Literal ) { - Object literalValue = ( (Literal) pattern ).getLiteralValue(); + if ( pattern instanceof Literal literal ) { + final Object literalValue = literal.getLiteralValue(); if ( literalValue == null ) { pattern.accept( this ); } @@ -8259,7 +8250,8 @@ public void visitNullnessPredicate(NullnessPredicate nullnessPredicate) { String separator = NO_SEPARATOR; // HQL has different semantics for the not null check on embedded attribute mappings // as the embeddable is not considered as null, if at least one sub-part is not null - if ( nullnessPredicate.isNegated() && expression.getExpressionType() instanceof AttributeMapping ) { + if ( nullnessPredicate.isNegated() + && expression.getExpressionType() instanceof AttributeMapping ) { appendSql( '(' ); for ( Expression exp : tuple.getExpressions() ) { appendSql( separator ); @@ -8336,16 +8328,16 @@ public void visitRelationalPredicate(ComparisonPredicate comparisonPredicate) { final SelectStatement subquery; // Handle emulation of quantified comparison - if ( rhsExpression instanceof SelectStatement ) { - subquery = (SelectStatement) rhsExpression; + if ( rhsExpression instanceof SelectStatement selectStatement ) { + subquery = selectStatement; all = true; } - else if ( rhsExpression instanceof Every ) { - subquery = ( (Every) rhsExpression ).getSubquery(); + else if ( rhsExpression instanceof Every every ) { + subquery = every.getSubquery(); all = true; } - else if ( rhsExpression instanceof Any ) { - subquery = ( (Any) rhsExpression ).getSubquery(); + else if ( rhsExpression instanceof Any any ) { + subquery = any.getSubquery(); all = false; } else { @@ -8387,7 +8379,8 @@ else if ( subquery != null && !supportsRowValueConstructorSyntaxInQuantifiedPred case EQUAL: case DISTINCT_FROM: case NOT_DISTINCT_FROM: { - // For this special case, we can rely on scalar subquery handling, given that the subquery fetches only one row + // For this special case, we can rely on scalar subquery handling, + // given that the subquery fetches only one row if ( isFetchFirstRowOnly( subquery.getQueryPart() ) ) { renderComparison( lhsTuple, operator, subquery ); return; @@ -8408,7 +8401,8 @@ else if ( needsTupleComparisonEmulation( operator ) ) { rhsTuple = SqlTupleContainer.getSqlTuple( rhsExpression ); assert rhsTuple != null; // If the DB supports tuples in the IN list predicate, use that syntax as it's more concise - if ( ( operator == ComparisonOperator.EQUAL || operator == ComparisonOperator.NOT_EQUAL ) && supportsRowValueConstructorSyntaxInInList() ) { + if ( ( operator == ComparisonOperator.EQUAL || operator == ComparisonOperator.NOT_EQUAL ) + && supportsRowValueConstructorSyntaxInInList() ) { comparisonPredicate.getLeftHandExpression().accept( this ); if ( operator == ComparisonOperator.NOT_EQUAL ) { appendSql( " not" ); @@ -8434,7 +8428,8 @@ else if ( ( rhsTuple = SqlTupleContainer.getSqlTuple( comparisonPredicate.getRig final Expression lhsExpression = comparisonPredicate.getLeftHandExpression(); if ( lhsExpression instanceof SqlTupleContainer - || lhsExpression instanceof SelectStatement && ( (SelectStatement) lhsExpression ).getQueryPart() instanceof QueryGroup ) { + || lhsExpression instanceof SelectStatement selectStatement + && selectStatement.getQueryPart() instanceof QueryGroup ) { if ( rhsTuple.getExpressions().size() == 1 ) { // Special case for tuples with arity 1 as any DBMS supports scalar IN predicates renderComparison(