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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy