Skip to content

Commit f0395d5

Browse files
committed
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.
1 parent 36e012e commit f0395d5

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

src/backend/executor/execQual.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.196 2006/10/06 17:13:59 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.197 2006/11/06 18:21:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2280,6 +2280,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
22802280
int *elem_lbs = NULL;
22812281
bool firstone = true;
22822282
bool havenulls = false;
2283+
bool haveempty = false;
22832284
char **subdata;
22842285
bits8 **subbitmaps;
22852286
int *subbytes;
@@ -2302,11 +2303,15 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23022303
bool eisnull;
23032304
Datum arraydatum;
23042305
ArrayType *array;
2306+
int this_ndims;
23052307

23062308
arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2307-
/* ignore null subarrays */
2309+
/* temporarily ignore null subarrays */
23082310
if (eisnull)
2311+
{
2312+
haveempty = true;
23092313
continue;
2314+
}
23102315

23112316
array = DatumGetArrayTypeP(arraydatum);
23122317

@@ -2320,10 +2325,18 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23202325
format_type_be(ARR_ELEMTYPE(array)),
23212326
format_type_be(element_type))));
23222327

2328+
this_ndims = ARR_NDIM(array);
2329+
/* temporarily ignore zero-dimensional subarrays */
2330+
if (this_ndims <= 0)
2331+
{
2332+
haveempty = true;
2333+
continue;
2334+
}
2335+
23232336
if (firstone)
23242337
{
23252338
/* Get sub-array details from first member */
2326-
elem_ndims = ARR_NDIM(array);
2339+
elem_ndims = this_ndims;
23272340
ndims = elem_ndims + 1;
23282341
if (ndims <= 0 || ndims > MAXDIM)
23292342
ereport(ERROR,
@@ -2341,7 +2354,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23412354
else
23422355
{
23432356
/* Check other sub-arrays are compatible */
2344-
if (elem_ndims != ARR_NDIM(array) ||
2357+
if (elem_ndims != this_ndims ||
23452358
memcmp(elem_dims, ARR_DIMS(array),
23462359
elem_ndims * sizeof(int)) != 0 ||
23472360
memcmp(elem_lbs, ARR_LBOUND(array),
@@ -2356,13 +2369,29 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23562369
subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
23572370
subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
23582371
nbytes += subbytes[outer_nelems];
2359-
subnitems[outer_nelems] = ArrayGetNItems(ARR_NDIM(array),
2372+
subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
23602373
ARR_DIMS(array));
23612374
nitems += subnitems[outer_nelems];
23622375
havenulls |= ARR_HASNULL(array);
23632376
outer_nelems++;
23642377
}
23652378

2379+
/*
2380+
* If all items were null or empty arrays, return an empty array;
2381+
* otherwise, if some were and some weren't, raise error. (Note:
2382+
* we must special-case this somehow to avoid trying to generate
2383+
* a 1-D array formed from empty arrays. It's not ideal...)
2384+
*/
2385+
if (haveempty)
2386+
{
2387+
if (ndims == 0) /* didn't find any nonempty array */
2388+
return PointerGetDatum(construct_empty_array(element_type));
2389+
ereport(ERROR,
2390+
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2391+
errmsg("multidimensional arrays must have array "
2392+
"expressions with matching dimensions")));
2393+
}
2394+
23662395
/* setup for multi-D array */
23672396
dims[0] = outer_nelems;
23682397
lbs[0] = 1;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy