Skip to content

Commit 85b762b

Browse files
committed
Clean up array-dimensions parser a bit.
This code still needs a lot of love, however ...
1 parent 12b401f commit 85b762b

File tree

1 file changed

+57
-41
lines changed

1 file changed

+57
-41
lines changed

src/backend/utils/adt/arrayfuncs.c

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.64 2000/07/27 03:50:52 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.65 2000/11/14 23:28:13 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -100,15 +100,12 @@ array_in(PG_FUNCTION_ARGS)
100100
Oid element_type = PG_GETARG_OID(1); /* type of an array element */
101101
int32 typmod = PG_GETARG_INT32(2); /* typmod for array elements */
102102
int typlen;
103-
bool typbyval,
104-
done;
103+
bool typbyval;
105104
char typdelim;
106105
Oid typinput;
107106
Oid typelem;
108107
char *string_save,
109-
*p,
110-
*q,
111-
*r;
108+
*p;
112109
FmgrInfo inputproc;
113110
int i,
114111
nitems;
@@ -120,64 +117,83 @@ array_in(PG_FUNCTION_ARGS)
120117
lBound[MAXDIM];
121118
char typalign;
122119

120+
/* Get info about element type, including its input conversion proc */
123121
system_cache_lookup(element_type, true, &typlen, &typbyval, &typdelim,
124122
&typelem, &typinput, &typalign);
125-
126123
fmgr_info(typinput, &inputproc);
127124

125+
/* Make a modifiable copy of the input */
126+
/* XXX why are we allocating an extra 2 bytes here? */
128127
string_save = (char *) palloc(strlen(string) + 3);
129128
strcpy(string_save, string);
130129

131-
/* --- read array dimensions ---------- */
132-
p = q = string_save;
133-
done = false;
134-
for (ndim = 0; !done;)
130+
/*
131+
* If the input string starts with dimension info, read and use that.
132+
* Otherwise, we require the input to be in curly-brace style, and we
133+
* prescan the input to determine dimensions.
134+
*
135+
* Dimension info takes the form of one or more [n] or [m:n] items.
136+
* The outer loop iterates once per dimension item.
137+
*/
138+
p = string_save;
139+
ndim = 0;
140+
for (;;)
135141
{
142+
char *q;
143+
int ub;
144+
145+
/*
146+
* Note: we currently allow whitespace between, but not within,
147+
* dimension items.
148+
*/
136149
while (isspace((int) *p))
137150
p++;
138-
if (*p == '[')
151+
if (*p != '[')
152+
break; /* no more dimension items */
153+
p++;
154+
if (ndim >= MAXDIM)
155+
elog(ERROR, "array_in: more than %d dimensions", MAXDIM);
156+
for (q = p; isdigit((int) *q); q++);
157+
if (q == p) /* no digits? */
158+
elog(ERROR, "array_in: missing dimension value");
159+
if (*q == ':')
139160
{
140-
p++;
141-
if ((r = (char *) strchr(p, ':')) == (char *) NULL)
142-
lBound[ndim] = 1;
143-
else
144-
{
145-
*r = '\0';
146-
lBound[ndim] = atoi(p);
147-
p = r + 1;
148-
}
149-
for (q = p; isdigit((int) *q); q++);
150-
if (*q != ']')
151-
elog(ERROR, "array_in: missing ']' in array declaration");
161+
/* [m:n] format */
152162
*q = '\0';
153-
dim[ndim] = atoi(p);
154-
if ((dim[ndim] < 0) || (lBound[ndim] < 0))
155-
elog(ERROR, "array_in: array dimensions need to be positive");
156-
dim[ndim] = dim[ndim] - lBound[ndim] + 1;
157-
if (dim[ndim] < 0)
158-
elog(ERROR, "array_in: upper_bound cannot be < lower_bound");
163+
lBound[ndim] = atoi(p);
159164
p = q + 1;
160-
ndim++;
165+
for (q = p; isdigit((int) *q); q++);
166+
if (q == p) /* no digits? */
167+
elog(ERROR, "array_in: missing dimension value");
161168
}
162169
else
163-
done = true;
170+
{
171+
/* [n] format */
172+
lBound[ndim] = 1;
173+
}
174+
if (*q != ']')
175+
elog(ERROR, "array_in: missing ']' in array declaration");
176+
*q = '\0';
177+
ub = atoi(p);
178+
p = q + 1;
179+
if (ub < lBound[ndim])
180+
elog(ERROR, "array_in: upper_bound cannot be < lower_bound");
181+
dim[ndim] = ub - lBound[ndim] + 1;
182+
ndim++;
164183
}
165184

166185
if (ndim == 0)
167186
{
168-
if (*p == '{')
169-
{
170-
ndim = ArrayCount(p, dim, typdelim);
171-
for (i = 0; i < ndim; i++)
172-
lBound[i] = 1;
173-
}
174-
else
187+
/* No array dimensions, so intuit dimensions from brace structure */
188+
if (*p != '{')
175189
elog(ERROR, "array_in: Need to specify dimension");
190+
ndim = ArrayCount(p, dim, typdelim);
191+
for (i = 0; i < ndim; i++)
192+
lBound[i] = 1;
176193
}
177194
else
178195
{
179-
while (isspace((int) *p))
180-
p++;
196+
/* If array dimensions are given, expect '=' operator */
181197
if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
182198
elog(ERROR, "array_in: missing assignment operator");
183199
p += strlen(ASSGN);

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