Re: problem with bytea and undecorated literals
Daniele Varrazzo <[email protected]> Thu, 29 Apr 2010 13:59:04 +0100
| Newsgroups | gmane.comp.python.db.psycopg.devel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Apr 29, 2010 at 11:32 AM, Karsten Hilbert <[email protected]> wrote: > On Thu, Apr 29, 2010 at 11:09:54AM +0100, Daniele Varrazzo wrote: > >> This is actually a shortcoming in the PostgreSQL casting algorithm, as >> the same problem would appear issuing the query directly in psql: >> >> test=> SELECT foo (ARRAY[E'abc\\\\000S', E'def']); >> ERROR: function foo(text[]) does not exist >> LINE 1: SELECT foo (ARRAY[E'abc\\\\000S', E'def']); >> ^ >> HINT: No function matches the given name and argument types. You >> might need to add explicit type casts. >> test=> SELECT foo (ARRAY[E'abc\\\\000S', E'def']::bytea[]); >> foo >> ----- >> 123 >> (1 row) > > I'm not sure I agree it's the same problem. Psql (and by > extension PostgreSQL) does NOT know the "intended" datatype > (and choses to not second guess) whereas psycopg2 DOES > (that's what it is proud of - mapping Python data types to > PG ones and back). > > Or am I missing something ? Well, Postgres does some educate guessing: when some text is passed as argument to a function and no signature exists for a text argument, Postgres does look for a datatype into which the argument can be casted: test=> create function haveadate(x timestamp) returns text language sql as $$ select 'got a ts'::text $$; CREATE FUNCTION test=> select haveadate ('2010-01-01'); haveadate ----------- got a ts (1 row) This doesn't work in Peter's example because a function accepting a text argument exists, shadowing the one the caller wanted to invoke. With arrays instead it seems Postgres is not so aggressive in casting the argument to one for which a signature is available: test=> create function haveadatea(x timestamp[]) returns text language sql as $$ select 'got a ts[]'::text $$; CREATE FUNCTION test=> select haveadatea (array['2010-01-01']); ERROR: function haveadatea(text[]) does not exist LINE 1: select haveadatea (array['2010-01-01']); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. So a cast is required even in places where the text representation of the argument would have worked for non-array case: test=> select haveadatea (array['2010-01-01'::timestamp]); haveadatea ------------ got a ts[] (1 row) test=> select haveadatea (array['2010-01-01']::timestamp[]); haveadatea ------------ got a ts[] (1 row) These problems can be worked around with explicit casting, but of course some help from psycopg wouldn't be bad to avoid surprises. -- Daniele