Skip to content

Commit e945246

Browse files
committed
Fix ARRAY[] construct so that in multidimensional case, elements can
be anything yielding an array of the proper kind, not only sub-ARRAY[] constructs; do subscript checking at runtime not parse time. Also, adjust array_cat to make array || array comply with the SQL99 spec. Joe Conway
1 parent de9c553 commit e945246

File tree

12 files changed

+105
-115
lines changed

12 files changed

+105
-115
lines changed

src/backend/executor/execQual.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.141 2003/08/08 21:41:39 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.142 2003/08/17 23:43:25 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1620,16 +1620,18 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
16201620
ArrayType *result;
16211621
List *element;
16221622
Oid element_type = arrayExpr->element_typeid;
1623-
int ndims = arrayExpr->ndims;
1623+
int ndims = 0;
16241624
int dims[MAXDIM];
16251625
int lbs[MAXDIM];
16261626

1627-
if (ndims == 1)
1627+
if (!arrayExpr->multidims)
16281628
{
1629+
/* Elements are presumably of scalar type */
16291630
int nelems;
16301631
Datum *dvalues;
16311632
int i = 0;
16321633

1634+
ndims = 1;
16331635
nelems = length(astate->elements);
16341636

16351637
/* Shouldn't happen here, but if length is 0, return NULL */
@@ -1667,6 +1669,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
16671669
}
16681670
else
16691671
{
1672+
/* Must be nested array expressions */
16701673
char *dat = NULL;
16711674
Size ndatabytes = 0;
16721675
int nbytes;
@@ -1677,12 +1680,6 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
16771680
bool firstone = true;
16781681
int i;
16791682

1680-
if (ndims <= 0 || ndims > MAXDIM)
1681-
ereport(ERROR,
1682-
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1683-
errmsg("number of array dimensions exceeds the maximum allowed, %d",
1684-
MAXDIM)));
1685-
16861683
/* loop through and get data area from each element */
16871684
foreach(element, astate->elements)
16881685
{
@@ -1701,14 +1698,32 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
17011698

17021699
array = DatumGetArrayTypeP(arraydatum);
17031700

1701+
/* run-time double-check on element type */
1702+
if (element_type != ARR_ELEMTYPE(array))
1703+
ereport(ERROR,
1704+
(errcode(ERRCODE_DATATYPE_MISMATCH),
1705+
errmsg("cannot merge incompatible arrays"),
1706+
errdetail("Array with element type %s cannot be "
1707+
"included in ARRAY construct with element type %s.",
1708+
format_type_be(ARR_ELEMTYPE(array)),
1709+
format_type_be(element_type))));
1710+
17041711
if (firstone)
17051712
{
17061713
/* Get sub-array details from first member */
17071714
elem_ndims = ARR_NDIM(array);
1715+
ndims = elem_ndims + 1;
1716+
if (ndims <= 0 || ndims > MAXDIM)
1717+
ereport(ERROR,
1718+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1719+
errmsg("number of array dimensions exceeds " \
1720+
"the maximum allowed, %d", MAXDIM)));
1721+
17081722
elem_dims = (int *) palloc(elem_ndims * sizeof(int));
17091723
memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
17101724
elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
17111725
memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
1726+
17121727
firstone = false;
17131728
}
17141729
else

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.264 2003/08/17 19:58:05 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.265 2003/08/17 23:43:25 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -947,7 +947,7 @@ _copyArrayExpr(ArrayExpr *from)
947947
COPY_SCALAR_FIELD(array_typeid);
948948
COPY_SCALAR_FIELD(element_typeid);
949949
COPY_NODE_FIELD(elements);
950-
COPY_SCALAR_FIELD(ndims);
950+
COPY_SCALAR_FIELD(multidims);
951951

952952
return newnode;
953953
}

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.208 2003/08/17 19:58:05 tgl Exp $
21+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.209 2003/08/17 23:43:26 tgl Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -409,7 +409,7 @@ _equalArrayExpr(ArrayExpr *a, ArrayExpr *b)
409409
COMPARE_SCALAR_FIELD(array_typeid);
410410
COMPARE_SCALAR_FIELD(element_typeid);
411411
COMPARE_NODE_FIELD(elements);
412-
COMPARE_SCALAR_FIELD(ndims);
412+
COMPARE_SCALAR_FIELD(multidims);
413413

