@@ -57,26 +57,49 @@ public class AnonymousTupleType<T>
57
57
private final Map <String , Integer > componentIndexMap ;
58
58
59
59
public AnonymousTupleType (SqmSelectQuery <T > selectQuery ) {
60
- final SqmSelectableNode <?>[] components = extractSqmExpressibles ( selectQuery );
61
- expressibles = new SqmBindableType <?>[components .length ];
62
- componentSourcePaths = new NavigablePath [components .length ];
63
- for ( int i = 0 ; i < components .length ; i ++ ) {
64
- expressibles [i ] = components [i ].getNodeType ();
65
- if ( components [i ] instanceof SqmPath <?> path ) {
66
- componentSourcePaths [i ] = path .getNavigablePath ();
60
+ final SqmSelectClause selectClause = selectQuery .getQueryPart ()
61
+ .getFirstQuerySpec ()
62
+ .getSelectClause ();
63
+
64
+ if ( selectClause == null || selectClause .getSelections ().isEmpty () ) {
65
+ throw new IllegalArgumentException ( "selectQuery has no selection items" );
66
+ }
67
+ // todo: right now, we "snapshot" the state of the selectQuery when creating this type, but maybe we shouldn't?
68
+ // i.e. what if the selectQuery changes later on? Or should we somehow mark the selectQuery to signal,
69
+ // that changes to the select clause are invalid after a certain point?
70
+
71
+ final List <SqmSelection <?>> selections = selectClause .getSelections ();
72
+ final List <SqmSelectableNode <?>> selectableNodes = new ArrayList <>();
73
+ final List <String > aliases = new ArrayList <>();
74
+ if ( selections != null ) {
75
+ for ( SqmSelection <?> selection : selections ) {
76
+ selection .getSelectableNode ().visitSubSelectableNodes ( selectableNodes ::add );
77
+
78
+ if ( selection .getSelectableNode ().isCompoundSelection () ) {
79
+ selection .getSelectableNode ().visitSubSelectableNodes ( node ->
80
+ aliases .add ( node .getAlias () )
81
+ );
82
+ }
83
+ else {
84
+ aliases .add ( selection .getAlias () );
85
+ }
67
86
}
68
87
}
88
+
89
+ final SqmSelectableNode <?>[] components = selectableNodes .toArray (new SqmSelectableNode [0 ]);
90
+
91
+ expressibles = new SqmBindableType <?>[components .length ];
92
+ componentSourcePaths = new NavigablePath [components .length ];
69
93
componentNames = new String [components .length ];
70
94
//noinspection unchecked
71
95
javaTypeDescriptor = (JavaType <T >) new ObjectArrayJavaType ( getTypeDescriptors ( components ) );
72
96
componentIndexMap = linkedMapOfSize ( components .length );
73
- final String [] aliases = extractAliases ( selectQuery );
74
97
for ( int i = 0 ; i < components .length ; i ++ ) {
75
- final SqmSelectableNode <?> component = components [i ];
76
- String alias = aliases [i ];
77
- if ( alias == null ) {
78
- alias = component .getAlias ();
98
+ expressibles [i ] = components [i ].getNodeType ();
99
+ if ( components [i ] instanceof SqmPath <?> path ) {
100
+ componentSourcePaths [i ] = path .getNavigablePath ();
79
101
}
102
+ String alias = aliases .get ( i );
80
103
if ( alias == null ) {
81
104
throw new SemanticException ( "Select item at position " + (i +1 ) + " in select list has no alias"
82
105
+ " (aliases are required in CTEs and in subqueries occurring in from clause)" );
@@ -112,33 +135,6 @@ public String getTypeName() {
112
135
return SqmDomainType .super .getTypeName ();
113
136
}
114
137
115
- private static SqmSelectableNode <?>[] extractSqmExpressibles (SqmSelectQuery <?> selectQuery ) {
116
- final SqmSelectClause selectClause = selectQuery .getQueryPart ()
117
- .getFirstQuerySpec ()
118
- .getSelectClause ();
119
- if ( selectClause == null || selectClause .getSelectionItems ().isEmpty () ) {
120
- throw new IllegalArgumentException ( "selectQuery has no selection items" );
121
- }
122
- // todo: right now, we "snapshot" the state of the selectQuery when creating this type, but maybe we shouldn't?
123
- // i.e. what if the selectQuery changes later on? Or should we somehow mark the selectQuery to signal,
124
- // that changes to the select clause are invalid after a certain point?
125
- return selectClause .getSelectionItems ().toArray ( SqmSelectableNode []::new );
126
- }
127
-
128
- private static String [] extractAliases (SqmSelectQuery <?> selectQuery ) {
129
- final SqmSelectClause selectClause = selectQuery .getQueryPart ()
130
- .getFirstQuerySpec ()
131
- .getSelectClause ();
132
- final List <String > aliases = new ArrayList <>();
133
- for (final SqmSelection <?> selection : selectClause .getSelections ()) {
134
- final String alias = selection .getAlias ();
135
- selection .getSelectableNode ().visitSubSelectableNodes ( node ->
136
- aliases .add ( alias == null ? node .getAlias () : alias )
137
- );
138
- }
139
- return aliases .toArray (String []::new );
140
- }
141
-
142
138
private static JavaType <?>[] getTypeDescriptors (SqmSelectableNode <?>[] components ) {
143
139
final JavaType <?>[] typeDescriptors = new JavaType <?>[components .length ];
144
140
for ( int i = 0 ; i < components .length ; i ++ ) {
0 commit comments