aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-01-05 11:33:51 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2017-01-05 11:33:51 -0500
commit82f8107b92c9104ec9d9465f3f6a4c6dab4c124a (patch)
tree8766ef53494ee7d41d05dc3ceae41d11b9042b91 /src/backend/utils/adt/arrayfuncs.c
parent2e44f379bc0219f6864dbfb901129796e6feec44 (diff)
downloadpostgresql-82f8107b92c9104ec9d9465f3f6a4c6dab4c124a.tar.gz
postgresql-82f8107b92c9104ec9d9465f3f6a4c6dab4c124a.zip
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
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c26
1 files changed, 7 insertions, 19 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 11e1bce4338..d9c8aa569c9 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -5734,25 +5734,19 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
/*
* Params checks
*/
- if (ARR_NDIM(dims) != 1)
+ if (ARR_NDIM(dims) > 1)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("wrong number of array subscripts"),
errdetail("Dimension array must be one dimensional.")));
- if (ARR_LBOUND(dims)[0] != 1)
- ereport(ERROR,
- (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("wrong range of array subscripts"),
- errdetail("Lower bound of dimension array must be one.")));
-
if (array_contains_nulls(dims))
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("dimension values cannot be null")));
dimv = (int *) ARR_DATA_PTR(dims);
- ndims = ARR_DIMS(dims)[0];
+ ndims = (ARR_NDIM(dims) > 0) ? ARR_DIMS(dims)[0] : 0;
if (ndims < 0) /* we do allow zero-dimension arrays */
ereport(ERROR,
@@ -5766,24 +5760,18 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
if (lbs != NULL)
{
- if (ARR_NDIM(lbs) != 1)
+ if (ARR_NDIM(lbs) > 1)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("wrong number of array subscripts"),
errdetail("Dimension array must be one dimensional.")));
- if (ARR_LBOUND(lbs)[0] != 1)
- ereport(ERROR,
- (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
- errmsg("wrong range of array subscripts"),
- errdetail("Lower bound of dimension array must be one.")));
-
if (array_contains_nulls(lbs))
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("dimension values cannot be null")));
- if (ARR_DIMS(lbs)[0] != ndims)
+ if (ndims != ((ARR_NDIM(lbs) > 0) ? ARR_DIMS(lbs)[0] : 0))
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("wrong number of array subscripts"),
@@ -5801,12 +5789,12 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
lbsv = deflbs;
}
+ nitems = ArrayGetNItems(ndims, dimv);
+
/* fast track for empty array */
- if (ndims == 0)
+ if (nitems <= 0)
return construct_empty_array(elmtype);
- nitems = ArrayGetNItems(ndims, dimv);
-
/*
* We arrange to look up info about element type only once per series of
* calls, assuming the element type doesn't change underneath us.