Split TableReference class into interface and NamedTableReference implementation to allow QueryPartTableReference and ValuesTableReference to fit into the picture

This commit is contained in:
Christian Beikov 2021-12-14 16:20:20 +01:00 committed by Steve Ebersole
parent 70114d30ec
commit b75277b421
66 changed files with 789 additions and 560 deletions

View File

@ -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<T extends Statement> extends BaseSqmTo
null,
null,
null,
new TableReference(
new NamedTableReference(
"(select 1)",
"dummy_(x)",
false,

View File

@ -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<T extends Statement> extends BaseSqmToSq
null,
null,
null,
new TableReference(
new NamedTableReference(
"(select 1)",
"dummy_(x)",
false,

View File

@ -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<T extends JdbcOperation> 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" );

View File

@ -247,10 +247,10 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
}
@Override
protected void renderValuesTableReference(ValuesTableReference tableReference) {
public void visitValuesTableReference(ValuesTableReference tableReference) {
final List<Values> valuesList = tableReference.getValuesList();
if ( valuesList.size() < 2 ) {
super.renderValuesTableReference( tableReference );
super.visitValuesTableReference( tableReference );
}
else {
append( '(' );

View File

@ -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<T extends JdbcOperation> 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<T extends JdbcOperation> 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

View File

@ -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<T extends JdbcOperation> 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" );

View File

@ -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<T extends JdbcOperation> 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" );
}

View File

@ -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<T extends Statement> extends BaseSqmToSq
null,
null,
null,
new TableReference(
new NamedTableReference(
"(select 1)",
"dummy_(x)",
false,

View File

@ -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()

View File

@ -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(

View File

@ -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
);

View File

@ -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(

View File

@ -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,

View File

@ -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;
}

View File

@ -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 ) );
}

View File

@ -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<ColumnReference> 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<JdbcMapping> jdbcMappings = getIdentifierMapping().getJdbcMappings();
return new ColumnReference(
tableReference.getIdentificationVariable(),
discriminatorColumnNameByTableName.get( tableReference.getTableExpression() ),
false,
null,
null,
jdbcMappings.get( 0 ),
getFactory()
);
}
}

View File

@ -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<Expression> 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 ) + ")"
);

View File

@ -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 ) );
}

View File

@ -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" );

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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<ColumnReference> 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
);

View File

@ -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<Map.Entry<SqmCteTableColumn, Assignment>> targetPathColumns = new ArrayList<>( size );
final List<SqmCteTableColumn> targetPathSqmCteColumns = new ArrayList<>( size );
final Map<SqmParameter, MappingModelExpressable> 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<Map.Entry<SqmCteTableColumn, Assignment>> 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;
}
}

View File

@ -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
);

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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<Consumer<SelectableConsumer>> 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,

View File

@ -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<Assignment> targetPathColumns = new ArrayList<>();
final Map<SqmParameter, MappingModelExpressable> 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()

View File

@ -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(

View File

@ -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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> extends Base
@Override
public SqlSelection resolveSqlSelection(
Expression expression,
JavaType javaTypeDescriptor,
JavaType<?> javaTypeDescriptor,
TypeConfiguration typeConfiguration) {
SqlSelection selection = delegate.resolveSqlSelection( expression, javaTypeDescriptor, typeConfiguration );
List<SqlSelection> sqlSelectionList = sqlSelectionsForSqmSelection[index];

View File

@ -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" );
}

View File

@ -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 ) {

View File

@ -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);

View File

@ -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<TableReferenceJoin> tableReferenceJoins = tableGroup.getTableReferenceJoins();
if ( ! tableReferenceJoins.isEmpty() ) {

View File

@ -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<T extends JdbcOperation> implemen
final Stack<Clause> 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<T extends JdbcOperation> implemen
final Stack<Clause> 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<T extends JdbcOperation> 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<T extends JdbcOperation> 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<String> 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<T extends JdbcOperation> implemen
return true;
}
protected void registerAffectedTable(TableReference tableReference) {
protected void registerAffectedTable(NamedTableReference tableReference) {
registerAffectedTable( tableReference.getTableExpression() );
}
@ -3755,7 +3778,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
}
@Override
public void visitTableReference(TableReference tableReference) {
public void visitNamedTableReference(NamedTableReference tableReference) {
// nothing to do... handled via TableGroup#render
}

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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 );
}
}

View File

@ -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);
}

View File

@ -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<ColumnReference> returningColumns;
public AbstractMutationStatement(TableReference targetTable) {
public AbstractMutationStatement(NamedTableReference targetTable) {
super( new LinkedHashMap<>() );
this.targetTable = targetTable;
this.returningColumns = Collections.emptyList();
}
public AbstractMutationStatement(Map<String, CteStatement> cteStatements, TableReference targetTable, List<ColumnReference> returningColumns) {
public AbstractMutationStatement(Map<String, CteStatement> cteStatements, NamedTableReference targetTable, List<ColumnReference> returningColumns) {
super( cteStatements );
this.targetTable = targetTable;
this.returningColumns = returningColumns;
}
@Override
public TableReference getTargetTable() {
public NamedTableReference getTargetTable() {
return targetTable;
}

View File

@ -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<ColumnReference> getReturningColumns();
}

View File

@ -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<JdbcParameter> 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
)
)
);
}
}
}

