@@ -103,9 +103,7 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
103
103
var inheritedExpressions = new Dictionary < ISelectExpression , SelectClause > ( ) ;
104
104
SelectExpressions = GetSelectExpressions ( ) ;
105
105
OriginalSelectExpressions = SelectExpressions . ToList ( ) ;
106
- NonScalarExpressions = ! Walker . IsShallowQuery
107
- ? new List < ISelectExpression > ( )
108
- : null ;
106
+ NonScalarExpressions = new List < ISelectExpression > ( ) ;
109
107
var length = SelectExpressions . Count ;
110
108
for ( var i = 0 ; i < length ; i ++ )
111
109
{
@@ -152,7 +150,7 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
152
150
153
151
if ( ! selectClause . IsScalarSelect )
154
152
{
155
- RemoveChild ( ( IASTNode ) expr ) ;
153
+ RemoveChildAndUnsetParent ( ( IASTNode ) expr ) ;
156
154
}
157
155
158
156
subqueryExpressions = new List < ISelectExpression > ( ) ;
@@ -180,7 +178,7 @@ public void InitializeExplicitSelectClause(FromClause fromClause)
180
178
var indexes = new List < int > ( subqueryExpressions . Count ) ;
181
179
foreach ( var expression in subqueryExpressions )
182
180
{
183
- inheritedExpressions . Add ( expression , selectClause ) ;
181
+ inheritedExpressions [ expression ] = selectClause ;
184
182
indexes . Add ( i ) ;
185
183
SelectExpressions . Insert ( i , expression ) ;
186
184
i ++ ;
@@ -227,16 +225,21 @@ private void Render(
227
225
InitializeScalarColumnNames ( ) ;
228
226
}
229
227
228
+ // generate id select fragment and then property select fragment for
229
+ // each expression, just like generateSelectFragments().
230
+ RenderNonScalarSelects ( fromClause , inheritedExpressions , GetFetchedFromElements ( fromClause ) ) ;
231
+ }
232
+
233
+ private List < FromElement > GetFetchedFromElements ( FromClause fromClause )
234
+ {
235
+ var fetchedFromElements = new List < FromElement > ( ) ;
230
236
if ( Walker . IsShallowQuery )
231
237
{
232
- RenderDerivedNonScalarIdentifiers ( fromClause ) ;
233
- return ;
238
+ return fetchedFromElements ;
234
239
}
235
240
236
- var fetchedFromElements = new List < FromElement > ( ) ;
237
241
// add the fetched entities
238
- var fromElements = fromClause . GetAllProjectionListTyped ( ) ;
239
- foreach ( FromElement fromElement in fromElements )
242
+ foreach ( FromElement fromElement in fromClause . GetAllProjectionListTyped ( ) )
240
243
{
241
244
if ( ! fromElement . IsFetch )
242
245
{
@@ -278,9 +281,7 @@ private void Render(
278
281
}
279
282
}
280
283
281
- // generate id select fragment and then property select fragment for
282
- // each expression, just like generateSelectFragments().
283
- RenderNonScalarSelects ( fromClause , inheritedExpressions , fetchedFromElements ) ;
284
+ return fetchedFromElements ;
284
285
}
285
286
286
287
private void AddExpression ( ISelectExpression expr , List < IType > queryReturnTypeList )
@@ -452,19 +453,40 @@ private void RenderNonScalarSelects(
452
453
{
453
454
var appender = new ASTAppender ( ASTFactory , this ) ;
454
455
var combinedFromElements = new List < FromElement > ( ) ;
456
+ var processedElements = new HashSet < FromElement > ( ) ;
455
457
foreach ( var e in NonScalarExpressions )
456
458
{
457
459
var fromElement = e . FromElement ;
458
- if ( fromElement != null )
460
+ if ( fromElement == null )
461
+ {
462
+ continue ;
463
+ }
464
+
465
+ var node = ( IASTNode ) e ;
466
+ if ( processedElements . Add ( fromElement ) )
459
467
{
460
468
combinedFromElements . Add ( fromElement ) ;
461
469
RenderNonScalarIdentifiers ( fromElement , inheritedExpressions . ContainsKey ( e ) ? null : e , appender ) ;
462
470
}
471
+ else if ( ! inheritedExpressions . ContainsKey ( e ) && node . Parent != null )
472
+ {
473
+ RemoveChildAndUnsetParent ( node ) ;
474
+ }
475
+ }
476
+
477
+ if ( Walker . IsShallowQuery )
478
+ {
479
+ return ;
463
480
}
464
481
465
482
// Append fetched elements
466
483
foreach ( var fetchedFromElement in fetchedFromElements )
467
484
{
485
+ if ( ! processedElements . Add ( fetchedFromElement ) )
486
+ {
487
+ continue ;
488
+ }
489
+
468
490
fetchedFromElement . EntitySuffix = Walker . GetEntitySuffix ( fetchedFromElement ) ;
469
491
combinedFromElements . Add ( fetchedFromElement ) ;
470
492
var fragment = fetchedFromElement . GetIdentifierSelectFragment ( fetchedFromElement . EntitySuffix ) ;
@@ -495,7 +517,9 @@ private void RenderNonScalarSelects(
495
517
var fromElements = currentFromClause . GetAllProjectionListTyped ( ) ;
496
518
foreach ( var fromElement in fromElements )
497
519
{
498
- if ( fromElement . IsCollectionOfValuesOrComponents && fromElement . IsFetch )
520
+ if ( fromElement . IsCollectionOfValuesOrComponents &&
521
+ fromElement . IsFetch &&
522
+ processedElements . Add ( fromElement ) )
499
523
{
500
524
var suffix = Walker . GetSuffix ( fromElement ) ;
501
525
var fragment = fromElement . GetValueCollectionSelectFragment ( suffix ) ;
@@ -514,25 +538,16 @@ private IASTNode Append(ASTAppender appender, int type, SelectFragment fragment)
514
538
return appender . Append ( type , fragment . ToSqlStringFragment ( false ) , false ) ;
515
539
}
516
540
517
- private void RenderDerivedNonScalarIdentifiers ( FromClause fromClause )
541
+ private void RenderNonScalarIdentifiers ( FromElement fromElement , ISelectExpression expr , ASTAppender appender )
518
542
{
519
- // Render only when scalar columns are not rendered
520
- if ( _derivedSelectExpressions == null || ! fromClause . IsScalarSubQuery )
543
+ if ( fromElement . FromClause . IsScalarSubQuery && _derivedSelectExpressions ? . Contains ( expr ) != true )
521
544
{
522
545
return ;
523
546
}
524
547
525
- var appender = new ASTAppender ( ASTFactory , this ) ;
526
- foreach ( var derivedSelectExpression in _derivedSelectExpressions )
527
- {
528
- RenderNonScalarIdentifiers ( derivedSelectExpression . FromElement , derivedSelectExpression , appender ) ;
529
- }
530
- }
531
-
532
- private void RenderNonScalarIdentifiers ( FromElement fromElement , ISelectExpression expr , ASTAppender appender )
533
- {
534
- if ( fromElement . FromClause . IsScalarSubQuery && _derivedSelectExpressions ? . Contains ( expr ) != true )
548
+ if ( Walker . IsShallowQuery && ! fromElement . FromClause . IsScalarSubQuery && SelectExpressions . Contains ( expr ) )
535
549
{
550
+ // A scalar column was generated
536
551
return ;
537
552
}
538
553
@@ -541,8 +556,7 @@ private void RenderNonScalarIdentifiers(FromElement fromElement, ISelectExpressi
541
556
if ( fragment == null )
542
557
{
543
558
// When a subquery join has a scalar select only
544
- var node = ( IASTNode ) expr ;
545
- node ? . Parent . RemoveChild ( node ) ;
559
+ RemoveChildAndUnsetParent ( ( IASTNode ) expr ) ;
546
560
return ;
547
561
}
548
562
@@ -706,5 +720,14 @@ public int GetColumnNamesStartPosition(int i)
706
720
{
707
721
return _columnNamesStartPositions [ i ] ;
708
722
}
723
+
724
+ private static void RemoveChildAndUnsetParent ( IASTNode node )
725
+ {
726
+ if ( node ? . Parent != null )
727
+ {
728
+ node . Parent . RemoveChild ( node ) ;
729
+ node . Parent = null ;
730
+ }
731
+ }
709
732
}
710
733
}
0 commit comments