summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--psycopg/adapter_list.c16
-rwxr-xr-xtests/test_types_basic.py9
3 files changed, 22 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 2d64e93..2e035a0 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,7 @@ What's new in psycopg 2.7.6
(:ticket:`#746`).
- Fixed building on modern FreeBSD versions with Python 3.7 (:ticket:`#755`).
- Fixed hang trying to :sql:`COPY` via `~cursor.execute()` (:ticket:`#781`).
+- Fixed adaptation of arrays of empty arrays (:ticket:`#788`).
- Fixed segfault accessing the `connection.readonly` and
`connection.deferrable` repeatedly (:ticket:`#790`).
- `~psycopg2.extras.execute_values()` accepts `~psycopg2.sql.Composable`
diff --git a/psycopg/adapter_list.c b/psycopg/adapter_list.c
index 3fdff76..5c6fa69 100644
--- a/psycopg/adapter_list.c
+++ b/psycopg/adapter_list.c
@@ -55,6 +55,8 @@ list_quote(listObject *self)
/* empty arrays are converted to NULLs (still searching for a way to
insert an empty array in postgresql */
if (len == 0) {
+ /* it cannot be ARRAY[] because it would make empty lists unusable
+ * in any() without a cast. But we may convert it into ARRAY[] below */
res = Bytes_FromString("'{}'");
goto exit;
}
@@ -79,7 +81,19 @@ list_quote(listObject *self)
/* Lists of arrays containing only nulls are also not supported
* by the ARRAY construct so we should do some special casing */
- if (!PyList_Check(wrapped) || Bytes_AS_STRING(qs[i])[0] == 'A') {
+ if (PyList_Check(wrapped)) {
+ if (Bytes_AS_STRING(qs[i])[0] == 'A') {
+ all_nulls = 0;
+ }
+ else if (0 == strcmp(Bytes_AS_STRING(qs[i]), "'{}'")) {
+ /* case of issue #788: '{{}}' is not supported but
+ * array[array[]] is */
+ all_nulls = 0;
+ Py_CLEAR(qs[i]);
+ qs[i] = Bytes_FromString("ARRAY[]");
+ }
+ }
+ else {
all_nulls = 0;
}
}
diff --git a/tests/test_types_basic.py b/tests/test_types_basic.py
index 63f74b0..499fdd1 100755
--- a/tests/test_types_basic.py
+++ b/tests/test_types_basic.py
@@ -167,9 +167,12 @@ class TypesBasicTests(ConnectingTestCase):
curs.execute("select col from array_test where id = 2")
self.assertEqual(curs.fetchone()[0], [])
- # issue #788 (test commented out until issue fixed)
- # curs.execute("select null = any(%s)", ([[]], ))
- # self.assertFalse(curs.fetchone()[0])
+ @testutils.skip_before_postgres(8, 4)
+ def testNestedEmptyArray(self):
+ # issue #788
+ curs = self.conn.cursor()
+ curs.execute("select 10 = any(%s::int[])", ([[]], ))
+ self.assertFalse(curs.fetchone()[0])
def testEmptyArrayNoCast(self):
s = self.execute("SELECT '{}' AS foo")