Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL case insensitive SELECT on array

Tags:

I'm having problems finding the answer here, on google or in the docs ...
I need to do a case insensitive select against an array type.

So if:

value = {"Foo","bar","bAz"} 

I need

SELECT value FROM table WHERE 'foo' = ANY(value) 

to match.

I've tried lots of combinations of lower() with no success.

ILIKE instead of = seems to work but I've always been nervous about LIKE - is that the best way?

like image 409
PerryW Avatar asked May 01 '13 00:05

PerryW


People also ask

How do I make a case-insensitive in PostgreSQL?

While using regular expressions, we need to use the PostgreSQL ~* operator instead of the like operator; we can also use the ilike operator in PostgreSQL. We can also create an extension name as citext to use the case insensitive query in PostgreSQL; we need to create it first to use the extension of citext.

Can Postgres be case-insensitive?

PostgreSQL names are case sensitive. By default, AWS Schema Conversion Tool (AWS SCT) uses object name in lowercase for PostgreSQL. In most cases, you'll want to use AWS Database Migration Service transformations to change schema, table, and column names to lower case.

Is like case sensitive in PostgreSQL?

String comparisons in PostgreSQL are case sensitive* (unless a case-insensitive collation were to be introduced). To work around this, PostgreSQL has several methods to match strings in a case-insensitive manner.


1 Answers

One alternative not mentioned is to install the citext extension that comes with PostgreSQL 8.4+ and use an array of citext:

regress=# CREATE EXTENSION citext; regress=# SELECT 'foo' = ANY( '{"Foo","bar","bAz"}'::citext[] );  ?column?  ----------  t (1 row) 

If you want to be strictly correct about this and avoid extensions you have to do some pretty ugly subqueries because Pg doesn't have many rich array operations, in particular no functional mapping operations. Something like:

SELECT array_agg(lower(($1)[n])) FROM generate_subscripts($1,1) n; 

... where $1 is the array parameter. In your case I think you can cheat a bit because you don't care about preserving the array's order, so you can do something like:

SELECT 'foo' IN (SELECT lower(x) FROM unnest('{"Foo","bar","bAz"}'::text[]) x); 
like image 104
Craig Ringer Avatar answered Sep 21 '22 13:09

Craig Ringer