Commit 85b762b4 authored by Tom Lane's avatar Tom Lane

Clean up array-dimensions parser a bit.

This code still needs a lot of love, however ...
parent 12b401f7
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -100,15 +100,12 @@ array_in(PG_FUNCTION_ARGS)
Oid element_type = PG_GETARG_OID(1); /* type of an array element */ Oid element_type = PG_GETARG_OID(1); /* type of an array element */
int32 typmod = PG_GETARG_INT32(2); /* typmod for array elements */ int32 typmod = PG_GETARG_INT32(2); /* typmod for array elements */
int typlen; int typlen;
bool typbyval, bool typbyval;
done;
char typdelim; char typdelim;
Oid typinput; Oid typinput;
Oid typelem; Oid typelem;
char *string_save, char *string_save,
*p, *p;
*q,
*r;
FmgrInfo inputproc; FmgrInfo inputproc;
int i, int i,
nitems; nitems;
...@@ -120,64 +117,83 @@ array_in(PG_FUNCTION_ARGS) ...@@ -120,64 +117,83 @@ array_in(PG_FUNCTION_ARGS)
lBound[MAXDIM]; lBound[MAXDIM];
char typalign; char typalign;
/* Get info about element type, including its input conversion proc */
system_cache_lookup(element_type, true, &typlen, &typbyval, &typdelim, system_cache_lookup(element_type, true, &typlen, &typbyval, &typdelim,
&typelem, &typinput, &typalign); &typelem, &typinput, &typalign);
fmgr_info(typinput, &inputproc); 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); string_save = (char *) palloc(strlen(string) + 3);
strcpy(string_save, string); strcpy(string_save, string);
/* --- read array dimensions ---------- */ /*
p = q = string_save; * If the input string starts with dimension info, read and use that.
done = false; * Otherwise, we require the input to be in curly-brace style, and we
for (ndim = 0; !done;) * 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)) while (isspace((int) *p))
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++; /* [m:n] format */
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");
*q = '\0'; *q = '\0';
dim[ndim] = atoi(p); lBound[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");
p = q + 1; p = q + 1;
ndim++; for (q = p; isdigit((int) *q); q++);
if (q == p) /* no digits? */
elog(ERROR, "array_in: missing dimension value");
} }
else 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 (ndim == 0)
{ {
if (*p == '{') /* No array dimensions, so intuit dimensions from brace structure */
{ if (*p != '{')
ndim = ArrayCount(p, dim, typdelim);
for (i = 0; i < ndim; i++)
lBound[i] = 1;
}
else
elog(ERROR, "array_in: Need to specify dimension"); elog(ERROR, "array_in: Need to specify dimension");
ndim = ArrayCount(p, dim, typdelim);
for (i = 0; i < ndim; i++)
lBound[i] = 1;
} }
else else
{ {
while (isspace((int) *p)) /* If array dimensions are given, expect '=' operator */
p++;
if (strncmp(p, ASSGN, strlen(ASSGN)) != 0) if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
elog(ERROR, "array_in: missing assignment operator"); elog(ERROR, "array_in: missing assignment operator");
p += strlen(ASSGN); p += strlen(ASSGN);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment