Skip to content

Commit ee9cb28

Browse files
committed
Fix handling of empty arrays in array_fill().
array_fill(..., array[0]) produced an empty array, which is probably what users expect, but it was a one-dimensional zero-length array which is not our standard representation of empty arrays. Also, for no very good reason, it rejected empty input arrays; that case should be allowed and produce an empty output array. In passing, remove the restriction that the input array(s) have lower bound 1. That seems rather pointless, and it would have needed extra complexity to make the check deal with empty input arrays. Per bug #14487 from Andrew Gierth. It's been broken all along, so back-patch to all supported branches. Discussion: https://postgr.es/m/20170105152156.10135.64195@wrigleys.postgresql.org
1 parent 5f89a98 commit ee9cb28

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed

src/backend/utils/adt/arrayfuncs.c

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4915,25 +4915,19 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
49154915
/*
49164916
* Params checks
49174917
*/
4918-
if (ARR_NDIM(dims) != 1)
4918+
if (ARR_NDIM(dims) > 1)
49194919
ereport(ERROR,
49204920
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49214921
errmsg("wrong number of array subscripts"),
49224922
errdetail("Dimension array must be one dimensional.")));
49234923

4924-
if (ARR_LBOUND(dims)[0] != 1)
4925-
ereport(ERROR,
4926-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4927-
errmsg("wrong range of array subscripts"),
4928-
errdetail("Lower bound of dimension array must be one.")));
4929-
49304924
if (array_contains_nulls(dims))
49314925
ereport(ERROR,
49324926
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
49334927
errmsg("dimension values cannot be null")));
49344928

49354929
dimv = (int *) ARR_DATA_PTR(dims);
4936-
ndims = ARR_DIMS(dims)[0];
4930+
ndims = (ARR_NDIM(dims) > 0) ? ARR_DIMS(dims)[0] : 0;
49374931

49384932
if (ndims < 0) /* we do allow zero-dimension arrays */
49394933
ereport(ERROR,
@@ -4947,24 +4941,18 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
49474941

49484942
if (lbs != NULL)
49494943
{
4950-
if (ARR_NDIM(lbs) != 1)
4944+
if (ARR_NDIM(lbs) > 1)
49514945
ereport(ERROR,
49524946
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49534947
errmsg("wrong number of array subscripts"),
49544948
errdetail("Dimension array must be one dimensional.")));
49554949

4956-
if (ARR_LBOUND(lbs)[0] != 1)
4957-
ereport(ERROR,
4958-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4959-
errmsg("wrong range of array subscripts"),
4960-
errdetail("Lower bound of dimension array must be one.")));
4961-
49624950
if (array_contains_nulls(lbs))
49634951
ereport(ERROR,
49644952
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
49654953
errmsg("dimension values cannot be null")));
49664954

4967-
if (ARR_DIMS(lbs)[0] != ndims)
4955+
if (ndims != ((ARR_NDIM(lbs) > 0) ? ARR_DIMS(lbs)[0] : 0))
49684956
ereport(ERROR,
49694957
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49704958
errmsg("wrong number of array subscripts"),
@@ -4982,12 +4970,12 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
49824970
lbsv = deflbs;
49834971
}
49844972

4973+
nitems = ArrayGetNItems(ndims, dimv);
4974+
49854975
/* fast track for empty array */
4986-
if (ndims == 0)
4976+
if (nitems <= 0)
49874977
return construct_empty_array(elmtype);
49884978

4989-
nitems = ArrayGetNItems(ndims, dimv);
4990-
49914979
/*
49924980
* We arrange to look up info about element type only once per series of
49934981
* calls, assuming the element type doesn't change underneath us.

src/test/regress/expected/arrays.out

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,16 +1289,43 @@ select array_fill('juhu'::text, array[3,3]);
12891289
{{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
12901290
(1 row)
12911291

1292+
select a, a = '{}' as is_eq, array_dims(a)
1293+
from (select array_fill(42, array[0]) as a) ss;
1294+
a | is_eq | array_dims
1295+
----+-------+------------
1296+
{} | t |
1297+
(1 row)
1298+
1299+
select a, a = '{}' as is_eq, array_dims(a)
1300+
from (select array_fill(42, '{}') as a) ss;
1301+
a | is_eq | array_dims
1302+
----+-------+------------
1303+
{} | t |
1304+
(1 row)
1305+
1306+
select a, a = '{}' as is_eq, array_dims(a)
1307+
from (select array_fill(42, '{}', '{}') as a) ss;
1308+
a | is_eq | array_dims
1309+
----+-------+------------
1310+
{} | t |
1311+
(1 row)
1312+
12921313
-- raise exception
12931314
select array_fill(1, null, array[2,2]);
12941315
ERROR: dimension array or low bound array cannot be null
12951316
select array_fill(1, array[2,2], null);
12961317
ERROR: dimension array or low bound array cannot be null
1318+
select array_fill(1, array[2,2], '{}');
1319+
ERROR: wrong number of array subscripts
1320+
DETAIL: Low bound array has different size than dimensions array.
12971321
select array_fill(1, array[3,3], array[1,1,1]);
12981322
ERROR: wrong number of array subscripts
12991323
DETAIL: Low bound array has different size than dimensions array.
13001324
select array_fill(1, array[1,2,null]);
13011325
ERROR: dimension values cannot be null
1326+
select array_fill(1, array[[1,2],[3,4]]);
1327+
ERROR: wrong number of array subscripts
1328+
DETAIL: Dimension array must be one dimensional.
13021329
select string_to_array('1|2|3', '|');
13031330
string_to_array
13041331
-----------------

src/test/regress/sql/arrays.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,11 +383,19 @@ select array_fill(7, array[3,3],array[2,2]);
383383
select array_fill(7, array[3,3]);
384384
select array_fill('juhu'::text, array[3,3],array[2,2]);
385385
select array_fill('juhu'::text, array[3,3]);
386+
select a, a = '{}' as is_eq, array_dims(a)
387+
from (select array_fill(42, array[0]) as a) ss;
388+
select a, a = '{}' as is_eq, array_dims(a)
389+
from (select array_fill(42, '{}') as a) ss;
390+
select a, a = '{}' as is_eq, array_dims(a)
391+
from (select array_fill(42, '{}', '{}') as a) ss;
386392
-- raise exception
387393
select array_fill(1, null, array[2,2]);
388394
select array_fill(1, array[2,2], null);
395+
select array_fill(1, array[2,2], '{}');
389396
select array_fill(1, array[3,3], array[1,1,1]);
390397
select array_fill(1, array[1,2,null]);
398+
select array_fill(1, array[[1,2],[3,4]]);
391399

392400
select string_to_array('1|2|3', '|');
393401
select string_to_array('1|2|3|', '|');

0 commit comments

Comments
 (0)