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.
This commit is contained in:
Daniele Varrazzo 2010-05-03 23:07:48 +01:00
parent 2020790ba1
commit c8aef26e15
3 changed files with 23 additions and 3 deletions

View File

@ -1,3 +1,8 @@
2010-05-03 Daniele Varrazzo <daniele.varrazzo@gmail.com>
* 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 <daniele.varrazzo@gmail.com>
* lib/pqpath.c: Fixed reference leak in notify reception.

View File

@ -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);
}

View File

@ -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__)