2018-05-06 8:26 GMT+02:00 Shay Rojansky <r...@roji.org>:

> Hi hackers.
>
> The following works well of course:
>
> test=# select strpos('Aa'::citext, 'a');
>  strpos
> --------
>       1
>
> However, if I pass a typed text parameter for the substring, I get
> case-sensitive behavior instead:
>
> test=# select strpos('Aa'::citext, 'a'::text);
>  strpos
> --------
>       2
>
> This seems like surprising behavior - my expectation was that the first
> parameter being citext would be enough to trigger case-insensitive
> behavior. The same may be happening with other string functions (e.g.
> regexp_matches). This is causing some difficulties in a real scenario where
> SQL and parameters are getting generated by an O/RM, and changing them
> isn't trivial.
>
> Do the above seem like problematic behavior like it does to me, or is it
> the expected behavior?
>

This is expected - it is side effect of PostgreSQL implementation of
function overloading and type conversions

after installation citext, you will have more instances of function strpos

strpos(citext, citext)
strpos(text, text)

the call strpos('aa'::citext, 'a') is effective strpos('aa'::citext,
'a'::unknown) and that strpos(citext, citext) can be used in this case.

strpos('aa'::citext, 'a'::text) is ambiguous (both functions can be used
with necessary conversion - cast citext<->text is available), and usually
it fails with related error message - but there is a exception - the text
type is PREFERRED - what means, so strpost(text, text) is selected.

PostgreSQL type system is very generic and works almost well, but sometimes
there can be unwanted effects when some functions are overloaded. In this
case is better to implement own instance of unique function and use only it.

some like

create or replace function strpos_ci(text, text) returns int as $$ select
strpos($1::citext, $2::citext) $$ language sql;
create or replace function strpos_ci(citext, citext) returns int as $$
select strpos($1, $1) $$ language sql;

Regards

Pavel




>
> Shay
>

Reply via email to