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/20570.1506198...@sss.pgh.pa.us

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

Reply via email to