Skip to content

Commit 6ed00fe

Browse files
committed
Convert array_map to use new fmgr interface.
1 parent 747527e commit 6ed00fe

File tree

3 files changed

+101
-64
lines changed

3 files changed

+101
-64
lines changed

src/backend/utils/adt/arrayfuncs.c

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.52 2000/01/26 05:57:12 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.53 2000/05/29 21:02:32 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -17,7 +17,6 @@
1717

1818
#include "postgres.h"
1919

20-
2120
#include "catalog/catalog.h"
2221
#include "catalog/pg_type.h"
2322
#include "fmgr.h"
@@ -1277,19 +1276,33 @@ array_assgn(ArrayType *array,
12771276
/*
12781277
* array_map()
12791278
*
1280-
* Map an arbitrary function to an array and return a new array with
1281-
* same dimensions and the source elements transformed by fn().
1279+
* Map an array through an arbitrary function. Return a new array with
1280+
* same dimensions and each source element transformed by fn(). Each
1281+
* source element is passed as the first argument to fn(); additional
1282+
* arguments to be passed to fn() can be specified by the caller.
1283+
* The output array can have a different element type than the input.
1284+
*
1285+
* Parameters are:
1286+
* * fcinfo: a function-call data structure pre-constructed by the caller
1287+
* to be ready to call the desired function, with everything except the
1288+
* first argument position filled in. In particular, flinfo identifies
1289+
* the function fn(), and if nargs > 1 then argument positions after the
1290+
* first must be preset to the additional values to be passed. The
1291+
* first argument position initially holds the input array value.
1292+
* * inpType: OID of element type of input array. This must be the same as,
1293+
* or binary-compatible with, the first argument type of fn().
1294+
* * retType: OID of element type of output array. This must be the same as,
1295+
* or binary-compatible with, the result type of fn().
1296+
*
1297+
* NB: caller must assure that input array is not NULL. Currently,
1298+
* any additional parameters passed to fn() may not be specified as NULL
1299+
* either.
12821300
*/
1283-
ArrayType *
1284-
array_map(ArrayType *v,
1285-
Oid type,
1286-
char *(*fn) (),
1287-
Oid retType,
1288-
int nargs,
1289-
...)
1301+
Datum
1302+
array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
12901303
{
1304+
ArrayType *v;
12911305
ArrayType *result;
1292-
void *args[4];
12931306
char **values;
12941307
char *elt;
12951308
int *dim;
@@ -1307,35 +1320,31 @@ array_map(ArrayType *v,
13071320
char typalign;
13081321
char *s;
13091322
char *p;
1310-
va_list ap;
1323+
1324+
/* Get input array */
1325+
if (fcinfo->nargs < 1)
1326+
elog(ERROR, "array_map: invalid nargs: %d", fcinfo->nargs);
1327+
if (PG_ARGISNULL(0))
1328+
elog(ERROR, "array_map: null input array");
1329+
v = (ArrayType *) PG_GETARG_POINTER(0);
13111330

13121331
/* Large objects not yet supported */
13131332
if (ARR_IS_LO(v) == true)
13141333
elog(ERROR, "array_map: large objects not supported");
13151334

1316-
/* Check nargs */
1317-
if ((nargs < 0) || (nargs > 4))
1318-
elog(ERROR, "array_map: invalid nargs: %d", nargs);
1319-
1320-
/* Copy extra args to local variable */
1321-
va_start(ap, nargs);
1322-
for (i = 0; i < nargs; i++)
1323-
args[i] = (void *) va_arg(ap, char *);
1324-
va_end(ap);
1325-
1326-
/* Lookup source and result types. Unneeded variables are reused. */
1327-
system_cache_lookup(type, false, &inp_typlen, &inp_typbyval,
1328-
&typdelim, &typelem, &proc, &typalign);
1329-
system_cache_lookup(retType, false, &typlen, &typbyval,
1330-
&typdelim, &typelem, &proc, &typalign);
1331-
13321335
ndim = ARR_NDIM(v);
13331336
dim = ARR_DIMS(v);
13341337
nitems = getNitems(ndim, dim);
13351338

13361339
/* Check for empty array */
13371340
if (nitems <= 0)
1338-
return v;
1341+
PG_RETURN_POINTER(v);
1342+
1343+
/* Lookup source and result types. Unneeded variables are reused. */
1344+
system_cache_lookup(inpType, false, &inp_typlen, &inp_typbyval,
1345+
&typdelim, &typelem, &proc, &typalign);
1346+
system_cache_lookup(retType, false, &typlen, &typbyval,
1347+
&typdelim, &typelem, &proc, &typalign);
13391348

13401349
/* Allocate temporary array for new values */
13411350
values = (char **) palloc(nitems * sizeof(char *));
@@ -1374,33 +1383,23 @@ array_map(ArrayType *v,
13741383
}
13751384

13761385
/*
1377-
* Apply the given function to source elt and extra args. nargs is
1378-
* the number of extra args taken by fn().
1386+
* Apply the given function to source elt and extra args.
1387+
*
1388+
* We assume the extra args are non-NULL, so need not check
1389+
* whether fn() is strict. Would need to do more work here
1390+
* to support arrays containing nulls, too.
13791391
*/
1380-
switch (nargs)
1381-
{
1382-
case 0:
1383-
p = (char *) (*fn) (elt);
1384-
break;
1385-
case 1:
1386-
p = (char *) (*fn) (elt, args[0]);
1387-
break;
1388-
case 2:
1389-
p = (char *) (*fn) (elt, args[0], args[1]);
1390-
break;
1391-
case 3:
1392-
p = (char *) (*fn) (elt, args[0], args[1], args[2]);
1393-
break;
1394-
case 4:
1395-
default:
1396-
p = (char *) (*fn) (elt, args[0], args[1], args[2], args[3]);
1397-
break;
1398-
}
1392+
fcinfo->arg[0] = (Datum) elt;
1393+
fcinfo->argnull[0] = false;
1394+
fcinfo->isnull = false;
1395+
p = (char *) FunctionCallInvoke(fcinfo);
1396+
if (fcinfo->isnull)
1397+
elog(ERROR, "array_map: cannot handle NULL in array");
13991398

14001399
/* Update values and total result size */
14011400
if (typbyval)
14021401
{
1403-
values[i] = (char *) p;
1402+
values[i] = p;
14041403
nbytes += typlen;
14051404
}
14061405
else
@@ -1414,7 +1413,7 @@ array_map(ArrayType *v,
14141413
p = (char *) palloc(len);
14151414
memcpy(p, elt, len);
14161415
}
1417-
values[i] = (char *) p;
1416+
values[i] = p;
14181417
nbytes += len;
14191418
}
14201419
}
@@ -1433,7 +1432,7 @@ array_map(ArrayType *v,
14331432
ARR_DATA_PTR(result), nitems,
14341433
typlen, typalign, typbyval);
14351434

1436-
return result;
1435+
PG_RETURN_POINTER(result);
14371436
}
14381437

