question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Potential bug when using (I)LIKE with array columns

See original GitHub issue

Dear Postgres team,

I created a repo with a minimal example to reproduce our issue with ILike. See the readme in the repo for a detailed description.

In short: We have array columns (by intention) to store e.g. a user’s competencies, topics etc. Now, users should be able to search across these columns, also with partial wording. Let’s say, user A stores ["Artificial Intelligence", "Big Data", "Robotics"]. Then, any user should be able to find this entry by search for "intelli".

Regarding to the “Array Type Mapping” documentation, we assumed that we could archive this by:

.Where(n => n.Topics.Any(s => EF.Functions.ILike(s, $"%{searchTerm1}%")))

It throws an NullReferenceException:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMappingOnAny(PostgresAnyExpression postgresAnyExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressionFactory.ApplyDefaultTypeMapping(SqlExpression sqlExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.Any(SqlExpression item, SqlExpression array, PostgresAnyOperatorType operatorType)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitArrayMethodCall(MethodInfo method, ReadOnlyCollection`1 arguments)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCall)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpressi
on lambdaExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at BugILikePostgres.Program.Main(String[] args) in C:\_Data\Repositories\BugILikePostgres\BugILikePostgres\Program.cs:line 73

When I exchanged the matchExpress with the pattern parameter, it “works” . But obviously, we cannot use pattern anymore in such a case. But this exchanging shows, that there is no null field.

Is this a bug, or have we misunderstood the documentation? 🙂

For reference: I mentioned this issue first on issue #395.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
JohnDitnocommented, Nov 24, 2020

@roji from further reading online I don’t believe unnest can use indexes so your right performance is likely to be poor.

I did find an extension called parray_gin (https://github.com/theirix/parray_gin/) which seems to provide GIN index and operator support for arrays with partial match but this is likely to fall outside of EFCore.PG support.

I think to best option to support this use case would be to normalise the array column into a separate table so LIKE operations can leverage the indexing for better performance

0reactions
rojicommented, Nov 24, 2020

Thanks for looking into this further.

FWIW I’m open to any translation that makes sense - including those which are complicated and/or require extensions (although exotic extensions are maybe a bit too much). What I’m wary of, is implementing translations which definitely yield bad performance in most/all cases where they’re used, and where this isn’t very obvious to the person writing the LINQ query.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a way to use like operator with an array in HiveQL?
1 Answer. Concatenate array using some delimiter, for example | and use concatenated string in RLIKE operator. Note: Pipe | in regex needs...
Read more >
Lookup against an array of column - Report a Bug
The two columns in my sheet are 'Email 1' and 'Email 2' which creates a virtual array column of 'Email'.
Read more >
Write an array column (via Lookup) to Google sheet
Hi friends! I don't know if this a bug or a limitation but I try to understand why Glide doesn't allow to write...
Read more >
PostgreSQL: Documentation: 15: 8.15. Arrays
PostgreSQL allows columns of a table to be defined as variable-length multidimensional arrays. Arrays of any built-in or user-defined base type, enum type, ......
Read more >
array_column - Manual
array_column () returns the values from a single column of the array , identified by the column_key . Optionally, an index_key may be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found