aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-11-14 23:28:13 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-11-14 23:28:13 +0000
commit85b762b49997b8f10913db9a015765f408f6f72c (patch)
tree2c82ccdb1abacf1824751127a935b3f9499778a5 /src/backend/utils/adt/arrayfuncs.c
parent12b401f73984240513bbb7d81aebf6c28f95b612 (diff)
downloadpostgresql-85b762b49997b8f10913db9a015765f408f6f72c.tar.gz
postgresql-85b762b49997b8f10913db9a015765f408f6f72c.zip
Clean up array-dimensions parser a bit.
This code still needs a lot of love, however ...
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index b0855b7740a..44f58840c36 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.64 2000/07/27 03:50:52 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.65 2000/11/14 23:28:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -100,15 +100,12 @@ array_in(PG_FUNCTION_ARGS)
Oid element_type = PG_GETARG_OID(1); /* type of an array element */
int32 typmod = PG_GETARG_INT32(2); /* typmod for array elements */
int typlen;
- bool typbyval,
- done;
+ bool typbyval;
char typdelim;
Oid typinput;
Oid typelem;
char *string_save,
- *p,
- *q,
- *r;
+ *p;
FmgrInfo inputproc;
int i,
nitems;
@@ -120,64 +117,83 @@ array_in(PG_FUNCTION_ARGS)
lBound[MAXDIM];
char typalign;
+ /* Get info about element type, including its input conversion proc */
system_cache_lookup(element_type, true, &typlen, &typbyval, &typdelim,
&typelem, &typinput, &typalign);
-
fmgr_info(typinput, &inputproc);
+ /* Make a modifiable copy of the input */
+ /* XXX why are we allocating an extra 2 bytes here? */
string_save = (char *) palloc(strlen(string) + 3);
strcpy(string_save, string);
- /* --- read array dimensions ---------- */
- p = q = string_save;
- done = false;
- for (ndim = 0; !done;)
+ /*
+ * If the input string starts with dimension info, read and use that.
+ * Otherwise, we require the input to be in curly-brace style, and we
+ * prescan the input to determine dimensions.
+ *
+ * Dimension info takes the form of one or more [n] or [m:n] items.
+ * The outer loop iterates once per dimension item.
+ */
+ p = string_save;
+ ndim = 0;
+ for (;;)
{
+ char *q;
+ int ub;
+
+ /*
+ * Note: we currently allow whitespace between, but not within,
+ * dimension items.
+ */
while (isspace((int) *p))
p++;
- if (*p == '[')
+ if (*p != '[')
+ break; /* no more dimension items */
+ p++;
+ if (ndim >= MAXDIM)
+ elog(ERROR, "array_in: more than %d dimensions", MAXDIM);
+ for (q = p; isdigit((int) *q); q++);
+ if (q == p) /* no digits? */
+ elog(ERROR, "array_in: missing dimension value");
+ if (*q == ':')
{
- p++;
- if ((r = (char *) strchr(p, ':')) == (char *) NULL)
- lBound[ndim] = 1;
- else
- {
- *r = '\0';
- lBound[ndim] = atoi(p);
- p = r + 1;
- }
- for (q = p; isdigit((int) *q); q++);
- if (*q != ']')
- elog(ERROR, "array_in: missing ']' in array declaration");
+ /* [m:n] format */
*q = '\0';
- dim[ndim] = atoi(p);
- if ((dim[ndim] < 0) || (lBound[ndim] < 0))
- elog(ERROR, "array_in: array dimensions need to be positive");
- dim[ndim] = dim[ndim] - lBound[ndim] + 1;
- if (dim[ndim] < 0)
- elog(ERROR, "array_in: upper_bound cannot be < lower_bound");
+ lBound[ndim] = atoi(p);
p = q + 1;
- ndim++;
+ for (q = p; isdigit((int) *q); q++);
+ if (q == p) /* no digits? */
+ elog(ERROR, "array_in: missing dimension value");
}
else
- done = true;
+ {
+ /* [n] format */
+ lBound[ndim] = 1;
+ }
+ if (*q != ']')
+ elog(ERROR, "array_in: missing ']' in array declaration");
+ *q = '\0';
+ ub = atoi(p);
+ p = q + 1;
+ if (ub < lBound[ndim])
+ elog(ERROR, "array_in: upper_bound cannot be < lower_bound");
+ dim[ndim] = ub - lBound[ndim] + 1;
+ ndim++;
}
if (ndim == 0)
{
- if (*p == '{')
- {
- ndim = ArrayCount(p, dim, typdelim);
- for (i = 0; i < ndim; i++)
- lBound[i] = 1;
- }
- else
+ /* No array dimensions, so intuit dimensions from brace structure */
+ if (*p != '{')
elog(ERROR, "array_in: Need to specify dimension");
+ ndim = ArrayCount(p, dim, typdelim);
+ for (i = 0; i < ndim; i++)
+ lBound[i] = 1;
}
else
{
- while (isspace((int) *p))
- p++;
+ /* If array dimensions are given, expect '=' operator */
if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
elog(ERROR, "array_in: missing assignment operator");
p += strlen(ASSGN);