View File

@ -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;
}

View File

@ -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<ColumnReference> returningColumns) {
super( new LinkedHashMap<>(), targetTable, returningColumns );
@ -43,7 +43,7 @@ public class DeleteStatement extends AbstractMutationStatement {
public DeleteStatement(
boolean withRecursive,
Map<String, CteStatement> cteStatements,
TableReference targetTable,
NamedTableReference targetTable,
Predicate restriction,
List<ColumnReference> 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;
}

View File

@ -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 );
}
}

View File

@ -112,7 +112,7 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
@Override
public void applyAffectedTableNames(Consumer<String> nameCollector) {
nameCollector.accept( getPrimaryTableReference().getTableExpression() );
getPrimaryTableReference().applyAffectedTableNames( nameCollector );
}
@Override

View File

@ -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<String> columnNames;
public DerivedTableReference(
String identificationVariable,
List<String> columnNames,
SessionFactoryImplementor sessionFactory) {
super( identificationVariable, false );
this.columnNames = columnNames;
}
@Override
public String getTableId() {
return null;
}
public List<String> 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;
}
}

View File

@ -44,17 +44,12 @@ public class FromClause implements SqlAstNode {
}
public void visitTableGroups(Consumer<TableGroup> action) {
for ( int i = 0; i < roots.size(); i++ ) {
visitTableGroups( roots.get( i ), action );
}
}
private void visitTableGroups(TableGroup tableGroup, Consumer<TableGroup> action) {
action.accept( tableGroup );
final List<TableGroupJoin> 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> T queryTableGroups(Function<TableGroup, T> action) {
@ -79,28 +74,28 @@ public class FromClause implements SqlAstNode {
return nestedResult;
}
}
final List<TableGroupJoin> 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<TableJoin> action) {
for ( int i = 0; i < roots.size(); i++ ) {
visitTableJoins( roots.get( i ), action );
}
}
private void visitTableJoins(TableGroup tableGroup, Consumer<TableJoin> action) {
tableGroup.getTableReferenceJoins().forEach( action );
final List<TableGroupJoin> 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> T queryTableJoins(Function<TableJoin, T> 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<TableGroupJoin> tableGroupJoins = tableGroup.getTableGroupJoins();
final T result = queryTableJoins( tableGroup.getTableGroupJoins(), action );
if ( result != null ) {
return result;
}
return queryTableJoins( tableGroup.getNestedTableGroupJoins(), action );
}
private <T> T queryTableJoins(List<TableGroupJoin> tableGroupJoins, Function<TableJoin, T> 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<TableGroupJoin> action) {
for ( int i = 0; i < roots.size(); i++ ) {
visitTableGroupJoins( roots.get( i ), action );
}
}
private void visitTableGroupJoins(TableGroup tableGroup, Consumer<TableGroupJoin> action) {
final List<TableGroupJoin> 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> T queryTableGroupJoins(Function<TableGroupJoin, T> action) {
@ -157,7 +153,14 @@ public class FromClause implements SqlAstNode {
}
private <T> T queryTableGroupJoins(TableGroup tableGroup, Function<TableGroupJoin, T> action) {
final List<TableGroupJoin> tableGroupJoins = tableGroup.getTableGroupJoins();
final T result = queryTableGroupJoins( tableGroup.getTableGroupJoins(), action );
if ( result != null ) {
return result;
}
return queryTableGroupJoins( tableGroup.getNestedTableGroupJoins(), action );
}
private <T> T queryTableGroupJoins(List<TableGroupJoin> tableGroupJoins, Function<TableGroupJoin, T> 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<TableReference> action) {
queryTableReferences(
tableGroupJoin -> {
action.accept( tableGroupJoin );
return null;
}
);
}
public <T> T queryTableReferences(Function<TableReference, T> 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> T queryTableReferences(TableGroup tableGroup, Function<TableReference, T> 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> T queryTableReferences(List<TableGroupJoin> tableGroupJoins, Function<TableReference, T> 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 );

View File

@ -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;

View File

@ -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<String> nameCollector) {
nameCollector.accept( getTableExpression() );
}
@Override
public List<String> getAffectedTableNames() {
return Collections.singletonList( getTableExpression() );
}
@Override
public boolean containsAffectedTableName(String requestedName) {
return getTableExpression().equals( requestedName );
}
@Override
public Boolean visitAffectedTableNames(Function<String, Boolean> 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() + ')';
}
}

View File

@ -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<String> 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<String, Boolean> nameCollector) {
final Function<TableReference, Boolean> tableReferenceBooleanFunction =
tableReference -> tableReference.visitAffectedTableNames( nameCollector );
return queryPart.queryQuerySpecs(
querySpec -> querySpec.getFromClause().queryTableReferences( tableReferenceBooleanFunction )
);
}
}

View File

@ -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<String> 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 );
}
}

