88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.196 2006/10 /0617:13:59 petere Exp $
11+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.197 2006/11 /0618:21:31 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -2280,6 +2280,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
22802280int * elem_lbs = NULL ;
22812281bool firstone = true;
22822282bool havenulls = false;
2283+ bool haveempty = false;
22832284char * * subdata ;
22842285bits8 * * subbitmaps ;
22852286int * subbytes ;
@@ -2302,11 +2303,15 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23022303bool eisnull ;
23032304Datum arraydatum ;
23042305ArrayType * array ;
2306+ int this_ndims ;
23052307
23062308arraydatum = ExecEvalExpr (e ,econtext ,& eisnull ,NULL );
2307- /* ignore null subarrays */
2309+ /*temporarily ignore null subarrays */
23082310if (eisnull )
2311+ {
2312+ haveempty = true;
23092313continue ;
2314+ }
23102315
23112316array = DatumGetArrayTypeP (arraydatum );
23122317
@@ -2320,10 +2325,18 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23202325format_type_be (ARR_ELEMTYPE (array )),
23212326format_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+
23232336if (firstone )
23242337{
23252338/* Get sub-array details from first member */
2326- elem_ndims = ARR_NDIM ( array ) ;
2339+ elem_ndims = this_ndims ;
23272340ndims = elem_ndims + 1 ;
23282341if (ndims <=0 || ndims > MAXDIM )
23292342ereport (ERROR ,
@@ -2341,7 +2354,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23412354else
23422355{
23432356/* Check other sub-arrays are compatible */
2344- if (elem_ndims != ARR_NDIM ( array ) ||
2357+ if (elem_ndims != this_ndims ||
23452358memcmp (elem_dims ,ARR_DIMS (array ),
23462359elem_ndims * sizeof (int ))!= 0 ||
23472360memcmp (elem_lbs ,ARR_LBOUND (array ),
@@ -2356,13 +2369,29 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
23562369subbitmaps [outer_nelems ]= ARR_NULLBITMAP (array );
23572370subbytes [outer_nelems ]= ARR_SIZE (array )- ARR_DATA_OFFSET (array );
23582371nbytes += subbytes [outer_nelems ];
2359- subnitems [outer_nelems ]= ArrayGetNItems (ARR_NDIM ( array ) ,
2372+ subnitems [outer_nelems ]= ArrayGetNItems (this_ndims ,
23602373ARR_DIMS (array ));
23612374nitems += subnitems [outer_nelems ];
23622375havenulls |=ARR_HASNULL (array );
23632376outer_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 */
23672396dims [0 ]= outer_nelems ;
23682397lbs [0 ]= 1 ;