Skip to content

Commit 38b7ede

Browse files
committed
HHH-19396 Parameter deduplicateSelectionItems must be set only for temporary tables and subqueries
Selection items representing same column in (sub)query will be represented with single instance, this will hide real alias
1 parent ce321da commit 38b7ede

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ private static CacheableSqmInterpretation buildCacheableSqmInterpretation(
491491
executionContext.getQueryParameterBindings(),
492492
executionContext.getSession().getLoadQueryInfluencers(),
493493
sessionFactory.getSqlTranslationEngine(),
494-
true
494+
sqm.getCteStatements().isEmpty()
495495
)
496496
.translate();
497497

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/cte/SqmCteTable.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ public class SqmCteTable<T> extends AnonymousTupleType<T> implements JpaCteCrite
3434
private SqmCteTable(
3535
String name,
3636
SqmCteStatement<T> cteStatement,
37-
SqmSelectableNode<?>[] sqmSelectableNodes) {
38-
super( sqmSelectableNodes );
37+
SqmSelectableNode<?>[] sqmSelectableNodes,
38+
List<String> aliases) {
39+
super( sqmSelectableNodes, aliases );
3940
this.name = name;
4041
this.cteStatement = cteStatement;
4142
final List<SqmCteTableColumn> columns = new ArrayList<>( componentCount() );
4243
for ( int i = 0; i < componentCount(); i++ ) {
43-
columns.add( new SqmCteTableColumn( this, getComponentName(i), get(i) ) );
44+
columns.add( new SqmCteTableColumn( this, aliases.get(i), get(i) ) );
4445
}
4546
this.columns = columns;
4647
}
@@ -54,7 +55,7 @@ public static <X> SqmCteTable<X> createStatementTable(
5455
.getSelectClause()
5556
.getSelectionItems()
5657
.toArray( SqmSelectableNode[]::new );
57-
return new SqmCteTable<>( name, cteStatement, sqmSelectableNodes );
58+
return new SqmCteTable<>( name, cteStatement, sqmSelectableNodes, extractAliases(selectStatement) );
5859
}
5960

6061
@Override

hibernate-core/src/main/java/org/hibernate/query/sqm/tuple/internal/AnonymousTupleType.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.hibernate.query.sqm.SqmPathSource;
2323
import org.hibernate.query.sqm.tree.domain.SqmDomainType;
2424
import org.hibernate.query.sqm.tree.domain.SqmPluralPersistentAttribute;
25+
import org.hibernate.query.sqm.tree.select.SqmSelectQuery;
2526
import org.hibernate.query.sqm.tuple.TupleType;
2627
import org.hibernate.query.SemanticException;
2728
import org.hibernate.query.sqm.SqmExpressible;
@@ -56,10 +57,10 @@ public class AnonymousTupleType<T>
5657
private final Map<String, Integer> componentIndexMap;
5758

5859
public AnonymousTupleType(SqmSubQuery<T> subQuery) {
59-
this( extractSqmExpressibles( subQuery ) );
60+
this( extractSqmExpressibles( subQuery ), extractAliases( subQuery ) );
6061
}
6162

62-
public AnonymousTupleType(SqmSelectableNode<?>[] components) {
63+
public AnonymousTupleType(SqmSelectableNode<?>[] components, List<String> aliases) {
6364
expressibles = new SqmBindableType<?>[components.length];
6465
componentSourcePaths = new NavigablePath[components.length];
6566
for ( int i = 0; i < components.length; i++ ) {
@@ -74,7 +75,10 @@ public AnonymousTupleType(SqmSelectableNode<?>[] components) {
7475
componentIndexMap = linkedMapOfSize( components.length );
7576
for ( int i = 0; i < components.length; i++ ) {
7677
final SqmSelectableNode<?> component = components[i];
77-
final String alias = component.getAlias();
78+
String alias = aliases == null ? null : aliases.get( i );
79+
if ( alias == null ) {
80+
alias = component.getAlias();
81+
}
7882
if ( alias == null ) {
7983
throw new SemanticException( "Select item at position " + (i+1) + " in select list has no alias"
8084
+ " (aliases are required in CTEs and in subqueries occurring in from clause)" );
@@ -121,6 +125,20 @@ private static SqmSelectableNode<?>[] extractSqmExpressibles(SqmSubQuery<?> subQ
121125
return selectClause.getSelectionItems().toArray( SqmSelectableNode[]::new );
122126
}
123127

128+
protected static List<String> extractAliases(SqmSelectQuery<?> subQuery) {
129+
final SqmSelectClause selectClause = subQuery.getQueryPart()
130+
.getFirstQuerySpec()
131+
.getSelectClause();
132+
final var aliases = new ArrayList<String>();
133+
for (final var selection : selectClause.getSelections()) {
134+
final var alias = selection.getAlias();
135+
selection.getSelectableNode().visitSubSelectableNodes( node ->
136+
aliases.add( alias == null ? node.getAlias() : alias )
137+
);
138+
}
139+
return aliases;
140+
}
141+
124142
private static JavaType<?>[] getTypeDescriptors(SqmSelectableNode<?>[] components) {
125143
final JavaType<?>[] typeDescriptors = new JavaType<?>[components.length];
126144
for ( int i = 0; i < components.length; i++ ) {

0 commit comments

Comments
 (0)