22
22
import org .hibernate .query .sqm .SqmPathSource ;
23
23
import org .hibernate .query .sqm .tree .domain .SqmDomainType ;
24
24
import org .hibernate .query .sqm .tree .domain .SqmPluralPersistentAttribute ;
25
+ import org .hibernate .query .sqm .tree .select .SqmSelectQuery ;
25
26
import org .hibernate .query .sqm .tuple .TupleType ;
26
27
import org .hibernate .query .SemanticException ;
27
28
import org .hibernate .query .sqm .SqmExpressible ;
@@ -56,10 +57,10 @@ public class AnonymousTupleType<T>
56
57
private final Map <String , Integer > componentIndexMap ;
57
58
58
59
public AnonymousTupleType (SqmSubQuery <T > subQuery ) {
59
- this ( extractSqmExpressibles ( subQuery ) );
60
+ this ( extractSqmExpressibles ( subQuery ), extractAliases ( subQuery ) );
60
61
}
61
62
62
- public AnonymousTupleType (SqmSelectableNode <?>[] components ) {
63
+ public AnonymousTupleType (SqmSelectableNode <?>[] components , List < String > aliases ) {
63
64
expressibles = new SqmBindableType <?>[components .length ];
64
65
componentSourcePaths = new NavigablePath [components .length ];
65
66
for ( int i = 0 ; i < components .length ; i ++ ) {
@@ -74,7 +75,10 @@ public AnonymousTupleType(SqmSelectableNode<?>[] components) {
74
75
componentIndexMap = linkedMapOfSize ( components .length );
75
76
for ( int i = 0 ; i < components .length ; i ++ ) {
76
77
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
+ }
78
82
if ( alias == null ) {
79
83
throw new SemanticException ( "Select item at position " + (i +1 ) + " in select list has no alias"
80
84
+ " (aliases are required in CTEs and in subqueries occurring in from clause)" );
@@ -121,6 +125,20 @@ private static SqmSelectableNode<?>[] extractSqmExpressibles(SqmSubQuery<?> subQ
121
125
return selectClause .getSelectionItems ().toArray ( SqmSelectableNode []::new );
122
126
}
123
127
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
+
124
142
private static JavaType <?>[] getTypeDescriptors (SqmSelectableNode <?>[] components ) {
125
143
final JavaType <?>[] typeDescriptors = new JavaType <?>[components .length ];
126
144
for ( int i = 0 ; i < components .length ; i ++ ) {
0 commit comments