@@ -57,32 +57,32 @@ public NpgsqlLTreeTranslator(
5757 nameof ( LTree . IsAncestorOf )
5858 => new PostgresBinaryExpression (
5959 PostgresExpressionType . Contains ,
60- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
61- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _ltreeTypeMapping ) ,
60+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
61+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _ltreeTypeMapping ) ,
6262 typeof ( bool ) ,
6363 _boolTypeMapping ) ,
6464
6565 nameof ( LTree . IsDescendantOf )
6666 => new PostgresBinaryExpression (
6767 PostgresExpressionType . ContainedBy ,
68- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
69- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _ltreeTypeMapping ) ,
68+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
69+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _ltreeTypeMapping ) ,
7070 typeof ( bool ) ,
7171 _boolTypeMapping ) ,
7272
7373 nameof ( LTree . MatchesLQuery )
7474 => new PostgresBinaryExpression (
7575 PostgresExpressionType . LTreeMatches ,
76- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
77- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _lqueryTypeMapping ) ,
76+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
77+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _lqueryTypeMapping ) ,
7878 typeof ( bool ) ,
7979 _boolTypeMapping ) ,
8080
8181 nameof ( LTree . MatchesLTxtQuery )
8282 => new PostgresBinaryExpression (
8383 PostgresExpressionType . LTreeMatches ,
84- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
85- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _ltxtqueryTypeMapping ) ,
84+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
85+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _ltxtqueryTypeMapping ) ,
8686 typeof ( bool ) ,
8787 _boolTypeMapping ) ,
8888
@@ -171,7 +171,7 @@ arguments[1] is LambdaExpression wherePredicate &&
171171 {
172172 return new PostgresBinaryExpression (
173173 PostgresExpressionType . LTreeMatchesAny ,
174- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateInstance ) , _ltreeTypeMapping ) ,
174+ ApplyTypeMappingOrConvert ( Visit ( predicateInstance ) , _ltreeTypeMapping ) ,
175175 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _lqueryArrayTypeMapping ) ,
176176 typeof ( bool ) ,
177177 _boolTypeMapping ) ;
@@ -184,7 +184,7 @@ arguments[1] is LambdaExpression wherePredicate &&
184184 return new PostgresBinaryExpression (
185185 PostgresExpressionType . Contains ,
186186 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
187- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
187+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
188188 typeof ( bool ) ,
189189 _boolTypeMapping ) ;
190190 }
@@ -196,7 +196,7 @@ arguments[1] is LambdaExpression wherePredicate &&
196196 return new PostgresBinaryExpression (
197197 PostgresExpressionType . ContainedBy ,
198198 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
199- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
199+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
200200 typeof ( bool ) ,
201201 _boolTypeMapping ) ;
202202 }
@@ -208,7 +208,7 @@ arguments[1] is LambdaExpression wherePredicate &&
208208 return new PostgresBinaryExpression (
209209 PostgresExpressionType . LTreeMatches ,
210210 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
211- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
211+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
212212 typeof ( bool ) ,
213213 _boolTypeMapping ) ;
214214 }
@@ -220,7 +220,7 @@ arguments[1] is LambdaExpression wherePredicate &&
220220 return new PostgresBinaryExpression (
221221 PostgresExpressionType . LTreeMatches ,
222222 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
223- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
223+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
224224 typeof ( bool ) ,
225225 _boolTypeMapping ) ;
226226 }
@@ -267,7 +267,7 @@ arguments[1] is LambdaExpression wherePredicate &&
267267 return new PostgresBinaryExpression (
268268 PostgresExpressionType . LTreeFirstAncestor ,
269269 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
270- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
270+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
271271 typeof ( LTree ) ,
272272 _ltreeTypeMapping ) ;
273273 }
@@ -279,7 +279,7 @@ arguments[1] is LambdaExpression wherePredicate &&
279279 return new PostgresBinaryExpression (
280280 PostgresExpressionType . LTreeFirstDescendent ,
281281 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
282- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
282+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
283283 typeof ( LTree ) ,
284284 _ltreeTypeMapping ) ;
285285 }
@@ -291,7 +291,7 @@ arguments[1] is LambdaExpression wherePredicate &&
291291 return new PostgresBinaryExpression (
292292 PostgresExpressionType . LTreeFirstMatches ,
293293 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
294- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
294+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
295295 typeof ( LTree ) ,
296296 _ltreeTypeMapping ) ;
297297 }
@@ -303,7 +303,7 @@ arguments[1] is LambdaExpression wherePredicate &&
303303 return new PostgresBinaryExpression (
304304 PostgresExpressionType . LTreeFirstMatches ,
305305 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
306- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
306+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
307307 typeof ( string ) ,
308308 _ltreeTypeMapping ) ;
309309 }
@@ -315,4 +315,18 @@ arguments[1] is LambdaExpression wherePredicate &&
315315 SqlExpression Visit ( Expression expression )
316316 => ( SqlExpression ) sqlTranslatingExpressionVisitor . Visit ( expression ) ;
317317 }
318+
319+ // Applying e.g. the LQuery type mapping on a function operator is a bit tricky.
320+ // If it's a constant, we can just apply the mapping: the constant will get rendered as an untyped string literal, and PG will
321+ // coerce it as the function parameter.
322+ // If it's a parameter, we can also just apply the mapping (which causes NpgsqlDbType to be set to LQuery).
323+ // For anything else, we may need an explicit cast to LQuery, e.g. a plain text column or a concatenation between strings;
324+ // apply the default type mapping and then apply an additional Convert node if the resulting mapping isn't what we need.
325+ private SqlExpression ApplyTypeMappingOrConvert ( SqlExpression sqlExpression , RelationalTypeMapping typeMapping )
326+ => sqlExpression is SqlConstantExpression or SqlParameterExpression
327+ ? _sqlExpressionFactory . ApplyTypeMapping ( sqlExpression , typeMapping )
328+ : _sqlExpressionFactory . ApplyDefaultTypeMapping ( sqlExpression ) is var expressionWithDefaultTypeMapping
329+ && expressionWithDefaultTypeMapping . TypeMapping ! . StoreType == typeMapping . StoreType
330+ ? expressionWithDefaultTypeMapping
331+ : _sqlExpressionFactory . Convert ( expressionWithDefaultTypeMapping , typeMapping . ClrType , typeMapping ) ;
318332}
0 commit comments