]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/adt/arrayfuncs.c
I had overlooked the fact that some fmgr-callable functions return void
[postgresql] / src / backend / utils / adt / arrayfuncs.c
index 2736f92555cde96fcb7512f7fa7d67f5955110c9..aae18aa047fc464691589be7b2911d844a43f847 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.55 2000/06/02 15:57:28 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.58 2000/06/14 05:24:48 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);
+               PG_RETURN_POINTER(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;
+       PG_RETURN_POINTER(retval);
 }
 
 /*-----------------------------------------------------------------------------
@@ -538,8 +539,11 @@ _ReadLOArray(char *str,
 
        if (inputfile == NULL)
                elog(ERROR, "array_in: missing file name");
-       lobjId = lo_creat(0);
-       *fd = lo_open(lobjId, INV_READ);
+       lobjId = DatumGetObjectId(DirectFunctionCall1(lo_creat,
+                                                                                                 Int32GetDatum(0)));
+       *fd = DatumGetInt32(DirectFunctionCall2(lo_open,
+                                                                                       ObjectIdGetDatum(lobjId),
+                                                                                       Int32GetDatum(INV_READ)));
        if (*fd < 0)
                elog(ERROR, "Large object create failed");
        retStr = inputfile;
@@ -575,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]);
@@ -589,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;
@@ -599,7 +605,6 @@ array_out(ArrayType *v, Oid element_type)
                                typelem;
        FmgrInfo        outputproc;
        char            typalign;
-
        char       *p,
                           *tmp,
                           *retval,
@@ -614,30 +619,28 @@ array_out(ArrayType *v, Oid element_type)
                                l,
 #endif
                                indx[MAXDIM];
-       bool            dummy_bool;
        int                     ndim,
                           *dim;
 
-       if (v == (ArrayType *) NULL)
-               return (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,
@@ -650,12 +653,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);
@@ -773,58 +775,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)
@@ -836,10 +841,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)
        {
 
@@ -849,17 +855,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))
        {
@@ -871,33 +877,39 @@ 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);
                else
                {
-                       if (lo_lseek(fd, offset, SEEK_SET) < 0)
-                               RETURN_NULL;
+                       if (DatumGetInt32(DirectFunctionCall3(lo_lseek,
+                                                         Int32GetDatum(fd),
+                                                         Int32GetDatum(offset),
+                                                         Int32GetDatum(SEEK_SET))) < 0)
+                               RETURN_NULL(Datum);
 #ifdef LOARRAY
-                       v = (struct varlena *) LOread(fd, elmlen);
+                       v = (struct varlena *)
+                               DatumGetPointer(DirectFunctionCall2(loread,
+                                                                                                       Int32GetDatum(fd),
+                                                                                                       Int32GetDatum(elmlen)));
 #endif
                }
                if (*isNull)
-                       RETURN_NULL;
+                       RETURN_NULL(Datum);
                if (VARSIZE(v) - VARHDRSZ < elmlen)
-                       RETURN_NULL;
-               lo_close(fd);
-               retval = (char *) _ArrayCast((char *) VARDATA(v), reftype, elmlen);
-               if (reftype == 0)
+                       RETURN_NULL(Datum);
+               DirectFunctionCall1(lo_close, Int32GetDatum(fd));
+               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)
@@ -905,32 +917,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);
        }
 }
 
@@ -941,13 +946,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,
@@ -961,22 +966,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))
        {
@@ -990,23 +993,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, nlen);
+               rsize = compute_size(lowerIndx, upperIndx, nSubscripts, elmlen);
                if (rsize < MAX_BUFF_SIZE)
                {
                        char       *buff;
@@ -1017,19 +1020,21 @@ 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);
                        }
                        memmove(buff, &rsize, VARHDRSZ);
 #ifdef LOARRAY
                        if (!*isNull)
-                               bytes = LOwrite(newfd, (struct varlena *) buff);
+                               bytes = DatumGetInt32(DirectFunctionCall2(lowrite,
+                                                                         Int32GetDatum(newfd),
+                                                                         PointerGetDatum(buff)));
 #endif
                        pfree(buff);
                }
@@ -1037,11 +1042,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);
@@ -1053,42 +1058,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)
@@ -1101,7 +1106,7 @@ array_set(ArrayType *array,
        char       *pos;
 
        if (array == (ArrayType *) NULL)
-               RETURN_NULL;
+               RETURN_NULL(ArrayType *);
        if (arraylen > 0)
        {
 
@@ -1111,20 +1116,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))
        {
@@ -1138,30 +1143,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 (lo_lseek(fd, offset, SEEK_SET) < 0)
-                       return (char *) array;
+               if (DatumGetInt32(DirectFunctionCall3(lo_lseek,
+                                                         Int32GetDatum(fd),
+                                                         Int32GetDatum(offset),
+                                                         Int32GetDatum(SEEK_SET))) < 0)
+                       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 = LOwrite(fd, v);
+               if (DatumGetInt32(DirectFunctionCall2(lowrite,
+                                                                                         Int32GetDatum(fd),
+                                                                                         PointerGetDatum(v)))
+                       != elmlen)
+                       RETURN_NULL(ArrayType *);
 #endif
-
-               /*
-                * if (n < VARSIZE(v) - VARHDRSZ) RETURN_NULL;
-                */
                pfree(v);
