summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/acl.c4
-rw-r--r--src/backend/utils/adt/arrayfuncs.c372
-rw-r--r--src/backend/utils/adt/float.c15
-rw-r--r--src/backend/utils/adt/name.c6
-rw-r--r--src/backend/utils/adt/numeric.c13
-rw-r--r--src/backend/utils/adt/pseudotypes.c9
-rw-r--r--src/backend/utils/adt/ruleutils.c4
-rw-r--r--src/backend/utils/adt/timestamp.c9
-rw-r--r--src/backend/utils/adt/varbit.c6
-rw-r--r--src/backend/utils/adt/varchar.c6
-rw-r--r--src/backend/utils/cache/lsyscache.c34
-rw-r--r--src/backend/utils/misc/guc.c53
12 files changed, 336 insertions, 195 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 494a262f0b..05493033d3 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.75 2002/08/09 16:45:14 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.76 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,6 +18,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_shadow.h"
+#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "utils/acl.h"
@@ -252,6 +253,7 @@ makeacl(int n)
new_acl->size = size;
new_acl->ndim = 1;
new_acl->flags = 0;
+ new_acl->elemtype = ACLITEMOID;
ARR_LBOUND(new_acl)[0] = 0;
ARR_DIMS(new_acl)[0] = n;
return new_acl;
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 30c2793192..53a4c83d63 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.78 2002/06/20 20:29:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.79 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,21 +24,37 @@
#include "utils/syscache.h"
-/*
- * An array has the following internal structure:
- * <nbytes> - total number of bytes
+/*----------
+ * A standard varlena array has the following internal structure:
+ * <size> - total number of bytes (also, TOAST info flags)
* <ndim> - number of dimensions of the array
* <flags> - bit mask of flags
- * <dim> - size of each array axis
- * <dim_lower> - lower boundary of each dimension
+ * <elemtype> - element type OID
+ * <dim> - size of each array axis (C array of int)
+ * <dim_lower> - lower boundary of each dimension (C array of int)
* <actual data> - whatever is the stored data
- * The actual data starts on a MAXALIGN boundary.
+ * The actual data starts on a MAXALIGN boundary. Individual items in the
+ * array are aligned as specified by the array element type.
*
* NOTE: it is important that array elements of toastable datatypes NOT be
* toasted, since the tupletoaster won't know they are there. (We could
* support compressed toasted items; only out-of-line items are dangerous.
* However, it seems preferable to store such items uncompressed and allow
* the toaster to compress the whole array as one input.)
+ *
+ * There is currently no support for NULL elements in arrays, either.
+ * A reasonable (and backwards-compatible) way to add support would be to
+ * add a nulls bitmap following the <dim_lower> array, which would be present
+ * if needed; and its presence would be signaled by a bit in the flags word.
+ *
+ *
+ * There are also some "fixed-length array" datatypes, such as NAME and
+ * OIDVECTOR. These are simply a sequence of a fixed number of items each
+ * of a fixed-length datatype, with no overhead; the item size must be
+ * a multiple of its alignment requirement, because we do no padding.
+ * We support subscripting on these types, but array_in() and array_out()
+ * only work with varlena arrays.
+ *----------
*/
@@ -54,28 +70,37 @@
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,
- char typalign, int *nbytes);
+ char typdelim,
+ int typlen, bool typbyval, char typalign,
+ int *nbytes);
static void CopyArrayEls(char *p, Datum *values, int nitems,
- bool typbyval, int typlen, char typalign,
+ int typlen, bool typbyval, char typalign,
bool freedata);
static void system_cache_lookup(Oid element_type, bool input, int *typlen,
bool *typbyval, char *typdelim, Oid *typelem,
Oid *proc, char *typalign);
static Datum ArrayCast(char *value, bool byval, int len);
-static int ArrayCastAndSet(Datum src, bool typbyval, int typlen, char *dest);
-static int array_nelems_size(char *ptr, int eltsize, int nitems);
-static char *array_seek(char *ptr, int eltsize, int nitems);
-static int array_copy(char *destptr, int eltsize, int nitems, char *srcptr);
+static int ArrayCastAndSet(Datum src,
+ int typlen, bool typbyval, char typalign,
+ char *dest);
+static int array_nelems_size(char *ptr, int nitems,
+ int typlen, bool typbyval, char typalign);
+static char *array_seek(char *ptr, int nitems,
+ int typlen, bool typbyval, char typalign);
+static int array_copy(char *destptr, int nitems, char *srcptr,
+ int typlen, bool typbyval, char typalign);
static int array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
- int eltsize, int *st, int *endp);
+ int *st, int *endp,
+ int typlen, bool typbyval, char typalign);
static void array_extract_slice(int ndim, int *dim, int *lb,
- char *arraydataptr, int eltsize,
- int *st, int *endp, char *destPtr);
+ char *arraydataptr,
+ int *st, int *endp, char *destPtr,
+ int typlen, bool typbyval, char typalign);
static void array_insert_slice(int ndim, int *dim, int *lb,
- char *origPtr, int origdatasize,
- char *destPtr, int eltsize,
- int *st, int *endp, char *srcPtr);
+ char *origPtr, int origdatasize,
+ char *destPtr,
+ int *st, int *endp, char *srcPtr,
+ int typlen, bool typbyval, char typalign);
/*---------------------------------------------------------------------
@@ -212,6 +237,7 @@ array_in(PG_FUNCTION_ARGS)
retval = (ArrayType *) palloc(sizeof(ArrayType));
MemSet(retval, 0, sizeof(ArrayType));
retval->size = sizeof(ArrayType);
+ retval->elemtype = element_type;
PG_RETURN_ARRAYTYPE_P(retval);
}
@@ -226,13 +252,14 @@ array_in(PG_FUNCTION_ARGS)
MemSet(retval, 0, nbytes);
retval->size = nbytes;
retval->ndim = ndim;
+ retval->elemtype = element_type;
memcpy((char *) ARR_DIMS(retval), (char *) dim,
ndim * sizeof(int));
memcpy((char *) ARR_LBOUND(retval), (char *) lBound,
ndim * sizeof(int));
CopyArrayEls(ARR_DATA_PTR(retval), dataPtr, nitems,
- typbyval, typlen, typalign, true);
+ typlen, typbyval, typalign, true);
pfree(dataPtr);
pfree(string_save);
PG_RETURN_ARRAYTYPE_P(retval);
@@ -336,7 +363,7 @@ ArrayCount(char *str, int *dim, char typdelim)
* internal format. The external format expected is like C array
* declaration. Unspecified elements are initialized to zero for fixed length
* base types and to empty varlena structures for variable length base
- * types.
+ * types. (This is pretty bogus; NULL would be much safer.)
* result :
* returns a palloc'd array of Datum representations of the array elements.
* If element type is pass-by-ref, the Datums point to palloc'd values.
@@ -482,7 +509,7 @@ ReadArrayStr(char *arrayStr,
*/
if (typlen > 0)
{
- *nbytes = nitems * typlen;
+ *nbytes = nitems * att_align(typlen, typalign);
if (!typbyval)
for (i = 0; i < nitems; i++)
if (values[i] == (Datum) 0)
@@ -493,23 +520,34 @@ ReadArrayStr(char *arrayStr,
}
else
{
+ Assert(!typbyval);
*nbytes = 0;
for (i = 0; i < nitems; i++)
{
if (values[i] != (Datum) 0)
{
/* let's just make sure data is not toasted */
- values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
- if (typalign == 'd')
- *nbytes += MAXALIGN(VARSIZE(DatumGetPointer(values[i])));
- else
- *nbytes += INTALIGN(VARSIZE(DatumGetPointer(values[i])));
+ if (typlen == -1)
+ values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
+ *nbytes = att_addlength(*nbytes, typlen, values[i]);
+ *nbytes = att_align(*nbytes, typalign);
}
- else
+ else if (typlen == -1)
{
- *nbytes += sizeof(int32);
+ /* dummy varlena value (XXX bogus, see notes above) */
values[i] = PointerGetDatum(palloc(sizeof(int32)));
VARATT_SIZEP(DatumGetPointer(values[i])) = sizeof(int32);
+ *nbytes += sizeof(int32);
+ *nbytes = att_align(*nbytes, typalign);
+ }
+ else
+ {
+ /* dummy cstring value */
+ Assert(typlen == -2);
+ values[i] = PointerGetDatum(palloc(1));
+ *((char *) DatumGetPointer(values[i])) = '\0';
+ *nbytes += 1;
+ *nbytes = att_align(*nbytes, typalign);
}
}
}
@@ -536,21 +574,19 @@ static void
CopyArrayEls(char *p,
Datum *values,
int nitems,
- bool typbyval,
int typlen,
+ bool typbyval,
char typalign,
bool freedata)
{
int i;
- int inc;
if (typbyval)
freedata = false;
for (i = 0; i < nitems; i++)
{
- inc = ArrayCastAndSet(values[i], typbyval, typlen, p);
- p += inc;
+ p += ArrayCastAndSet(values[i], typlen, typbyval, typalign, p);
if (freedata)
pfree(DatumGetPointer(values[i]));
}
@@ -566,7 +602,7 @@ Datum
array_out(PG_FUNCTION_ARGS)
{
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
- Oid element_type = PG_GETARG_OID(1);
+ Oid element_type;
int typlen;
bool typbyval;
char typdelim;
@@ -588,9 +624,11 @@ array_out(PG_FUNCTION_ARGS)
int ndim,
*dim;
+ element_type = ARR_ELEMTYPE(v);
system_cache_lookup(element_type, false, &typlen, &typbyval,
&typdelim, &typelem, &typoutput, &typalign);
fmgr_info(typoutput, &outputproc);
+
ndim = ARR_NDIM(v);
dim = ARR_DIMS(v);
nitems = ArrayGetNItems(ndim, dim);
@@ -620,10 +658,8 @@ array_out(PG_FUNCTION_ARGS)
itemvalue,
ObjectIdGetDatum(typelem),
Int32GetDatum(-1)));
- if (typlen > 0)
- p += typlen;
- else
- p += INTALIGN(*(int32 *) p);
+ p = att_addlength(p, typlen, PointerGetDatum(p));
+ p = (char *) att_align(p, typalign);
/* count data plus backslashes; detect chars needing quotes */
nq = (values[i][0] == '\0'); /* force quotes for empty string */
@@ -774,9 +810,10 @@ Datum
array_ref(ArrayType *array,
int nSubscripts,
int *indx,
- bool elmbyval,
- int elmlen,
int arraylen,
+ int elmlen,
+ bool elmbyval,
+ char elmalign,
bool *isNull)
{
int i,
@@ -806,7 +843,7 @@ array_ref(ArrayType *array,
}
else
{
- /* detoast input if necessary */
+ /* detoast input array if necessary */
array = DatumGetArrayTypeP(PointerGetDatum(array));
ndim = ARR_NDIM(array);
@@ -829,7 +866,7 @@ array_ref(ArrayType *array,
*/
offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
- retptr = array_seek(arraydataptr, elmlen, offset);
+ retptr = array_seek(arraydataptr, offset, elmlen, elmbyval, elmalign);
*isNull = false;
return ArrayCast(retptr, elmbyval, elmlen);
@@ -850,9 +887,10 @@ array_get_slice(ArrayType *array,
int nSubscripts,
int *upperIndx,
int *lowerIndx,
- bool elmbyval,
- int elmlen,
int arraylen,
+ int elmlen,
+ bool elmbyval,
+ char elmalign,
bool *isNull)
{
int i,
@@ -882,6 +920,7 @@ array_get_slice(ArrayType *array,
/*
* fixed-length arrays -- these are assumed to be 1-d, 0-based
+ * XXX where would we get the correct ELEMTYPE from?
*/
ndim = 1;
fixedDim[0] = arraylen / elmlen;
@@ -892,7 +931,7 @@ array_get_slice(ArrayType *array,
}
else
{
- /* detoast input if necessary */
+ /* detoast input array if necessary */
array = DatumGetArrayTypeP(PointerGetDatum(array));
ndim = ARR_NDIM(array);
@@ -931,13 +970,15 @@ array_get_slice(ArrayType *array,
mda_get_range(ndim, span, lowerIndx, upperIndx);
bytes = array_slice_size(ndim, dim, lb, arraydataptr,
- elmlen, lowerIndx, upperIndx);
+ lowerIndx, upperIndx,
+ elmlen, elmbyval, elmalign);
bytes += ARR_OVERHEAD(ndim);
newarray = (ArrayType *) palloc(bytes);
newarray->size = bytes;
newarray->ndim = ndim;
newarray->flags = 0;
+ newarray->elemtype = ARR_ELEMTYPE(array);
memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));
/*
* Lower bounds of the new array are set to 1. Formerly (before 7.3)
@@ -947,8 +988,9 @@ array_get_slice(ArrayType *array,
for (i = 0; i < ndim; i++)
newlb[i] = 1;
- array_extract_slice(ndim, dim, lb, arraydataptr, elmlen,
- lowerIndx, upperIndx, ARR_DATA_PTR(newarray));
+ array_extract_slice(ndim, dim, lb, arraydataptr,
+ lowerIndx, upperIndx, ARR_DATA_PTR(newarray),
+ elmlen, elmbyval, elmalign);
return newarray;
}
@@ -976,9 +1018,10 @@ array_set(ArrayType *array,
int nSubscripts,
int *indx,
Datum dataValue,
- bool elmbyval,
- int elmlen,
int arraylen,
+ int elmlen,
+ bool elmbyval,
+ char elmalign,
bool *isNull)
{
int i,
@@ -1014,15 +1057,15 @@ array_set(ArrayType *array,
newarray = (ArrayType *) palloc(arraylen);
memcpy(newarray, array, arraylen);
elt_ptr = (char *) newarray + indx[0] * elmlen;
- ArrayCastAndSet(dataValue, elmbyval, elmlen, elt_ptr);
+ ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
return newarray;
}
/* make sure item to be inserted is not toasted */
- if (elmlen < 0)
+ if (elmlen == -1)
dataValue = PointerGetDatum(PG_DETOAST_DATUM(dataValue));
- /* detoast input if necessary */
+ /* detoast input array if necessary */
array = DatumGetArrayTypeP(PointerGetDatum(array));
ndim = ARR_NDIM(array);
@@ -1081,19 +1124,16 @@ array_set(ArrayType *array,
else
{
offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
- elt_ptr = array_seek(ARR_DATA_PTR(array), elmlen, offset);
+ elt_ptr = array_seek(ARR_DATA_PTR(array), offset,
+ elmlen, elmbyval, elmalign);
lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));
- if (elmlen > 0)
- olditemlen = elmlen;
- else
- olditemlen = INTALIGN(*(int32 *) elt_ptr);
+ olditemlen = att_addlength(0, elmlen, PointerGetDatum(elt_ptr));
+ olditemlen = att_align(olditemlen, elmalign);
lenafter = (int) (olddatasize - lenbefore - olditemlen);
}
- if (elmlen > 0)
- newitemlen = elmlen;
- else
- newitemlen = INTALIGN(*(int32 *) DatumGetPointer(dataValue));
+ newitemlen = att_addlength(0, elmlen, dataValue);
+ newitemlen = att_align(newitemlen, elmalign);
newsize = overheadlen + lenbefore + newitemlen + lenafter;
@@ -1104,6 +1144,7 @@ array_set(ArrayType *array,
newarray->size = newsize;
newarray->ndim = ndim;
newarray->flags = 0;
+ newarray->elemtype = ARR_ELEMTYPE(array);
memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
memcpy((char *) newarray + overheadlen,
@@ -1113,7 +1154,7 @@ array_set(ArrayType *array,
(char *) array + overheadlen + lenbefore + olditemlen,
lenafter);
- ArrayCastAndSet(dataValue, elmbyval, elmlen,
+ ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign,
(char *) newarray + overheadlen + lenbefore);
return newarray;
@@ -1143,9 +1184,10 @@ array_set_slice(ArrayType *array,
int *upperIndx,
int *lowerIndx,
ArrayType *srcArray,
- bool elmbyval,
- int elmlen,
int arraylen,
+ int elmlen,
+ bool elmbyval,
+ char elmalign,
bool *isNull)
{
int i,
@@ -1240,8 +1282,8 @@ array_set_slice(ArrayType *array,
* Compute space occupied by new entries, space occupied by replaced
* entries, and required space for new array.
*/
- newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), elmlen,
- nsrcitems);
+ newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), nsrcitems,
+ elmlen, elmbyval, elmalign);
overheadlen = ARR_OVERHEAD(ndim);
olddatasize = ARR_SIZE(array) - overheadlen;
if (ndim > 1)
@@ -1251,7 +1293,8 @@ array_set_slice(ArrayType *array,
* would be a lot more complicated if we had to do so...
*/
olditemsize = array_slice_size(ndim, dim, lb, ARR_DATA_PTR(array),
- elmlen, lowerIndx, upperIndx);
+ lowerIndx, upperIndx,
+ elmlen, elmbyval, elmalign);
lenbefore = lenafter = 0; /* keep compiler quiet */
}
else
@@ -1266,15 +1309,14 @@ array_set_slice(ArrayType *array,
int sliceub = Min(oldub, upperIndx[0]);
char *oldarraydata = ARR_DATA_PTR(array);
- lenbefore = array_nelems_size(oldarraydata,
- elmlen,
- slicelb - oldlb);
+ lenbefore = array_nelems_size(oldarraydata, slicelb - oldlb,
+ elmlen, elmbyval, elmalign);
if (slicelb > sliceub)
olditemsize = 0;
else
olditemsize = array_nelems_size(oldarraydata + lenbefore,
- elmlen,
- sliceub - slicelb + 1);
+ sliceub - slicelb + 1,
+ elmlen, elmbyval, elmalign);
lenafter = olddatasize - lenbefore - olditemsize;
}
@@ -1284,6 +1326,7 @@ array_set_slice(ArrayType *array,
newarray->size = newsize;
newarray->ndim = ndim;
newarray->flags = 0;
+ newarray->elemtype = ARR_ELEMTYPE(array);
memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
@@ -1294,8 +1337,9 @@ array_set_slice(ArrayType *array,
* would be a lot more complicated if we had to do so...
*/
array_insert_slice(ndim, dim, lb, ARR_DATA_PTR(array), olddatasize,
- ARR_DATA_PTR(newarray), elmlen,
- lowerIndx, upperIndx, ARR_DATA_PTR(srcArray));
+ ARR_DATA_PTR(newarray),
+ lowerIndx, upperIndx, ARR_DATA_PTR(srcArray),
+ elmlen, elmbyval, elmalign);
}
else
{
@@ -1352,12 +1396,13 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
int nbytes = 0;
int inp_typlen;
bool inp_typbyval;
+ char inp_typalign;
int typlen;
bool typbyval;
+ char typalign;
char typdelim;
Oid typelem;
Oid proc;
- char typalign;
char *s;
/* Get input array */
@@ -1367,6 +1412,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
elog(ERROR, "array_map: null input array");
v = PG_GETARG_ARRAYTYPE_P(0);
+ Assert(ARR_ELEMTYPE(v) == inpType);
+
ndim = ARR_NDIM(v);
dim = ARR_DIMS(v);
nitems = ArrayGetNItems(ndim, dim);
@@ -1377,7 +1424,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
/* Lookup source and result types. Unneeded variables are reused. */
system_cache_lookup(inpType, false, &inp_typlen, &inp_typbyval,
- &typdelim, &typelem, &proc, &typalign);
+ &typdelim, &typelem, &proc, &inp_typalign);
system_cache_lookup(retType, false, &typlen, &typbyval,
&typdelim, &typelem, &proc, &typalign);
@@ -1391,10 +1438,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
/* Get source element */
elt = fetch_att(s, inp_typbyval, inp_typlen);
- if (inp_typlen > 0)
- s += inp_typlen;
- else
- s += INTALIGN(*(int32 *) s);
+ s = att_addlength(s, inp_typlen, PointerGetDatum(s));
+ s = (char *) att_align(s, inp_typalign);
/*
* Apply the given function to source elt and extra args.
@@ -1410,14 +1455,13 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
if (fcinfo->isnull)
elog(ERROR, "array_map: cannot handle NULL in array");
- /* Ensure data is not toasted, and update total result size */
- if (typbyval || typlen > 0)
- nbytes += typlen;
- else
- {
+ /* Ensure data is not toasted */
+ if (typlen == -1)
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
- nbytes += INTALIGN(VARSIZE(DatumGetPointer(values[i])));
- }
+
+ /* Update total result size */
+ nbytes = att_addlength(nbytes, typlen, values[i]);
+ nbytes = att_align(nbytes, typalign);
}
/* Allocate and initialize the result array */
@@ -1427,6 +1471,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
result->size = nbytes;
result->ndim = ndim;
+ result->elemtype = retType;
memcpy(ARR_DIMS(result), ARR_DIMS(v), 2 * ndim * sizeof(int));
/*
@@ -1434,7 +1479,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
* function
*/
CopyArrayEls(ARR_DATA_PTR(result), values, nitems,
- typbyval, typlen, typalign, false);
+ typlen, typbyval, typalign, false);
pfree(values);
PG_RETURN_ARRAYTYPE_P(result);
@@ -1445,34 +1490,43 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
*
* elems: array of Datum items to become the array contents
* nelems: number of items
- * elmbyval, elmlen, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
*
* A palloc'd 1-D array object is constructed and returned. Note that
* elem values will be copied into the object even if pass-by-ref type.
* NULL element values are not supported.
+ *
+ * NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
+ * from the system catalogs, given the elmtype. However, in most current
+ * uses the type is hard-wired into the caller and so we can save a lookup
+ * cycle by hard-wiring the type info as well.
*----------
*/
ArrayType *
construct_array(Datum *elems, int nelems,
- bool elmbyval, int elmlen, char elmalign)
+ Oid elmtype,
+ int elmlen, bool elmbyval, char elmalign)
{
ArrayType *result;
int nbytes;
int i;
+ /* compute required space */
if (elmlen > 0)
{
- /* XXX what about alignment? */
- nbytes = elmlen * nelems;
+ nbytes = nelems * att_align(elmlen, elmalign);
}
else
{
- /* varlena type ... make sure it is untoasted */
+ Assert(!elmbyval);
nbytes = 0;
for (i = 0; i < nelems; i++)
{
- elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
- nbytes += INTALIGN(VARSIZE(DatumGetPointer(elems[i])));
+ /* make sure data is not toasted */
+ if (elmlen == -1)
+ elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
+ nbytes = att_addlength(nbytes, elmlen, elems[i]);
+ nbytes = att_align(nbytes, elmalign);
}
}
@@ -1483,11 +1537,12 @@ construct_array(Datum *elems, int nelems,
result->size = nbytes;
result->ndim = 1;
result->flags = 0;
+ result->elemtype = elmtype;
ARR_DIMS(result)[0] = nelems;
ARR_LBOUND(result)[0] = 1;
CopyArrayEls(ARR_DATA_PTR(result), elems, nelems,
- elmbyval, elmlen, elmalign, false);
+ elmlen, elmbyval, elmalign, false);
return result;
}
@@ -1496,17 +1551,23 @@ construct_array(Datum *elems, int nelems,
* deconstruct_array --- simple method for extracting data from an array
*
* array: array object to examine (must not be NULL)
- * elmbyval, elmlen, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
* elemsp: return value, set to point to palloc'd array of Datum values
* nelemsp: return value, set to number of extracted values
*
* If array elements are pass-by-ref data type, the returned Datums will
* be pointers into the array object.
+ *
+ * NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
+ * from the system catalogs, given the elmtype. However, in most current
+ * uses the type is hard-wired into the caller and so we can save a lookup
+ * cycle by hard-wiring the type info as well.
*----------
*/
void
deconstruct_array(ArrayType *array,
- bool elmbyval, int elmlen, char elmalign,
+ Oid elmtype,
+ int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, int *nelemsp)
{
Datum *elems;
@@ -1514,6 +1575,8 @@ deconstruct_array(ArrayType *array,
char *p;
int i;
+ Assert(ARR_ELEMTYPE(array) == elmtype);
+
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
if (nelems <= 0)
{
@@ -1528,10 +1591,8 @@ deconstruct_array(ArrayType *array,
for (i = 0; i < nelems; i++)
{
elems[i] = fetch_att(p, elmbyval, elmlen);
- if (elmlen > 0)
- p += elmlen;
- else
- p += INTALIGN(VARSIZE(p));
+ p = att_addlength(p, elmlen, PointerGetDatum(p));
+ p = (char *) att_align(p, elmalign);
}
}
@@ -1586,8 +1647,7 @@ system_cache_lookup(Oid element_type,
ObjectIdGetDatum(element_type),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
- elog(ERROR, "array_out: Cache lookup failed for type %u",
- element_type);
+ elog(ERROR, "cache lookup failed for type %u", element_type);
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
*typlen = typeStruct->typlen;
@@ -1613,13 +1673,12 @@ ArrayCast(char *value, bool byval, int len)
/*
* Copy datum to *dest and return total space used (including align padding)
- *
- * XXX this routine needs to be told typalign too!
*/
static int
ArrayCastAndSet(Datum src,
- bool typbyval,
int typlen,
+ bool typbyval,
+ char typalign,
char *dest)
{
int inc;
@@ -1627,24 +1686,17 @@ ArrayCastAndSet(Datum src,
if (typlen > 0)
{
if (typbyval)
- {
store_att_byval(dest, src, typlen);
- /* For by-val types, assume no alignment padding is needed */
- inc = typlen;
- }
else
- {
memmove(dest, DatumGetPointer(src), typlen);
- /* XXX WRONG: need to consider type's alignment requirement */
- inc = typlen;
- }
+ inc = att_align(typlen, typalign);
}
else
{
- /* varlena type */
- memmove(dest, DatumGetPointer(src), VARSIZE(DatumGetPointer(src)));
- /* XXX WRONG: should use MAXALIGN or type's alignment requirement */
- inc = INTALIGN(VARSIZE(DatumGetPointer(src)));
+ Assert(!typbyval);
+ inc = att_addlength(0, typlen, src);
+ memmove(dest, DatumGetPointer(src), inc);
+ inc = att_align(inc, typalign);
}
return inc;
@@ -1652,22 +1704,25 @@ ArrayCastAndSet(Datum src,
/*
* Compute total size of the nitems array elements starting at *ptr
- *
- * XXX should consider alignment spec for fixed-length types
*/
static int
-array_nelems_size(char *ptr, int eltsize, int nitems)
+array_nelems_size(char *ptr, int nitems,
+ int typlen, bool typbyval, char typalign)
{
char *origptr;
int i;
/* fixed-size elements? */
- if (eltsize > 0)
- return eltsize * nitems;
- /* else assume they are varlena items */
+ if (typlen > 0)
+ return nitems * att_align(typlen, typalign);
+
+ Assert(!typbyval);
origptr = ptr;
for (i = 0; i < nitems; i++)
- ptr += INTALIGN(*(int32 *) ptr);
+ {
+ ptr = att_addlength(ptr, typlen, PointerGetDatum(ptr));
+ ptr = (char *) att_align(ptr, typalign);
+ }
return ptr - origptr;
}
@@ -1675,9 +1730,11 @@ array_nelems_size(char *ptr, int eltsize, int nitems)
* Advance ptr over nitems array elements
*/
static char *
-array_seek(char *ptr, int eltsize, int nitems)
+array_seek(char *ptr, int nitems,
+ int typlen, bool typbyval, char typalign)
{
- return ptr + array_nelems_size(ptr, eltsize, nitems);
+ return ptr + array_nelems_size(ptr, nitems,
+ typlen, typbyval, typalign);
}
/*
@@ -1686,9 +1743,11 @@ array_seek(char *ptr, int eltsize, int nitems)
* Returns number of bytes copied
*/
static int
-array_copy(char *destptr, int eltsize, int nitems, char *srcptr)
+array_copy(char *destptr, int nitems, char *srcptr,
+ int typlen, bool typbyval, char typalign)
{
- int numbytes = array_nelems_size(srcptr, eltsize, nitems);
+ int numbytes = array_nelems_size(srcptr, nitems,
+ typlen, typbyval, typalign);
memmove(destptr, srcptr, numbytes);
return numbytes;
@@ -1701,7 +1760,8 @@ array_copy(char *destptr, int eltsize, int nitems, char *srcptr)
*/
static int
array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
- int eltsize, int *st, int *endp)
+ int *st, int *endp,
+ int typlen, bool typbyval, char typalign)
{
int st_pos,
span[MAXDIM],
@@ -1717,12 +1777,13 @@ array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
mda_get_range(ndim, span, st, endp);
/* Pretty easy for fixed element length ... */
- if (eltsize > 0)
- return ArrayGetNItems(ndim, span) * eltsize;
+ if (typlen > 0)
+ return ArrayGetNItems(ndim, span) * att_align(typlen, typalign);
/* Else gotta do it the hard way */
st_pos = ArrayGetOffset(ndim, dim, lb, st);
- ptr = array_seek(arraydataptr, eltsize, st_pos);
+ ptr = array_seek(arraydataptr, st_pos,
+ typlen, typbyval, typalign);
mda_get_prod(ndim, dim, prod);
mda_get_offset_values(ndim, dist, prod, span);
for (i = 0; i < ndim; i++)
@@ -1730,8 +1791,10 @@ array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
j = ndim - 1;
do
{
- ptr = array_seek(ptr, eltsize, dist[j]);
- inc = INTALIGN(*(int32 *) ptr);
+ ptr = array_seek(ptr, dist[j],
+ typlen, typbyval, typalign);
+ inc = att_addlength(0, typlen, PointerGetDatum(ptr));
+ inc = att_align(inc, typalign);
ptr += inc;
count += inc;
} while ((j = mda_next_tuple(ndim, indx, span)) != -1);
@@ -1749,10 +1812,12 @@ array_extract_slice(int ndim,
int *dim,
int *lb,
char *arraydataptr,
- int eltsize,
int *st,
int *endp,
- char *destPtr)
+ char *destPtr,
+ int typlen,
+ bool typbyval,
+ char typalign)
{
int st_pos,
prod[MAXDIM],
@@ -1765,7 +1830,8 @@ array_extract_slice(int ndim,
inc;
st_pos = ArrayGetOffset(ndim, dim, lb, st);
- srcPtr = array_seek(arraydataptr, eltsize, st_pos);
+ srcPtr = array_seek(arraydataptr, st_pos,
+ typlen, typbyval, typalign);
mda_get_prod(ndim, dim, prod);
mda_get_range(ndim, span, st, endp);
mda_get_offset_values(ndim, dist, prod, span);
@@ -1774,8 +1840,10 @@ array_extract_slice(int ndim,
j = ndim - 1;
do
{
- srcPtr = array_seek(srcPtr, eltsize, dist[j]);
- inc = array_copy(destPtr, eltsize, 1, srcPtr);
+ srcPtr = array_seek(srcPtr, dist[j],
+ typlen, typbyval, typalign);
+ inc = array_copy(destPtr, 1, srcPtr,
+ typlen, typbyval, typalign);
destPtr += inc;
srcPtr += inc;
} while ((j = mda_next_tuple(ndim, indx, span)) != -1);
@@ -1801,10 +1869,12 @@ array_insert_slice(int ndim,
char *origPtr,
int origdatasize,
char *destPtr,
- int eltsize,
int *st,
int *endp,
- char *srcPtr)
+ char *srcPtr,
+ int typlen,
+ bool typbyval,
+ char typalign)
{
int st_pos,
prod[MAXDIM],
@@ -1817,7 +1887,8 @@ array_insert_slice(int ndim,
inc;
st_pos = ArrayGetOffset(ndim, dim, lb, st);
- inc = array_copy(destPtr, eltsize, st_pos, origPtr);
+ inc = array_copy(destPtr, st_pos, origPtr,
+ typlen, typbyval, typalign);
destPtr += inc;
origPtr += inc;
mda_get_prod(ndim, dim, prod);
@@ -1829,15 +1900,18 @@ array_insert_slice(int ndim,
do
{
/* Copy/advance over elements between here and next part of slice */
- inc = array_copy(destPtr, eltsize, dist[j], origPtr);
+ inc = array_copy(destPtr, dist[j], origPtr,
+ typlen, typbyval, typalign);
destPtr += inc;
origPtr += inc;
/* Copy new element at this slice position */
- inc = array_copy(destPtr, eltsize, 1, srcPtr);
+ inc = array_copy(destPtr, 1, srcPtr,
+ typlen, typbyval, typalign);
destPtr += inc;
srcPtr += inc;
/* Advance over old element at this slice position */
- origPtr = array_seek(origPtr, eltsize, 1);
+ origPtr = array_seek(origPtr, 1,
+ typlen, typbyval, typalign);
} while ((j = mda_next_tuple(ndim, indx, span)) != -1);
/* don't miss any data at the end */
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 84233ebd1c..5edea787af 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.79 2002/06/20 20:29:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.80 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,6 +61,7 @@
#include <ieeefp.h>
#endif
+#include "catalog/pg_type.h"
#include "fmgr.h"
#include "utils/array.h"
#include "utils/builtins.h"
@@ -1480,9 +1481,9 @@ check_float8_array(ArrayType *transarray, const char *caller)
* don't need to use deconstruct_array() since the array data is just
* going to look like a C array of 3 float8 values.
*/
- if (ARR_SIZE(transarray) != (ARR_OVERHEAD(1) + 3 * sizeof(float8)) ||
- ARR_NDIM(transarray) != 1 ||
- ARR_DIMS(transarray)[0] != 3)
+ if (ARR_NDIM(transarray) != 1 ||
+ ARR_DIMS(transarray)[0] != 3 ||
+ ARR_ELEMTYPE(transarray) != FLOAT8OID)
elog(ERROR, "%s: expected 3-element float8 array", caller);
return (float8 *) ARR_DATA_PTR(transarray);
}
@@ -1513,7 +1514,8 @@ float8_accum(PG_FUNCTION_ARGS)
transdatums[2] = Float8GetDatumFast(sumX2);
result = construct_array(transdatums, 3,
- false /* float8 byval */ , sizeof(float8), 'd');
+ FLOAT8OID,
+ sizeof(float8), false /*float8 byval*/, 'd');
PG_RETURN_ARRAYTYPE_P(result);
}
@@ -1548,7 +1550,8 @@ float4_accum(PG_FUNCTION_ARGS)
transdatums[2] = Float8GetDatumFast(sumX2);
result = construct_array(transdatums, 3,
- false /* float8 byval */ , sizeof(float8), 'd');
+ FLOAT8OID,
+ sizeof(float8), false /*float8 byval*/, 'd');
PG_RETURN_ARRAYTYPE_P(result);
}
diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c
index de3f04a7df..41eca445f6 100644
--- a/src/backend/utils/adt/name.c
+++ b/src/backend/utils/adt/name.c
@@ -12,13 +12,14 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.39 2002/06/20 20:29:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.40 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/namespace.h"
+#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
@@ -271,8 +272,9 @@ current_schemas(PG_FUNCTION_ARGS)
}
array = construct_array(names, nnames,
- false, /* Name is not by-val */
+ NAMEOID,
NAMEDATALEN, /* sizeof(Name) */
+ false, /* Name is not by-val */
'i'); /* alignment of Name */
PG_RETURN_POINTER(array);
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 1af7402fb3..99ef1327e4 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -5,7 +5,7 @@
*
* 1998 Jan Wieck
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.50 2002/02/18 14:25:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.51 2002/08/26 17:53:58 tgl Exp $
*
* ----------
*/
@@ -18,6 +18,7 @@
#include <errno.h>
#include <sys/types.h>
+#include "catalog/pg_type.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/int8.h"
@@ -1734,7 +1735,7 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
- false, -1, 'i',
+ NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "do_numeric_accum: expected 3-element numeric array");
@@ -1755,7 +1756,7 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
transdatums[2] = sumX2;
result = construct_array(transdatums, 3,
- false, -1, 'i');
+ NUMERICOID, -1, false, 'i');
return result;
}
@@ -1825,7 +1826,7 @@ numeric_avg(PG_FUNCTION_ARGS)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
- false, -1, 'i',
+ NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "numeric_avg: expected 3-element numeric array");
@@ -1861,7 +1862,7 @@ numeric_variance(PG_FUNCTION_ARGS)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
- false, -1, 'i',
+ NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "numeric_variance: expected 3-element numeric array");
@@ -1940,7 +1941,7 @@ numeric_stddev(PG_FUNCTION_ARGS)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
- false, -1, 'i',
+ NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "numeric_stddev: expected 3-element numeric array");
diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c
index cb374e8f93..63f585fe32 100644
--- a/src/backend/utils/adt/pseudotypes.c
+++ b/src/backend/utils/adt/pseudotypes.c
@@ -16,12 +16,13 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.2 2002/08/24 15:00:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.3 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "utils/array.h"
#include "utils/builtins.h"
@@ -112,13 +113,13 @@ anyarray_in(PG_FUNCTION_ARGS)
/*
* anyarray_out - output routine for pseudo-type ANYARRAY.
+ *
+ * We may as well allow this, since array_out will in fact work.
*/
Datum
anyarray_out(PG_FUNCTION_ARGS)
{
- elog(ERROR, "Cannot display a value of type %s", "ANYARRAY");
-
- PG_RETURN_VOID(); /* keep compiler quiet */
+ return array_out(fcinfo);
}
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 0f5d0fca86..1011636456 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.117 2002/08/18 09:36:25 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.118 2002/08/26 17:53:58 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -725,7 +725,7 @@ decompile_column_index_array(Datum column_index_array, Oid relId,
/* Extract data from array of int16 */
deconstruct_array(DatumGetArrayTypeP(column_index_array),
- true, 2, 's',
+ INT2OID, 2, true, 's',
&keys, &nKeys);
for (j = 0; j < nKeys; j++)
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 5be34e6199..1b2553ec94 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.69 2002/08/04 06:44:47 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.70 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,6 +24,7 @@
#include "access/hash.h"
#include "access/xact.h"
+#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
@@ -1917,7 +1918,7 @@ interval_accum(PG_FUNCTION_ARGS)
/* We assume the input is array of interval */
deconstruct_array(transarray,
- false, 12, 'd',
+ INTERVALOID, 12, false, 'd',
&transdatums, &ndatums);
if (ndatums != 2)
elog(ERROR, "interval_accum: expected 2-element interval array");
@@ -1943,7 +1944,7 @@ interval_accum(PG_FUNCTION_ARGS)
transdatums[1] = IntervalPGetDatum(&N);
result = construct_array(transdatums, 2,
- false, 12, 'd');
+ INTERVALOID, 12, false, 'd');
PG_RETURN_ARRAYTYPE_P(result);
}
@@ -1959,7 +1960,7 @@ interval_avg(PG_FUNCTION_ARGS)
/* We assume the input is array of interval */
deconstruct_array(transarray,
- false, 12, 'd',
+ INTERVALOID, 12, false, 'd',
&transdatums, &ndatums);
if (ndatums != 2)
elog(ERROR, "interval_avg: expected 2-element interval array");
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index 8779acddb4..97c3567f1a 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.23 2002/08/04 06:33:48 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.24 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -226,7 +226,7 @@ bit(PG_FUNCTION_ARGS)
Datum
_bit(PG_FUNCTION_ARGS)
{
- ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
+ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
@@ -439,7 +439,7 @@ varbit(PG_FUNCTION_ARGS)
Datum
_varbit(PG_FUNCTION_ARGS)
{
- ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
+ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 2520d415d5..cdf5c301d2 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.90 2002/06/20 20:29:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.91 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -283,7 +283,7 @@ bpchar(PG_FUNCTION_ARGS)
Datum
_bpchar(PG_FUNCTION_ARGS)
{
- ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
+ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
@@ -533,7 +533,7 @@ varchar(PG_FUNCTION_ARGS)
Datum
_varchar(PG_FUNCTION_ARGS)
{
- ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
+ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index a916dc9401..079ba2152a 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.79 2002/08/22 00:01:44 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.80 2002/08/26 17:53:59 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@@ -885,6 +885,30 @@ get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
ReleaseSysCache(tp);
}
+/*
+ * get_typlenbyvalalign
+ *
+ * A three-fer: given the type OID, return typlen, typbyval, typalign.
+ */
+void
+get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
+ char *typalign)
+{
+ HeapTuple tp;
+ Form_pg_type typtup;
+
+ tp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for type %u", typid);
+ typtup = (Form_pg_type) GETSTRUCT(tp);
+ *typlen = typtup->typlen;
+ *typbyval = typtup->typbyval;
+ *typalign = typtup->typalign;
+ ReleaseSysCache(tp);
+}
+
#ifdef NOT_USED
char
get_typalign(Oid typid)
@@ -1287,7 +1311,9 @@ get_attstatsslot(HeapTuple statstuple,
* Do initial examination of the array. This produces a list of
* text Datums --- ie, pointers into the text array value.
*/
- deconstruct_array(statarray, false, -1, 'i', values, nvalues);
+ deconstruct_array(statarray,
+ TEXTOID, -1, false, 'i',
+ values, nvalues);
narrayelem = *nvalues;
/*
@@ -1346,8 +1372,8 @@ get_attstatsslot(HeapTuple statstuple,
*/
narrayelem = ARR_DIMS(statarray)[0];
if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
- ARR_SIZE(statarray) != (ARR_OVERHEAD(1) + narrayelem * sizeof(float4)))
- elog(ERROR, "get_attstatsslot: stanumbers is bogus");
+ ARR_ELEMTYPE(statarray) != FLOAT4OID)
+ elog(ERROR, "get_attstatsslot: stanumbers is not a 1-D float4 array");
*numbers = (float4 *) palloc(narrayelem * sizeof(float4));
memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
*nnumbers = narrayelem;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a759b3f527..b73118289f 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5,7 +5,7 @@
* command, configuration file, and command line options.
* See src/backend/utils/misc/README for more information.
*
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.83 2002/08/18 03:03:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.84 2002/08/26 17:53:59 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -2680,6 +2680,7 @@ assign_defaultxactisolevel(const char *newval, bool doit, bool interactive)
/*
* Handle options fetched from pg_database.datconfig or pg_shadow.useconfig.
+ * The array parameter must be an array of TEXT.
*/
void
ProcessGUCArray(ArrayType *array, GucSource source)
@@ -2687,6 +2688,9 @@ ProcessGUCArray(ArrayType *array, GucSource source)
int i;
Assert(array != NULL);
+ Assert(ARR_ELEMTYPE(array) == TEXTOID);
+ Assert(ARR_NDIM(array) == 1);
+ Assert(ARR_LBOUND(array)[0] == 1);
Assert(source == PGC_S_DATABASE || source == PGC_S_USER);
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
@@ -2698,9 +2702,10 @@ ProcessGUCArray(ArrayType *array, GucSource source)
char *value;
d = array_ref(array, 1, &i,
- false /*notbyvalue*/,
- -1 /*varlenelem*/,
-1 /*varlenarray*/,
+ -1 /*TEXT's typlen*/,
+ false /*TEXT's typbyval*/,
+ 'i' /*TEXT's typalign*/,
&isnull);
if (isnull)
@@ -2756,6 +2761,10 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
bool isnull;
int i;
+ Assert(ARR_ELEMTYPE(array) == TEXTOID);
+ Assert(ARR_NDIM(array) == 1);
+ Assert(ARR_LBOUND(array)[0] == 1);
+
index = ARR_DIMS(array)[0] + 1; /* add after end */
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
@@ -2764,10 +2773,13 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
char *current;
d = array_ref(array, 1, &i,
- false /*notbyvalue*/,
- -1 /*varlenelem*/,
-1 /*varlenarray*/,
+ -1 /*TEXT's typlen*/,
+ false /*TEXT's typbyval*/,
+ 'i' /*TEXT's typalign*/,
&isnull);
+ if (isnull)
+ continue;
current = DatumGetCString(DirectFunctionCall1(textout, d));
if (strncmp(current, newval, strlen(name) + 1)==0)
{
@@ -2777,10 +2789,18 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
}
isnull = false;
- a = array_set(array, 1, &index, datum, false/*notbyval*/, -1, -1, &isnull);
+ a = array_set(array, 1, &index,
+ datum,
+ -1 /*varlenarray*/,
+ -1 /*TEXT's typlen*/,
+ false /*TEXT's typbyval*/,
+ 'i' /*TEXT's typalign*/,
+ &isnull);
}
else
- a = construct_array(&datum, 1, false, -1, 'i');
+ a = construct_array(&datum, 1,
+ TEXTOID,
+ -1, false, 'i');
return a;
}
@@ -2802,7 +2822,9 @@ GUCArrayDelete(ArrayType *array, const char *name)
superuser() ? PGC_SUSET : PGC_USERSET,
PGC_S_SESSION, false, false);
- newarray = construct_array(NULL, 0, false, -1, 'i');
+ newarray = construct_array(NULL, 0,
+ TEXTOID,
+ -1, false, 'i');
index = 1;
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
@@ -2812,10 +2834,13 @@ GUCArrayDelete(ArrayType *array, const char *name)
bool isnull;
d = array_ref(array, 1, &i,
- false /*notbyvalue*/,
- -1 /*varlenelem*/,
-1 /*varlenarray*/,
+ -1 /*TEXT's typlen*/,
+ false /*TEXT's typbyval*/,
+ 'i' /*TEXT's typalign*/,
&isnull);
+ if (isnull)
+ continue;
val = DatumGetCString(DirectFunctionCall1(textout, d));
if (strncmp(val, name, strlen(name))==0
@@ -2823,7 +2848,13 @@ GUCArrayDelete(ArrayType *array, const char *name)
continue;
isnull = false;
- newarray = array_set(newarray, 1, &index, d, false/*notbyval*/, -1, -1, &isnull);
+ newarray = array_set(newarray, 1, &index,
+ d,
+ -1 /*varlenarray*/,
+ -1 /*TEXT's typlen*/,
+ false /*TEXT's typbyval*/,
+ 'i' /*TEXT's typalign*/,
+ &isnull);
index++;
}