14391438
/*-----------------------------------------------------------------------------

src/backend/utils/adt/varchar.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.60 2000/04/12 17:15:52 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.61 2000/05/29 21:02:32 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -17,6 +17,7 @@
1717
#include "access/htup.h"
1818
#include "catalog/pg_type.h"
1919
#include "utils/builtins.h"
20+
#include "utils/fmgroids.h"
2021

2122
#ifdef MULTIBYTE
2223
#include "mb/pg_wchar.h"
@@ -206,7 +207,26 @@ bpchar(char *s, int32 len)
206207
ArrayType *
207208
_bpchar(ArrayType *v, int32 len)
208209
{
209-
return array_map(v, BPCHAROID, bpchar, BPCHAROID, 1, len);
210+
FunctionCallInfoData locfcinfo;
211+
Datum result;
212+
/* Since bpchar() is a built-in function, we should only need to
213+
* look it up once per run.
214+
*/
215+
static FmgrInfo bpchar_finfo;
216+
217+
if (bpchar_finfo.fn_oid == InvalidOid)
218+
fmgr_info(F_BPCHAR, &bpchar_finfo);
219+
220+
MemSet(&locfcinfo, 0, sizeof(locfcinfo));
221+
locfcinfo.flinfo = &bpchar_finfo;
222+
locfcinfo.nargs = 2;
223+
/* We assume we are "strict" and need not worry about null inputs */
224+
locfcinfo.arg[0] = PointerGetDatum(v);
225+
locfcinfo.arg[1] = Int32GetDatum(len);
226+
227+
result = array_map(&locfcinfo, BPCHAROID, BPCHAROID);
228+
229+
return (ArrayType *) DatumGetPointer(result);
210230
}
211231