View File

@ -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<String> nameCollector) {
visitAffectedTableNames(
name -> {
nameCollector.accept( name );
return null;
}
);
}
default List<String> getAffectedTableNames() {
final List<String> affectedTableNames = new ArrayList<>();
visitAffectedTableNames(
name -> {
affectedTableNames.add( name );
return null;
}
);
return affectedTableNames;
}
default boolean containsAffectedTableName(String requestedName) {
return visitAffectedTableNames( requestedName::equals );
}
Boolean visitAffectedTableNames(Function<String, Boolean> 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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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(

View File

@ -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<Values> valuesList;
private final List<String> columnNames;
public ValuesTableReference(
List<Values> valuesList,
String identificationVariable,
List<String> 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<Values> getValuesList() {
return valuesList;
}
public List<String> 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<String, Boolean> nameCollector) {
return null;
}
}

View File

@ -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<ColumnReference> targetColumnReferences;
private QueryPart sourceSelectStatement;
private List<Values> valuesList = new ArrayList<>();
public InsertStatement(TableReference targetTable) {
public InsertStatement(NamedTableReference targetTable) {
super( targetTable );
}
public InsertStatement(TableReference targetTable, List<ColumnReference> returningColumns) {
public InsertStatement(NamedTableReference targetTable, List<ColumnReference> returningColumns) {
super( new LinkedHashMap<>(), targetTable, returningColumns );
}
public InsertStatement(boolean withRecursive, Map<String, CteStatement> cteStatements, TableReference targetTable, List<ColumnReference> returningColumns) {
public InsertStatement(boolean withRecursive, Map<String, CteStatement> cteStatements, NamedTableReference targetTable, List<ColumnReference> returningColumns) {
super( cteStatements, targetTable, returningColumns );
setWithRecursive( withRecursive );
}

View File

@ -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<QuerySpec> querySpecConsumer) {
public void visitQuerySpecs(Consumer<QuerySpec> querySpecConsumer) {
for ( int i = 0; i < queryParts.size(); i++ ) {
queryParts.get( i ).forEachQuerySpec( querySpecConsumer );
queryParts.get( i ).visitQuerySpecs( querySpecConsumer );
}
}
@Override
public <T> T queryQuerySpecs(Function<QuerySpec, T> 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;
}

View File

@ -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<QuerySpec> querySpecConsumer);
public abstract void visitQuerySpecs(Consumer<QuerySpec> querySpecConsumer);
public abstract <T> T queryQuerySpecs(Function<QuerySpec, T> querySpecConsumer);
/**
* Does this QueryPart map to the statement's root query (as

View File

@ -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<QuerySpec> querySpecConsumer) {
public void visitQuerySpecs(Consumer<QuerySpec> querySpecConsumer) {
querySpecConsumer.accept( this );
}
@Override
public <T> T queryQuerySpecs(Function<QuerySpec, T> querySpecConsumer) {
return querySpecConsumer.apply( this );
}
public FromClause getFromClause() {
return fromClause;
}

View File

@ -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<Assignment> assignments,
Predicate restriction) {
super( targetTable );
@ -36,7 +36,7 @@ public class UpdateStatement extends AbstractMutationStatement {
}
public UpdateStatement(
TableReference targetTable,
NamedTableReference targetTable,
List<Assignment> assignments,
Predicate restriction,
List<ColumnReference> returningColumns) {
@ -48,7 +48,7 @@ public class UpdateStatement extends AbstractMutationStatement {
public UpdateStatement(
boolean withRecursive,
Map<String, CteStatement> cteStatements,
TableReference targetTable,
NamedTableReference targetTable,
List<Assignment> assignments,
Predicate restriction,
List<ColumnReference> returningColumns) {
@ -67,11 +67,11 @@ public class UpdateStatement extends AbstractMutationStatement {
}
public static class UpdateStatementBuilder {
private final TableReference targetTableRef;
private final NamedTableReference targetTableRef;
private List<Assignment> assignments;
private Predicate restriction;
public UpdateStatementBuilder(TableReference targetTableRef) {
public UpdateStatementBuilder(NamedTableReference targetTableRef) {
this.targetTableRef = targetTableRef;
}

View File

@ -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 ) );

View File

@ -179,7 +179,7 @@ public class CollectionMapWithComponentValueTest extends BaseCoreFunctionalTestC
@TestForIssue(jiraKey = "HHH-10577")
public void testMapKeyExpressionDereferenceInSelect() {
doInHibernate( this::sessionFactory, s -> {
List<String> keyValueNames = s.createQuery( "select key(v).name as name from TestEntity te join te.values v order by name", String.class ).list();
List<String> 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 ) );

View File

@ -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;
}