problem with bytea and undecorated literals
Peter Eisentraut <[email protected]> Thu, 29 Apr 2010 11:33:07 +0300
| Newsgroups | gmane.comp.python.db.psycopg.devel |
|---|---|
| Message-ID | <[email protected]> |
Consider this example:
create function bar1(x bytea) returns text language sql
as $$ select 'bytea version'::text $$; -- I want to call this one.
create function bar1(x text) returns text language sql
as $$ select 'text version'::text $$;
import psycopg2
from psycopg2 import Binary
conn = psycopg2.connect("dbname=test")
cursor = conn.cursor()
a = Binary('abc')
print cursor.mogrify('SELECT bar1(%s)', [a])
cursor.execute('SELECT bar1(%s)', [a])
print cursor.fetchall()
Output:
SELECT bar1(E'abc')
[('text version',)] # WRONG
This would work correctly if the substitution of the Binary type created
something like:
SELECT bar1(E'abc'::bytea)
I think this might be a more widespread problem. A cursory test with
the Date type revealed a similar problem. PostgreSQL is going to
default unknown literals to text, so adding an explicit type decoration
is advisable.
Another instance of this problem is that array support with types like
these is broken:
create function foo(x bytea[]) returns int language sql
as $$ select 123 $$;
import psycopg2
from psycopg2 import Binary
conn = psycopg2.connect("dbname=test")
cursor = conn.cursor()
b = [Binary('abc\000\123'), Binary('def')]
cursor.execute('SELECT foo (%s)', [b])
print cursor.fetchall()
psycopg2.ProgrammingError: function foo(text[]) does not exist
For the bytea type, the following patch will fix both of these problems.
But again, this might affect other data types as well.
diff --git a/psycopg/adapter_binary.c b/psycopg/adapter_binary.c
index ba39ebc..599580d 100644
--- a/psycopg/adapter_binary.c
+++ b/psycopg/adapter_binary.c
@@ -157,7 +157,7 @@ binary_quote(binaryObject *self)
if (len > 0)
self->buffer = PyString_FromFormat(
(self->conn && ((connectionObject*)self->conn)->equote)
- ? "E'%s'" : "'%s'" , to);
+ ? "E'%s'::bytea" : "'%s'::bytea" , to);
else
self->buffer = PyString_FromString("''");
(patch is against python2 branch HEAD)