@@ -67,14 +67,15 @@ public void InitializeDerivedSelectClause(FromClause fromClause)
67
67
_derivedSelectExpressions = new HashSet < ISelectExpression > ( ) ;
68
68
foreach ( FromElement fromElement in fromElements )
69
69
{
70
- if ( fromElement . SelectType == null || fromElement . IsFetch || fromElement . IsCollectionOfValuesOrComponents )
70
+ IType type ;
71
+ if ( fromElement . IsFetch || fromElement . IsCollectionOfValuesOrComponents || ( ( type = fromElement . SelectType ) == null ) )
71
72
{
72
73
continue ;
73
74
}
74
75
75
76
var node = ( IdentNode ) appender . Append ( HqlSqlWalker . IDENT , fromElement . ClassAlias ?? "" , true ) ;
76
77
node . FromElement = fromElement ;
77
- node . DataType = fromElement . SelectType ;
78
+ node . DataType = type ;
78
79
_derivedSelectExpressions . Add ( node ) ;
79
80
}
80
81
@@ -112,69 +113,22 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
112
113
{
113
114
_constructorNode = ( ConstructorNode ) expr ;
114
115
_scalarSelect = true ;
115
- NonScalarExpressions ? . AddRange ( _constructorNode . GetSelectExpressions ( true , o => ! o . IsScalar ) ) ;
116
+ SelectExpressions . RemoveAt ( i ) ;
117
+ NonScalarExpressions . AddRange ( _constructorNode . GetSelectExpressions ( true , o => ! o . IsScalar ) ) ;
116
118
foreach ( var argumentExpression in _constructorNode . GetSelectExpressions ( ) )
117
119
{
118
120
SelectExpressions . Insert ( i , argumentExpression ) ;
119
121
i ++ ;
120
122
AddExpression ( argumentExpression , queryReturnTypeList ) ;
121
123
}
122
124
123
- SelectExpressions . Remove ( expr ) ;
124
- length = SelectExpressions . Count ;
125
125
i -- ;
126
+ length = SelectExpressions . Count ;
126
127
}
127
- else if ( expr . FromElement is JoinSubqueryFromElement joinSubquery )
128
+ else if ( expr . FromElement is JoinSubqueryFromElement joinSubquery &&
129
+ TryProcessSubqueryExpressions ( expr , joinSubquery , out var selectClause , out var subqueryExpressions ) )
128
130
{
129
- SelectClause selectClause ;
130
- List < ISelectExpression > subqueryExpressions ;
131
- if ( expr is IdentNode )
132
- {
133
- selectClause = joinSubquery . QueryNode . GetSelectClause ( ) ;
134
- subqueryExpressions = selectClause . SelectExpressions ;
135
- NonScalarExpressions . Add ( expr ) ;
136
- }
137
- else if ( expr is DotNode dotNode )
138
- {
139
- var relatedExpressions = joinSubquery . PropertyMapping . GetRelatedSelectExpressions ( dotNode . PropertyPath , out selectClause ) ;
140
- if ( relatedExpressions == null )
141
- {
142
- if ( ! expr . IsScalar )
143
- {
144
- NonScalarExpressions . Add ( expr ) ;
145
- }
146
-
147
- AddExpression ( expr , queryReturnTypeList ) ;
148
- continue ;
149
- }
150
-
151
- if ( ! selectClause . IsScalarSelect )
152
- {
153
- RemoveChildAndUnsetParent ( ( IASTNode ) expr ) ;
154
- }
155
-
156
- subqueryExpressions = new List < ISelectExpression > ( ) ;
157
- foreach ( var relatedExpression in relatedExpressions )
158
- {
159
- if ( ! relatedExpression . IsScalar )
160
- {
161
- NonScalarExpressions . Add ( relatedExpression ) ;
162
- }
163
-
164
- subqueryExpressions . Add ( relatedExpression ) ;
165
- }
166
- }
167
- else
168
- {
169
- if ( ! expr . IsScalar )
170
- {
171
- NonScalarExpressions ? . Add ( expr ) ;
172
- }
173
-
174
- AddExpression ( expr , queryReturnTypeList ) ;
175
- continue ;
176
- }
177
-
131
+ SelectExpressions . RemoveAt ( i ) ;
178
132
var indexes = new List < int > ( subqueryExpressions . Count ) ;
179
133
foreach ( var expression in subqueryExpressions )
180
134
{
@@ -185,16 +139,15 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
185
139
AddExpression ( expression , queryReturnTypeList ) ;
186
140
}
187
141
188
- _replacedExpressions . Add ( expr , indexes ) ;
189
- SelectExpressions . Remove ( expr ) ;
190
- length = SelectExpressions . Count ;
191
142
i -- ;
143
+ length = SelectExpressions . Count ;
144
+ _replacedExpressions . Add ( expr , indexes ) ;
192
145
}
193
146
else
194
147
{
195
148
if ( ! expr . IsScalar )
196
149
{
197
- NonScalarExpressions ? . Add ( expr ) ;
150
+ NonScalarExpressions . Add ( expr ) ;
198
151
}
199
152
200
153
AddExpression ( expr , queryReturnTypeList ) ;
@@ -214,6 +167,49 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
214
167
FinishInitialization ( ) ;
215
168
}
216
169
170
+ private bool TryProcessSubqueryExpressions (
171
+ ISelectExpression selectExpression ,
172
+ JoinSubqueryFromElement joinSubquery ,
173
+ out SelectClause selectClause ,
174
+ out List < ISelectExpression > subqueryExpressions )
175
+ {
176
+ if ( selectExpression is IdentNode )
177
+ {
178
+ selectClause = joinSubquery . QueryNode . GetSelectClause ( ) ;
179
+ subqueryExpressions = selectClause . SelectExpressions ;
180
+ NonScalarExpressions . Add ( selectExpression ) ;
181
+ }
182
+ else if ( selectExpression is DotNode dotNode )
183
+ {
184
+ subqueryExpressions = joinSubquery . GetRelatedSelectExpressions ( dotNode , out selectClause ) ;
185
+ if ( subqueryExpressions == null )
186
+ {
187
+ return false ;
188
+ }
189
+
190
+ if ( ! selectClause . IsScalarSelect )
191
+ {
192
+ RemoveChildAndUnsetParent ( ( IASTNode ) selectExpression ) ;
193
+ }
194
+
195
+ foreach ( var expression in subqueryExpressions )
196
+ {
197
+ if ( ! expression . IsScalar )
198
+ {
199
+ NonScalarExpressions . Add ( expression ) ;
200
+ }
201
+ }
202
+ }
203
+ else
204
+ {
205
+ selectClause = null ;
206
+ subqueryExpressions = null ;
207
+ return false ;
208
+ }
209
+
210
+ return true ;
211
+ }
212
+
217
213
private void Render (
218
214
FromClause fromClause ,
219
215
Dictionary < ISelectExpression , SelectClause > inheritedExpressions )
@@ -454,6 +450,46 @@ private void RenderNonScalarSelects(
454
450
var appender = new ASTAppender ( ASTFactory , this ) ;
455
451
var combinedFromElements = new List < FromElement > ( ) ;
456
452
var processedElements = new HashSet < FromElement > ( ) ;
453
+ RenderNonScalarIdentifiers ( appender , processedElements , combinedFromElements , inheritedExpressions ) ;
454
+ if ( Walker . IsShallowQuery )
455
+ {
456
+ return ;
457
+ }
458
+
459
+ // Append fetched elements
460
+ RenderFetchedNonScalarIdentifiers ( appender , fetchedFromElements , processedElements , combinedFromElements ) ;
461
+ if ( currentFromClause . IsScalarSubQuery )
462
+ {
463
+ return ;
464
+ }
465
+
466
+ // Generate the property select tokens.
467
+ foreach ( var fromElement in combinedFromElements )
468
+ {
469
+ RenderNonScalarProperties ( appender , fromElement ) ;
470
+ }
471
+
472
+ // Generate properties for fetched collections of components or values
473
+ var fromElements = currentFromClause . GetAllProjectionListTyped ( ) ;
474
+ foreach ( var fromElement in fromElements )
475
+ {
476
+ if ( fromElement . IsCollectionOfValuesOrComponents &&
477
+ fromElement . IsFetch &&
478
+ processedElements . Add ( fromElement ) )
479
+ {
480
+ var suffix = Walker . GetSuffix ( fromElement ) ;
481
+ var fragment = fromElement . GetValueCollectionSelectFragment ( suffix ) ;
482
+ Append ( appender , HqlSqlWalker . SQL_TOKEN , fragment ) ;
483
+ }
484
+ }
485
+ }
486
+
487
+ private void RenderNonScalarIdentifiers (
488
+ ASTAppender appender ,
489
+ HashSet < FromElement > processedElements ,
490
+ List < FromElement > combinedFromElements ,
491
+ Dictionary < ISelectExpression , SelectClause > inheritedExpressions )
492
+ {
457
493
foreach ( var e in NonScalarExpressions )
458
494
{
459
495
var fromElement = e . FromElement ;
@@ -473,13 +509,14 @@ private void RenderNonScalarSelects(
473
509
RemoveChildAndUnsetParent ( node ) ;
474
510
}
475
511
}
512
+ }
476
513
477
- if ( Walker . IsShallowQuery )
478
- {
479
- return ;
480
- }
481
-
482
- // Append fetched elements
514
+ private void RenderFetchedNonScalarIdentifiers (
515
+ ASTAppender appender ,
516
+ IList < FromElement > fetchedFromElements ,
517
+ HashSet < FromElement > processedElements ,
518
+ List < FromElement > combinedFromElements )
519
+ {
483
520
foreach ( var fetchedFromElement in fetchedFromElements )
484
521
{
485
522
if ( ! processedElements . Add ( fetchedFromElement ) )
@@ -493,39 +530,14 @@ private void RenderNonScalarSelects(
493
530
if ( fragment == null )
494
531
{
495
532
// When a subquery join has a scalar select only
496
- continue ;
533
+ continue ;
497
534
}
498
535
499
536
var generatedExpr = ( SelectExpressionImpl ) Append ( appender , HqlSqlWalker . SELECT_EXPR , fragment ) ;
500
537
generatedExpr . FromElement = fetchedFromElement ;
501
538
generatedExpr . DataType = fetchedFromElement . DataType ;
502
539
NonScalarExpressions . Add ( generatedExpr ) ;
503
540
}
504
-
505
- if ( currentFromClause . IsScalarSubQuery )
506
- {
507
- return ;
508
- }
509
-
510
- // Generate the property select tokens.
511
- foreach ( var fromElement in combinedFromElements )
512
- {
513
- RenderNonScalarProperties ( appender , fromElement ) ;
514
- }
515
-
516
- // Generate properties for fetched collections of components or values
517
- var fromElements = currentFromClause . GetAllProjectionListTyped ( ) ;
518
- foreach ( var fromElement in fromElements )
519
- {
520
- if ( fromElement . IsCollectionOfValuesOrComponents &&
521
- fromElement . IsFetch &&
522
- processedElements . Add ( fromElement ) )
523
- {
524
- var suffix = Walker . GetSuffix ( fromElement ) ;
525
- var fragment = fromElement . GetValueCollectionSelectFragment ( suffix ) ;
526
- Append ( appender , HqlSqlWalker . SQL_TOKEN , fragment ) ;
527
- }
528
- }
529
541
}
530
542
531
543
private IASTNode Append ( ASTAppender appender , int type , SelectFragment fragment )
0 commit comments