From c8aef26e1500c84628b9dedb9d9c34e6c5030306 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Mon, 3 May 2010 23:07:48 +0100 Subject: [PATCH] Adapt buffer objects using an explicit cast on the string literal. Don't rely on Postgres casting the literal according to the context: this doesn't work e.g. passing the object as function argument where a function with the same name but taking a text exists. It doesn't work either when the object is in an ARRAY construct. Added test to check the type is respected in a complete Py -> PG -> Py roundtrip without context. Bug and solution reported by Peter Eisentraut. --- ChangeLog | 5 +++++ psycopg/adapter_binary.c | 4 ++-- tests/types_basic.py | 17 ++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12cc6ab3..cac156d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-03 Daniele Varrazzo + + * psycopg/adapter_binary.c: Adapt buffer objects using an explicit cast on + the string literal (bug reported by Peter Eisentraut) + 2010-04-20 Daniele Varrazzo * lib/pqpath.c: Fixed reference leak in notify reception. diff --git a/psycopg/adapter_binary.c b/psycopg/adapter_binary.c index ba39ebcb..36372bca 100644 --- a/psycopg/adapter_binary.c +++ b/psycopg/adapter_binary.c @@ -157,9 +157,9 @@ 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("''"); + self->buffer = PyString_FromString("''::bytea"); PQfreemem(to); } diff --git a/tests/types_basic.py b/tests/types_basic.py index aaca2374..f59e4cf5 100755 --- a/tests/types_basic.py +++ b/tests/types_basic.py @@ -96,7 +96,7 @@ class TypesBasicTests(unittest.TestCase): def testBinaryEmptyString(self): # test to make sure an empty Binary is converted to an empty string b = psycopg2.Binary('') - self.assertEqual(str(b), "''") + self.assertEqual(str(b), "''::bytea") def testBinaryRoundTrip(self): # test to make sure buffers returned by psycopg2 are @@ -113,6 +113,21 @@ class TypesBasicTests(unittest.TestCase): self.failUnless(s == ['one', 'two', 'three'], "wrong array quoting " + str(s)) + def testTypeRoundtripBinary(self): + o1 = buffer("".join(map(chr, range(256)))) + o2 = self.execute("select %s;", (o1,)) + self.assertEqual(type(o1), type(o2)) + + # Test with an empty buffer + o1 = buffer("") + o2 = self.execute("select %s;", (o1,)) + self.assertEqual(type(o1), type(o2)) + + def testTypeRoundtripBinaryArray(self): + o1 = buffer("".join(map(chr, range(256)))) + o1 = [o1] + o2 = self.execute("select %s;", (o1,)) + self.assertEqual(type(o1[0]), type(o2[0])) def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__)