Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 82f8107

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 2e44f37 commit 82f8107

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
@@ -5734,25 +5734,19 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
57345734
/*
57355735
* Params checks
57365736
*/
5737-
if (ARR_NDIM(dims) != 1)
5737+
if (ARR_NDIM(dims) > 1)
57385738
ereport(ERROR,
57395739
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
57405740
errmsg("wrong number of array subscripts"),
57415741
errdetail("Dimension array must be one dimensional.")));
57425742

5743-
if (ARR_LBOUND(dims)[0] != 1)
5744-
ereport(ERROR,
5745-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5746-
errmsg("wrong range of array subscripts"),
5747-
errdetail("Lower bound of dimension array must be one.")));
5748-
57495743
if (array_contains_nulls(dims))
57505744
ereport(ERROR,
57515745
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
57525746
errmsg("dimension values cannot be null")));
57535747

57545748
dimv = (int *) ARR_DATA_PTR(dims);
5755-
ndims = ARR_DIMS(dims)[0];
5749+
ndims = (ARR_NDIM(dims) > 0) ? ARR_DIMS(dims)[0] : 0;
57565750

57575751
if (ndims < 0) /* we do allow zero-dimension arrays */
57585752
ereport(ERROR,
@@ -5766,24 +5760,18 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
57665760

57675761
if (lbs != NULL)
57685762
{
5769-
if (ARR_NDIM(lbs) != 1)
5763+
if (ARR_NDIM(lbs) > 1)
57705764
ereport(ERROR,
57715765
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
57725766
errmsg("wrong number of array subscripts"),
57735767
errdetail("Dimension array must be one dimensional.")));
57745768

5775-
if (ARR_LBOUND(lbs)[0] != 1)
5776-
ereport(ERROR,
5777-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5778-
errmsg("wrong range of array subscripts"),
5779-
errdetail("Lower bound of dimension array must be one.")));
5780-
57815769
if (array_contains_nulls(lbs))
57825770
ereport(ERROR,
57835771
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
57845772
errmsg("dimension values cannot be null")));
57855773

5786-
if (ARR_DIMS(lbs)[0] != ndims)
5774+
if (ndims != ((ARR_NDIM(lbs) > 0) ? ARR_DIMS(lbs)[0] : 0))
57875775
ereport(ERROR,
57885776
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
57895777
errmsg("wrong number of array subscripts"),
@@ -5801,12 +5789,12 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
58015789
lbsv = deflbs;
58025790
}
58035791

5792+
nitems = ArrayGetNItems(ndims, dimv);
5793+
58045794
/* fast track for empty array */
5805-
if (ndims == 0)
5795+
if (nitems <= 0)
58065796
return construct_empty_array(elmtype);
58075797

5808-
nitems = ArrayGetNItems(ndims, dimv);
5809-
58105798
/*
58115799
* We arrange to look up info about element type only once per series of
58125800
* 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
@@ -1553,16 +1553,43 @@ select array_fill('juhu'::text, array[3,3]);
15531553
{{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
15541554
(1 row)
15551555

1556+
select a, a = '{}' as is_eq, array_dims(a)
1557+
from (select array_fill(42, array[0]) as a) ss;
1558+
a | is_eq | array_dims
1559+
----+-------+------------
1560+
{} | t |
1561+
(1 row)
1562+
1563+
select a, a = '{}' as is_eq, array_dims(a)
1564+
from (select array_fill(42, '{}') as a) ss;
1565+
a | is_eq | array_dims
1566+
----+-------+------------
1567+
{} | t |
1568+
(1 row)
1569+
1570+
select a, a = '{}' as is_eq, array_dims(a)
1571+
from (select array_fill(42, '{}', '{}') as a) ss;
1572+
a | is_eq | array_dims
1573+
----+-------+------------
1574+
{} | t |
1575+
(1 row)
1576+
15561577
-- raise exception
15571578
select array_fill(1, null, array[2,2]);
15581579
ERROR: dimension array or low bound array cannot be null
15591580
select array_fill(1, array[2,2], null);
15601581
ERROR: dimension array or low bound array cannot be null
1582+
select array_fill(1, array[2,2], '{}');
1583+
ERROR: wrong number of array subscripts
1584+
DETAIL: Low bound array has different size than dimensions array.
15611585
select array_fill(1, array[3,3], array[1,1,1]);
15621586
ERROR: wrong number of array subscripts
15631587
DETAIL: Low bound array has different size than dimensions array.
15641588
select array_fill(1, array[1,2,null]);
15651589
ERROR: dimension values cannot be null
1590+
select array_fill(1, array[[1,2],[3,4]]);
1591+
ERROR: wrong number of array subscripts
1592+
DETAIL: Dimension array must be one dimensional.
15661593
select string_to_array('1|2|3', '|');
15671594
string_to_array
15681595
-----------------

src/test/regress/sql/arrays.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,19 @@ select array_fill(7, array[3,3],array[2,2]);
482482
select array_fill(7, array[3,3]);
483483
select array_fill('juhu'::text, array[3,3],array[2,2]);
484484
select array_fill('juhu'::text, array[3,3]);
485+
select a, a = '{}' as is_eq, array_dims(a)
486+
from (select array_fill(42, array[0]) as a) ss;
487+
select a, a = '{}' as is_eq, array_dims(a)
488+
from (select array_fill(42, '{}') as a) ss;
489+
select a, a = '{}' as is_eq, array_dims(a)
490+
from (select array_fill(42, '{}', '{}') as a) ss;
485491
-- raise exception
486492
select array_fill(1, null, array[2,2]);
487493
select array_fill(1, array[2,2], null);
494+
select array_fill(1, array[2,2], '{}');
488495
select array_fill(1, array[3,3], array[1,1,1]);
489496
select array_fill(1, array[1,2,null]);
497+
select array_fill(1, array[[1,2],[3,4]]);
490498

491499
select string_to_array('1|2|3', '|');
492500
select string_to_array('1|2|3|', '|');

0 commit comments

Comments
 (0)