@@ -67,14 +67,15 @@ public void InitializeDerivedSelectClause(FromClause fromClause)
6767 _derivedSelectExpressions = new HashSet < ISelectExpression > ( ) ;
6868 foreach ( FromElement fromElement in fromElements )
6969 {
70- if ( fromElement . SelectType == null || fromElement . IsFetch || fromElement . IsCollectionOfValuesOrComponents )
70+ IType type ;
71+ if ( fromElement . IsFetch || fromElement . IsCollectionOfValuesOrComponents || ( ( type = fromElement . SelectType ) == null ) )
7172 {
7273 continue ;
7374 }
7475
7576 var node = ( IdentNode ) appender . Append ( HqlSqlWalker . IDENT , fromElement . ClassAlias ?? "" , true ) ;
7677 node . FromElement = fromElement ;
77- node . DataType = fromElement . SelectType ;
78+ node . DataType = type ;
7879 _derivedSelectExpressions . Add ( node ) ;
7980 }
8081
@@ -112,69 +113,22 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
112113 {
113114 _constructorNode = ( ConstructorNode ) expr ;
114115 _scalarSelect = true ;
115- NonScalarExpressions ? . AddRange ( _constructorNode . GetSelectExpressions ( true , o => ! o . IsScalar ) ) ;
116+ SelectExpressions . RemoveAt ( i ) ;
117+ NonScalarExpressions . AddRange ( _constructorNode . GetSelectExpressions ( true , o => ! o . IsScalar ) ) ;
116118 foreach ( var argumentExpression in _constructorNode . GetSelectExpressions ( ) )
117119 {
118120 SelectExpressions . Insert ( i , argumentExpression ) ;
119121 i ++ ;
120122 AddExpression ( argumentExpression , queryReturnTypeList ) ;
121123 }
122124
123- SelectExpressions . Remove ( expr ) ;
124- length = SelectExpressions . Count ;
125125 i -- ;
126+ length = SelectExpressions . Count ;
126127 }
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 ) )
128130 {
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 ) ;
178132 var indexes = new List < int > ( subqueryExpressions . Count ) ;
179133 foreach ( var expression in subqueryExpressions )
180134 {
@@ -185,16 +139,15 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
185139 AddExpression ( expression , queryReturnTypeList ) ;
186140 }
187141
188- _replacedExpressions . Add ( expr , indexes ) ;
189- SelectExpressions . Remove ( expr ) ;
190- length = SelectExpressions . Count ;
191142 i -- ;
143+ length = SelectExpressions . Count ;
144+ _replacedExpressions . Add ( expr , indexes ) ;
192145 }
193146 else
194147 {
195148 if ( ! expr . IsScalar )
196149 {
197- NonScalarExpressions ? . Add ( expr ) ;
150+ NonScalarExpressions . Add ( expr ) ;
198151 }
199152
200153 AddExpression ( expr , queryReturnTypeList ) ;
@@ -214,6 +167,49 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
214167 FinishInitialization ( ) ;
215168 }
216169
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+
217213 private void Render (
218214 FromClause fromClause ,
219215 Dictionary < ISelectExpression , SelectClause > inheritedExpressions )
@@ -454,6 +450,46 @@ private void RenderNonScalarSelects(
454450 var appender = new ASTAppender ( ASTFactory , this ) ;
455451 var combinedFromElements = new List < FromElement > ( ) ;
456452 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+ {
457493 foreach ( var e in NonScalarExpressions )
458494 {
459495 var fromElement = e . FromElement ;
@@ -473,13 +509,14 @@ private void RenderNonScalarSelects(
473509 RemoveChildAndUnsetParent ( node ) ;
474510 }
475511 }
512+ }
476513
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+ {
483520 foreach ( var fetchedFromElement in fetchedFromElements )
484521 {
485522 if ( ! processedElements . Add ( fetchedFromElement ) )
@@ -493,39 +530,14 @@ private void RenderNonScalarSelects(
493530 if ( fragment == null )
494531 {
495532 // When a subquery join has a scalar select only
496- continue ;
533+ continue ;
497534 }
498535
499536 var generatedExpr = ( SelectExpressionImpl ) Append ( appender , HqlSqlWalker . SELECT_EXPR , fragment ) ;
500537 generatedExpr . FromElement = fetchedFromElement ;
501538 generatedExpr . DataType = fetchedFromElement . DataType ;
502539 NonScalarExpressions . Add ( generatedExpr ) ;
503540 }
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- }
529541 }
530542
531543 private IASTNode Append ( ASTAppender appender , int type , SelectFragment fragment )
0 commit comments