@@ -70,32 +70,32 @@ public NpgsqlLTreeTranslator(
7070 nameof ( LTree . IsAncestorOf )
7171 => new PostgresBinaryExpression (
7272 PostgresExpressionType . Contains ,
73- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
74- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _ltreeTypeMapping ) ,
73+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
74+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _ltreeTypeMapping ) ,
7575 typeof ( bool ) ,
7676 _boolTypeMapping ) ,
7777
7878 nameof ( LTree . IsDescendantOf )
7979 => new PostgresBinaryExpression (
8080 PostgresExpressionType . ContainedBy ,
81- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
82- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _ltreeTypeMapping ) ,
81+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
82+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _ltreeTypeMapping ) ,
8383 typeof ( bool ) ,
8484 _boolTypeMapping ) ,
8585
8686 nameof ( LTree . MatchesLQuery )
8787 => new PostgresBinaryExpression (
8888 PostgresExpressionType . LTreeMatches ,
89- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
90- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _lqueryTypeMapping ) ,
89+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
90+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _lqueryTypeMapping ) ,
9191 typeof ( bool ) ,
9292 _boolTypeMapping ) ,
9393
9494 nameof ( LTree . MatchesLTxtQuery )
9595 => new PostgresBinaryExpression (
9696 PostgresExpressionType . LTreeMatches ,
97- _sqlExpressionFactory . ApplyTypeMapping ( instance ! , _ltreeTypeMapping ) ,
98- _sqlExpressionFactory . ApplyTypeMapping ( arguments [ 0 ] , _ltxtqueryTypeMapping ) ,
97+ ApplyTypeMappingOrConvert ( instance ! , _ltreeTypeMapping ) ,
98+ ApplyTypeMappingOrConvert ( arguments [ 0 ] , _ltxtqueryTypeMapping ) ,
9999 typeof ( bool ) ,
100100 _boolTypeMapping ) ,
101101
@@ -185,7 +185,7 @@ arguments[1] is LambdaExpression wherePredicate &&
185185 {
186186 return new PostgresBinaryExpression (
187187 PostgresExpressionType . LTreeMatchesAny ,
188- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateInstance ) , _ltreeTypeMapping ) ,
188+ ApplyTypeMappingOrConvert ( Visit ( predicateInstance ) , _ltreeTypeMapping ) ,
189189 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _lqueryArrayTypeMapping ) ,
190190 typeof ( bool ) ,
191191 _boolTypeMapping ) ;
@@ -198,7 +198,7 @@ arguments[1] is LambdaExpression wherePredicate &&
198198 return new PostgresBinaryExpression (
199199 PostgresExpressionType . Contains ,
200200 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
201- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
201+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
202202 typeof ( bool ) ,
203203 _boolTypeMapping ) ;
204204 }
@@ -210,7 +210,7 @@ arguments[1] is LambdaExpression wherePredicate &&
210210 return new PostgresBinaryExpression (
211211 PostgresExpressionType . ContainedBy ,
212212 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
213- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
213+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
214214 typeof ( bool ) ,
215215 _boolTypeMapping ) ;
216216 }
@@ -222,7 +222,7 @@ arguments[1] is LambdaExpression wherePredicate &&
222222 return new PostgresBinaryExpression (
223223 PostgresExpressionType . LTreeMatches ,
224224 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
225- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
225+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
226226 typeof ( bool ) ,
227227 _boolTypeMapping ) ;
228228 }
@@ -234,7 +234,7 @@ arguments[1] is LambdaExpression wherePredicate &&
234234 return new PostgresBinaryExpression (
235235 PostgresExpressionType . LTreeMatches ,
236236 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
237- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
237+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
238238 typeof ( bool ) ,
239239 _boolTypeMapping ) ;
240240 }
@@ -281,7 +281,7 @@ arguments[1] is LambdaExpression wherePredicate &&
281281 return new PostgresBinaryExpression (
282282 PostgresExpressionType . LTreeFirstAncestor ,
283283 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
284- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
284+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
285285 typeof ( LTree ) ,
286286 _ltreeTypeMapping ) ;
287287 }
@@ -293,7 +293,7 @@ arguments[1] is LambdaExpression wherePredicate &&
293293 return new PostgresBinaryExpression (
294294 PostgresExpressionType . LTreeFirstDescendent ,
295295 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
296- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
296+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltreeTypeMapping ) ,
297297 typeof ( LTree ) ,
298298 _ltreeTypeMapping ) ;
299299 }
@@ -305,7 +305,7 @@ arguments[1] is LambdaExpression wherePredicate &&
305305 return new PostgresBinaryExpression (
306306 PostgresExpressionType . LTreeFirstMatches ,
307307 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
308- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
308+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _lqueryTypeMapping ) ,
309309 typeof ( LTree ) ,
310310 _ltreeTypeMapping ) ;
311311 }
@@ -317,7 +317,7 @@ arguments[1] is LambdaExpression wherePredicate &&
317317 return new PostgresBinaryExpression (
318318 PostgresExpressionType . LTreeFirstMatches ,
319319 _sqlExpressionFactory . ApplyTypeMapping ( Visit ( array ) , _ltreeArrayTypeMapping ) ,
320- _sqlExpressionFactory . ApplyTypeMapping ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
320+ ApplyTypeMappingOrConvert ( Visit ( predicateArguments [ 0 ] ) , _ltxtqueryTypeMapping ) ,
321321 typeof ( string ) ,
322322 _ltreeTypeMapping ) ;
323323 }
@@ -329,4 +329,18 @@ arguments[1] is LambdaExpression wherePredicate &&
329329 SqlExpression Visit ( Expression expression )
330330 => ( SqlExpression ) sqlTranslatingExpressionVisitor . Visit ( expression ) ;
331331 }
332+
333+ // Applying e.g. the LQuery type mapping on a function operator is a bit tricky.
334+ // If it's a constant, we can just apply the mapping: the constant will get rendered as an untyped string literal, and PG will
335+ // coerce it as the function parameter.
336+ // If it's a parameter, we can also just apply the mapping (which causes NpgsqlDbType to be set to LQuery).
337+ // For anything else, we may need an explicit cast to LQuery, e.g. a plain text column or a concatenation between strings;
338+ // apply the default type mapping and then apply an additional Convert node if the resulting mapping isn't what we need.
339+ private SqlExpression ApplyTypeMappingOrConvert ( SqlExpression sqlExpression , RelationalTypeMapping typeMapping )
340+ => sqlExpression is SqlConstantExpression or SqlParameterExpression
341+ ? _sqlExpressionFactory . ApplyTypeMapping ( sqlExpression , typeMapping )
342+ : _sqlExpressionFactory . ApplyDefaultTypeMapping ( sqlExpression ) is var expressionWithDefaultTypeMapping
343+ && expressionWithDefaultTypeMapping . TypeMapping ! . StoreType == typeMapping . StoreType
344+ ? expressionWithDefaultTypeMapping
345+ : _sqlExpressionFactory . Convert ( expressionWithDefaultTypeMapping , typeMapping . ClrType , typeMapping ) ;
332346}
0 commit comments