diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-06-13 07:35:40 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-06-13 07:35:40 +0000 |
commit | f2d120532207b8873a5e74e7350dd2904f377289 (patch) | |
tree | 992c89e023c4b29b42bf4fd6563de91f8d6ec8ca /src/backend/utils/adt/arrayfuncs.c | |
parent | 8f057d971d663fff9bbb2ae7d053bf71cf09b4a2 (diff) | |
download | postgresql-f2d120532207b8873a5e74e7350dd2904f377289.tar.gz postgresql-f2d120532207b8873a5e74e7350dd2904f377289.zip |
Another batch of fmgr updates. I think I have gotten all old-style
functions that take pass-by-value datatypes. Should be ready for
port testing ...
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r-- | src/backend/utils/adt/arrayfuncs.c | 362 |
1 files changed, 179 insertions, 183 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index b721728919b..d54a6847bd2 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.56 2000/06/09 01:11:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.57 2000/06/13 07:35:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -68,7 +68,7 @@ static void _LOArrayRange(int *st, int *endp, int bsize, int srcfd, int destfd, ArrayType *array, int isSrcLO, bool *isNull); static void _ReadArray(int *st, int *endp, int bsize, int srcfd, int destfd, ArrayType *array, int isDestLO, bool *isNull); -static int ArrayCastAndSet(char *src, bool typbyval, int typlen, char *dest); +static int ArrayCastAndSet(Datum src, bool typbyval, int typlen, char *dest); static int SanityCheckInput(int ndim, int n, int *dim, int *lb, int *indx); static int array_read(char *destptr, int eltsize, int nitems, char *srcptr); static char *array_seek(char *ptr, int eltsize, int nitems); @@ -76,16 +76,17 @@ static char *array_seek(char *ptr, int eltsize, int nitems); /*--------------------------------------------------------------------- * array_in : * converts an array from the external format in "string" to - * it internal format. + * its internal format. * return value : * the internal representation of the input array *-------------------------------------------------------------------- */ -char * -array_in(char *string, /* input array in external form */ - Oid element_type, /* type OID of an array element */ - int32 typmod) +Datum +array_in(PG_FUNCTION_ARGS) { + char *string = PG_GETARG_CSTRING(0); /* external form */ + 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; @@ -101,7 +102,7 @@ array_in(char *string, /* input array in external form */ nitems; int32 nbytes; char *dataPtr; - ArrayType *retval = NULL; + ArrayType *retval; int ndim, dim[MAXDIM], lBound[MAXDIM]; @@ -183,11 +184,10 @@ array_in(char *string, /* input array in external form */ nitems = getNitems(ndim, dim); if (nitems == 0) { - char *emptyArray = palloc(sizeof(ArrayType)); - - MemSet(emptyArray, 0, sizeof(ArrayType)); - *(int32 *) emptyArray = sizeof(ArrayType); - return emptyArray; + retval = (ArrayType *) palloc(sizeof(ArrayType)); + MemSet(retval, 0, sizeof(ArrayType)); + *(int32 *) retval = sizeof(ArrayType); + return PointerGetDatum(retval); } if (*p == '{') @@ -235,9 +235,10 @@ array_in(char *string, /* input array in external form */ memmove(ARR_DATA_PTR(retval), dataPtr, bytes); #endif elog(ERROR, "large object arrays not supported"); + PG_RETURN_NULL(); } pfree(string_save); - return (char *) retval; + return PointerGetDatum(retval); } /*----------------------------------------------------------------------------- @@ -578,7 +579,7 @@ _CopyArrayEls(char **values, { int inc; - inc = ArrayCastAndSet(values[i], typbyval, typlen, p); + inc = ArrayCastAndSet((Datum) values[i], typbyval, typlen, p); p += inc; if (!typbyval) pfree(values[i]); @@ -592,9 +593,11 @@ _CopyArrayEls(char **values, * containing the array in its external format. *------------------------------------------------------------------------- */ -char * -array_out(ArrayType *v, Oid element_type) +Datum +array_out(PG_FUNCTION_ARGS) { + ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0); + Oid element_type = PG_GETARG_OID(1); int typlen; bool typbyval; char typdelim; @@ -602,7 +605,6 @@ array_out(ArrayType *v, Oid element_type) typelem; FmgrInfo outputproc; char typalign; - char *p, *tmp, *retval, @@ -617,30 +619,31 @@ array_out(ArrayType *v, Oid element_type) l, #endif indx[MAXDIM]; - bool dummy_bool; int ndim, *dim; if (v == (ArrayType *) NULL) - return (char *) NULL; + PG_RETURN_CSTRING((char *) NULL); if (ARR_IS_LO(v) == true) { - char *p, - *save_p; - int nbytes; + text *p; + int plen, + nbytes; - /* get a wide string to print to */ - p = array_dims(v, &dummy_bool); - nbytes = strlen(ARR_DATA_PTR(v)) + VARHDRSZ + *(int *) p; + p = (text *) DatumGetPointer(DirectFunctionCall1(array_dims, + PointerGetDatum(v))); + plen = VARSIZE(p) - VARHDRSZ; - save_p = (char *) palloc(nbytes); + /* get a wide string to print to */ + nbytes = strlen(ARR_DATA_PTR(v)) + strlen(ASSGN) + plen + 1; + retval = (char *) palloc(nbytes); - strcpy(save_p, p + sizeof(int)); - strcat(save_p, ASSGN); - strcat(save_p, ARR_DATA_PTR(v)); + memcpy(retval, VARDATA(p), plen); + strcpy(retval + plen, ASSGN); + strcat(retval, ARR_DATA_PTR(v)); pfree(p); - return save_p; + PG_RETURN_CSTRING(retval); } system_cache_lookup(element_type, false, &typlen, &typbyval, @@ -653,12 +656,11 @@ array_out(ArrayType *v, Oid element_type) if (nitems == 0) { - char *emptyArray = palloc(3); - - emptyArray[0] = '{'; - emptyArray[1] = '}'; - emptyArray[2] = '\0'; - return emptyArray; + retval = (char *) palloc(3); + retval[0] = '{'; + retval[1] = '}'; + retval[2] = '\0'; + PG_RETURN_CSTRING(retval); } p = ARR_DATA_PTR(v); @@ -776,58 +778,61 @@ array_out(ArrayType *v, Oid element_type) } while (j != -1); pfree(values); - return retval; + PG_RETURN_CSTRING(retval); } /*----------------------------------------------------------------------------- * array_dims : - * returns the dimension of the array pointed to by "v" + * returns the dimensions of the array pointed to by "v", as a "text" *---------------------------------------------------------------------------- */ -char * -array_dims(ArrayType *v, bool *isNull) +Datum +array_dims(PG_FUNCTION_ARGS) { - char *p, - *save_p; + ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0); + text *result; + char *p; int nbytes, i; int *dimv, *lb; - if (v == (ArrayType *) NULL) - RETURN_NULL; - nbytes = ARR_NDIM(v) * 33; - + nbytes = ARR_NDIM(v) * 33 + 1; /* * 33 since we assume 15 digits per number + ':' +'[]' + * + * +1 allows for temp trailing null */ - save_p = p = (char *) palloc(nbytes + VARHDRSZ); - MemSet(save_p, 0, nbytes + VARHDRSZ); + + result = (text *) palloc(nbytes + VARHDRSZ); + MemSet(result, 0, nbytes + VARHDRSZ); + p = VARDATA(result); + dimv = ARR_DIMS(v); lb = ARR_LBOUND(v); - p += VARHDRSZ; + for (i = 0; i < ARR_NDIM(v); i++) { sprintf(p, "[%d:%d]", lb[i], dimv[i] + lb[i] - 1); p += strlen(p); } - nbytes = strlen(save_p + VARHDRSZ) + VARHDRSZ; - memmove(save_p, &nbytes, VARHDRSZ); - return save_p; + VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ; + + PG_RETURN_TEXT_P(result); } /*--------------------------------------------------------------------------- * array_ref : - * This routing takes an array pointer and an index array and returns + * This routine takes an array pointer and an index array and returns * a pointer to the referred element if element is passed by * reference otherwise returns the value of the referred element. *--------------------------------------------------------------------------- */ Datum array_ref(ArrayType *array, - int n, + int nSubscripts, int *indx, - int reftype, + bool elmbyval, int elmlen, int arraylen, bool *isNull) @@ -839,10 +844,11 @@ array_ref(ArrayType *array, offset, nbytes; struct varlena *v = NULL; - char *retval = NULL; + Datum result; + char *retval; if (array == (ArrayType *) NULL) - RETURN_NULL; + RETURN_NULL(Datum); if (arraylen > 0) { @@ -852,17 +858,17 @@ array_ref(ArrayType *array, if (indx[0] * elmlen > arraylen) elog(ERROR, "array_ref: array bound exceeded"); retval = (char *) array + indx[0] * elmlen; - return _ArrayCast(retval, reftype, elmlen); + return _ArrayCast(retval, elmbyval, elmlen); } dim = ARR_DIMS(array); lb = ARR_LBOUND(array); ndim = ARR_NDIM(array); nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim); - if (!SanityCheckInput(ndim, n, dim, lb, indx)) - RETURN_NULL; + if (!SanityCheckInput(ndim, nSubscripts, dim, lb, indx)) + RETURN_NULL(Datum); - offset = GetOffset(n, dim, lb, indx); + offset = GetOffset(nSubscripts, dim, lb, indx); if (ARR_IS_LO(array)) { @@ -874,7 +880,7 @@ array_ref(ArrayType *array, lo_name = (char *) ARR_DATA_PTR(array); #ifdef LOARRAY if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_READ : O_RDONLY)) < 0) - RETURN_NULL; + RETURN_NULL(Datum); #endif if (ARR_IS_CHUNKED(array)) v = _ReadChunkArray1El(indx, elmlen, fd, array, isNull); @@ -884,7 +890,7 @@ array_ref(ArrayType *array, Int32GetDatum(fd), Int32GetDatum(offset), Int32GetDatum(SEEK_SET))) < 0) - RETURN_NULL; + RETURN_NULL(Datum); #ifdef LOARRAY v = (struct varlena *) DatumGetPointer(DirectFunctionCall2(loread, @@ -893,20 +899,20 @@ array_ref(ArrayType *array, #endif } if (*isNull) - RETURN_NULL; + RETURN_NULL(Datum); if (VARSIZE(v) - VARHDRSZ < elmlen) - RETURN_NULL; + RETURN_NULL(Datum); DirectFunctionCall1(lo_close, Int32GetDatum(fd)); - retval = (char *) _ArrayCast((char *) VARDATA(v), reftype, elmlen); - if (reftype == 0) + result = _ArrayCast((char *) VARDATA(v), elmbyval, elmlen); + if (! elmbyval) { /* not by value */ char *tempdata = palloc(elmlen); - memmove(tempdata, retval, elmlen); - retval = tempdata; + memmove(tempdata, DatumGetPointer(result), elmlen); + result = PointerGetDatum(tempdata); } pfree(v); - return (Datum) retval; + return result; } if (elmlen > 0) @@ -914,32 +920,25 @@ array_ref(ArrayType *array, offset = offset * elmlen; /* off the end of the array */ if (nbytes - offset < 1) - RETURN_NULL; + RETURN_NULL(Datum); retval = ARR_DATA_PTR(array) + offset; - return _ArrayCast(retval, reftype, elmlen); + return _ArrayCast(retval, elmbyval, elmlen); } else { - bool done = false; - char *temp; int bytes = nbytes; - temp = ARR_DATA_PTR(array); + retval = ARR_DATA_PTR(array); i = 0; - while (bytes > 0 && !done) + while (bytes > 0) { if (i == offset) - { - retval = temp; - done = true; - } - bytes -= INTALIGN(*(int32 *) temp); - temp += INTALIGN(*(int32 *) temp); + return PointerGetDatum(retval); + bytes -= INTALIGN(*(int32 *) retval); + retval += INTALIGN(*(int32 *) retval); i++; } - if (!done) - RETURN_NULL; - return (Datum) retval; + RETURN_NULL(Datum); } } @@ -950,13 +949,13 @@ array_ref(ArrayType *array, * and returns a pointer to it. *----------------------------------------------------------------------------- */ -Datum +ArrayType * array_clip(ArrayType *array, - int n, + int nSubscripts, int *upperIndx, int *lowerIndx, - int reftype, - int len, + bool elmbyval, + int elmlen, bool *isNull) { int i, @@ -970,22 +969,20 @@ array_clip(ArrayType *array, /* timer_start(); */ if (array == (ArrayType *) NULL) - RETURN_NULL; + RETURN_NULL(ArrayType *); dim = ARR_DIMS(array); lb = ARR_LBOUND(array); ndim = ARR_NDIM(array); nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim); - if (!SanityCheckInput(ndim, n, dim, lb, upperIndx)) - RETURN_NULL; + if (!SanityCheckInput(ndim, nSubscripts, dim, lb, upperIndx) || + !SanityCheckInput(ndim, nSubscripts, dim, lb, lowerIndx)) + RETURN_NULL(ArrayType *); - if (!SanityCheckInput(ndim, n, dim, lb, lowerIndx)) - RETURN_NULL; - - for (i = 0; i < n; i++) + for (i = 0; i < nSubscripts; i++) if (lowerIndx[i] > upperIndx[i]) elog(ERROR, "lowerIndex cannot be larger than upperIndx"); - mda_get_range(n, span, lowerIndx, upperIndx); + mda_get_range(nSubscripts, span, lowerIndx, upperIndx); if (ARR_IS_LO(array)) { @@ -999,23 +996,23 @@ array_clip(ArrayType *array, isDestLO = true, rsize; - if (len < 0) - elog(ERROR, "array_clip: array of variable length objects not supported"); + if (elmlen < 0) + elog(ERROR, "array_clip: array of variable length objects not implemented"); #ifdef LOARRAY lo_name = (char *) ARR_DATA_PTR(array); if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_READ : O_RDONLY)) < 0) - RETURN_NULL; + RETURN_NULL(ArrayType *); newname = _array_newLO(&newfd, Unix); #endif - bytes = strlen(newname) + 1 + ARR_OVERHEAD(n); + bytes = strlen(newname) + 1 + ARR_OVERHEAD(nSubscripts); newArr = (ArrayType *) palloc(bytes); memmove(newArr, array, sizeof(ArrayType)); memmove(newArr, &bytes, sizeof(int)); - memmove(ARR_DIMS(newArr), span, n * sizeof(int)); - memmove(ARR_LBOUND(newArr), lowerIndx, n * sizeof(int)); + memmove(ARR_DIMS(newArr), span, nSubscripts * sizeof(int)); + memmove(ARR_LBOUND(newArr), lowerIndx, nSubscripts * sizeof(int)); strcpy(ARR_DATA_PTR(newArr), newname); - rsize = compute_size(lowerIndx, upperIndx, n, len); + rsize = compute_size(lowerIndx, upperIndx, nSubscripts, elmlen); if (rsize < MAX_BUFF_SIZE) { char *buff; @@ -1026,12 +1023,12 @@ array_clip(ArrayType *array, isDestLO = false; if (ARR_IS_CHUNKED(array)) { - _ReadChunkArray(lowerIndx, upperIndx, len, fd, &(buff[VARHDRSZ]), + _ReadChunkArray(lowerIndx, upperIndx, elmlen, fd, &(buff[VARHDRSZ]), array, 0, isNull); } else { - _ReadArray(lowerIndx, upperIndx, len, fd, (int) &(buff[VARHDRSZ]), + _ReadArray(lowerIndx, upperIndx, elmlen, fd, (int) &(buff[VARHDRSZ]), array, 0, isNull); } @@ -1048,11 +1045,11 @@ array_clip(ArrayType *array, { if (ARR_IS_CHUNKED(array)) { - _ReadChunkArray(lowerIndx, upperIndx, len, fd, (char *) newfd, array, + _ReadChunkArray(lowerIndx, upperIndx, elmlen, fd, (char *) newfd, array, 1, isNull); } else - _ReadArray(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull); + _ReadArray(lowerIndx, upperIndx, elmlen, fd, newfd, array, 1, isNull); } #ifdef LOARRAY LOclose(fd); @@ -1064,42 +1061,42 @@ array_clip(ArrayType *array, newArr = NULL; } /* timer_end(); */ - return (Datum) newArr; + return newArr; } - if (len > 0) + if (elmlen > 0) { - bytes = getNitems(n, span); - bytes = bytes * len + ARR_OVERHEAD(n); + bytes = getNitems(nSubscripts, span); + bytes = bytes * elmlen + ARR_OVERHEAD(nSubscripts); } else { bytes = _ArrayClipCount(lowerIndx, upperIndx, array); - bytes += ARR_OVERHEAD(n); + bytes += ARR_OVERHEAD(nSubscripts); } newArr = (ArrayType *) palloc(bytes); memmove(newArr, array, sizeof(ArrayType)); memmove(newArr, &bytes, sizeof(int)); - memmove(ARR_DIMS(newArr), span, n * sizeof(int)); - memmove(ARR_LBOUND(newArr), lowerIndx, n * sizeof(int)); - _ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 1); - return (Datum) newArr; + memmove(ARR_DIMS(newArr), span, nSubscripts * sizeof(int)); + memmove(ARR_LBOUND(newArr), lowerIndx, nSubscripts * sizeof(int)); + _ArrayRange(lowerIndx, upperIndx, elmlen, ARR_DATA_PTR(newArr), array, 1); + return newArr; } /*----------------------------------------------------------------------------- * array_set : - * This routine sets the value of an array location (specified by an index array) - * to a new value specified by "dataPtr". + * This routine sets the value of an array location (specified by + * an index array) to a new value specified by "dataValue". * result : * returns a pointer to the modified array. *----------------------------------------------------------------------------- */ -char * +ArrayType * array_set(ArrayType *array, - int n, + int nSubscripts, int *indx, - char *dataPtr, - int reftype, + Datum dataValue, + bool elmbyval, int elmlen, int arraylen, bool *isNull) @@ -1112,7 +1109,7 @@ array_set(ArrayType *array, char *pos; if (array == (ArrayType *) NULL) - RETURN_NULL; + RETURN_NULL(ArrayType *); if (arraylen > 0) { @@ -1122,20 +1119,20 @@ array_set(ArrayType *array, if (indx[0] * elmlen > arraylen) elog(ERROR, "array_ref: array bound exceeded"); pos = (char *) array + indx[0] * elmlen; - ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos); - return (char *) array; + ArrayCastAndSet(dataValue, elmbyval, elmlen, pos); + return array; } dim = ARR_DIMS(array); lb = ARR_LBOUND(array); ndim = ARR_NDIM(array); nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim); - if (!SanityCheckInput(ndim, n, dim, lb, indx)) + if (!SanityCheckInput(ndim, nSubscripts, dim, lb, indx)) { elog(ERROR, "array_set: array bound exceeded"); - return (char *) array; + return array; } - offset = GetOffset(n, dim, lb, indx); + offset = GetOffset(nSubscripts, dim, lb, indx); if (ARR_IS_LO(array)) { @@ -1149,35 +1146,33 @@ array_set(ArrayType *array, lo_name = ARR_DATA_PTR(array); if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_WRITE : O_WRONLY)) < 0) - return (char *) array; + return array; #endif if (DatumGetInt32(DirectFunctionCall3(lo_lseek, Int32GetDatum(fd), Int32GetDatum(offset), Int32GetDatum(SEEK_SET))) < 0) - return (char *) array; + return array; v = (struct varlena *) palloc(elmlen + VARHDRSZ); VARSIZE(v) = elmlen + VARHDRSZ; - ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, VARDATA(v)); + ArrayCastAndSet(dataValue, elmbyval, elmlen, VARDATA(v)); #ifdef LOARRAY - n = DatumGetInt32(DirectFunctionCall2(lowrite, + if (DatumGetInt32(DirectFunctionCall2(lowrite, Int32GetDatum(fd), - PointerGetDatum(v))); + PointerGetDatum(v))) + != elmlen) + RETURN_NULL(ArrayType *); #endif - - /* - * if (n < VARSIZE(v) - VARHDRSZ) RETURN_NULL; - */ pfree(v); DirectFunctionCall1(lo_close, Int32GetDatum(fd)); - return (char *) array; + return array; } if (elmlen > 0) { offset = offset * elmlen; /* off the end of the array */ if (nbytes - offset < 1) - return (char *) array; + return array; pos = ARR_DATA_PTR(array) + offset; } else @@ -1194,18 +1189,18 @@ array_set(ArrayType *array, elt_ptr = array_seek(ARR_DATA_PTR(array), -1, offset); oldlen = INTALIGN(*(int32 *) elt_ptr); - newlen = INTALIGN(*(int32 *) dataPtr); + newlen = INTALIGN(*(int32 *) DatumGetPointer(dataValue)); if (oldlen == newlen) { /* new element with same size, overwrite old data */ - ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, elt_ptr); - return (char *) array; + ArrayCastAndSet(dataValue, elmbyval, elmlen, elt_ptr); + return array; } /* new element with different size, reallocate the array */ oldsize = array->size; - lth0 = ARR_OVERHEAD(n); + lth0 = ARR_OVERHEAD(nSubscripts); lth1 = (int) (elt_ptr - ARR_DATA_PTR(array)); lth2 = (int) (oldsize - lth0 - lth1 - oldlen); newsize = lth0 + lth1 + newlen + lth2; @@ -1213,16 +1208,16 @@ array_set(ArrayType *array, newarray = (ArrayType *) palloc(newsize); memmove((char *) newarray, (char *) array, lth0 + lth1); newarray->size = newsize; - newlen = ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, + newlen = ArrayCastAndSet(dataValue, elmbyval, elmlen, (char *) newarray + lth0 + lth1); memmove((char *) newarray + lth0 + lth1 + newlen, (char *) array + lth0 + lth1 + oldlen, lth2); /* ??? who should free this storage ??? */ - return (char *) newarray; + return newarray; } - ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos); - return (char *) array; + ArrayCastAndSet(dataValue, elmbyval, elmlen, pos); + return array; } /*---------------------------------------------------------------------------- @@ -1234,14 +1229,14 @@ array_set(ArrayType *array, * returns a pointer to the modified array. *---------------------------------------------------------------------------- */ -char * +ArrayType * array_assgn(ArrayType *array, - int n, + int nSubscripts, int *upperIndx, int *lowerIndx, ArrayType *newArr, - int reftype, - int len, + bool elmbyval, + int elmlen, bool *isNull) { int i, @@ -1250,19 +1245,19 @@ array_assgn(ArrayType *array, *lb; if (array == (ArrayType *) NULL) - RETURN_NULL; - if (len < 0) - elog(ERROR, "array_assgn:updates on arrays of variable length elements not allowed"); + RETURN_NULL(ArrayType *); + if (elmlen < 0) + elog(ERROR, "array_assgn: updates on arrays of variable length elements not implemented"); dim = ARR_DIMS(array); lb = ARR_LBOUND(array); ndim = ARR_NDIM(array); - if (!SanityCheckInput(ndim, n, dim, lb, upperIndx) || - !SanityCheckInput(ndim, n, dim, lb, lowerIndx)) - return (char *) array; + if (!SanityCheckInput(ndim, nSubscripts, dim, lb, upperIndx) || + !SanityCheckInput(ndim, nSubscripts, dim, lb, lowerIndx)) + RETURN_NULL(ArrayType *); - for (i = 0; i < n; i++) + for (i = 0; i < nSubscripts; i++) if (lowerIndx[i] > upperIndx[i]) elog(ERROR, "lowerIndex larger than upperIndx"); @@ -1276,28 +1271,28 @@ array_assgn(ArrayType *array, lo_name = (char *) ARR_DATA_PTR(array); if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_WRITE : O_WRONLY)) < 0) - return (char *) array; + return array; #endif if (ARR_IS_LO(newArr)) { #ifdef LOARRAY lo_name = (char *) ARR_DATA_PTR(newArr); if ((newfd = LOopen(lo_name, ARR_IS_INV(newArr) ? INV_READ : O_RDONLY)) < 0) - return (char *) array; + return array; #endif - _LOArrayRange(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull); + _LOArrayRange(lowerIndx, upperIndx, elmlen, fd, newfd, array, 1, isNull); DirectFunctionCall1(lo_close, Int32GetDatum(newfd)); } else { - _LOArrayRange(lowerIndx, upperIndx, len, fd, (int) ARR_DATA_PTR(newArr), + _LOArrayRange(lowerIndx, upperIndx, elmlen, fd, (int) ARR_DATA_PTR(newArr), array, 0, isNull); } DirectFunctionCall1(lo_close, Int32GetDatum(fd)); - return (char *) array; + return array; } - _ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 0); - return (char *) array; + _ArrayRange(lowerIndx, upperIndx, elmlen, ARR_DATA_PTR(newArr), array, 0); + return array; } /* @@ -1353,7 +1348,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType) elog(ERROR, "array_map: invalid nargs: %d", fcinfo->nargs); if (PG_ARGISNULL(0)) elog(ERROR, "array_map: null input array"); - v = (ArrayType *) PG_GETARG_POINTER(0); + v = (ArrayType *) PG_GETARG_VARLENA_P(0); /* Large objects not yet supported */ if (ARR_IS_LO(v) == true) @@ -1466,19 +1461,20 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType) * array_eq : * compares two arrays for equality * result : - * returns 1 if the arrays are equal, 0 otherwise. + * returns true if the arrays are equal, false otherwise. *----------------------------------------------------------------------------- */ -int -array_eq(ArrayType *array1, ArrayType *array2) +Datum +array_eq(PG_FUNCTION_ARGS) { - if ((array1 == NULL) || (array2 == NULL)) - return 0; - if (*(int *) array1 != *(int *) array2) - return 0; - if (memcmp(array1, array2, *(int *) array1)) - return 0; - return 1; + ArrayType *array1 = (ArrayType *) PG_GETARG_VARLENA_P(0); + ArrayType *array2 = (ArrayType *) PG_GETARG_VARLENA_P(1); + + if (*(int32 *) array1 != *(int32 *) array2) + PG_RETURN_BOOL(false); + if (memcmp(array1, array2, *(int32 *) array1) != 0) + PG_RETURN_BOOL(false); + PG_RETURN_BOOL(true); } /***************************************************************************/ @@ -1545,7 +1541,7 @@ _ArrayCast(char *value, bool byval, int len) static int -ArrayCastAndSet(char *src, +ArrayCastAndSet(Datum src, bool typbyval, int typlen, char *dest) @@ -1565,18 +1561,18 @@ ArrayCastAndSet(char *src, *(int16 *) dest = DatumGetInt16(src); break; case 4: - *(int32 *) dest = (int32) src; + *(int32 *) dest = DatumGetInt32(src); break; } } else - memmove(dest, src, typlen); + memmove(dest, DatumGetPointer(src), typlen); inc = typlen; } else { - memmove(dest, src, *(int32 *) src); - inc = (INTALIGN(*(int32 *) src)); + memmove(dest, DatumGetPointer(src), *(int32 *) DatumGetPointer(src)); + inc = (INTALIGN(*(int32 *) DatumGetPointer(src))); } return inc; } |