-               lo_close(fd);
-               return (char *) array;
+               DirectFunctionCall1(lo_close, Int32GetDatum(fd));
+               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
@@ -1178,18 +1186,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;
@@ -1197,16 +1205,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;
 }
 
 /*----------------------------------------------------------------------------
@@ -1218,14 +1226,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,
@@ -1234,19 +1242,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");
 
@@ -1260,28 +1268,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);
-                       lo_close(newfd);
+                       _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);
                }
-               lo_close(fd);
-               return (char *) array;
+               DirectFunctionCall1(lo_close, Int32GetDatum(fd));
+               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;
 }
 
 /*
@@ -1337,7 +1345,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)
@@ -1450,19 +1458,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);
 }
 
 /***************************************************************************/
@@ -1529,7 +1538,7 @@ _ArrayCast(char *value, bool byval, int len)
 
 
 static int
-ArrayCastAndSet(char *src,
+ArrayCastAndSet(Datum src,
                                bool typbyval,
                                int typlen,
                                char *dest)
@@ -1549,18 +1558,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;
 }
@@ -1758,7 +1767,10 @@ _LOArrayRange(int *st,
        mda_get_prod(n, dim, prod);
        st_pos = tuple2linear(n, st, prod);
        offset = st_pos * bsize;
-       if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+       if (DatumGetInt32(DirectFunctionCall3(lo_lseek,
+                                                         Int32GetDatum(srcfd),
+                                                         Int32GetDatum(offset),
+                                                         Int32GetDatum(SEEK_SET))) < 0)
                return;
        mda_get_range(n, span, st, endp);
        mda_get_offset_values(n, dist, prod, span);
@@ -1770,7 +1782,10 @@ _LOArrayRange(int *st,
        do
        {
                offset += (dist[j] * bsize);
-               if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+               if (DatumGetInt32(DirectFunctionCall3(lo_lseek,
+                                                         Int32GetDatum(srcfd),
+                                                         Int32GetDatum(offset),
+                                                         Int32GetDatum(SEEK_SET))) < 0)
                        return;
                tmp = _LOtransfer((char **) &srcfd, inc, 1, (char **) &destfd, isSrcLO, 1);
                if (tmp < inc)
@@ -1812,7 +1827,10 @@ _ReadArray(int *st,
        mda_get_prod(n, dim, prod);
        st_pos = tuple2linear(n, st, prod);
        offset = st_pos * bsize;
-       if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+       if (DatumGetInt32(DirectFunctionCall3(lo_lseek,
+                                                         Int32GetDatum(srcfd),
+                                                         Int32GetDatum(offset),
+                                                         Int32GetDatum(SEEK_SET))) < 0)
                return;
        mda_get_range(n, span, st, endp);
        mda_get_offset_values(n, dist, prod, span);
@@ -1824,7 +1842,10 @@ _ReadArray(int *st,
        do
        {
                offset += (dist[j] * bsize);
-               if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+               if (DatumGetInt32(DirectFunctionCall3(lo_lseek,
+                                                         Int32GetDatum(srcfd),
+                                                         Int32GetDatum(offset),
+                                                         Int32GetDatum(SEEK_SET))) < 0)
                        return;
                tmp = _LOtransfer((char **) &destfd, inc, 1, (char **) &srcfd, 1, isDestLO);
                if (tmp < inc)
@@ -1857,13 +1878,18 @@ _LOtransfer(char **destfd,
                         resid > 0 && (inc = min(resid, MAX_READ)) > 0; resid -= inc)
                {
 #ifdef LOARRAY
-                       v = (struct varlena *) LOread((int) *srcfd, inc);
+                       v = (struct varlena *)
+                               DatumGetPointer(DirectFunctionCall2(loread,
+                                                               Int32GetDatum((int32) *srcfd),
+                                                               Int32GetDatum(inc)));
                        if (VARSIZE(v) - VARHDRSZ < inc)
                        {
                                pfree(v);
                                return -1;
                        }
-                       tmp += LOwrite((int) *destfd, v);
+                       tmp += DatumGetInt32(DirectFunctionCall2(lowrite,
+                                                                Int32GetDatum((int32) *destfd),
+                                                                PointerGetDatum(v)));
 #endif
                        pfree(v);