diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqmToSqlAstConverter.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqmToSqlAstConverter.java index cf9a3a0239..9dbf1e0490 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqmToSqlAstConverter.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqmToSqlAstConverter.java @@ -18,8 +18,8 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.StandardTableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.select.QuerySpec; /** @@ -54,7 +54,7 @@ public class InformixSqmToSqlAstConverter extends BaseSqmTo null, null, null, - new TableReference( + new NamedTableReference( "(select 1)", "dummy_(x)", false, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqmToSqlAstConverter.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqmToSqlAstConverter.java index 6094646a23..0d00d5318c 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqmToSqlAstConverter.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqmToSqlAstConverter.java @@ -18,8 +18,8 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.StandardTableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.select.QuerySpec; /** @@ -54,7 +54,7 @@ public class IngresSqmToSqlAstConverter extends BaseSqmToSq null, null, null, - new TableReference( + new NamedTableReference( "(select 1)", "dummy_(x)", false, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java index 3d95f89895..01b5653418 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java @@ -23,7 +23,7 @@ import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.expression.Summarization; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.select.QueryPart; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectClause; @@ -93,8 +93,8 @@ public class SybaseAnywhereSqlAstTranslator extends Abs } @Override - protected boolean renderTableReference(TableReference tableReference, LockMode lockMode) { - super.renderTableReference( tableReference, lockMode ); + protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) { + super.renderNamedTableReference( tableReference, lockMode ); if ( getDialect().getVersion().isBefore( 10 ) ) { if ( LockMode.READ.lessThan( lockMode ) ) { appendSql( " holdlock" ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java index 81eb8db1bb..c26a60058f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java @@ -247,10 +247,10 @@ public class OracleSqlAstTranslator extends AbstractSql } @Override - protected void renderValuesTableReference(ValuesTableReference tableReference) { + public void visitValuesTableReference(ValuesTableReference tableReference) { final List valuesList = tableReference.getValuesList(); if ( valuesList.size() < 2 ) { - super.renderValuesTableReference( tableReference ); + super.visitValuesTableReference( tableReference ); } else { append( '(' ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java index d98dcc2143..c90c32ee6c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java @@ -22,7 +22,7 @@ import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.expression.Summarization; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.UnionTableReference; import org.hibernate.sql.ast.tree.select.QueryGroup; import org.hibernate.sql.ast.tree.select.QueryPart; @@ -45,7 +45,7 @@ public class SQLServerSqlAstTranslator extends Abstract } @Override - protected boolean renderTableReference(TableReference tableReference, LockMode lockMode) { + protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) { final String tableExpression = tableReference.getTableExpression(); if ( tableReference instanceof UnionTableReference && lockMode != LockMode.NONE && tableExpression.charAt( 0 ) == '(' ) { // SQL Server requires to push down the lock hint to the actual table names @@ -72,7 +72,7 @@ public class SQLServerSqlAstTranslator extends Abstract } } else { - super.renderTableReference( tableReference, lockMode ); + super.renderNamedTableReference( tableReference, lockMode ); renderLockHint( lockMode ); } // Just always return true because SQL Server doesn't support the FOR UPDATE clause diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java index d31668a25d..8cf30d7a07 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java @@ -25,8 +25,8 @@ import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.expression.Summarization; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableReference; import org.hibernate.sql.ast.tree.select.QueryGroup; import org.hibernate.sql.ast.tree.select.QueryPart; @@ -98,8 +98,8 @@ public class SybaseASESqlAstTranslator extends Abstract } @Override - protected boolean renderTableReference(TableReference tableReference, LockMode lockMode) { - super.renderTableReference( tableReference, lockMode ); + protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) { + super.renderNamedTableReference( tableReference, lockMode ); if ( getDialect().getVersion().isBefore( 15, 7 ) ) { if ( LockMode.READ.lessThan( lockMode ) ) { appendSql( " holdlock" ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java index 8eab3562d6..a9cbb7a796 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java @@ -23,7 +23,7 @@ import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.expression.Summarization; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.select.QueryPart; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -92,8 +92,8 @@ public class SybaseSqlAstTranslator extends AbstractSql } @Override - protected boolean renderTableReference(TableReference tableReference, LockMode lockMode) { - super.renderTableReference( tableReference, lockMode ); + protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) { + super.renderNamedTableReference( tableReference, lockMode ); if ( LockMode.READ.lessThan( lockMode ) ) { appendSql( " holdlock" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqmToSqlAstConverter.java index 7aef709eba..9913f76f43 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqmToSqlAstConverter.java @@ -18,8 +18,8 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.StandardTableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.select.QuerySpec; /** @@ -54,7 +54,7 @@ public class SybaseSqmToSqlAstConverter extends BaseSqmToSq null, null, null, - new TableReference( + new NamedTableReference( "(select 1)", "dummy_(x)", false, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java index c5496a7043..4c47042b37 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java @@ -226,7 +226,7 @@ public abstract class AbstractCompositeIdentifierMapping final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() ); getEmbeddableTypeDescriptor().forEachSelectable( (columnIndex, selection) -> { - final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() ) + final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null ? defaultTableReference : tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ); final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver() diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java index afce61af15..cd7e3c2ef4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java @@ -279,7 +279,7 @@ public class EmbeddedAttributeMapping final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() ); getEmbeddableTypeDescriptor().forEachSelectable( (columnIndex, selection) -> { - final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() ) + final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null ? defaultTableReference : tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ); final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java index 5f88901b60..ab03f5a12b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java @@ -406,14 +406,16 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor { } protected TableReference getTableReference(TableGroup lhs, TableGroup tableGroup, String table) { - if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) { - return lhs.getPrimaryTableReference(); + TableReference tableReference = lhs.getPrimaryTableReference().resolveTableReference( table ); + if ( tableReference != null ) { + return tableReference; } - else if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) { - return tableGroup.getPrimaryTableReference(); + tableReference = tableGroup.getPrimaryTableReference().resolveTableReference( table ); + if ( tableReference != null ) { + return tableReference; } - final TableReference tableReference = lhs.resolveTableReference( + tableReference = lhs.resolveTableReference( lhs.getNavigablePath().append( getNavigableRole().getNavigableName() ), table ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/NonAggregatedIdentifierMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/NonAggregatedIdentifierMappingImpl.java index cd7e292aae..0c7843b223 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/NonAggregatedIdentifierMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/NonAggregatedIdentifierMappingImpl.java @@ -20,7 +20,6 @@ import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; -import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; @@ -175,13 +174,9 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif offset += attributeMapping.forEachSelectable( offset, (columnIndex, selection) -> { - final TableReference tableReference = selection.getContainingTableExpression().equals( - defaultTableReference.getTableExpression() ) + final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null ? defaultTableReference - : tableGroup.resolveTableReference( - navigablePath, - selection.getContainingTableExpression() - ); + : tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ); final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver() .resolveSqlExpression( SqlExpressionResolver.createColumnReferenceKey( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java index 81a16f26e6..8308f94b27 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java @@ -51,6 +51,7 @@ import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.from.CollectionTableGroup; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer; @@ -663,7 +664,7 @@ public class PluralAttributeMappingImpl assert !getCollectionDescriptor().isOneToMany(); final String collectionTableName = ( (Joinable) collectionDescriptor ).getTableName(); - final TableReference collectionTableReference = new TableReference( + final TableReference collectionTableReference = new NamedTableReference( collectionTableName, sqlAliasBase.generateNewAlias(), true, diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 4e2d7026a2..e97a00e62d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -1870,7 +1870,7 @@ public abstract class AbstractCollectionPersister alias = tableReference.getIdentificationVariable(); } else { - alias = tableReference.getTableExpression(); + alias = tableReference.getTableId(); } applyWhereFragments( predicateConsumer, alias, tableGroup, creationState ); @@ -1937,7 +1937,7 @@ public abstract class AbstractCollectionPersister alias = tableReference.getIdentificationVariable(); } else { - alias = tableReference.getTableExpression(); + alias = tableReference.getTableId(); } applyWhereFragments( predicateConsumer, alias, manyToManyWhereTemplate ); @@ -1984,11 +1984,6 @@ public abstract class AbstractCollectionPersister return elementPropertyMapping.toColumns( propertyName ); } -// @Override -// public Type getType() { -// return elementPropertyMapping.getType(); // ==elementType ?? -// } - @Override public String getName() { return getRole(); @@ -2079,7 +2074,6 @@ public abstract class AbstractCollectionPersister return factory; } - protected boolean isInsertCallable() { return insertCallable; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index ec78c376e3..91755d05e7 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -230,6 +230,7 @@ import org.hibernate.sql.ast.tree.expression.AliasedExpression; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.StandardTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; @@ -1347,7 +1348,7 @@ public abstract class AbstractEntityPersister for ( int i = 0; i < subclassTableNames.length; i++ ) { if ( tableExpression.equals( subclassTableNames[ i ] ) ) { final boolean isNullableTable = isNullableSubclassTable( i ); - final TableReference joinedTableReference = new TableReference( + final NamedTableReference joinedTableReference = new NamedTableReference( tableExpression, sqlAliasBase.generateNewAlias(), isNullableTable, @@ -1420,7 +1421,7 @@ public abstract class AbstractEntityPersister SqlAstJoinType joinType, String[] targetColumns, SqlExpressionResolver sqlExpressionResolver) { - final TableReference joinedTableReference = new TableReference( + final NamedTableReference joinedTableReference = new NamedTableReference( joinTableExpression, sqlAliasBase.generateNewAlias(), joinType != SqlAstJoinType.INNER, @@ -1440,7 +1441,7 @@ public abstract class AbstractEntityPersister } protected TableReference resolvePrimaryTableReference(SqlAliasBase sqlAliasBase) { - return new TableReference( + return new NamedTableReference( getTableName(), sqlAliasBase.generateNewAlias(), false, @@ -4027,11 +4028,18 @@ public abstract class AbstractEntityPersister return; } - final FilterAliasGenerator aliasGenerator = useQualifier && tableGroup != null - ? getFilterAliasGenerator( tableGroup ) - : null; + final String alias; + if ( tableGroup == null ) { + alias = null; + } + else if ( useQualifier && tableGroup.getPrimaryTableReference().getIdentificationVariable() != null ) { + alias = tableGroup.getPrimaryTableReference().getIdentificationVariable(); + } + else { + alias = tableGroup.getPrimaryTableReference().getTableId(); + } - final String fragment = StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, aliasGenerator.getAlias( getTableName() ) ); + final String fragment = StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias ); predicateConsumer.accept( new SqlFragmentPredicate( fragment ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 22e179e5d0..9067e1bd30 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -45,7 +45,6 @@ import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityVersionMapping; -import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl; import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl; import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper; @@ -55,15 +54,10 @@ import org.hibernate.query.NavigablePath; import org.hibernate.sql.InFragment; import org.hibernate.sql.Insert; import org.hibernate.sql.ast.SqlAstJoinType; -import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; -import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.expression.Expression; -import org.hibernate.sql.ast.tree.expression.QueryLiteral; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; -import org.hibernate.sql.ast.tree.predicate.NullnessPredicate; -import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl; @@ -1346,7 +1340,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { final TableReferenceJoin[] oldJoins = tableReferenceJoins.toArray( new TableReferenceJoin[0] ); tableReferenceJoins.clear(); for ( TableReferenceJoin oldJoin : oldJoins ) { - final TableReference joinedTableReference = oldJoin.getJoinedTableReference(); + final NamedTableReference joinedTableReference = oldJoin.getJoinedTableReference(); if ( retainedTableReferences.contains( joinedTableReference ) ) { if ( oldJoin.getJoinType() != SqlAstJoinType.INNER && sharedSuperclassTables.contains( joinedTableReference.getTableExpression() ) ) { @@ -1383,80 +1377,4 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { } } - private static class CaseSearchedExpressionInfo{ - CaseSearchedExpression caseSearchedExpression; - List columnReferences = new ArrayList<>( ); - } - - private CaseSearchedExpressionInfo getCaseSearchedExpression(TableGroup entityTableGroup) { - CaseSearchedExpressionInfo info = new CaseSearchedExpressionInfo(); - - final TableReference primaryTableReference = entityTableGroup.getPrimaryTableReference(); - final BasicType discriminatorType = (BasicType) getDiscriminatorType(); - final CaseSearchedExpression caseSearchedExpression = new CaseSearchedExpression( discriminatorType ); - - boolean addPrimaryTableCaseAsLastCaseExpression = false; - for ( String tableName : discriminatorValuesByTableName.keySet() ) { - if ( !primaryTableReference.getTableExpression().equals( tableName ) ) { - TableReference tableReference = entityTableGroup.getTableReference( entityTableGroup.getNavigablePath(), tableName ); - if ( tableReference == null ) { - // we have not yet created a TableReference for this sub-class table, but we need to because - // it has a discriminator value associated with it - tableReference = entityTableGroup.resolveTableReference( entityTableGroup.getNavigablePath(), tableName ); - } - - final ColumnReference identifierColumnReference = getIdentifierColumnReference( tableReference ); - info.columnReferences.add( identifierColumnReference ); - addWhen( - caseSearchedExpression, - tableReference, - identifierColumnReference, - discriminatorType - ); - } - else { - addPrimaryTableCaseAsLastCaseExpression = true; - } - } - - if ( addPrimaryTableCaseAsLastCaseExpression ) { - addWhen( - caseSearchedExpression, - primaryTableReference, - getIdentifierColumnReference( primaryTableReference ), - discriminatorType - ); - } - - info.caseSearchedExpression = caseSearchedExpression; - return info; - } - - private void addWhen( - CaseSearchedExpression caseSearchedExpression, - TableReference table, - ColumnReference identifierColumnReference, - BasicType resultType) { - final Predicate predicate = new NullnessPredicate( identifierColumnReference, true ); - final Expression expression = new QueryLiteral<>( - discriminatorValuesByTableName.get( table.getTableExpression() ), - resultType - ); - - caseSearchedExpression.when( predicate, expression ); - } - - private ColumnReference getIdentifierColumnReference(TableReference tableReference) { - final List jdbcMappings = getIdentifierMapping().getJdbcMappings(); - return new ColumnReference( - tableReference.getIdentificationVariable(), - discriminatorColumnNameByTableName.get( tableReference.getTableExpression() ), - false, - null, - null, - jdbcMappings.get( 0 ), - getFactory() - ); - } - } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index e87d57f38f..0ea9e3406a 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -52,6 +52,7 @@ import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.QueryLiteral; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; @@ -846,6 +847,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { if ( additionalPredicateCollectorAccess != null && needsDiscriminator() ) { final Predicate discriminatorPredicate = createDiscriminatorPredicate( + tableGroup.getPrimaryTableReference().getIdentificationVariable(), tableGroup, expressionResolver, creationContext @@ -865,6 +867,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { if ( needsDiscriminator() ) { predicateConsumer.accept( createDiscriminatorPredicate( + alias, tableGroup, creationState.getSqlExpressionResolver(), creationState.getCreationContext() @@ -875,6 +878,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { } private Predicate createDiscriminatorPredicate( + String alias, TableGroup tableGroup, SqlExpressionResolver sqlExpressionResolver, SqlAstCreationContext creationContext) { @@ -899,15 +903,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { final Expression sqlExpression = sqlExpressionResolver.resolveSqlExpression( columnReferenceKey, sqlAstProcessingState -> new ColumnReference( - tableGroup.getPrimaryTableReference().getIdentificationVariable(), + alias, discriminatorExpression, isDiscriminatorFormula(), null, null, - (discriminatorType).getJdbcMapping(), + discriminatorType.getJdbcMapping(), getFactory() ) ); + if ( hasSubclasses() ) { final Object[] discriminatorValues = fullDiscriminatorValues(); final List values = new ArrayList<>( discriminatorValues.length ); @@ -941,6 +946,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { } return p; } + final Object value = getDiscriminatorValue(); final boolean hasNotNullDiscriminator = value == NOT_NULL_DISCRIMINATOR; final boolean hasNullDiscriminator = value == NULL_DISCRIMINATOR; @@ -967,7 +973,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { return; } // The optimization is to simply add the discriminator filter fragment for all treated entity names - final TableReference tableReference = tableGroup.getPrimaryTableReference(); + final NamedTableReference tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); tableReference.setPrunedTableExpression( "(select * from " + getTableName() + " t where " + discriminatorFilterFragment( "t", treatedEntityNames ) + ")" ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java index 4ef279f242..5102372187 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java @@ -52,6 +52,7 @@ import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.ColumnReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableGroup; @@ -257,13 +258,13 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister { SqlExpressionResolver expressionResolver, FromClauseAccess fromClauseAccess, SqlAstCreationContext creationContext) { - final TableReference tableReference = resolvePrimaryTableReference( sqlAliasBase ); + final UnionTableReference tableReference = resolvePrimaryTableReference( sqlAliasBase ); return new UnionTableGroup( canUseInnerJoins, navigablePath, tableReference, this, explicitSourceAlias ); } @Override - protected TableReference resolvePrimaryTableReference(SqlAliasBase sqlAliasBase) { + protected UnionTableReference resolvePrimaryTableReference(SqlAliasBase sqlAliasBase) { return new UnionTableReference( getTableName(), subclassTableExpressions, @@ -401,7 +402,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister { if ( treatedEntityNames.contains( getEntityName() ) ) { return; } - final TableReference tableReference = tableGroup.resolveTableReference( getRootTableName() ); + final NamedTableReference tableReference = (NamedTableReference) tableGroup.resolveTableReference( getRootTableName() ); // Replace the default union sub-query with a specially created one that only selects the tables for the treated entity names tableReference.setPrunedTableExpression( generateSubquery( treatedEntityNames ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java index a18d0ff562..f077c0495e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java @@ -292,7 +292,7 @@ public class DomainResultCreationStateImpl @Override public SqlSelection resolveSqlSelection( Expression expression, - JavaType javaTypeDescriptor, + JavaType javaTypeDescriptor, TypeConfiguration typeConfiguration) { if ( expression == null ) { throw new IllegalArgumentException( "Expression cannot be null" ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmMutationStrategyHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmMutationStrategyHelper.java index 1bd7e11af9..e2e6445fe3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmMutationStrategyHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmMutationStrategyHelper.java @@ -16,10 +16,10 @@ import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; -import org.hibernate.query.spi.SqlOmittingQueryOptions; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.sql.ast.tree.delete.DeleteStatement; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.exec.spi.ExecutionContext; @@ -130,7 +130,12 @@ public class SqmMutationStrategyHelper { else { // element-collection or many-to-many - delete the collection-table row - final TableReference tableReference = new TableReference( separateCollectionTable, DeleteStatement.DEFAULT_ALIAS, true, sessionFactory ); + final NamedTableReference tableReference = new NamedTableReference( + separateCollectionTable, + DeleteStatement.DEFAULT_ALIAS, + true, + sessionFactory + ); final DeleteStatement sqlAstDelete = new DeleteStatement( tableReference, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java index 2ecfcf16f3..aa1e75d629 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java @@ -45,6 +45,7 @@ import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.SqlTuple; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableReference; import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate; @@ -177,7 +178,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, count ) ); querySpec.getFromClause().addRoot( new CteTableGroup( - new TableReference( + new NamedTableReference( idSelectCte.getCteTable().getTableExpression(), CTE_TABLE_IDENTIFIER, false, @@ -241,7 +242,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler CteStatement idSelectCte, ModelPart fkModelPart, SessionFactoryImplementor factory) { - final TableReference idSelectTableReference = new TableReference( + final NamedTableReference idSelectTableReference = new NamedTableReference( idSelectCte.getCteTable().getTableExpression(), CTE_TABLE_IDENTIFIER, false, @@ -313,11 +314,11 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler SessionFactoryImplementor factory); - protected TableReference resolveUnionTableReference( + protected NamedTableReference resolveUnionTableReference( TableReference tableReference, String tableExpression) { if ( tableReference instanceof UnionTableReference ) { - return new TableReference( + return new NamedTableReference( tableExpression, tableReference.getIdentificationVariable(), tableReference.isOptional(), @@ -325,7 +326,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler ); } else { - return tableReference; + return (NamedTableReference) tableReference; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java index 80d4187874..f110472e33 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java @@ -27,6 +27,7 @@ import org.hibernate.sql.ast.tree.cte.CteTable; import org.hibernate.sql.ast.tree.delete.DeleteStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.JdbcParameter; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.select.SelectStatement; @@ -106,7 +107,12 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele idSelectCte.getCteTable().getCteColumns(), factory ); - final TableReference dmlTableReference = new TableReference( tableExpression, null, true, factory ); + final NamedTableReference dmlTableReference = new NamedTableReference( + tableExpression, + DeleteStatement.DEFAULT_ALIAS, + true, + factory + ); final List columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() ); pluralAttribute.getKeyDescriptor().visitKeySelectables( (index, selectable) -> columnReferences.add( @@ -147,7 +153,7 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele true, true ); - final TableReference dmlTableReference = resolveUnionTableReference( + final NamedTableReference dmlTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java index d4b71b87ff..afda4222f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java @@ -76,7 +76,7 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.Over; import org.hibernate.sql.ast.tree.expression.QueryLiteral; import org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression; -import org.hibernate.sql.ast.tree.from.StandardTableGroup; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; @@ -189,7 +189,7 @@ public class CteInsertHandler implements InsertHandler { final List> targetPathColumns = new ArrayList<>( size ); final List targetPathSqmCteColumns = new ArrayList<>( size ); final Map paramTypeResolutions = new LinkedHashMap<>(); - final TableReference entityTableReference = new TableReference( + final NamedTableReference entityTableReference = new NamedTableReference( cteTable.getCteName(), TemporaryTable.DEFAULT_ALIAS, true, @@ -240,7 +240,7 @@ public class CteInsertHandler implements InsertHandler { final Statement queryStatement; if ( sqmInsertStatement instanceof SqmInsertSelectStatement ) { final QueryPart queryPart = sqmConverter.visitQueryPart( ( (SqmInsertSelectStatement) sqmInsertStatement ).getSelectQueryPart() ); - queryPart.forEachQuerySpec( + queryPart.visitQuerySpecs( querySpec -> { // This returns true if the insertion target uses a sequence with an optimizer // in which case we will fill the row_number column instead of the id column @@ -407,7 +407,7 @@ public class CteInsertHandler implements InsertHandler { final QuerySpec rowsWithSequenceQuery = new QuerySpec( true ); rowsWithSequenceQuery.getFromClause().addRoot( new CteTableGroup( - new TableReference( + new NamedTableReference( baseTableName, "e", false, @@ -465,7 +465,7 @@ public class CteInsertHandler implements InsertHandler { final TableGroup baseTableGroup = new TableGroupImpl( navigablePath, null, - new TableReference( + new NamedTableReference( baseTableName, "e", false, @@ -475,7 +475,7 @@ public class CteInsertHandler implements InsertHandler { null ); final TableGroup rowsWithSequenceTableGroup = new CteTableGroup( - new TableReference( + new NamedTableReference( ROW_NUMBERS_WITH_SEQUENCE_VALUE, "t", false, @@ -639,7 +639,7 @@ public class CteInsertHandler implements InsertHandler { querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, count ) ); querySpec.getFromClause().addRoot( new CteTableGroup( - new TableReference( + new NamedTableReference( // We want to return the insertion count of the base table baseInsertCte, CTE_TABLE_IDENTIFIER, @@ -789,7 +789,7 @@ public class CteInsertHandler implements InsertHandler { true ); final List> assignmentList = assignmentsByTable.get( updatingTableReference ); - final TableReference dmlTableReference = resolveUnionTableReference( + final NamedTableReference dmlTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); @@ -806,7 +806,7 @@ public class CteInsertHandler implements InsertHandler { final String baseTableName = "base_" + queryCte.getCteTable().getTableExpression(); insertSelectSpec.getFromClause().addRoot( new CteTableGroup( - new TableReference( + new NamedTableReference( baseTableName, "e", false, @@ -862,7 +862,7 @@ public class CteInsertHandler implements InsertHandler { final TableGroup baseTableGroup = new TableGroupImpl( navigablePath, null, - new TableReference( + new NamedTableReference( baseTableName, "e", false, @@ -872,7 +872,7 @@ public class CteInsertHandler implements InsertHandler { null ); final TableGroup rootInsertCteTableGroup = new CteTableGroup( - new TableReference( + new NamedTableReference( getCteTableName( tableExpression ), "t", false, @@ -950,7 +950,7 @@ public class CteInsertHandler implements InsertHandler { final QuerySpec finalResultQuery = new QuerySpec( true ); finalResultQuery.getFromClause().addRoot( new CteTableGroup( - new TableReference( + new NamedTableReference( dmlResultCte.getTableExpression(), "e", false, @@ -1008,7 +1008,7 @@ public class CteInsertHandler implements InsertHandler { else { insertSelectSpec.getFromClause().addRoot( new CteTableGroup( - new TableReference( + new NamedTableReference( queryCte.getCteTable().getTableExpression(), "e", false, @@ -1103,11 +1103,11 @@ public class CteInsertHandler implements InsertHandler { return getCteTableName( rootTableName ); } - protected TableReference resolveUnionTableReference( + protected NamedTableReference resolveUnionTableReference( TableReference tableReference, String tableExpression) { if ( tableReference instanceof UnionTableReference ) { - return new TableReference( + return new NamedTableReference( tableExpression, tableReference.getIdentificationVariable(), tableReference.isOptional(), @@ -1115,7 +1115,7 @@ public class CteInsertHandler implements InsertHandler { ); } else { - return tableReference; + return (NamedTableReference) tableReference; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java index b3eb45075d..ef707d4253 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java @@ -32,6 +32,7 @@ import org.hibernate.sql.ast.tree.cte.CteStatement; import org.hibernate.sql.ast.tree.cte.CteTable; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.JdbcParameter; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; @@ -154,7 +155,7 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda if ( assignmentList == null ) { return; } - final TableReference dmlTableReference = resolveUnionTableReference( + final NamedTableReference dmlTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InlineDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InlineDeleteHandler.java index b4f2462f21..eea6012195 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InlineDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InlineDeleteHandler.java @@ -18,7 +18,6 @@ import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.PluralAttributeMapping; -import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.query.spi.DomainQueryExecutionContext; import org.hibernate.query.sqm.internal.DomainParameterXref; import org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter; @@ -27,7 +26,7 @@ import org.hibernate.query.sqm.mutation.internal.MatchingIdSelectionHelper; import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.delete.DeleteStatement; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.spi.JdbcDelete; @@ -160,7 +159,7 @@ public class InlineDeleteHandler implements DeleteHandler { ModelPart valueModelPart, JdbcParameterBindings jdbcParameterBindings, DomainQueryExecutionContext executionContext) { - final TableReference targetTableReference = new TableReference( + final NamedTableReference targetTableReference = new NamedTableReference( targetTableExpression, DeleteStatement.DEFAULT_ALIAS, false, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/ExecuteWithTemporaryTableHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/ExecuteWithTemporaryTableHelper.java index 76770bc858..0a9242ab01 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/ExecuteWithTemporaryTableHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/ExecuteWithTemporaryTableHelper.java @@ -31,6 +31,7 @@ import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.QueryLiteral; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.StandardTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; @@ -65,9 +66,9 @@ public final class ExecuteWithTemporaryTableHelper { assert mutatingTableGroup.getModelPart() instanceof EntityMappingType; final EntityMappingType mutatingEntityDescriptor = (EntityMappingType) mutatingTableGroup.getModelPart(); - final TableReference idTableReference = new TableReference( + final NamedTableReference idTableReference = new NamedTableReference( idTable.getTableExpression(), - null, + InsertStatement.DEFAULT_ALIAS, false, factory ); @@ -153,7 +154,7 @@ public final class ExecuteWithTemporaryTableHelper { // Visit the table joins and reset the lock mode if we encounter OUTER joins that are not supported if ( temporaryTableInsert.getSourceSelectStatement() != null && !jdbcEnvironment.getDialect().supportsOuterJoinForUpdate() ) { - temporaryTableInsert.getSourceSelectStatement().forEachQuerySpec( + temporaryTableInsert.getSourceSelectStatement().visitQuerySpecs( querySpec -> { querySpec.getFromClause().visitTableJoins( tableJoin -> { @@ -197,7 +198,7 @@ public final class ExecuteWithTemporaryTableHelper { ExecutionContext executionContext) { final QuerySpec querySpec = new QuerySpec( false ); - final TableReference idTableReference = new TableReference( + final NamedTableReference idTableReference = new NamedTableReference( idTable.getTableExpression(), TemporaryTable.DEFAULT_ALIAS, true, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java index 309c0e8f48..fb0b8f328e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.Map; import java.util.function.Function; -import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.temptable.TemporaryTable; import org.hibernate.dialect.temptable.TemporaryTableColumn; import org.hibernate.engine.FetchTiming; @@ -23,7 +22,6 @@ import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; -import org.hibernate.id.IdentityGenerator; import org.hibernate.id.OptimizableGenerator; import org.hibernate.id.PostInsertIdentifierGenerator; import org.hibernate.id.PostInsertIdentityPersister; @@ -48,6 +46,7 @@ import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.insert.SqmInsertStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.JdbcParameter; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableReference; @@ -227,9 +226,9 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio throw new SemanticException( "Assignment referred to column of a joined association: " + columnReference ); } - private TableReference resolveUnionTableReference(TableReference tableReference, String tableExpression) { + private NamedTableReference resolveUnionTableReference(TableReference tableReference, String tableExpression) { if ( tableReference instanceof UnionTableReference ) { - return new TableReference( + return new NamedTableReference( tableExpression, tableReference.getIdentificationVariable(), tableReference.isOptional(), @@ -237,7 +236,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio ); } else { - return tableReference; + return (NamedTableReference) tableReference; } } @@ -259,20 +258,21 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio throw new IllegalStateException( "There must be at least a single root table assignment" ); } - final TableReference dmlTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); + final NamedTableReference dmlTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Create the SQL AST and convert it into a JdbcOperation final QuerySpec querySpec = new QuerySpec( true ); + final NamedTableReference temporaryTableReference = new NamedTableReference( + insertStatement.getTargetTable().getTableExpression(), + updatingTableReference.getIdentificationVariable(), + false, + sessionFactory + ); final TableGroupImpl temporaryTableGroup = new TableGroupImpl( updatingTableGroup.getNavigablePath(), null, - new TableReference( - insertStatement.getTargetTable().getTableExpression(), - updatingTableReference.getIdentificationVariable(), - false, - sessionFactory - ), + temporaryTableReference, entityDescriptor, null ); @@ -386,7 +386,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio entityTable.getColumns().size() - 1 ); final UpdateStatement updateStatement = new UpdateStatement( - temporaryTableGroup.getPrimaryTableReference(), + temporaryTableReference, temporaryTableAssignments, new ComparisonPredicate( new ColumnReference( @@ -524,7 +524,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio ) ); final UpdateStatement updateStatement = new UpdateStatement( - temporaryTableGroup.getPrimaryTableReference(), + temporaryTableReference, temporaryTableAssignments, new ComparisonPredicate( new ColumnReference( @@ -595,13 +595,13 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio // no assignments for this table - skip it return; } - final TableReference dmlTargetTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); + final NamedTableReference dmlTargetTableReference = resolveUnionTableReference( updatingTableReference, tableExpression ); final QuerySpec querySpec = new QuerySpec( true ); final TableGroupImpl temporaryTableGroup = new TableGroupImpl( updatingTableGroup.getNavigablePath(), null, - new TableReference( + new NamedTableReference( insertStatement.getTargetTable().getTableExpression(), updatingTableReference.getIdentificationVariable(), false, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java index a48b9f1665..9d3e53d49b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java @@ -47,6 +47,7 @@ import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.SqlTuple; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableReference; @@ -210,7 +211,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle final EntityPersister rootEntityPersister = entityDescriptor.getEntityPersister(); final String rootTableName = ( (Joinable) rootEntityPersister ).getTableName(); - final TableReference rootTableReference = tableGroup.resolveTableReference( + final NamedTableReference rootTableReference = (NamedTableReference) tableGroup.resolveTableReference( tableGroup.getNavigablePath(), rootTableName ); @@ -279,7 +280,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle final MutableInteger rows = new MutableInteger(); entityDescriptor.visitConstraintOrderedTables( (tableExpression, tableKeyColumnVisitationSupplier) -> { - final TableReference tableReference = new TableReference( + final NamedTableReference tableReference = new NamedTableReference( tableExpression, tableGroup.getPrimaryTableReference().getIdentificationVariable(), false, @@ -312,7 +313,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle entityDescriptor.visitConstraintOrderedTables( (tableExpression, tableKeyColumnVisitationSupplier) -> { if ( !tableExpression.equals( rootTableName ) ) { - final TableReference tableReference = tableGroup.getTableReference( + final NamedTableReference tableReference = (NamedTableReference) tableGroup.getTableReference( tableGroup.getNavigablePath(), tableExpression, true, @@ -349,7 +350,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle } private int deleteFromRootTableWithoutIdTable( - TableReference rootTableReference, + NamedTableReference rootTableReference, Predicate predicate, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) { @@ -361,7 +362,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle } private int deleteFromNonRootTableWithoutIdTable( - TableReference targetTableReference, + NamedTableReference targetTableReference, Supplier> tableKeyColumnVisitationSupplier, SqlExpressionResolver sqlExpressionResolver, TableGroup rootTableGroup, @@ -371,7 +372,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle assert targetTableReference != null; log.tracef( "deleteFromNonRootTable - %s", targetTableReference.getTableExpression() ); - final TableReference deleteTableReference = new TableReference( + final NamedTableReference deleteTableReference = new NamedTableReference( targetTableReference.getTableExpression(), DeleteStatement.DEFAULT_ALIAS, true, @@ -573,7 +574,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle final SessionFactoryImplementor factory = executionContext.getSession().getFactory(); final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor ); - final TableReference targetTable = new TableReference( + final NamedTableReference targetTable = new NamedTableReference( tableExpression, DeleteStatement.DEFAULT_ALIAS, true, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java index a418cdafac..1bce273518 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java @@ -41,6 +41,7 @@ import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.Over; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; @@ -140,7 +141,7 @@ public class TableBasedInsertHandler implements InsertHandler { final List targetPathColumns = new ArrayList<>(); final Map paramTypeResolutions = new LinkedHashMap<>(); - final TableReference entityTableReference = new TableReference( + final NamedTableReference entityTableReference = new NamedTableReference( entityTable.getTableExpression(), TemporaryTable.DEFAULT_ALIAS, true, @@ -171,7 +172,7 @@ public class TableBasedInsertHandler implements InsertHandler { if ( sqmInsertStatement instanceof SqmInsertSelectStatement ) { final QueryPart queryPart = converterDelegate.visitQueryPart( ( (SqmInsertSelectStatement) sqmInsertStatement ).getSelectQueryPart() ); - queryPart.forEachQuerySpec( + queryPart.visitQuerySpecs( querySpec -> { if ( additionalInsertValues.applySelections( querySpec, sessionFactory ) ) { final TemporaryTableColumn rowNumberColumn = entityTable.getColumns() diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/UpdateExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/UpdateExecutionDelegate.java index 3bd6541c5f..95fc60be56 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/UpdateExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/UpdateExecutionDelegate.java @@ -31,6 +31,7 @@ import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.JdbcParameter; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableReference; @@ -200,18 +201,18 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio throw new SemanticException( "Assignment referred to column of a joined association: " + columnReference ); } - private TableReference resolveUnionTableReference( + private NamedTableReference resolveUnionTableReference( TableReference tableReference, String tableExpression) { if ( tableReference instanceof UnionTableReference ) { - return new TableReference( + return new NamedTableReference( tableExpression, tableReference.getIdentificationVariable(), tableReference.isOptional(), sessionFactory ); } - return tableReference; + return (NamedTableReference) tableReference; } private void updateTable( 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 280468209b..db2d8e6c98 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 @@ -106,7 +106,9 @@ import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot; import org.hibernate.sql.ast.tree.expression.Over; import org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression; import org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.PluralTableGroup; +import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.exec.internal.VersionTypeSeedParameterSpecification; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; @@ -316,7 +318,6 @@ import org.hibernate.sql.ast.tree.from.PluralTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.VirtualTableGroup; import org.hibernate.sql.ast.tree.insert.InsertStatement; import org.hibernate.sql.ast.tree.insert.Values; @@ -711,7 +712,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base return new UpdateStatement( sqmStatement.isWithRecursive(), cteStatements, - rootTableGroup.getPrimaryTableReference(), + (NamedTableReference) rootTableGroup.getPrimaryTableReference(), assignments, SqlAstTreeHelper.combinePredicates( suppliedPredicate, additionalRestrictions ), Collections.emptyList() @@ -940,7 +941,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base return new DeleteStatement( statement.isWithRecursive(), cteStatements, - rootTableGroup.getPrimaryTableReference(), + (NamedTableReference) rootTableGroup.getPrimaryTableReference(), SqlAstTreeHelper.combinePredicates( suppliedPredicate, additionalRestrictions ), Collections.emptyList() ); @@ -995,7 +996,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base insertStatement = new InsertStatement( sqmStatement.isWithRecursive(), cteStatements, - rootTableGroup.getPrimaryTableReference(), + (NamedTableReference) rootTableGroup.getPrimaryTableReference(), Collections.emptyList() ); additionalInsertValues = visitInsertionTargetPaths( @@ -1019,7 +1020,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base visitQueryPart( selectQueryPart ) ); - insertStatement.getSourceSelectStatement().forEachQuerySpec( + insertStatement.getSourceSelectStatement().visitQuerySpecs( querySpec -> { final boolean appliedRowNumber = additionalInsertValues.applySelections( querySpec, @@ -1074,7 +1075,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base final InsertStatement insertStatement = new InsertStatement( sqmStatement.isWithRecursive(), cteStatements, - rootTableGroup.getPrimaryTableReference(), + (NamedTableReference) rootTableGroup.getPrimaryTableReference(), Collections.emptyList() ); @@ -5833,7 +5834,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public SqlSelection resolveSqlSelection( Expression expression, - JavaType javaTypeDescriptor, + JavaType javaTypeDescriptor, TypeConfiguration typeConfiguration) { return delegate.resolveSqlSelection( expression, javaTypeDescriptor, typeConfiguration ); } @@ -5889,7 +5890,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base @Override public SqlSelection resolveSqlSelection( Expression expression, - JavaType javaTypeDescriptor, + JavaType javaTypeDescriptor, TypeConfiguration typeConfiguration) { SqlSelection selection = delegate.resolveSqlSelection( expression, javaTypeDescriptor, typeConfiguration ); List sqlSelectionList = sqlSelectionsForSqmSelection[index]; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java index 2258f25951..90a705bbd5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java @@ -140,7 +140,7 @@ public class SqlAstProcessingStateImpl @Override public SqlSelection resolveSqlSelection( Expression expression, - JavaType javaTypeDescriptor, + JavaType javaTypeDescriptor, TypeConfiguration typeConfiguration) { throw new ConversionException( "Unexpected call to resolve SqlSelection outside of QuerySpec processing" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQueryPartProcessingStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQueryPartProcessingStateImpl.java index 1c83d4f546..0c08bbe210 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQueryPartProcessingStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQueryPartProcessingStateImpl.java @@ -68,7 +68,7 @@ public class SqlAstQueryPartProcessingStateImpl @Override public SqlSelection resolveSqlSelection( Expression expression, - JavaType javaTypeDescriptor, + JavaType javaTypeDescriptor, TypeConfiguration typeConfiguration) { final SqlSelection existing; if ( sqlSelectionMap == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java index c9c332f682..da5396d20b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java @@ -38,10 +38,12 @@ import org.hibernate.sql.ast.tree.expression.Summarization; import org.hibernate.sql.ast.tree.expression.TrimSpecification; import org.hibernate.sql.ast.tree.expression.UnaryOperation; import org.hibernate.sql.ast.tree.from.FromClause; +import org.hibernate.sql.ast.tree.from.NamedTableReference; +import org.hibernate.sql.ast.tree.from.QueryPartTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; +import org.hibernate.sql.ast.tree.from.ValuesTableReference; import org.hibernate.sql.ast.tree.insert.InsertStatement; import org.hibernate.sql.ast.tree.predicate.BetweenPredicate; import org.hibernate.sql.ast.tree.predicate.BooleanExpressionPredicate; @@ -100,7 +102,11 @@ public interface SqlAstWalker { void visitTableGroupJoin(TableGroupJoin tableGroupJoin); - void visitTableReference(TableReference tableReference); + void visitNamedTableReference(NamedTableReference tableReference); + + void visitValuesTableReference(ValuesTableReference tableReference); + + void visitQueryPartTableReference(QueryPartTableReference tableReference); void visitTableReferenceJoin(TableReferenceJoin tableReferenceJoin); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreePrinter.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreePrinter.java index a8dd91ace3..20b332d9e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreePrinter.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreePrinter.java @@ -13,10 +13,17 @@ import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.delete.DeleteStatement; import org.hibernate.sql.ast.tree.from.FromClause; import org.hibernate.sql.ast.tree.from.LazyTableGroup; +import org.hibernate.sql.ast.tree.from.NamedTableReference; +import org.hibernate.sql.ast.tree.from.QueryPartTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; +import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; +import org.hibernate.sql.ast.tree.from.ValuesTableReference; import org.hibernate.sql.ast.tree.insert.InsertStatement; +import org.hibernate.sql.ast.tree.select.QueryGroup; +import org.hibernate.sql.ast.tree.select.QueryPart; +import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.ast.tree.update.UpdateStatement; @@ -50,7 +57,7 @@ public class SqlTreePrinter { final SelectStatement selectStatement = (SelectStatement) sqlAstStatement; logNode( "SelectStatement", - () -> visitFromClause( selectStatement.getQuerySpec().getFromClause() ) + () -> visitQueryPart( selectStatement.getQueryPart() ) ); } else if ( sqlAstStatement instanceof DeleteStatement ) { @@ -85,6 +92,30 @@ public class SqlTreePrinter { } } + private void visitQueryPart(QueryPart queryPart) { + if ( queryPart instanceof QueryGroup ) { + visitQueryGroup( (QueryGroup) queryPart ); + } + else { + visitQuerySpec( (QuerySpec) queryPart ); + } + } + + private void visitQueryGroup(QueryGroup queryGroup) { + logNode( + "QueryGroup: " + queryGroup.getSetOperator(), + () -> { + for ( QueryPart queryPart : queryGroup.getQueryParts() ) { + visitQueryPart( queryPart ); + } + } + ); + } + + private void visitQuerySpec(QuerySpec querySpec) { + visitFromClause( querySpec.getFromClause() ); + } + private void visitFromClause(FromClause fromClause) { logNode( "FromClause", @@ -114,11 +145,30 @@ public class SqlTreePrinter { } return; } - logWithIndentation( - "primaryTableReference : %s as %s", - tableGroup.getPrimaryTableReference().getTableExpression(), - tableGroup.getPrimaryTableReference().getIdentificationVariable() - ); + if ( tableGroup.getPrimaryTableReference() instanceof NamedTableReference ) { + logWithIndentation( + "primaryTableReference : %s as %s", + tableGroup.getPrimaryTableReference().getTableId(), + tableGroup.getPrimaryTableReference().getIdentificationVariable() + ); + } + else { + if ( tableGroup.getPrimaryTableReference() instanceof ValuesTableReference ) { + logWithIndentation( + "primaryTableReference : values (..) as %s", + tableGroup.getPrimaryTableReference().getIdentificationVariable() + ); + } + else { + logNode( + "PrimaryTableReference as " + tableGroup.getPrimaryTableReference().getIdentificationVariable(), + () -> { + QueryPart queryPart = ( (QueryPartTableReference) tableGroup.getPrimaryTableReference() ).getQueryPart(); + visitQueryPart( queryPart ); + } + ); + } + } final List tableReferenceJoins = tableGroup.getTableReferenceJoins(); if ( ! tableReferenceJoins.isEmpty() ) { 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 272f1a06da..26cdaaf52a 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 @@ -111,6 +111,8 @@ import org.hibernate.sql.ast.tree.expression.TrimSpecification; import org.hibernate.sql.ast.tree.expression.UnaryOperation; import org.hibernate.sql.ast.tree.from.FromClause; import org.hibernate.sql.ast.tree.from.LazyTableGroup; +import org.hibernate.sql.ast.tree.from.NamedTableReference; +import org.hibernate.sql.ast.tree.from.QueryPartTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; @@ -848,7 +850,7 @@ public abstract class AbstractSqlAstTranslator implemen final Stack clauseStack = getClauseStack(); try { clauseStack.push( Clause.DELETE ); - renderTableReference( statement.getTargetTable(), LockMode.NONE ); + renderNamedTableReference( statement.getTargetTable(), LockMode.NONE ); } finally { clauseStack.pop(); @@ -873,7 +875,7 @@ public abstract class AbstractSqlAstTranslator implemen final Stack clauseStack = getClauseStack(); try { clauseStack.push( Clause.UPDATE ); - renderTableReference( statement.getTargetTable(), LockMode.NONE ); + renderNamedTableReference( statement.getTargetTable(), LockMode.NONE ); } finally { clauseStack.pop(); @@ -3615,8 +3617,31 @@ public abstract class AbstractSqlAstTranslator implemen return false; } + protected boolean renderTableReference(TableReference tableReference, LockMode lockMode) { + if ( tableReference instanceof NamedTableReference ) { + return renderNamedTableReference( (NamedTableReference) tableReference, lockMode ); + } + tableReference.accept( this ); + return false; + } + @SuppressWarnings("WeakerAccess") - protected void renderValuesTableReference(ValuesTableReference tableReference) { + protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) { + appendSql( tableReference.getTableExpression() ); + registerAffectedTable( tableReference ); + final Clause currentClause = clauseStack.getCurrent(); + if ( rendersTableReferenceAlias( currentClause ) ) { + final String identificationVariable = tableReference.getIdentificationVariable(); + if ( identificationVariable != null ) { + appendSql( WHITESPACE ); + appendSql( identificationVariable ); + } + } + return false; + } + + @Override + public void visitValuesTableReference(ValuesTableReference tableReference) { append( '(' ); visitValuesList( tableReference.getValuesList() ); append( ')' ); @@ -3635,24 +3660,22 @@ public abstract class AbstractSqlAstTranslator implemen } } - @SuppressWarnings("WeakerAccess") - protected boolean renderTableReference(TableReference tableReference, LockMode lockMode) { - if ( tableReference instanceof ValuesTableReference ) { - renderValuesTableReference( (ValuesTableReference) tableReference ); - } - else { - appendSql( tableReference.getTableExpression() ); - registerAffectedTable( tableReference ); - final Clause currentClause = clauseStack.getCurrent(); - if ( rendersTableReferenceAlias( currentClause ) ) { - final String identificationVariable = tableReference.getIdentificationVariable(); - if ( identificationVariable != null ) { - appendSql( WHITESPACE ); - appendSql( identificationVariable ); - } + @Override + public void visitQueryPartTableReference(QueryPartTableReference tableReference) { + tableReference.getQueryPart().accept( this ); + final String identificationVariable = tableReference.getIdentificationVariable(); + if ( identificationVariable != null ) { + append( WHITESPACE ); + append( tableReference.getIdentificationVariable() ); + final List columnNames = tableReference.getColumnNames(); + append( '(' ); + append( columnNames.get( 0 ) ); + for ( int i = 1; i < columnNames.size(); i++ ) { + append( ',' ); + append( columnNames.get( i ) ); } + append( ')' ); } - return false; } public static boolean rendersTableReferenceAlias(Clause clause) { @@ -3666,7 +3689,7 @@ public abstract class AbstractSqlAstTranslator implemen return true; } - protected void registerAffectedTable(TableReference tableReference) { + protected void registerAffectedTable(NamedTableReference tableReference) { registerAffectedTable( tableReference.getTableExpression() ); } @@ -3755,7 +3778,7 @@ public abstract class AbstractSqlAstTranslator implemen } @Override - public void visitTableReference(TableReference tableReference) { + public void visitNamedTableReference(NamedTableReference tableReference) { // nothing to do... handled via TableGroup#render } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java index db777a4f3e..6dda3ed350 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java @@ -43,10 +43,12 @@ import org.hibernate.sql.ast.tree.expression.Summarization; import org.hibernate.sql.ast.tree.expression.TrimSpecification; import org.hibernate.sql.ast.tree.expression.UnaryOperation; import org.hibernate.sql.ast.tree.from.FromClause; +import org.hibernate.sql.ast.tree.from.NamedTableReference; +import org.hibernate.sql.ast.tree.from.QueryPartTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; +import org.hibernate.sql.ast.tree.from.ValuesTableReference; import org.hibernate.sql.ast.tree.insert.InsertStatement; import org.hibernate.sql.ast.tree.insert.Values; import org.hibernate.sql.ast.tree.predicate.BetweenPredicate; @@ -472,6 +474,20 @@ public class AbstractSqlAstWalker implements SqlAstWalker { } @Override - public void visitTableReference(TableReference tableReference) { + public void visitNamedTableReference(NamedTableReference tableReference) { + } + + @Override + public void visitValuesTableReference(ValuesTableReference tableReference) { + for ( Values values : tableReference.getValuesList() ) { + for ( Expression expression : values.getExpressions() ) { + expression.accept( this ); + } + } + } + + @Override + public void visitQueryPartTableReference(QueryPartTableReference tableReference) { + tableReference.getQueryPart().accept( this ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AggregateFunctionChecker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AggregateFunctionChecker.java index 7a72f4f23b..ae2546b2df 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AggregateFunctionChecker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AggregateFunctionChecker.java @@ -19,6 +19,7 @@ import org.hibernate.sql.ast.tree.expression.Duration; import org.hibernate.sql.ast.tree.expression.DurationUnit; import org.hibernate.sql.ast.tree.expression.EntityTypeLiteral; import org.hibernate.sql.ast.tree.expression.Every; +import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.ExtractUnit; import org.hibernate.sql.ast.tree.expression.Format; import org.hibernate.sql.ast.tree.expression.FunctionExpression; @@ -33,11 +34,14 @@ import org.hibernate.sql.ast.tree.expression.Star; import org.hibernate.sql.ast.tree.expression.Summarization; import org.hibernate.sql.ast.tree.expression.TrimSpecification; import org.hibernate.sql.ast.tree.from.FromClause; +import org.hibernate.sql.ast.tree.from.NamedTableReference; +import org.hibernate.sql.ast.tree.from.QueryPartTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; +import org.hibernate.sql.ast.tree.from.ValuesTableReference; import org.hibernate.sql.ast.tree.insert.InsertStatement; +import org.hibernate.sql.ast.tree.insert.Values; import org.hibernate.sql.ast.tree.predicate.ExistsPredicate; import org.hibernate.sql.ast.tree.predicate.FilterPredicate; import org.hibernate.sql.ast.tree.predicate.InListPredicate; @@ -230,7 +234,15 @@ public class AggregateFunctionChecker extends AbstractSqlAstWalker { } @Override - public void visitTableReference(TableReference tableReference) { + public void visitNamedTableReference(NamedTableReference tableReference) { + } + + @Override + public void visitValuesTableReference(ValuesTableReference tableReference) { + } + + @Override + public void visitQueryPartTableReference(QueryPartTableReference tableReference) { } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AliasCollector.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AliasCollector.java index 5f69706981..65d6650d70 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AliasCollector.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AliasCollector.java @@ -11,7 +11,12 @@ import java.util.HashMap; import java.util.Map; import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.from.NamedTableReference; +import org.hibernate.sql.ast.tree.from.QueryPartTableReference; import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.ValuesTableReference; +import org.hibernate.sql.ast.tree.insert.Values; /** * A simple walker that checks for aggregate functions. @@ -29,7 +34,17 @@ public class AliasCollector extends AbstractSqlAstWalker { } @Override - public void visitTableReference(TableReference tableReference) { + public void visitNamedTableReference(NamedTableReference tableReference) { + tableReferenceMap.put( tableReference.getIdentificationVariable(), tableReference ); + } + + @Override + public void visitValuesTableReference(ValuesTableReference tableReference) { + tableReferenceMap.put( tableReference.getIdentificationVariable(), tableReference ); + } + + @Override + public void visitQueryPartTableReference(QueryPartTableReference tableReference) { tableReferenceMap.put( tableReference.getIdentificationVariable(), tableReference ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java index 41c4f54689..e38eafa125 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java @@ -6,6 +6,7 @@ */ package org.hibernate.sql.ast.spi; +import java.util.Objects; import java.util.function.Function; import org.hibernate.metamodel.mapping.SelectableMapping; @@ -50,10 +51,8 @@ public interface SqlExpressionResolver { static String createColumnReferenceKey(TableReference tableReference, String columnExpression) { assert tableReference != null : "tableReference expected to be non-null"; assert columnExpression != null : "columnExpression expected to be non-null"; - - final String qualifier = tableReference.getIdentificationVariable() == null - ? tableReference.getTableExpression() - : tableReference.getIdentificationVariable(); + assert tableReference.getIdentificationVariable() != null : "tableReference#identificationVariable expected to be non-null"; + final String qualifier = tableReference.getIdentificationVariable(); return qualifier + columnExpression; } @@ -61,8 +60,8 @@ public interface SqlExpressionResolver { * Convenience form for creating a key from TableReference and SelectableMapping */ static String createColumnReferenceKey(TableReference tableReference, SelectableMapping selectable) { - assert selectable.getContainingTableExpression().equals( tableReference.getTableExpression() ) - : String.format( ROOT, "Expecting tables to match between TableReference (%s) and SelectableMapping (%s)", tableReference.getTableExpression(), selectable.getContainingTableExpression() ); + assert Objects.equals( selectable.getContainingTableExpression(), tableReference.getTableId() ) + : String.format( ROOT, "Expecting tables to match between TableReference (%s) and SelectableMapping (%s)", tableReference.getTableId(), selectable.getContainingTableExpression() ); return createColumnReferenceKey( tableReference, selectable.getSelectionExpression() ); } @@ -77,6 +76,6 @@ public interface SqlExpressionResolver { */ SqlSelection resolveSqlSelection( Expression expression, - JavaType javaTypeDescriptor, + JavaType javaTypeDescriptor, TypeConfiguration typeConfiguration); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/AbstractMutationStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/AbstractMutationStatement.java index 0ddace5ca8..7fdb37b60e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/AbstractMutationStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/AbstractMutationStatement.java @@ -13,30 +13,30 @@ import java.util.Map; import org.hibernate.sql.ast.tree.cte.CteStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; /** * @author Christian Beikov */ public abstract class AbstractMutationStatement extends AbstractStatement implements MutationStatement { - private final TableReference targetTable; + private final NamedTableReference targetTable; private final List returningColumns; - public AbstractMutationStatement(TableReference targetTable) { + public AbstractMutationStatement(NamedTableReference targetTable) { super( new LinkedHashMap<>() ); this.targetTable = targetTable; this.returningColumns = Collections.emptyList(); } - public AbstractMutationStatement(Map cteStatements, TableReference targetTable, List returningColumns) { + public AbstractMutationStatement(Map cteStatements, NamedTableReference targetTable, List returningColumns) { super( cteStatements ); this.targetTable = targetTable; this.returningColumns = returningColumns; } @Override - public TableReference getTargetTable() { + public NamedTableReference getTargetTable() { return targetTable; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java index 379f853227..9f13db25b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java @@ -9,7 +9,7 @@ package org.hibernate.sql.ast.tree; import java.util.List; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; /** * Specialization of Statement for mutation (DML) statements @@ -17,6 +17,6 @@ import org.hibernate.sql.ast.tree.from.TableReference; * @author Steve Ebersole */ public interface MutationStatement extends Statement { - TableReference getTargetTable(); + NamedTableReference getTargetTable(); List getReturningColumns(); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java index 4d86b9811b..33ac1b5979 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java @@ -7,24 +7,10 @@ package org.hibernate.sql.ast.tree.cte; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import org.hibernate.LockMode; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.metamodel.mapping.Bindable; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.query.NavigablePath; -import org.hibernate.sql.ast.Clause; -import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.expression.JdbcParameter; -import org.hibernate.sql.ast.tree.from.StandardTableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; -import org.hibernate.sql.ast.tree.select.QuerySpec; -import org.hibernate.sql.exec.internal.JdbcParameterImpl; -import org.hibernate.sql.exec.spi.ExecutionContext; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; -import org.hibernate.sql.results.internal.SqlSelectionImpl; /** * Describes the table definition for the CTE - its name amd its columns @@ -67,120 +53,4 @@ public class CteTable { return new CteTable( name, cteColumns, sessionFactory ); } - public QuerySpec createCteDefinition( - List matchingIds, - Bindable bindable, - JdbcParameterBindings jdbcParameterBindings, - ExecutionContext executionContext) { - final QuerySpec querySpec = new QuerySpec( false ); - - final TableReference tableValueConstructorReference = createCteDefinitionTableValueCtor( - matchingIds, - bindable, - jdbcParameterBindings, - executionContext - ); - - final StandardTableGroup tableValueCtorGroup = new StandardTableGroup( - true, - new NavigablePath( "cte" ), - null, - null, - tableValueConstructorReference, - null, - sessionFactory - ); - - querySpec.getFromClause().addRoot( tableValueCtorGroup ); - - applySelections( querySpec, tableValueConstructorReference ); - - return querySpec; - } - - private TableReference createCteDefinitionTableValueCtor( - List matchingValues, - Bindable bindable, - JdbcParameterBindings jdbcParameterBindings, - ExecutionContext executionContext) { - // use `DerivedTable` as the TableValueConstructor - // so its `#expression` would be something like `values ( (a1, b1), (a2, b2), ... )` - - final int numberOfColumns = getCteColumns().size(); - - final StringBuilder tableValueCtorExpressionBuffer = new StringBuilder( "values(" ); - final List jdbcParameters = Arrays.asList( new JdbcParameterImpl[numberOfColumns] ); - String rowSeparator = ""; - for ( Object matchingId : matchingValues ) { - tableValueCtorExpressionBuffer.append( rowSeparator ); - - char separator = '('; - for ( int i = 0; i < numberOfColumns; i++ ) { - tableValueCtorExpressionBuffer.append( separator ); - tableValueCtorExpressionBuffer.append( '?' ); - separator = ','; - jdbcParameters.set( i, new JdbcParameterImpl( cteColumns.get( i ).getJdbcMapping() ) ); - } - tableValueCtorExpressionBuffer.append( ')' ); - - jdbcParameterBindings.registerParametersForEachJdbcValue( - matchingId, - Clause.IRRELEVANT, - bindable, - jdbcParameters, - executionContext.getSession() - ); - - rowSeparator = ", "; - } - - tableValueCtorExpressionBuffer.append( ')' ); - - return new TableReference( - tableValueCtorExpressionBuffer.toString(), - cteName, - false, - sessionFactory - ); - } - - public QuerySpec createCteSubQuery(@SuppressWarnings("unused") ExecutionContext executionContext) { - final QuerySpec querySpec = new QuerySpec( false ); - - final TableReference cteTableReference = new TableReference( - getTableExpression(), - null, - false, - sessionFactory - ); - - final CteTableGroup cteTableGroup = new CteTableGroup( cteTableReference ); - querySpec.getFromClause().addRoot( cteTableGroup ); - - applySelections( querySpec, cteTableReference ); - - return querySpec; - } - - private void applySelections(QuerySpec querySpec, TableReference tableReference) { - for ( int i = 0; i < cteColumns.size(); i++ ) { - final CteColumn cteColumn = cteColumns.get( i ); - querySpec.getSelectClause().addSqlSelection( - new SqlSelectionImpl( - i + 1, - i, - // todo (6.0) : handle read/write transformers for the CTE columns - new ColumnReference( - tableReference, - cteColumn.getColumnExpression(), - false, - null, - null, - cteColumn.getJdbcMapping(), - sessionFactory - ) - ) - ); - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTableGroup.java index 942d139b85..013c5d62f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTableGroup.java @@ -13,23 +13,24 @@ import java.util.function.Consumer; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPartContainer; import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; /** - * Wraps a {@link TableReference} representing the CTE and adapts it to + * Wraps a {@link NamedTableReference} representing the CTE and adapts it to * {@link TableGroup} for use in SQL AST * * @author Steve Ebersole */ public class CteTableGroup implements TableGroup { private final NavigablePath navigablePath; - private final TableReference cteTableReference; + private final NamedTableReference cteTableReference; @SuppressWarnings("WeakerAccess") - public CteTableGroup(TableReference cteTableReference) { + public CteTableGroup(NamedTableReference cteTableReference) { this.navigablePath = new NavigablePath( cteTableReference.getTableExpression() ); this.cteTableReference = cteTableReference; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/delete/DeleteStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/delete/DeleteStatement.java index 9f5061dfdb..595c2565fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/delete/DeleteStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/delete/DeleteStatement.java @@ -15,7 +15,7 @@ import org.hibernate.sql.ast.spi.SqlAstHelper; import org.hibernate.sql.ast.tree.AbstractMutationStatement; import org.hibernate.sql.ast.tree.cte.CteStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.predicate.Junction; import org.hibernate.sql.ast.tree.predicate.Predicate; @@ -27,13 +27,13 @@ public class DeleteStatement extends AbstractMutationStatement { public static final String DEFAULT_ALIAS = "to_delete_"; private final Predicate restriction; - public DeleteStatement(TableReference targetTable, Predicate restriction) { + public DeleteStatement(NamedTableReference targetTable, Predicate restriction) { super( targetTable ); this.restriction = restriction; } public DeleteStatement( - TableReference targetTable, + NamedTableReference targetTable, Predicate restriction, List returningColumns) { super( new LinkedHashMap<>(), targetTable, returningColumns ); @@ -43,7 +43,7 @@ public class DeleteStatement extends AbstractMutationStatement { public DeleteStatement( boolean withRecursive, Map cteStatements, - TableReference targetTable, + NamedTableReference targetTable, Predicate restriction, List returningColumns) { super( cteStatements, targetTable, returningColumns ); @@ -56,10 +56,10 @@ public class DeleteStatement extends AbstractMutationStatement { } public static class DeleteStatementBuilder { - private final TableReference targetTable; + private final NamedTableReference targetTable; private Predicate restriction; - public DeleteStatementBuilder(TableReference targetTable) { + public DeleteStatementBuilder(NamedTableReference targetTable) { this.targetTable = targetTable; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractTableReference.java new file mode 100644 index 0000000000..bfb4d372e4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractTableReference.java @@ -0,0 +1,48 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ + +package org.hibernate.sql.ast.tree.from; + +import java.util.Objects; + +public abstract class AbstractTableReference implements TableReference { + protected final String identificationVariable; + protected final boolean isOptional; + + public AbstractTableReference(String identificationVariable, boolean isOptional) { + assert identificationVariable != null; + this.identificationVariable = identificationVariable; + this.isOptional = isOptional; + } + + @Override + public String getIdentificationVariable() { + return identificationVariable; + } + + @Override + public boolean isOptional() { + return isOptional; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + TableReference that = (TableReference) o; + return Objects.equals( identificationVariable, that.getIdentificationVariable() ); + } + + @Override + public int hashCode() { + return Objects.hash( identificationVariable ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java index 194436dad4..ecb90dd3f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java @@ -112,7 +112,7 @@ public class CorrelatedTableGroup extends AbstractTableGroup { @Override public void applyAffectedTableNames(Consumer nameCollector) { - nameCollector.accept( getPrimaryTableReference().getTableExpression() ); + getPrimaryTableReference().applyAffectedTableNames( nameCollector ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java new file mode 100644 index 0000000000..06d99cc473 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java @@ -0,0 +1,55 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.sql.ast.tree.from; + +import java.util.List; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.NavigablePath; + +/** + * @author Christian Beikov + */ +public abstract class DerivedTableReference extends AbstractTableReference { + + private final List columnNames; + + public DerivedTableReference( + String identificationVariable, + List columnNames, + SessionFactoryImplementor sessionFactory) { + super( identificationVariable, false ); + this.columnNames = columnNames; + } + + @Override + public String getTableId() { + return null; + } + + public List getColumnNames() { + return columnNames; + } + + @Override + public TableReference resolveTableReference( + NavigablePath navigablePath, + String tableExpression, + boolean allowFkOptimization) { + throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" ); + } + + @Override + public TableReference getTableReference( + NavigablePath navigablePath, + String tableExpression, + boolean allowFkOptimization, + boolean resolve) { + return null; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java index 0acd0cc626..a325571282 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java @@ -44,17 +44,12 @@ public class FromClause implements SqlAstNode { } public void visitTableGroups(Consumer action) { - for ( int i = 0; i < roots.size(); i++ ) { - visitTableGroups( roots.get( i ), action ); - } - } - - private void visitTableGroups(TableGroup tableGroup, Consumer action) { - action.accept( tableGroup ); - final List tableGroupJoins = tableGroup.getTableGroupJoins(); - for ( int i = 0; i < tableGroupJoins.size(); i++ ) { - visitTableGroups( tableGroupJoins.get( i ).getJoinedGroup(), action ); - } + queryTableGroups( + tableGroup -> { + action.accept( tableGroup ); + return null; + } + ); } public T queryTableGroups(Function action) { @@ -79,28 +74,28 @@ public class FromClause implements SqlAstNode { return nestedResult; } } + final List nestedTableGroupJoins = tableGroup.getNestedTableGroupJoins(); + for ( int i = 0; i < nestedTableGroupJoins.size(); i++ ) { + final T nestedResult = queryTableGroups( nestedTableGroupJoins.get( i ).getJoinedGroup(), action ); + if ( nestedResult != null ) { + return nestedResult; + } + } return null; } public void visitTableJoins(Consumer action) { - for ( int i = 0; i < roots.size(); i++ ) { - visitTableJoins( roots.get( i ), action ); - } - } - - private void visitTableJoins(TableGroup tableGroup, Consumer action) { - tableGroup.getTableReferenceJoins().forEach( action ); - final List tableGroupJoins = tableGroup.getTableGroupJoins(); - for ( int i = 0; i < tableGroupJoins.size(); i++ ) { - final TableGroupJoin tableGroupJoin = tableGroupJoins.get( i ); - action.accept( tableGroupJoin ); - visitTableJoins( tableGroupJoin.getJoinedGroup(), action ); - } + queryTableJoins( + tableGroupJoin -> { + action.accept( tableGroupJoin ); + return null; + } + ); } public T queryTableJoins(Function action) { for ( int i = 0; i < roots.size(); i++ ) { - final T result = queryTableJoins( roots.get( i ), action ); + T result = queryTableJoins( roots.get( i ), action ); if ( result != null ) { return result; } @@ -116,7 +111,14 @@ public class FromClause implements SqlAstNode { } } - final List tableGroupJoins = tableGroup.getTableGroupJoins(); + final T result = queryTableJoins( tableGroup.getTableGroupJoins(), action ); + if ( result != null ) { + return result; + } + return queryTableJoins( tableGroup.getNestedTableGroupJoins(), action ); + } + + private T queryTableJoins(List tableGroupJoins, Function action) { for ( int i = 0; i < tableGroupJoins.size(); i++ ) { final TableGroupJoin tableGroupJoin = tableGroupJoins.get( i ); T result = action.apply( tableGroupJoin ); @@ -132,18 +134,12 @@ public class FromClause implements SqlAstNode { } public void visitTableGroupJoins(Consumer action) { - for ( int i = 0; i < roots.size(); i++ ) { - visitTableGroupJoins( roots.get( i ), action ); - } - } - - private void visitTableGroupJoins(TableGroup tableGroup, Consumer action) { - final List tableGroupJoins = tableGroup.getTableGroupJoins(); - for ( int i = 0; i < tableGroupJoins.size(); i++ ) { - final TableGroupJoin tableGroupJoin = tableGroupJoins.get( i ); - action.accept( tableGroupJoin ); - visitTableGroupJoins( tableGroupJoin.getJoinedGroup(), action ); - } + queryTableGroupJoins( + tableGroupJoin -> { + action.accept( tableGroupJoin ); + return null; + } + ); } public T queryTableGroupJoins(Function action) { @@ -157,7 +153,14 @@ public class FromClause implements SqlAstNode { } private T queryTableGroupJoins(TableGroup tableGroup, Function action) { - final List tableGroupJoins = tableGroup.getTableGroupJoins(); + final T result = queryTableGroupJoins( tableGroup.getTableGroupJoins(), action ); + if ( result != null ) { + return result; + } + return queryTableGroupJoins( tableGroup.getNestedTableGroupJoins(), action ); + } + + private T queryTableGroupJoins(List tableGroupJoins, Function action) { for ( int i = 0; i < tableGroupJoins.size(); i++ ) { final TableGroupJoin tableGroupJoin = tableGroupJoins.get( i ); T result = action.apply( tableGroupJoin ); @@ -172,6 +175,55 @@ public class FromClause implements SqlAstNode { return null; } + public void visitTableReferences(Consumer action) { + queryTableReferences( + tableGroupJoin -> { + action.accept( tableGroupJoin ); + return null; + } + ); + } + + public T queryTableReferences(Function action) { + for ( int i = 0; i < roots.size(); i++ ) { + T result = queryTableReferences( roots.get( i ), action ); + if ( result != null ) { + return result; + } + } + return null; + } + + private T queryTableReferences(TableGroup tableGroup, Function action) { + final T result = action.apply( tableGroup.getPrimaryTableReference() ); + if ( result != null ) { + return result; + } + for ( TableReferenceJoin tableReferenceJoin : tableGroup.getTableReferenceJoins() ) { + final T nestedResult = action.apply( tableReferenceJoin.getJoinedTableReference() ); + if ( nestedResult != null ) { + return nestedResult; + } + } + + final T nestedResult = queryTableReferences( tableGroup.getTableGroupJoins(), action ); + if ( nestedResult != null ) { + return nestedResult; + } + return queryTableReferences( tableGroup.getNestedTableGroupJoins(), action ); + } + + private T queryTableReferences(List tableGroupJoins, Function action) { + for ( int i = 0; i < tableGroupJoins.size(); i++ ) { + final TableGroupJoin tableGroupJoin = tableGroupJoins.get( i ); + T result = queryTableReferences( tableGroupJoin.getJoinedGroup(), action ); + if ( result != null ) { + return result; + } + } + return null; + } + @Override public void accept(SqlAstWalker sqlTreeWalker) { sqlTreeWalker.visitFromClause( this ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MutatingTableReferenceGroupWrapper.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MutatingTableReferenceGroupWrapper.java index 502af0e49d..4a706cb52f 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MutatingTableReferenceGroupWrapper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MutatingTableReferenceGroupWrapper.java @@ -23,12 +23,12 @@ import org.hibernate.query.NavigablePath; public class MutatingTableReferenceGroupWrapper implements VirtualTableGroup { private final NavigablePath navigablePath; private final ModelPartContainer modelPart; - private final TableReference mutatingTableReference; + private final NamedTableReference mutatingTableReference; public MutatingTableReferenceGroupWrapper( NavigablePath navigablePath, ModelPartContainer modelPart, - TableReference mutatingTableReference) { + NamedTableReference mutatingTableReference) { this.navigablePath = navigablePath; this.modelPart = modelPart; this.mutatingTableReference = mutatingTableReference; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java new file mode 100644 index 0000000000..a18443dc4b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java @@ -0,0 +1,104 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.sql.ast.tree.from; + +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.SqlAstWalker; + +/** + * Represents a reference to a "named" table in a query's from clause. + * + * @author Steve Ebersole + */ +public class NamedTableReference extends AbstractTableReference { + private final String tableExpression; + + private String prunedTableExpression; + + public NamedTableReference( + String tableExpression, + String identificationVariable, + boolean isOptional, + SessionFactoryImplementor sessionFactory) { + super( identificationVariable, isOptional ); + assert tableExpression != null; + this.tableExpression = tableExpression; + } + + public String getTableExpression() { + return prunedTableExpression == null ? tableExpression : prunedTableExpression; + } + + @Override + public String getTableId() { + return getTableExpression(); + } + + public void setPrunedTableExpression(String prunedTableExpression) { + this.prunedTableExpression = prunedTableExpression; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitNamedTableReference( this ); + } + + @Override + public void applyAffectedTableNames(Consumer nameCollector) { + nameCollector.accept( getTableExpression() ); + } + + @Override + public List getAffectedTableNames() { + return Collections.singletonList( getTableExpression() ); + } + + @Override + public boolean containsAffectedTableName(String requestedName) { + return getTableExpression().equals( requestedName ); + } + + @Override + public Boolean visitAffectedTableNames(Function nameCollector) { + return nameCollector.apply( getTableExpression() ); + } + + @Override + public TableReference resolveTableReference( + NavigablePath navigablePath, + String tableExpression, + boolean allowFkOptimization) { + if ( tableExpression.equals( getTableExpression() ) ) { + return this; + } + throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" ); + } + + @Override + public TableReference getTableReference( + NavigablePath navigablePath, + String tableExpression, + boolean allowFkOptimization, + boolean resolve) { + if ( this.tableExpression.equals( tableExpression ) ) { + return this; + } + return null; + } + + @Override + public String toString() { + return getTableExpression() + "(" + getIdentificationVariable() + ')'; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/QueryPartTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/QueryPartTableReference.java new file mode 100644 index 0000000000..c7cbfe9207 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/QueryPartTableReference.java @@ -0,0 +1,49 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.sql.ast.tree.from; + +import java.util.List; +import java.util.function.Function; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.sql.ast.SqlAstWalker; +import org.hibernate.sql.ast.tree.select.QueryPart; + +/** + * @author Christian Beikov + */ +public class QueryPartTableReference extends DerivedTableReference { + + private final QueryPart queryPart; + + public QueryPartTableReference( + QueryPart queryPart, + String identificationVariable, + List columnNames, + SessionFactoryImplementor sessionFactory) { + super( identificationVariable, columnNames, sessionFactory ); + this.queryPart = queryPart; + } + + public QueryPart getQueryPart() { + return queryPart; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitQueryPartTableReference( this ); + } + + @Override + public Boolean visitAffectedTableNames(Function nameCollector) { + final Function tableReferenceBooleanFunction = + tableReference -> tableReference.visitAffectedTableNames( nameCollector ); + return queryPart.queryQuerySpecs( + querySpec -> querySpec.getFromClause().queryTableReferences( tableReferenceBooleanFunction ) + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java index 27022f277f..6ee8ed5465 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardTableGroup.java @@ -45,7 +45,7 @@ public class StandardTableGroup extends AbstractTableGroup { this.tableReferenceJoinCreator = null; this.tableReferenceJoinNameChecker = s -> { for ( int i = 0; i < tableJoins.size(); i++ ) { - if ( tableJoins.get( i ).getJoinedTableReference().getTableExpression().equals( s ) ) { + if ( tableJoins.get( i ).getJoinedTableReference().containsAffectedTableName( s ) ) { return true; } } @@ -97,9 +97,9 @@ public class StandardTableGroup extends AbstractTableGroup { @Override public void applyAffectedTableNames(Consumer nameCollector) { // todo (6.0) : if we implement dynamic TableReference creation, this still needs to return the expressions for all mapped tables not just the ones with a TableReference at this time - nameCollector.accept( getPrimaryTableReference().getTableExpression() ); + getPrimaryTableReference().applyAffectedTableNames( nameCollector ); for ( TableReferenceJoin tableReferenceJoin : tableJoins ) { - nameCollector.accept( tableReferenceJoin.getJoinedTableReference().getTableExpression() ); + tableReferenceJoin.getJoinedTableReference().applyAffectedTableNames( nameCollector ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReference.java index 68ffa0069e..82fa062655 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReference.java @@ -6,9 +6,11 @@ */ package org.hibernate.sql.ast.tree.from; -import java.util.Objects; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.NavigablePath; import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -18,87 +20,56 @@ import org.hibernate.sql.ast.tree.SqlAstNode; * * @author Steve Ebersole */ -public class TableReference implements SqlAstNode, ColumnReferenceQualifier { - private final String tableExpression; - private final String identificationVariable; +public interface TableReference extends SqlAstNode, ColumnReferenceQualifier { - private final boolean isOptional; - private String prunedTableExpression; + String getIdentificationVariable(); - public TableReference( - String tableExpression, - String identificationVariable, - boolean isOptional, - SessionFactoryImplementor sessionFactory) { - this.tableExpression = tableExpression; - this.identificationVariable = identificationVariable; - this.isOptional = isOptional; - } + /** + * An identifier for the table reference. May be null if this is not a named table reference. + */ + String getTableId(); - public String getTableExpression() { - return prunedTableExpression == null ? tableExpression : prunedTableExpression; - } - - public String getIdentificationVariable() { - return identificationVariable; - } - - public boolean isOptional() { - return isOptional; - } - - public void setPrunedTableExpression(String prunedTableExpression) { - this.prunedTableExpression = prunedTableExpression; - } + boolean isOptional(); @Override - public void accept(SqlAstWalker sqlTreeWalker) { - sqlTreeWalker.visitTableReference( this ); + void accept(SqlAstWalker sqlTreeWalker); + + default void applyAffectedTableNames(Consumer nameCollector) { + visitAffectedTableNames( + name -> { + nameCollector.accept( name ); + return null; + } + ); } + default List getAffectedTableNames() { + final List affectedTableNames = new ArrayList<>(); + visitAffectedTableNames( + name -> { + affectedTableNames.add( name ); + return null; + } + ); + return affectedTableNames; + } + + default boolean containsAffectedTableName(String requestedName) { + return visitAffectedTableNames( requestedName::equals ); + } + + Boolean visitAffectedTableNames(Function nameCollector); + @Override - public TableReference resolveTableReference( + TableReference resolveTableReference( NavigablePath navigablePath, String tableExpression, - boolean allowFkOptimization) { - if ( tableExpression.equals( getTableExpression() ) ) { - return this; - } - throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" ); - } + boolean allowFkOptimization); @Override - public TableReference getTableReference( + TableReference getTableReference( NavigablePath navigablePath, String tableExpression, boolean allowFkOptimization, - boolean resolve) { - if ( this.tableExpression.equals( tableExpression ) ) { - return this; - } - return null; - } - - @Override - public String toString() { - return getTableExpression() + "(" + getIdentificationVariable() + ')'; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - TableReference that = (TableReference) o; - return Objects.equals( identificationVariable, that.identificationVariable ); - } - - @Override - public int hashCode() { - return Objects.hash( identificationVariable ); - } - + boolean resolve); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceJoin.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceJoin.java index 22488ed6b4..bac99482e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceJoin.java @@ -20,10 +20,10 @@ import org.hibernate.sql.ast.tree.predicate.PredicateContainer; */ public class TableReferenceJoin implements TableJoin, PredicateContainer { private final SqlAstJoinType sqlAstJoinType; - private final TableReference joinedTableBinding; + private final NamedTableReference joinedTableBinding; private Predicate predicate; - public TableReferenceJoin(SqlAstJoinType sqlAstJoinType, TableReference joinedTableBinding, Predicate predicate) { + public TableReferenceJoin(SqlAstJoinType sqlAstJoinType, NamedTableReference joinedTableBinding, Predicate predicate) { this.sqlAstJoinType = sqlAstJoinType == null ? SqlAstJoinType.LEFT : sqlAstJoinType; this.joinedTableBinding = joinedTableBinding; this.predicate = predicate; @@ -40,7 +40,7 @@ public class TableReferenceJoin implements TableJoin, PredicateContainer { return sqlAstJoinType; } - public TableReference getJoinedTableReference() { + public NamedTableReference getJoinedTableReference() { return joinedTableBinding; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableGroup.java index d6088f779b..2e954e2c12 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableGroup.java @@ -27,12 +27,12 @@ public class UnionTableGroup implements VirtualTableGroup { private final UnionSubclassEntityPersister modelPart; private final String sourceAlias; - private final TableReference tableReference; + private final UnionTableReference tableReference; public UnionTableGroup( boolean canUseInnerJoins, NavigablePath navigablePath, - TableReference tableReference, + UnionTableReference tableReference, UnionSubclassEntityPersister modelPart, String sourceAlias) { this.canUseInnerJoins = canUseInnerJoins; @@ -124,7 +124,7 @@ public class UnionTableGroup implements VirtualTableGroup { } @Override - public TableReference getPrimaryTableReference() { + public UnionTableReference getPrimaryTableReference() { return tableReference; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java index 6e77b42ba7..fc156b99cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java @@ -12,7 +12,7 @@ import org.hibernate.query.NavigablePath; /** * @author Andrea Boriero */ -public class UnionTableReference extends TableReference { +public class UnionTableReference extends NamedTableReference { private final String[] subclassTableSpaceExpressions; public UnionTableReference( diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/ValuesTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/ValuesTableReference.java index 883a175e05..aa19180de3 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/ValuesTableReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/ValuesTableReference.java @@ -7,51 +7,45 @@ package org.hibernate.sql.ast.tree.from; import java.util.List; +import java.util.function.Function; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.tree.insert.Values; /** * @author Christian Beikov */ -public class ValuesTableReference extends TableReference { +public class ValuesTableReference extends DerivedTableReference { private final List valuesList; - private final List columnNames; public ValuesTableReference( List valuesList, String identificationVariable, List columnNames, SessionFactoryImplementor sessionFactory) { - super( null, identificationVariable, false, sessionFactory ); + super( identificationVariable, columnNames, sessionFactory ); this.valuesList = valuesList; - this.columnNames = columnNames; + } + + @Override + public String getTableId() { + return null; } public List getValuesList() { return valuesList; } - public List getColumnNames() { - return columnNames; + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitValuesTableReference( this ); } @Override - public TableReference resolveTableReference( - NavigablePath navigablePath, - String tableExpression, - boolean allowFkOptimization) { - throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" ); - } - - @Override - public TableReference getTableReference( - NavigablePath navigablePath, - String tableExpression, - boolean allowFkOptimization, - boolean resolve) { + public Boolean visitAffectedTableNames(Function nameCollector) { return null; } + } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/insert/InsertStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/insert/InsertStatement.java index 96c6e15f90..947391f439 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/insert/InsertStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/insert/InsertStatement.java @@ -14,10 +14,9 @@ import java.util.Map; import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.tree.AbstractMutationStatement; -import org.hibernate.sql.ast.tree.MutationStatement; import org.hibernate.sql.ast.tree.cte.CteStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.select.QueryPart; /** @@ -25,19 +24,20 @@ import org.hibernate.sql.ast.tree.select.QueryPart; */ public class InsertStatement extends AbstractMutationStatement { + public static final String DEFAULT_ALIAS = "to_insert_"; private List targetColumnReferences; private QueryPart sourceSelectStatement; private List valuesList = new ArrayList<>(); - public InsertStatement(TableReference targetTable) { + public InsertStatement(NamedTableReference targetTable) { super( targetTable ); } - public InsertStatement(TableReference targetTable, List returningColumns) { + public InsertStatement(NamedTableReference targetTable, List returningColumns) { super( new LinkedHashMap<>(), targetTable, returningColumns ); } - public InsertStatement(boolean withRecursive, Map cteStatements, TableReference targetTable, List returningColumns) { + public InsertStatement(boolean withRecursive, Map cteStatements, NamedTableReference targetTable, List returningColumns) { super( cteStatements, targetTable, returningColumns ); setWithRecursive( withRecursive ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryGroup.java index 18b2879214..8c2be76556 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryGroup.java @@ -8,6 +8,7 @@ package org.hibernate.sql.ast.tree.select; import java.util.List; import java.util.function.Consumer; +import java.util.function.Function; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.SetOperator; @@ -39,12 +40,23 @@ public class QueryGroup extends QueryPart { } @Override - public void forEachQuerySpec(Consumer querySpecConsumer) { + public void visitQuerySpecs(Consumer querySpecConsumer) { for ( int i = 0; i < queryParts.size(); i++ ) { - queryParts.get( i ).forEachQuerySpec( querySpecConsumer ); + queryParts.get( i ).visitQuerySpecs( querySpecConsumer ); } } + @Override + public T queryQuerySpecs(Function querySpecConsumer) { + for ( int i = 0; i < queryParts.size(); i++ ) { + T result = queryParts.get( i ).queryQuerySpecs( querySpecConsumer ); + if ( result != null ) { + return result; + } + } + return null; + } + public SetOperator getSetOperator() { return setOperator; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryPart.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryPart.java index 1d4ad7cabf..6f903fe8d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryPart.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QueryPart.java @@ -9,6 +9,7 @@ package org.hibernate.sql.ast.tree.select; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import java.util.function.Function; import org.hibernate.query.FetchClauseType; import org.hibernate.query.sqm.sql.internal.DomainResultProducer; @@ -37,7 +38,9 @@ public abstract class QueryPart implements SqlAstNode, Expression, DomainResultP public abstract QuerySpec getLastQuerySpec(); - public abstract void forEachQuerySpec(Consumer querySpecConsumer); + public abstract void visitQuerySpecs(Consumer querySpecConsumer); + + public abstract T queryQuerySpecs(Function querySpecConsumer); /** * Does this QueryPart map to the statement's root query (as diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java index b24ac419e8..7d049506f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java @@ -9,6 +9,7 @@ package org.hibernate.sql.ast.tree.select; import java.util.Collections; import java.util.List; import java.util.function.Consumer; +import java.util.function.Function; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.sqm.sql.internal.DomainResultProducer; @@ -63,10 +64,15 @@ public class QuerySpec extends QueryPart implements SqlAstNode, PredicateContain } @Override - public void forEachQuerySpec(Consumer querySpecConsumer) { + public void visitQuerySpecs(Consumer querySpecConsumer) { querySpecConsumer.accept( this ); } + @Override + public T queryQuerySpecs(Function querySpecConsumer) { + return querySpecConsumer.apply( this ); + } + public FromClause getFromClause() { return fromClause; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java index f8955f8ea8..69abaa25c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java @@ -16,7 +16,7 @@ import org.hibernate.sql.ast.spi.SqlAstTreeHelper; import org.hibernate.sql.ast.tree.AbstractMutationStatement; import org.hibernate.sql.ast.tree.cte.CteStatement; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.predicate.Predicate; /** @@ -27,7 +27,7 @@ public class UpdateStatement extends AbstractMutationStatement { private final Predicate restriction; public UpdateStatement( - TableReference targetTable, + NamedTableReference targetTable, List assignments, Predicate restriction) { super( targetTable ); @@ -36,7 +36,7 @@ public class UpdateStatement extends AbstractMutationStatement { } public UpdateStatement( - TableReference targetTable, + NamedTableReference targetTable, List assignments, Predicate restriction, List returningColumns) { @@ -48,7 +48,7 @@ public class UpdateStatement extends AbstractMutationStatement { public UpdateStatement( boolean withRecursive, Map cteStatements, - TableReference targetTable, + NamedTableReference targetTable, List assignments, Predicate restriction, List returningColumns) { @@ -67,11 +67,11 @@ public class UpdateStatement extends AbstractMutationStatement { } public static class UpdateStatementBuilder { - private final TableReference targetTableRef; + private final NamedTableReference targetTableRef; private List assignments; private Predicate restriction; - public UpdateStatementBuilder(TableReference targetTableRef) { + public UpdateStatementBuilder(NamedTableReference targetTableRef) { this.targetTableRef = targetTableRef; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java index f7e5cdac92..027a5631db 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java @@ -96,7 +96,7 @@ public class SmokeTests { final TableGroup rootTableGroup = fromClause.getRoots().get( 0 ); assertThat( rootTableGroup.getPrimaryTableReference(), notNullValue() ); - assertThat( rootTableGroup.getPrimaryTableReference().getTableExpression(), is( "mapping_simple_entity" ) ); + assertThat( rootTableGroup.getPrimaryTableReference().getTableId(), is( "mapping_simple_entity" ) ); assertThat( rootTableGroup.getTableReferenceJoins().size(), is( 0 ) ); @@ -155,7 +155,7 @@ public class SmokeTests { final TableGroup rootTableGroup = fromClause.getRoots().get( 0 ); assertThat( rootTableGroup.getPrimaryTableReference(), notNullValue() ); - assertThat( rootTableGroup.getPrimaryTableReference().getTableExpression(), is( "mapping_simple_entity" ) ); + assertThat( rootTableGroup.getPrimaryTableReference().getTableId(), is( "mapping_simple_entity" ) ); assertThat( rootTableGroup.getTableReferenceJoins().size(), is( 0 ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionMapWithComponentValueTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionMapWithComponentValueTest.java index 320139000e..cfa8e37481 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionMapWithComponentValueTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/CollectionMapWithComponentValueTest.java @@ -179,7 +179,7 @@ public class CollectionMapWithComponentValueTest extends BaseCoreFunctionalTestC @TestForIssue(jiraKey = "HHH-10577") public void testMapKeyExpressionDereferenceInSelect() { doInHibernate( this::sessionFactory, s -> { - List keyValueNames = s.createQuery( "select key(v).name as name from TestEntity te join te.values v order by name", String.class ).list(); + List keyValueNames = s.createQuery( "select key(v).name as name from TestEntity te join te.values v order by name", String.class ).getResultList(); assertEquals( 2, keyValueNames.size() ); assertEquals( "key1", keyValueNames.get( 0 ) ); assertEquals( "key2", keyValueNames.get( 1 ) ); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/function/OrderByFragmentFunction.java b/hibernate-envers/src/main/java/org/hibernate/envers/function/OrderByFragmentFunction.java index 6896eb9e92..aeb0f64943 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/function/OrderByFragmentFunction.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/function/OrderByFragmentFunction.java @@ -29,6 +29,7 @@ import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.expression.SqmLiteral; import org.hibernate.sql.ast.spi.SqlAstQueryPartProcessingState; +import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; @@ -117,7 +118,7 @@ public class OrderByFragmentFunction extends AbstractSqmFunctionDescriptor { public AuditingTableGroup(TableGroup delegate, String normalTableExpression) { this.delegate = delegate; - this.auditTableExpression = delegate.getPrimaryTableReference().getTableExpression(); + this.auditTableExpression = ( (NamedTableReference) delegate.getPrimaryTableReference() ).getTableExpression(); this.normalTableExpression = normalTableExpression; }