Skip to content
Snippets Groups Projects
Commit 01783ac3 authored by Tom Lane's avatar Tom Lane
Browse files

Fix yet more problems with incorrectly-constructed zero-length arrays.

Commit 716ea626 attempted to fix the problem of building 1-D zero-size
arrays once and for all.  But it turns out that contrib/intarray has some
code that doesn't use construct_array() but just builds arrays by hand,
so it didn't get the memo.  This appears to affect all of subarray(),
intset_subtract(), inner_int_union(), inner_int_inter(), and
intarray_concat_arrays().

Back-patch into v11.  In the past we've not back-patched this type of
change, but since v11 is still in beta it seems all right to include
this fix in it.  Besides it's more consistent to make the fix in v11
where 716ea626 appeared.

Report and patch by Alexey Kryuchkov, some cosmetic adjustments by me

Report: https://postgr.es/m/153053285112.13258.434620894305716755@wrigleys.postgresql.org
Discussion: https://postgr.es/m/CAN85JcYphDLYt4CpMDLZjjNVqGDrFJ5eS3YF=wLAhFoDQuBsyg@mail.gmail.com
parent 6abad005
No related branches found
No related tags found
No related merge requests found
......@@ -220,7 +220,16 @@ ArrayType *
new_intArrayType(int num)
{
ArrayType *r;
int nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
int nbytes;
/* if no elements, return a zero-dimensional array */
if (num <= 0)
{
r = construct_empty_array(INT4OID);
return r;
}
nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
r = (ArrayType *) palloc0(nbytes);
......@@ -237,11 +246,11 @@ new_intArrayType(int num)
ArrayType *
resize_intArrayType(ArrayType *a, int num)
{
int nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
int nbytes;
int i;
/* if no elements, return a zero-dimensional array */
if (num == 0)
if (num <= 0)
{
ARR_NDIM(a) = 0;
return a;
......@@ -250,6 +259,8 @@ resize_intArrayType(ArrayType *a, int num)
if (num == ARRNELEMS(a))
return a;
nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
a = (ArrayType *) repalloc(a, nbytes);
SET_VARSIZE(a, nbytes);
......
......@@ -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
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment