I'm trying to match a string pattern to any string in an array:
SELECT 'abc' LIKE ANY('{"abc","def"}') -- TRUE
-- BUT
SELECT 'ab%' LIKE ANY('{"abc","def"}') -- FALSE, I expect TRUE
What is wrong with the second query?
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It only takes a minute to sign up.
Sign up to join this community% could be used in LIKE part, but not in string
SELECT 'abc' LIKE ANY('{"ab%","def"}')
would be correct form for your 2nd example
It would be nice if PostgreSQL allowed ANY on the left hand operand, but sadly it doesn't. So you need the commutator of LIKE. PostgreSQL doesn't come with one, but you can create your own.
You need a function that reverses the order of arguments to LIKE, and then use that to create an operator that can be used in conjunction with ANY. User created operators have to be named with symbols, not text, so I'm picking '<~~'. '~~' is the built-in synonym for LIKE, so I'm adding '<' as a pneumonic to make it "go the other way". You can pick any unused name you want, though.
create function reverse_like (text, text) returns boolean language sql as $$ select $2 like $1 $$;
create operator <~~ ( function =reverse_like, leftarg = text, rightarg=text );
SELECT 'ab%' <~~ ANY('{"abc","def"}');
You should probably tag the function as immutable, and if you are using v9.6 or above, also as parallel safe.
create or replace function reverse_like (text, text) returns boolean language sql as
$$ select $2 like $1 $$ immutable parallel safe;
ERROR: operator procedure must be specified
Aug 21, 2019 at 20:08
create operator <~~ ( procedure =reverse_like, leftarg = text, rightarg=text );
Note the keyword procedure replaces function from the above answer
Aug 21, 2019 at 20:13