212232

@@ -409,7 +429,26 @@ varchar(char *s, int32 slen)
409429
ArrayType *
410430
_varchar(ArrayType *v, int32 len)
411431
{
412-
return array_map(v, VARCHAROID, varchar, VARCHAROID, 1, len);
432+
FunctionCallInfoData locfcinfo;
433+
Datum result;
434+
/* Since varchar() is a built-in function, we should only need to
435+
* look it up once per run.
436+
*/
437+
static FmgrInfo varchar_finfo;
438+
439+
if (varchar_finfo.fn_oid == InvalidOid)
440+
fmgr_info(F_VARCHAR, &varchar_finfo);
441+
442+
MemSet(&locfcinfo, 0, sizeof(locfcinfo));
443+
locfcinfo.flinfo = &varchar_finfo;
444+
locfcinfo.nargs = 2;
445+
/* We assume we are "strict" and need not worry about null inputs */
446+
locfcinfo.arg[0] = PointerGetDatum(v);
447+
locfcinfo.arg[1] = Int32GetDatum(len);
448+
449+
result = array_map(&locfcinfo, VARCHAROID, VARCHAROID);
450+
451+
return (ArrayType *) DatumGetPointer(result);
413452
}
414453

415454

src/include/utils/array.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*-------------------------------------------------------------------------
22
*
33
* array.h
4-
* Utilities for the new array code. Contain prototypes from the
4+
* Utilities for the new array code. Contains prototypes from the
55
* following files:
66
* utils/adt/arrayfuncs.c
77
* utils/adt/arrayutils.c
@@ -11,18 +11,19 @@
1111
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $Id: array.h,v 1.23 2000/04/12 17:16:54 momjian Exp $
14+
* $Id: array.h,v 1.24 2000/05/29 21:02:32 tgl Exp $
1515
*
1616
* NOTES
17-
* XXX the data array should be LONGALIGN'd -- notice that the array
17+
* XXX the data array should be MAXALIGN'd -- notice that the array
1818
* allocation code does not allocate the extra space required for this,
19-
* even though the array-packing code does the LONGALIGNs.
19+
* even though the array-packing code does the MAXALIGNs.
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
2323
#ifndef ARRAY_H
2424
#define ARRAY_H
2525

26+
#include "fmgr.h"
2627
#include "utils/memutils.h"
2728

2829
typedef struct
@@ -123,9 +124,7 @@ extern char *array_set(ArrayType *array, int n, int *indx, char *dataPtr,
123124
extern char *array_assgn(ArrayType *array, int n, int *upperIndx,
124125
int *lowerIndx, ArrayType *newArr, int reftype,
125126
int len, bool *isNull);
126-
extern ArrayType *array_map(ArrayType *v, Oid type,
127-
char *(*fn) (),
128-
Oid retType, int nargs,...);
127+
extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType);
129128
extern int array_eq(ArrayType *array1, ArrayType *array2);
130129
extern int _LOtransfer(char **destfd, int size, int nitems, char **srcfd,
131130
int isSrcLO, int isDestLO);

0 commit comments

Comments
 (0)