8000 Fix handling of empty arrays in array_fill(). · hackingwu/postgres@e0d59c6 · GitHub
[go: up one dir, main page]

Skip to content

Commit e0d59c6

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 6c4cf2b commit e0d59c6

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
@@ -4909,25 +4909,19 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
49094909
/*
49104910
* Params checks
49114911
*/
4912-
if (ARR_NDIM(dims) != 1)
4912+
if (ARR_NDIM(dims) > 1)
49134913
ereport(ERROR,
49144914
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49154915
errmsg("wrong number of array subscripts"),
49164916
errdetail("Dimension array must be one dimensional.")));
49174917

4918-
if (ARR_LBOUND(dims)[0] != 1)
4919-
ereport(ERROR,
4920-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4921-
errmsg("wrong range of array subscripts"),
4922-
errdetail("Lower bound of dimension array must be one.")));
4923-
49244918
if (array_contains_nulls(dims))
49254919
ereport(ERROR,
49264920
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
49274921
errmsg("dimension values cannot be null")));
49284922

49294923
dimv = (int *) ARR_DATA_PTR(dims);
4930-
ndims = ARR_DIMS(dims)[0];
4924+
ndims = (ARR_NDIM(dims) > 0) ? ARR_DIMS(dims)[0] : 0;
49314925

49324926
if (ndims < 0) /* we do allow zero-dimension arrays */
49334927
ereport(ERROR,
@@ -4941,24 +4935,18 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
49414935

49424936
if (lbs != NULL)
49434937
{
4944-
if (ARR_NDIM(lbs) != 1)
4938+
if (ARR_NDIM(lbs) > 1)
49454939
ereport(ERROR,
49464940
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49474941
errmsg("wrong number of array subscripts"),
49484942
errdetail("Dimension array must be one dimensional.")));
49494943

4950-
if (ARR_LBOUND(lbs)[0] != 1)
4951-
ereport(ERROR,
4952-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4953-
errmsg("wrong range of array subscripts"),
4954-
errdetail("Lower bound of dimension array must be one.")));
4955-
49564944
if (array_contains_nulls(lbs))
49574945
ereport(ERROR,
49584946
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
49594947
errmsg("dimension values cannot be null")));
49604948

4961-
if (ARR_DIMS(lbs)[0] != ndims)
4949+
if (ndims != ((ARR_NDIM(lbs) > 0) ? ARR_DIMS(lbs)[0] : 0))
49624950
ereport(ERROR,
49634951
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49644952
errmsg("wrong number of array subscripts"),
@@ -4976,12 +4964,12 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
49764964
lbsv = deflbs;
49774965
}
49784966

4967+
nitems = ArrayGetNItems(ndims, dimv);
4968+
49794969
/* fast track for empty array */
4980-
if (ndims == 0)
4970+
if (nitems <= 0)
49814971
return construct_empty_array(elmtype);
49824972

4983-
nitems = ArrayGetNItems(ndims, dimv);
4984-
49854973
/*
49864974
* We arrange to look up info about element type only once per series of
49874975
* 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
@@ -1290,16 +1290,43 @@ select array_fill('juhu'::text, array[3,3]);
12901290
{{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
12911291
(1 row)
12921292

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

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)
0