summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-03-17 20:05:59 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-03-17 20:05:59 +0000
commitbbc1fb07c62526469af4896a634b895623d403a1 (patch)
tree9d5d4ff736c9f0c1a47456b3552094df11e3bb44 /src
parentefec53adb3a35b5ebbff3f12a0063685c1cd3e09 (diff)
Backpatch array I/O code and documentation fixes, also array slice
lower subscript bounds change.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c195
1 files changed, 108 insertions, 87 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 0cfa371c998..0c8edf4120b 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.72 2001/11/29 21:02:41 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.72.2.1 2002/03/17 20:05:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -46,19 +46,12 @@
* Local definitions
* ----------
*/
-#ifndef MIN
-#define MIN(a,b) (((a)<(b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b) (((a)>(b)) ? (a) : (b))
-#endif
-
#define ASSGN "="
#define RETURN_NULL(type) do { *isNull = true; return (type) 0; } while (0)
-static int ArrayCount(char *str, int *dim, int typdelim);
+static int ArrayCount(char *str, int *dim, char typdelim);
static Datum *ReadArrayStr(char *arrayStr, int nitems, int ndim, int *dim,
FmgrInfo *inputproc, Oid typelem, int32 typmod,
char typdelim, int typlen, bool typbyval,
@@ -252,7 +245,7 @@ array_in(PG_FUNCTION_ARGS)
*-----------------------------------------------------------------------------
*/
static int
-ArrayCount(char *str, int *dim, int typdelim)
+ArrayCount(char *str, int *dim, char typdelim)
{
int nest_level = 0,
i;
@@ -260,7 +253,7 @@ ArrayCount(char *str, int *dim, int typdelim)
temp[MAXDIM];
bool scanning_string = false;
bool eoArray = false;
- char *q;
+ char *ptr;
for (i = 0; i < MAXDIM; ++i)
temp[i] = dim[i] = 0;
@@ -268,65 +261,68 @@ ArrayCount(char *str, int *dim, int typdelim)
if (strncmp(str, "{}", 2) == 0)
return 0;
- q = str;
- while (eoArray != true)
+ ptr = str;
+ while (!eoArray)
{
- bool done = false;
+ bool itemdone = false;
- while (!done)
+ while (!itemdone)
{
- switch (*q)
+ switch (*ptr)
{
- case '\\':
- /* skip escaped characters (\ and ") inside strings */
- if (scanning_string && *(q + 1))
- q++;
- break;
case '\0':
-
- /*
- * Signal a premature end of the string. DZ -
- * 2-9-1996
- */
+ /* Signal a premature end of the string */
elog(ERROR, "malformed array constant: %s", str);
break;
+ case '\\':
+ /* skip the escaped character */
+ if (*(ptr + 1))
+ ptr++;
+ else
+ elog(ERROR, "malformed array constant: %s", str);
+ break;
case '\"':
scanning_string = !scanning_string;
break;
case '{':
if (!scanning_string)
{
+ if (nest_level >= MAXDIM)
+ elog(ERROR, "array_in: illformed array constant");
temp[nest_level] = 0;
nest_level++;
+ if (ndim < nest_level)
+ ndim = nest_level;
}
break;
case '}':
if (!scanning_string)
{
- if (!ndim)
- ndim = nest_level;
+ if (nest_level == 0)
+ elog(ERROR, "array_in: illformed array constant");
nest_level--;
- if (nest_level)
- temp[nest_level - 1]++;
if (nest_level == 0)
- eoArray = done = true;
+ eoArray = itemdone = true;
+ else
+ {
+ /*
+ * We don't set itemdone here; see comments in
+ * ReadArrayStr
+ */
+ temp[nest_level - 1]++;
+ }
}
break;
default:
- if (!ndim)
- ndim = nest_level;
- if (*q == typdelim && !scanning_string)
- done = true;
+ if (*ptr == typdelim && !scanning_string)
+ itemdone = true;
break;
}
- if (!done)
- q++;
+ if (!itemdone)
+ ptr++;
}
temp[ndim - 1]++;
- q++;
- if (!eoArray)
- while (isspace((unsigned char) *q))
- q++;
+ ptr++;
}
for (i = 0; i < ndim; ++i)
dim[i] = temp[i];
@@ -366,103 +362,119 @@ ReadArrayStr(char *arrayStr,
int i,
nest_level = 0;
Datum *values;
- char *p,
- *q,
- *r;
+ char *ptr;
bool scanning_string = false;
+ bool eoArray = false;
int indx[MAXDIM],
prod[MAXDIM];
- bool eoArray = false;
mda_get_prod(ndim, dim, prod);
values = (Datum *) palloc(nitems * sizeof(Datum));
MemSet(values, 0, nitems * sizeof(Datum));
MemSet(indx, 0, sizeof(indx));
- q = p = arrayStr;
/* read array enclosed within {} */
+ ptr = arrayStr;
while (!eoArray)
{
- bool done = false;
+ bool itemdone = false;
int i = -1;
+ char *itemstart;
- while (!done)
+ /* skip leading whitespace */
+ while (isspace((unsigned char) *ptr))
+ ptr++;
+ itemstart = ptr;
+
+ while (!itemdone)
{
- switch (*q)
+ switch (*ptr)
{
+ case '\0':
+ /* Signal a premature end of the string */
+ elog(ERROR, "malformed array constant: %s", arrayStr);
+ break;
case '\\':
+ {
+ char *cptr;
+
/* Crunch the string on top of the backslash. */
- for (r = q; *r != '\0'; r++)
- *r = *(r + 1);
+ for (cptr = ptr; *cptr != '\0'; cptr++)
+ *cptr = *(cptr + 1);
+ if (*ptr == '\0')
+ elog(ERROR, "malformed array constant: %s", arrayStr);
break;
+ }
case '\"':
- if (!scanning_string)
- {
- while (p != q)
- p++;
- p++; /* get p past first doublequote */
- }
- else
- *q = '\0';
+ {
+ char *cptr;
+
scanning_string = !scanning_string;
+ /* Crunch the string on top of the quote. */
+ for (cptr = ptr; *cptr != '\0'; cptr++)
+ *cptr = *(cptr + 1);
+ /* Back up to not miss following character. */
+ ptr--;
break;
+ }
case '{':
if (!scanning_string)
{
- p++;
- nest_level++;
- if (nest_level > ndim)
+ if (nest_level >= ndim)
elog(ERROR, "array_in: illformed array constant");
+ nest_level++;
indx[nest_level - 1] = 0;
- indx[ndim - 1] = 0;
+ /* skip leading whitespace */
+ while (isspace((unsigned char) *(ptr+1)))
+ ptr++;
+ itemstart = ptr+1;
}
break;
case '}':
if (!scanning_string)
{
+ if (nest_level == 0)
+ elog(ERROR, "array_in: illformed array constant");
if (i == -1)
i = ArrayGetOffset0(ndim, indx, prod);
+ indx[nest_level - 1] = 0;
nest_level--;
if (nest_level == 0)
- eoArray = done = true;
+ eoArray = itemdone = true;
else
{
- *q = '\0';
+ /*
+ * tricky coding: terminate item value string at
+ * first '}', but don't process it till we see
+ * a typdelim char or end of array. This handles
+ * case where several '}'s appear successively
+ * in a multidimensional array.
+ */
+ *ptr = '\0';
indx[nest_level - 1]++;
}
}
break;
default:
- if (*q == typdelim && !scanning_string)
+ if (*ptr == typdelim && !scanning_string)
{
if (i == -1)
i = ArrayGetOffset0(ndim, indx, prod);
- done = true;
+ itemdone = true;
indx[ndim - 1]++;
}
break;
}
- if (!done)
- q++;
+ if (!itemdone)
+ ptr++;
}
- *q = '\0';
- if (i >= nitems)
+ *ptr++ = '\0';
+ if (i < 0 || i >= nitems)
elog(ERROR, "array_in: illformed array constant");
values[i] = FunctionCall3(inputproc,
- CStringGetDatum(p),
+ CStringGetDatum(itemstart),
ObjectIdGetDatum(typelem),
Int32GetDatum(typmod));
- p = ++q;
-
- /*
- * if not at the end of the array skip white space
- */
- if (!eoArray)
- while (isspace((unsigned char) *q))
- {
- p++;
- q++;
- }
}
/*
@@ -819,6 +831,7 @@ array_ref(ArrayType *array,
retptr = array_seek(arraydataptr, elmlen, offset);
+ *isNull = false;
return ArrayCast(retptr, elmbyval, elmlen);
}
@@ -845,7 +858,8 @@ array_get_slice(ArrayType *array,
int i,
ndim,
*dim,
- *lb;
+ *lb,
+ *newlb;
int fixedDim[1],
fixedLb[1];
char *arraydataptr;
@@ -917,7 +931,14 @@ array_get_slice(ArrayType *array,
newarray->ndim = ndim;
newarray->flags = 0;
memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));
- memcpy(ARR_LBOUND(newarray), lowerIndx, ndim * sizeof(int));
+ /*
+ * Lower bounds of the new array are set to 1. Formerly (before 7.3)
+ * we copied the given lowerIndx values ... but that seems confusing.
+ */
+ newlb = ARR_LBOUND(newarray);
+ for (i = 0; i < ndim; i++)
+ newlb[i] = 1;
+
array_extract_slice(ndim, dim, lb, arraydataptr, elmlen,
lowerIndx, upperIndx, ARR_DATA_PTR(newarray));
@@ -1222,8 +1243,8 @@ array_set_slice(ArrayType *array,
*/
int oldlb = ARR_LBOUND(array)[0];
int oldub = oldlb + ARR_DIMS(array)[0] - 1;
- int slicelb = MAX(oldlb, lowerIndx[0]);
- int sliceub = MIN(oldub, upperIndx[0]);
+ int slicelb = Max(oldlb, lowerIndx[0]);
+ int sliceub = Min(oldub, upperIndx[0]);
char *oldarraydata = ARR_DATA_PTR(array);
lenbefore = array_nelems_size(oldarraydata,