The attached patch fixes Bug #15259 [1] in the intarray module, making the
'&' array intersection operator return proper zero-dimensional empty arrays
instead of one-dimensional, zero-length "empty" arrays.
In [2] this problem was addressed by changing the behaviour of
construct_[md_]array(), but the intarray module does not use these
functions. The patch I propose contains the relevant fixes to the
intarray module, along with regression tests.
[1]:
https://www.postgresql.org/message-id/153053285112.13258.434620894305716755%40wrigleys.postgresql.org
[2]: https://www.postgresql.org/message-id/[email protected]
Best regards,
Alexey Kryuchkov
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index ee8fb64a47..7fe82a8f12 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -4,6 +4,7 @@
#include "postgres.h"
#include "catalog/pg_type.h"
+#include "utils/array.h"
#include "_int.h"
@@ -222,6 +223,13 @@ new_intArrayType(int num)
ArrayType *r;
int nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
+ /* if no elements, return a zero-dimensional array */
+ if (num == 0)
+ {
+ r = construct_empty_array(INT4OID);
+ return r;
+ }
+
r = (ArrayType *) palloc0(nbytes);
SET_VARSIZE(r, nbytes);
diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out
index 0a5dd463ac..105c951bad 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -151,6 +151,30 @@ SELECT '{-1,3,1}'::int[] & '{1,2}';
{1}
(1 row)
+SELECT '{1}'::int[] & '{2}'::int[];
+ ?column?
+----------
+ {}
+(1 row)
+
+SELECT array_dims('{1}'::int[] & '{2}'::int[]);
+ array_dims
+------------
+
+(1 row)
+
+SELECT ('{1}'::int[] & '{2}'::int[]) = '{}'::int[];
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT ('{}'::int[] & '{}'::int[]) = '{}'::int[];
+ ?column?
+----------
+ t
+(1 row)
+
--test query_int
SELECT '1'::query_int;
query_int
diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql
index 44e1a729b4..40225c65ab 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -30,6 +30,10 @@ SELECT '{123,623,445}'::int[] | 1623;
SELECT '{123,623,445}'::int[] | '{1623,623}';
SELECT '{123,623,445}'::int[] & '{1623,623}';
SELECT '{-1,3,1}'::int[] & '{1,2}';
+SELECT '{1}'::int[] & '{2}'::int[];
+SELECT array_dims('{1}'::int[] & '{2}'::int[]);
+SELECT ('{1}'::int[] & '{2}'::int[]) = '{}'::int[];
+SELECT ('{}'::int[] & '{}'::int[]) = '{}'::int[];
--test query_int