summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-11-06 18:21:47 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-11-06 18:21:47 +0000
commitfc8c5fbf5d7763b070f50b1afa85c7f955a83d77 (patch)
tree301fc46329f2ef894164e3e69747979f515d439c
parentb4f5429fa84d08a6466f49b15d2586df9f183eb5 (diff)
downloadpostgresql-fc8c5fbf5d7763b070f50b1afa85c7f955a83d77.tar.gz
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.
-rw-r--r--src/backend/executor/execQual.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 5ff95e1087..91271423b0 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -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;