Skip to content

Commit 5126bf6

Browse files
committed
HHH-19396 Parameter deduplicateSelectionItems must be set to false in SqlAstQueryPartProcessingStateImpl
Selection items representing same column in (sub)query will be represented with single instance, this will hide real alias
1 parent 2ad9a6a commit 5126bf6

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,11 @@ public QuerySpec visitQuerySpec(SqmQuerySpec<?> sqmQuerySpec) {
19151915
final boolean oldInNestedContext = inNestedContext;
19161916
inNestedContext = false;
19171917

1918+
final boolean originalDeduplicateSelectionItems = deduplicateSelectionItems;
1919+
sqmQueryPartStack.push( sqmQuerySpec );
1920+
// In sub-queries, we can never deduplicate the selection items as that might change semantics
1921+
deduplicateSelectionItems = false;
1922+
19181923
final SqlAstQueryPartProcessingStateImpl processingState;
19191924
if ( trackAliasedNodePositions( sqmQuerySpec ) ) {
19201925
processingState = new SqlAstQueryPartProcessingStateImpl(
@@ -1936,10 +1941,6 @@ public QuerySpec visitQuerySpec(SqmQuerySpec<?> sqmQuerySpec) {
19361941
);
19371942
}
19381943

1939-
final boolean originalDeduplicateSelectionItems = deduplicateSelectionItems;
1940-
sqmQueryPartStack.push( sqmQuerySpec );
1941-
// In sub-queries, we can never deduplicate the selection items as that might change semantics
1942-
deduplicateSelectionItems = false;
19431944
pushProcessingState( processingState );
19441945
queryTransformers.push( new ArrayList<>() );
19451946

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.hibernate.query.criteria.JpaCteCriteriaAttribute;
1313
import org.hibernate.query.criteria.JpaCteCriteriaType;
1414
import org.hibernate.query.sqm.SqmBindableType;
15+
import org.hibernate.query.sqm.tree.select.SqmSelectClause;
1516
import org.hibernate.query.sqm.tuple.internal.AnonymousTupleSimpleSqmPathSource;
1617
import org.hibernate.query.sqm.tuple.internal.AnonymousTupleType;
1718
import org.hibernate.query.sqm.tuple.internal.CteTupleTableGroupProducer;
@@ -34,13 +35,14 @@ public class SqmCteTable<T> extends AnonymousTupleType<T> implements JpaCteCrite
3435
private SqmCteTable(
3536
String name,
3637
SqmCteStatement<T> cteStatement,
37-
SqmSelectableNode<?>[] sqmSelectableNodes) {
38-
super( sqmSelectableNodes );
38+
SqmSelectableNode<?>[] sqmSelectableNodes,
39+
List<String> aliases) {
40+
super( sqmSelectableNodes, aliases );
3941
this.name = name;
4042
this.cteStatement = cteStatement;
4143
final List<SqmCteTableColumn> columns = new ArrayList<>( componentCount() );
4244
for ( int i = 0; i < componentCount(); i++ ) {
43-
columns.add( new SqmCteTableColumn( this, getComponentName(i), get(i) ) );
45+
columns.add( new SqmCteTableColumn( this, aliases.get(i), get(i) ) );
4446
}
4547
this.columns = columns;
4648
}
@@ -49,12 +51,20 @@ public static <X> SqmCteTable<X> createStatementTable(
4951
String name,
5052
SqmCteStatement<X> cteStatement,
5153
SqmSelectQuery<X> selectStatement) {
52-
final SqmSelectableNode<?>[] sqmSelectableNodes = selectStatement.getQueryPart()
54+
final SqmSelectClause selectClause = selectStatement.getQueryPart()
5355
.getFirstQuerySpec()
54-
.getSelectClause()
56+
.getSelectClause();
57+
final SqmSelectableNode<?>[] sqmSelectableNodes = selectClause
5558
.getSelectionItems()
5659
.toArray( SqmSelectableNode[]::new );
57-
return new SqmCteTable<>( name, cteStatement, sqmSelectableNodes );
60+
final var aliases = new ArrayList<String>();
61+
for (final var selection : selectClause.getSelections()) {
62+
final var alias = selection.getAlias();
63+
selection.getSelectableNode().visitSubSelectableNodes( node ->
64+
aliases.add( alias == null ? node.getAlias() : alias )
65+
);
66+
}
67+
return new SqmCteTable<>( name, cteStatement, sqmSelectableNodes, aliases );
5868
}
5969

6070
@Override

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ public AnonymousTupleType(SqmSubQuery<T> subQuery) {
6060
}
6161

6262
public AnonymousTupleType(SqmSelectableNode<?>[] components) {
63+
this(components, null);
64+
}
65+
66+
public AnonymousTupleType(SqmSelectableNode<?>[] components, List<String> aliases) {
6367
expressibles = new SqmBindableType<?>[components.length];
6468
componentSourcePaths = new NavigablePath[components.length];
6569
for ( int i = 0; i < components.length; i++ ) {
@@ -74,7 +78,10 @@ public AnonymousTupleType(SqmSelectableNode<?>[] components) {
7478
componentIndexMap = linkedMapOfSize( components.length );
7579
for ( int i = 0; i < components.length; i++ ) {
7680
final SqmSelectableNode<?> component = components[i];
77-
final String alias = component.getAlias();
81+
String alias = aliases == null ? null : aliases.get( i );
82+
if ( alias == null ) {
83+
alias = component.getAlias();
84+
}
7885
if ( alias == null ) {
7986
throw new SemanticException( "Select item at position " + (i+1) + " in select list has no alias"
8087
+ " (aliases are required in CTEs and in subqueries occurring in from clause)" );

0 commit comments

Comments
 (0)