8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -2280,6 +2280,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2280
2280
int * elem_lbs = NULL ;
2281
2281
bool firstone = true;
2282
2282
bool havenulls = false;
2283
+ bool haveempty = false;
2283
2284
char * * subdata ;
2284
2285
bits8 * * subbitmaps ;
2285
2286
int * subbytes ;
@@ -2302,11 +2303,15 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2302
2303
bool eisnull ;
2303
2304
Datum arraydatum ;
2304
2305
ArrayType * array ;
2306
+ int this_ndims ;
2305
2307
2306
2308
arraydatum = ExecEvalExpr (e , econtext , & eisnull , NULL );
2307
- /* ignore null subarrays */
2309
+ /* temporarily ignore null subarrays */
2308
2310
if (eisnull )
2311
+ {
2312
+ haveempty = true;
2309
2313
continue ;
2314
+ }
2310
2315
2311
2316
array = DatumGetArrayTypeP (arraydatum );
2312
2317
@@ -2320,10 +2325,18 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2320
2325
format_type_be (ARR_ELEMTYPE (array )),
2321
2326
format_type_be (element_type ))));
2322
2327
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
+
2323
2336
if (firstone )
2324
2337
{
2325
2338
/* Get sub-array details from first member */
2326
- elem_ndims = ARR_NDIM ( array ) ;
2339
+ elem_ndims = this_ndims ;
2327
2340
ndims = elem_ndims + 1 ;
2328
2341
if (ndims <= 0 || ndims > MAXDIM )
2329
2342
ereport (ERROR ,
@@ -2341,7 +2354,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2341
2354
else
2342
2355
{
2343
2356
/* Check other sub-arrays are compatible */
2344
- if (elem_ndims != ARR_NDIM ( array ) ||
2357
+ if (elem_ndims != this_ndims ||
2345
2358
memcmp (elem_dims , ARR_DIMS (array ),
2346
2359
elem_ndims * sizeof (int )) != 0 ||
2347
2360
memcmp (elem_lbs , ARR_LBOUND (array ),
@@ -2356,13 +2369,29 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2356
2369
subbitmaps [outer_nelems ] = ARR_NULLBITMAP (array );
2357
2370
subbytes [outer_nelems ] = ARR_SIZE (array ) - ARR_DATA_OFFSET (array );
2358
2371
nbytes += subbytes [outer_nelems ];
2359
- subnitems [outer_nelems ] = ArrayGetNItems (ARR_NDIM ( array ) ,
2372
+ subnitems [outer_nelems ] = ArrayGetNItems (this_ndims ,
2360
2373
ARR_DIMS (array ));
2361
2374
nitems += subnitems [outer_nelems ];
2362
2375
havenulls |= ARR_HASNULL (array );
2363
2376
outer_nelems ++ ;
2364
2377
}
2365
2378
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
+
2366
2395
/* setup for multi-D array */
2367
2396
dims [0 ] = outer_nelems ;
2368
2397
lbs [0 ] = 1 ;
0 commit comments