aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/executor/execQual.c33
-rw-r--r--src/backend/nodes/copyfuncs.c4
-rw-r--r--src/backend/nodes/equalfuncs.c4
-rw-r--r--src/backend/nodes/outfuncs.c4
-rw-r--r--src/backend/nodes/readfuncs.c4
-rw-r--r--src/backend/optimizer/util/clauses.c4
-rw-r--r--src/backend/parser/parse_expr.c43
-rw-r--r--src/backend/utils/adt/array_userfuncs.c70
8 files changed, 77 insertions, 89 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 4ecae71cd68..d05eedceecf 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.141 2003/08/08 21:41:39 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.142 2003/08/17 23:43:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1620,16 +1620,18 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
ArrayType *result;
List *element;
Oid element_type = arrayExpr->element_typeid;
- int ndims = arrayExpr->ndims;
+ int ndims = 0;
int dims[MAXDIM];
int lbs[MAXDIM];
- if (ndims == 1)
+ if (!arrayExpr->multidims)
{
+ /* Elements are presumably of scalar type */
int nelems;
Datum *dvalues;
int i = 0;
+ ndims = 1;
nelems = length(astate->elements);
/* Shouldn't happen here, but if length is 0, return NULL */
@@ -1667,6 +1669,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
}
else
{
+ /* Must be nested array expressions */
char *dat = NULL;
Size ndatabytes = 0;
int nbytes;
@@ -1677,12 +1680,6 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
bool firstone = true;
int i;
- if (ndims <= 0 || ndims > MAXDIM)
- ereport(ERROR,
- (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("number of array dimensions exceeds the maximum allowed, %d",
- MAXDIM)));
-
/* loop through and get data area from each element */
foreach(element, astate->elements)
{
@@ -1701,14 +1698,32 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
array = DatumGetArrayTypeP(arraydatum);
+ /* run-time double-check on element type */
+ if (element_type != ARR_ELEMTYPE(array))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("cannot merge incompatible arrays"),
+ errdetail("Array with element type %s cannot be "
+ "included in ARRAY construct with element type %s.",
+ format_type_be(ARR_ELEMTYPE(array)),
+ format_type_be(element_type))));
+
if (firstone)
{
/* Get sub-array details from first member */
elem_ndims = ARR_NDIM(array);
+ ndims = elem_ndims + 1;
+ if (ndims <= 0 || ndims > MAXDIM)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("number of array dimensions exceeds " \
+ "the maximum allowed, %d", MAXDIM)));
+
elem_dims = (int *) palloc(elem_ndims * sizeof(int));
memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
+
firstone = false;
}
else
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 55076ec48d3..17b32cd4ab8 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.264 2003/08/17 19:58:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.265 2003/08/17 23:43:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -947,7 +947,7 @@ _copyArrayExpr(ArrayExpr *from)
COPY_SCALAR_FIELD(array_typeid);
COPY_SCALAR_FIELD(element_typeid);
COPY_NODE_FIELD(elements);
- COPY_SCALAR_FIELD(ndims);
+ COPY_SCALAR_FIELD(multidims);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index e3a59f4739a..5066a556e45 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.208 2003/08/17 19:58:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.209 2003/08/17 23:43:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -409,7 +409,7 @@ _equalArrayExpr(ArrayExpr *a, ArrayExpr *b)
COMPARE_SCALAR_FIELD(array_typeid);
COMPARE_SCALAR_FIELD(element_typeid);
COMPARE_NODE_FIELD(elements);
- COMPARE_SCALAR_FIELD(ndims);
+ COMPARE_SCALAR_FIELD(multidims);
return true;
}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index b7c1a370695..97d9aed2407 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.217 2003/08/08 21:41:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.218 2003/08/17 23:43:26 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
@@ -785,7 +785,7 @@ _outArrayExpr(StringInfo str, ArrayExpr *node)
WRITE_OID_FIELD(array_typeid);
WRITE_OID_FIELD(element_typeid);
WRITE_NODE_FIELD(elements);
- WRITE_INT_FIELD(ndims);
+ WRITE_BOOL_FIELD(multidims);
}
static void
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index d261ac7f862..74d25c7db1b 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.161 2003/08/04 02:39:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.162 2003/08/17 23:43:26 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
@@ -659,7 +659,7 @@ _readArrayExpr(void)
READ_OID_FIELD(array_typeid);
READ_OID_FIELD(element_typeid);
READ_NODE_FIELD(elements);
- READ_INT_FIELD(ndims);
+ READ_BOOL_FIELD(multidims);
READ_DONE();
}
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index b95002ef43e..5de4d19a5b8 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.152 2003/08/08 21:41:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.153 2003/08/17 23:43:26 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1515,7 +1515,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
newarray->array_typeid = arrayexpr->array_typeid;
newarray->element_typeid = arrayexpr->element_typeid;
newarray->elements = FastListValue(&newelems);
- newarray->ndims = arrayexpr->ndims;
+ newarray->multidims = arrayexpr->multidims;
if (all_const)
return (Node *) evaluate_expr((Expr *) newarray,
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 64718a48699..06f8917db60 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.160 2003/08/04 02:40:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.161 2003/08/17 23:43:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -748,7 +748,6 @@ transformExpr(ParseState *pstate, Node *expr)
List *element;
Oid array_type;
Oid element_type;
- int ndims;
/* Transform the element expressions */
foreach(element, a->elements)
@@ -781,11 +780,13 @@ transformExpr(ParseState *pstate, Node *expr)
if (array_type != InvalidOid)
{
/* Elements are presumably of scalar type */
- ndims = 1;
+ newa->multidims = false;
}
else
{
/* Must be nested array expressions */
+ newa->multidims = true;
+
array_type = element_type;
element_type = get_element_type(array_type);
if (!OidIsValid(element_type))
@@ -793,47 +794,11 @@ transformExpr(ParseState *pstate, Node *expr)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find array type for datatype %s",
format_type_be(array_type))));
-
- /*
- * make sure the element expressions all have the same
- * number of dimensions
- */
- ndims = 0;
- foreach(element, newcoercedelems)
- {
- ArrayExpr *e = (ArrayExpr *) lfirst(element);
-
- if (!IsA(e, ArrayExpr))
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("multidimensional ARRAY[] must be built from nested array expressions")));
- if (ndims == 0)
- ndims = e->ndims;
- else if (e->ndims != ndims)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("nested array expressions must have common number of dimensions")));
- if (e->element_typeid != element_type)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("nested array expressions must have common element type")));
-
- }
- /* increment the number of dimensions */
- ndims++;
-
- /* make sure we don't have too many dimensions now */
- if (ndims > MAXDIM)
- ereport(ERROR,
- (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("number of array dimensions exceeds the maximum allowed, %d",
- MAXDIM)));
}
newa->array_typeid = array_type;
newa->element_typeid = element_type;
newa->elements = newcoercedelems;
- newa->ndims = ndims;
result = (Node *) newa;
break;
diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c
index a32ea871b58..ced3233d218 100644
--- a/src/backend/utils/adt/array_userfuncs.c
+++ b/src/backend/utils/adt/array_userfuncs.c
@@ -6,7 +6,7 @@
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.7 2003/08/04 00:43:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.8 2003/08/17 23:43:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -132,7 +132,7 @@ array_push(PG_FUNCTION_ARGS)
/*-----------------------------------------------------------------------------
* array_cat :
- * concatenate two nD arrays to form an (n+1)D array, or
+ * concatenate two nD arrays to form an nD array, or
* push an (n-1)D array onto the end of an nD array
*----------------------------------------------------------------------------
*/
@@ -154,6 +154,7 @@ array_cat(PG_FUNCTION_ARGS)
*lbs2,
ndims2,
ndatabytes2;
+ int i;
char *dat1,
*dat2;
Oid element_type;
@@ -164,11 +165,14 @@ array_cat(PG_FUNCTION_ARGS)
v1 = PG_GETARG_ARRAYTYPE_P(0);
v2 = PG_GETARG_ARRAYTYPE_P(1);
- /*
- * We must have one of the following combinations of inputs: 1) one
- * empty array, and one non-empty array 2) both arrays empty 3) two
- * arrays with ndims1 == ndims2 4) ndims1 == ndims2 - 1 5) ndims1 ==
- * ndims2 + 1
+ /*----------
+ * We must have one of the following combinations of inputs:
+ * 1) one empty array, and one non-empty array
+ * 2) both arrays empty
+ * 3) two arrays with ndims1 == ndims2
+ * 4) ndims1 == ndims2 - 1
+ * 5) ndims1 == ndims2 + 1
+ *----------
*/
ndims1 = ARR_NDIM(v1);
ndims2 = ARR_NDIM(v2);
@@ -185,8 +189,10 @@ array_cat(PG_FUNCTION_ARGS)
if (ndims2 == 0)
PG_RETURN_ARRAYTYPE_P(v1);
- /* the rest fall into combo 2, 3, or 4 */
- if (ndims1 != ndims2 && ndims1 != ndims2 - 1 && ndims1 != ndims2 + 1)
+ /* the rest fall under rule 3, 4, or 5 */
+ if (ndims1 != ndims2 &&
+ ndims1 != ndims2 - 1 &&
+ ndims1 != ndims2 + 1)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("cannot concatenate incompatible arrays"),
@@ -197,7 +203,7 @@ array_cat(PG_FUNCTION_ARGS)
element_type1 = ARR_ELEMTYPE(v1);
element_type2 = ARR_ELEMTYPE(v2);
- /* Do we have a matching element types */
+ /* Check we have matching element types */
if (element_type1 != element_type2)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -223,29 +229,27 @@ array_cat(PG_FUNCTION_ARGS)
if (ndims1 == ndims2)
{
/*
- * resulting array has two element outer array made up of input
- * argument arrays
+ * resulting array is made up of the elements (possibly arrays
+ * themselves) of the input argument arrays
*/
- int i;
-
- ndims = ndims1 + 1;
+ ndims = ndims1;
dims = (int *) palloc(ndims * sizeof(int));
lbs = (int *) palloc(ndims * sizeof(int));
- dims[0] = 2; /* outer array made up of two input arrays */
- lbs[0] = 1; /* start lower bound at 1 */
+ dims[0] = dims1[0] + dims2[0];
+ lbs[0] = lbs1[0];
- for (i = 0; i < ndims1; i++)
+ for (i = 1; i < ndims; i++)
{
if (dims1[i] != dims2[i] || lbs1[i] != lbs2[i])
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("cannot concatenate incompatible arrays"),
- errdetail("Arrays with differing dimensions are not "
- "compatible for concatenation.")));
+ errdetail("Arrays with differing element dimensions are "
+ "not compatible for concatenation.")));
- dims[i + 1] = dims1[i];
- lbs[i + 1] = lbs1[i];
+ dims[i] = dims1[i];
+ lbs[i] = lbs1[i];
}
}
else if (ndims1 == ndims2 - 1)
@@ -255,15 +259,18 @@ array_cat(PG_FUNCTION_ARGS)
* with the first argument appended to the front of the outer
* dimension
*/
- int i;
-
ndims = ndims2;
- dims = dims2;
- lbs = lbs2;
+ dims = (int *) palloc(ndims * sizeof(int));
+ lbs = (int *) palloc(ndims * sizeof(int));
+ memcpy(dims, dims2, ndims * sizeof(int));
+ memcpy(lbs, lbs2, ndims * sizeof(int));
/* increment number of elements in outer array */
dims[0] += 1;
+ /* decrement outer array lower bound */
+ lbs[0] -= 1;
+
/* make sure the added element matches our existing elements */
for (i = 0; i < ndims1; i++)
{
@@ -276,17 +283,18 @@ array_cat(PG_FUNCTION_ARGS)
}
}
else
-/* (ndims1 == ndims2 + 1) */
{
/*
+ * (ndims1 == ndims2 + 1)
+ *
* resulting array has the first argument as the outer array, with
* the second argument appended to the end of the outer dimension
*/
- int i;
-
ndims = ndims1;
- dims = dims1;
- lbs = lbs1;
+ dims = (int *) palloc(ndims * sizeof(int));
+ lbs = (int *) palloc(ndims * sizeof(int));
+ memcpy(dims, dims1, ndims * sizeof(int));
+ memcpy(lbs, lbs1, ndims * sizeof(int));
/* increment number of elements in outer array */
dims[0] += 1;