I’m trying to move from ILIKE to Postgres ~* operator. Tables have bpchar columns (cannot changed). Tried in Postgres 12
create temp table test ( tasudok char(25), nimetus char (100) ) on commit drop ;
insert into test values ('123','Teie Arve 123 tasumine');
select nimetus ~* '*. '||tasudok||' *.' from test;
but got error
ERROR: invalid regular expression: quantifier operand invalid
How to use substring match with ~* operator?
2
Answers
Simply:
You do not need to pad the pattern at all like you would have to with
ILIKE
. Equivalent 1:1 Except for special characters in the "pattern" column
tasudok
that would have different meaning. See:Operator precedence
Notably,
ILIKE
andLIKE
rank one step below default operators in operator precedence, so no parentheses are required for my expression. Strictly speaking,LIKE
is not an operator, but an SQL construct, that is implemented with the Postgres operator~~
internally. (~~*
forILIKE
,!~~
forNOT LIKE
,!~~*
forNOT ILIKE
)Also notably, those internal operators have default operator precedence (as do the regex operators
~
,~*
,!~
, and!~*
). So parentheses are required around the concatenated string for those.It’s just that you do not need to concatenate anything to begin with for your example. Would be expensive noise.
Your
*.
was probably supposed to be.*
and it’s reversed for some reason. The leading*
is expecting to be preceded by something, but it’s right at the start of the pattern, hence the error. Flip those and it’ll work just fine:demo at db-fiddle
9.7.3.1. Regular Expression Details has a note warning against just that:
You also probably want to parenthesize the concatenated strings, otherwise they get evaluated left-to-right. As a result, only the first one’s matched, and the resulting
boolean
gets cast totext
, then concatenated totasudok
, then to' *.'
: