mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
Repair bug #2694 concerning an ARRAY[] construct whose inputs are empty
sub-arrays. Per discussion, if all inputs are empty arrays then result must be an empty array too, whereas a mix of empty and nonempty arrays should (and already did) draw an error. In the back branches, the construct was strict: any NULL input immediately yielded a NULL output; so I left that behavior alone. HEAD was simply ignoring NULL sub-arrays, which doesn't seem very sensible. For lack of a better idea it now treats NULL sub-arrays the same as empty ones.
This commit is contained in:
parent
b4f5429fa8
commit
fc8c5fbf5d
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.171.4.1 2005/10/19 22:51:26 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.171.4.2 2006/11/06 18:21:47 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2170,6 +2170,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
|
||||
int *elem_dims = NULL;
|
||||
int *elem_lbs = NULL;
|
||||
bool firstone = true;
|
||||
bool haveempty = false;
|
||||
int i;
|
||||
|
||||
/* loop through and get data area from each element */
|
||||
@ -2179,6 +2180,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
|
||||
bool eisnull;
|
||||
Datum arraydatum;
|
||||
ArrayType *array;
|
||||
int this_ndims;
|
||||
int elem_ndatabytes;
|
||||
|
||||
arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
|
||||
@ -2200,10 +2202,18 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
|
||||
format_type_be(ARR_ELEMTYPE(array)),
|
||||
format_type_be(element_type))));
|
||||
|
||||
this_ndims = ARR_NDIM(array);
|
||||
/* temporarily ignore zero-dimensional subarrays */
|
||||
if (this_ndims <= 0)
|
||||
{
|
||||
haveempty = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (firstone)
|
||||
{
|
||||
/* Get sub-array details from first member */
|
||||
elem_ndims = ARR_NDIM(array);
|
||||
elem_ndims = this_ndims;
|
||||
ndims = elem_ndims + 1;
|
||||
if (ndims <= 0 || ndims > MAXDIM)
|
||||
ereport(ERROR,
|
||||
@ -2221,7 +2231,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
|
||||
else
|
||||
{
|
||||
/* Check other sub-arrays are compatible */
|
||||
if (elem_ndims != ARR_NDIM(array) ||
|
||||
if (elem_ndims != this_ndims ||
|
||||
memcmp(elem_dims, ARR_DIMS(array),
|
||||
elem_ndims * sizeof(int)) != 0 ||
|
||||
memcmp(elem_lbs, ARR_LBOUND(array),
|
||||
@ -2244,6 +2254,29 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
|
||||
elem_ndatabytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* If all items were empty arrays, return an empty array;
|
||||
* otherwise, if some were and some weren't, raise error. (Note:
|
||||
* we must special-case this somehow to avoid trying to generate
|
||||
* a 1-D array formed from empty arrays. It's not ideal...)
|
||||
*/
|
||||
if (haveempty)
|
||||
{
|
||||
if (ndims == 0) /* didn't find any nonempty array */
|
||||
{
|
||||
result = (ArrayType *) palloc(sizeof(ArrayType));
|
||||
result->size = sizeof(ArrayType);
|
||||
result->ndim = 0;
|
||||
result->flags = 0;
|
||||
result->elemtype = element_type;
|
||||
return PointerGetDatum(result);
|
||||
}
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("multidimensional arrays must have array "
|
||||
"expressions with matching dimensions")));
|
||||
}
|
||||
|
||||
/* setup for multi-D array */
|
||||
dims[0] = outer_nelems;
|
||||
lbs[0] = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user