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