414414
return true;
415415
}

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.217 2003/08/08 21:41:44 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.218 2003/08/17 23:43:26 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -785,7 +785,7 @@ _outArrayExpr(StringInfo str, ArrayExpr *node)
785785
WRITE_OID_FIELD(array_typeid);
786786
WRITE_OID_FIELD(element_typeid);
787787
WRITE_NODE_FIELD(elements);
788-
WRITE_INT_FIELD(ndims);
788+
WRITE_BOOL_FIELD(multidims);
789789
}
790790

791791
static void

src/backend/nodes/readfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.161 2003/08/04 02:39:59 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.162 2003/08/17 23:43:26 tgl Exp $
1212
*
1313
* NOTES
1414
* Path and Plan nodes do not have any readfuncs support, because we
@@ -659,7 +659,7 @@ _readArrayExpr(void)
659659
READ_OID_FIELD(array_typeid);
660660
READ_OID_FIELD(element_typeid);
661661
READ_NODE_FIELD(elements);
662-
READ_INT_FIELD(ndims);
662+
READ_BOOL_FIELD(multidims);
663663

664664
READ_DONE();
665665
}

src/backend/optimizer/util/clauses.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.152 2003/08/08 21:41:55 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.153 2003/08/17 23:43:26 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHOR DATE MAJOR EVENT
@@ -1515,7 +1515,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
15151515
newarray->array_typeid = arrayexpr->array_typeid;
15161516
newarray->element_typeid = arrayexpr->element_typeid;
15171517
newarray->elements = FastListValue(&newelems);
1518-
newarray->ndims = arrayexpr->ndims;
1518+
newarray->multidims = arrayexpr->multidims;
15191519

15201520
if (all_const)
15211521
return (Node *) evaluate_expr((Expr *) newarray,

src/backend/parser/parse_expr.c

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.160 2003/08/04 02:40:01 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.161 2003/08/17 23:43:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -748,7 +748,6 @@ transformExpr(ParseState *pstate, Node *expr)
748748
List *element;
749749
Oid array_type;
750750
Oid element_type;
751-
int ndims;
752751

753752
/* Transform the element expressions */
754753
foreach(element, a->elements)
@@ -781,59 +780,25 @@ transformExpr(ParseState *pstate, Node *expr)
781780
if (array_type != InvalidOid)
782781
{
783782
/* Elements are presumably of scalar type */
784-
ndims = 1;
783+
newa->multidims = false;
785784
}
786785
else
787786
{
788787
/* Must be nested array expressions */
788+
newa->multidims = true;
789+
789790
array_type = element_type;
790791
element_type = get_element_type(array_type);
791792
if (!OidIsValid(element_type))
792793
ereport(ERROR,
793794
(errcode(ERRCODE_UNDEFINED_OBJECT),
794795
errmsg("could not find array type for datatype %s",
795796
format_type_be(array_type))));
796-
797-
/*
798-
* make sure the element expressions all have the same
799-
* number of dimensions
800-
*/
801-
ndims = 0;
802-
foreach(element, newcoercedelems)
803-
{
804-
ArrayExpr *e = (ArrayExpr *) lfirst(element);
805-
806-
if (!IsA(e, ArrayExpr))
807-
ereport(ERROR,
808-
(errcode(ERRCODE_SYNTAX_ERROR),
809-
errmsg("multidimensional ARRAY[] must be built from nested array expressions")));
810-
if (ndims == 0)
811-
ndims = e->ndims;
812-
else if (e->ndims != ndims)
813-
ereport(ERROR,
814-
(errcode(ERRCODE_SYNTAX_ERROR),
815-
errmsg("nested array expressions must have common number of dimensions")));
816-
if (e->element_typeid != element_type)
817-
ereport(ERROR,
818-
(errcode(ERRCODE_SYNTAX_ERROR),
819-
errmsg("nested array expressions must have common element type")));
820-
821-
}
822-
/* increment the number of dimensions */
823-
ndims++;
824-
825-
/* make sure we don't have too many dimensions now */
826-
if (ndims > MAXDIM)
827-
ereport(ERROR,
828-
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
829-
errmsg("number of array dimensions exceeds the maximum allowed, %d",
830-
MAXDIM)));
831797
}
832798

833799
newa->array_typeid = array_type;
834800
newa->element_typeid = element_type;
835801
newa->elements = newcoercedelems;
836-
newa->ndims = ndims;
837802

838803
result = (Node *) newa;
839804
break;

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