Please look on the following scenario;
my_db=# select version();
version
------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 9.6.9 on x86_64-pc-linux-gnu (Debian 9.6.9-2.pgdg90+1), compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
CREATE TABLE binary_data ("data" BYTEA NOT NULL);
CREATE OR REPLACE FUNCTION random_string(lengh integer)
RETURNS varchar AS $$
SELECT array_to_string(ARRAY(
SELECT substr('abcdefghijklmnopqrstuv',trunc(random()*21+1)::int,1)
FROM generate_series(1,$1)),'')
$$ LANGUAGE sql VOLATILE;
insert into binary_data ("data") select CONVERT_TO(random_string(64), 'utf8') FROM generate_series(1,1000000);
Now if we run following query it works really well;
select CONVERT_FROM(data, 'utf8') from binary_data where "data" like '%me%' limit 10;
Bu if we run following query;
select CONVERT_FROM(data, 'utf8') from binary_data where "data" like CONCAT('%', 'me', '%') limit 10;
It failed with following error
Kernel error: ERROR: operator does not exist: bytea ~~ text
Can't understand what's the difference between '%me%'
and CONCAT('%', 'me', '%')
.
First guess was the type must be different to check it I run:
SELECT pg_typeof('%me'), pg_typeof(CONCAT('%', 'me', '%'));
And yes my guess was right;
unknown text
So '%me%' is treated as unknown
and CONCAT('%', 'me', '%')
is treated as text
. To use the same query with CONCAT('%', 'me', '%')::UNKNOWN
result to another error.
Kernel error: ERROR: failed to find conversion function from unknown to bytea
Any one have any idea what's going wrong with above queries?
Best Answer
The first is an untyped string literal. The second is type
text
since the functionconcat()
returnstext
. Not exactly the same thing for Operator Type Resolution! Quoting the manual there:And there is no implicit conversion for
text
->bytea
in standard Postgres.And there is no variant of
LIKE
forbytea
/text
, only for:bytea
/bytea
name
/text
text
/text
db<>fiddle here (testing in Postgres 11)
To solve, add an explicit cast to
bytea
(text
can be cast to any type):