mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-26 10:53:44 +03:00
Add a type converter to handle untyped empty arrays.
Empty array can be returned untyped by postgres. To handle this case, a special handler is added for the type UNKNOWNOID. If the value return by the database is strictly equal to "{}", the value is converted. Otherwise, the conversion fallback on the default handler.
This commit is contained in:
parent
4bc4f85229
commit
5ee60571a5
|
@ -177,6 +177,28 @@ typecast_parse_time(const char* s, const char** t, Py_ssize_t* len,
|
|||
#endif
|
||||
|
||||
#include "psycopg/typecast_array.c"
|
||||
|
||||
static long int typecast_default_DEFAULT[] = {0};
|
||||
static typecastObject_initlist typecast_default = {
|
||||
"DEFAULT", typecast_default_DEFAULT, typecast_STRING_cast};
|
||||
|
||||
static PyObject *
|
||||
typecast_UNKNOWN_cast(const char *str, Py_ssize_t len, PyObject *curs)
|
||||
{
|
||||
Dprintf("typecast_UNKNOWN_cast: str = '%s',"
|
||||
" len = " FORMAT_CODE_PY_SSIZE_T, str, len);
|
||||
|
||||
// PostgreSQL returns {} for empty array without explicit type. We convert
|
||||
// that to list in order to handle empty lists.
|
||||
if (len == 2 && str[0] == '{' && str[1] == '}') {
|
||||
return PyList_New(0);
|
||||
}
|
||||
|
||||
Dprintf("typecast_UNKNOWN_cast: fallback to default cast");
|
||||
|
||||
return typecast_default.cast(str, len, curs);
|
||||
}
|
||||
|
||||
#include "psycopg/typecast_builtins.c"
|
||||
|
||||
#define typecast_PYDATETIMEARRAY_cast typecast_GENERIC_ARRAY_cast
|
||||
|
@ -225,10 +247,6 @@ PyObject *psyco_default_cast;
|
|||
PyObject *psyco_binary_types;
|
||||
PyObject *psyco_default_binary_cast;
|
||||
|
||||
static long int typecast_default_DEFAULT[] = {0};
|
||||
static typecastObject_initlist typecast_default = {
|
||||
"DEFAULT", typecast_default_DEFAULT, typecast_STRING_cast};
|
||||
|
||||
|
||||
/* typecast_init - initialize the dictionary and create default types */
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ static long int typecast_DATEARRAY_types[] = {1182, 0};
|
|||
static long int typecast_INTERVALARRAY_types[] = {1187, 0};
|
||||
static long int typecast_BINARYARRAY_types[] = {1001, 0};
|
||||
static long int typecast_ROWIDARRAY_types[] = {1028, 1013, 0};
|
||||
static long int typecast_UNKNOWN_types[] = {705, 0};
|
||||
|
||||
|
||||
static typecastObject_initlist typecast_builtins[] = {
|
||||
|
@ -55,6 +56,7 @@ static typecastObject_initlist typecast_builtins[] = {
|
|||
{"INTERVALARRAY", typecast_INTERVALARRAY_types, typecast_INTERVALARRAY_cast, "INTERVAL"},
|
||||
{"BINARYARRAY", typecast_BINARYARRAY_types, typecast_BINARYARRAY_cast, "BINARY"},
|
||||
{"ROWIDARRAY", typecast_ROWIDARRAY_types, typecast_ROWIDARRAY_cast, "ROWID"},
|
||||
{"UNKNOWN", typecast_UNKNOWN_types, typecast_UNKNOWN_cast, NULL},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -176,6 +176,16 @@ class TypesBasicTests(unittest.TestCase):
|
|||
curs.execute("select col from array_test where id = 2")
|
||||
self.assertEqual(curs.fetchone()[0], [])
|
||||
|
||||
def testEmptyArray(self):
|
||||
s = self.execute("SELECT '{}' AS foo")
|
||||
self.failUnlessEqual(s, [])
|
||||
s = self.execute("SELECT '{}'::text[] AS foo")
|
||||
self.failUnlessEqual(s, [])
|
||||
s = self.execute("SELECT %s AS foo", ([],))
|
||||
self.failUnlessEqual(s, [])
|
||||
s = self.execute("SELECT 1 != ALL(%s)", ([],))
|
||||
self.failUnlessEqual(s, True)
|
||||
|
||||
@testutils.skip_from_python(3)
|
||||
def testTypeRoundtripBuffer(self):
|
||||
o1 = buffer("".join(map(chr, range(256))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user