Commit f0395d50 authored by Tom Lane's avatar Tom Lane

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.
parent 36e012e7
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.196 2006/10/06 17:13:59 petere Exp $
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.197 2006/11/06 18:21:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2280,6 +2280,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
int *elem_lbs = NULL;
bool firstone = true;
bool havenulls = false;
bool haveempty = false;
char **subdata;
bits8 **subbitmaps;
int *subbytes;
......@@ -2302,11 +2303,15 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
bool eisnull;
Datum arraydatum;
ArrayType *array;
int this_ndims;
arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
/* ignore null subarrays */
/* temporarily ignore null subarrays */
if (eisnull)
{
haveempty = true;
continue;
}
array = DatumGetArrayTypeP(arraydatum);
......@@ -2320,10 +2325,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,
......@@ -2341,7 +2354,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),
......@@ -2356,13 +2369,29 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
nbytes += subbytes[outer_nelems];
subnitems[outer_nelems] = ArrayGetNItems(ARR_NDIM(array),
subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
ARR_DIMS(array));
nitems += subnitems[outer_nelems];
havenulls |= ARR_HASNULL(array);
outer_nelems++;
}
/*
* If all items were null or 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 */
return PointerGetDatum(construct_empty_array(element_type));
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment