1
+ using System ;
1
2
using System . Collections . Generic ;
2
3
using System . Diagnostics . CodeAnalysis ;
3
4
using System . Linq ;
@@ -55,15 +56,26 @@ public virtual Expression Process(Expression expression)
55
56
switch ( expression )
56
57
{
57
58
case ShapedQueryExpression shapedQueryExpression :
58
- return shapedQueryExpression . UpdateQueryExpression ( Visit ( shapedQueryExpression . QueryExpression ) ) ;
59
+ shapedQueryExpression = shapedQueryExpression . UpdateQueryExpression ( Visit ( shapedQueryExpression . QueryExpression ) ) ;
60
+ shapedQueryExpression = shapedQueryExpression . UpdateShaperExpression ( Visit ( shapedQueryExpression . ShaperExpression ) ) ;
61
+ return shapedQueryExpression ;
62
+ case RelationalSplitCollectionShaperExpression relationalSplitCollectionShaperExpression :
63
+ var newSelect = Visit ( relationalSplitCollectionShaperExpression . SelectExpression ) ;
64
+ var newInner = Visit ( relationalSplitCollectionShaperExpression . InnerShaper ) ;
65
+ relationalSplitCollectionShaperExpression = relationalSplitCollectionShaperExpression . Update (
66
+ relationalSplitCollectionShaperExpression . ParentIdentifier ,
67
+ relationalSplitCollectionShaperExpression . ChildIdentifier , ( SelectExpression ) newSelect , newInner ) ;
68
+ return relationalSplitCollectionShaperExpression ;
69
+ case NonQueryExpression nonQueryExpression :
70
+ return nonQueryExpression ;
59
71
case SelectExpression selectExpression :
60
72
{
61
73
Dictionary < int , ( int ? indexcol , OrderingExpression ? orderexp , bool ascend , bool rewrite , bool referstocurouter ) > columnsToRewrite = new ( ) ;
62
74
bool isscalarselect = selectExpression is { Limit : SqlConstantExpression { Value : 1 } , Projection . Count : 1 } ;
63
75
for ( int i = 0 ; i < selectExpression . Orderings . Count ; i ++ )
64
76
{
65
77
var sqlExpression = selectExpression . Orderings [ i ] . Expression ;
66
- if ( sqlExpression is not ColumnExpression )
78
+ if ( sqlExpression is not ColumnExpression && sqlExpression is not SqlConstantExpression && sqlExpression is not SqlParameterExpression )
67
79
{
68
80
var locate = new JetLocateScalarSubqueryVisitor ( _typeMappingSource , _sqlExpressionFactory ) ;
69
81
var locatedExpression = locate . Visit ( sqlExpression ) ;
@@ -72,24 +84,26 @@ public virtual Expression Process(Expression expression)
72
84
{
73
85
int index = selectExpression . AddToProjection ( sqlExpression ) ;
74
86
columnsToRewrite . Add ( i , ( index , null , selectExpression . Orderings [ i ] . IsAscending , true , false ) ) ;
87
+ continue ;
88
+ }
89
+
90
+ var existingIndex = selectExpression . Projection . ToList ( ) . FindIndex ( pe => pe . Expression . Equals ( sqlExpression ) ) ;
91
+ if ( existingIndex != - 1 )
92
+ {
93
+ columnsToRewrite . Add ( i , ( existingIndex , null , selectExpression . Orderings [ i ] . IsAscending , true , false ) ) ;
75
94
}
76
95
}
77
96
else
78
97
{
79
- var foundproj = selectExpression . Projection . FirstOrDefault ( p =>
80
- p . Expression . Equals ( sqlExpression ) ) ;
81
- if ( foundproj == null && sqlExpression is ColumnExpression colexp && ! selectExpression . Tables . Contains ( colexp . Table ) )
82
- {
83
- var ix = selectExpression . AddToProjection ( sqlExpression ) ;
84
- columnsToRewrite . Add ( i , ( ix , null , selectExpression . Orderings [ i ] . IsAscending , false , false ) ) ;
85
- }
86
- else
98
+ var existingIndex = selectExpression . Projection . ToList ( ) . FindIndex ( pe => pe . Expression . Equals ( sqlExpression ) ) ;
99
+ if ( existingIndex != - 1 )
87
100
{
88
101
bool referouter = sqlExpression is ColumnExpression colexp1 &&
89
- selectExpression . Tables . Contains ( colexp1 . Table ) ;
102
+ selectExpression . Tables . Contains ( colexp1 . Table ) ;
90
103
columnsToRewrite . Add ( i ,
91
- ( null , selectExpression . Orderings [ i ] , selectExpression . Orderings [ i ] . IsAscending , false , referouter ) ) ;
104
+ ( existingIndex , selectExpression . Orderings [ i ] , selectExpression . Orderings [ i ] . IsAscending , false , referouter ) ) ;
92
105
}
106
+
93
107
}
94
108
}
95
109
@@ -98,20 +112,21 @@ public virtual Expression Process(Expression expression)
98
112
return base . Visit ( expression ) ;
99
113
}
100
114
101
- for ( int A = 0 ; A < columnsToRewrite . Count ; A ++ )
115
+ selectExpression . ClearOrdering ( ) ;
116
+ //Keep the limit in parent expression
117
+ if ( selectExpression . Limit != null )
102
118
{
103
- if ( ! columnsToRewrite [ A ] . referstocurouter )
104
- {
105
- continue ;
106
- }
107
- var col = columnsToRewrite [ A ] . orderexp ! . Expression as ColumnExpression ;
108
- var colitem = columnsToRewrite [ A ] ;
109
- colitem . indexcol = selectExpression . AddToProjection ( col ! ) ;
110
- columnsToRewrite [ A ] = colitem ;
119
+ var limit = selectExpression . Limit ;
120
+ selectExpression = selectExpression . Update ( selectExpression . Projection , selectExpression . Tables ,
121
+ selectExpression . Predicate , selectExpression . GroupBy , selectExpression . Having ,
122
+ selectExpression . Orderings , null , null ) ;
123
+ selectExpression . PushdownIntoSubquery ( ) ;
124
+ selectExpression . ApplyLimit ( limit ) ;
125
+ }
126
+ else
127
+ {
128
+ selectExpression . PushdownIntoSubquery ( ) ;
111
129
}
112
-
113
- selectExpression . ClearOrdering ( ) ;
114
- selectExpression . PushdownIntoSubquery ( ) ;
115
130
116
131
for ( int j = 0 ; j < columnsToRewrite . Count ; j ++ )
117
132
{
0 commit comments