8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
17
17
18
18
#include "postgres.h"
19
19
20
-
21
20
#include "catalog/catalog.h"
22
21
#include "catalog/pg_type.h"
23
22
#include "fmgr.h"
@@ -1277,19 +1276,33 @@ array_assgn(ArrayType *array,
1277
1276
/*
1278
1277
* array_map()
1279
1278
*
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.
1282
1300
*/
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 )
1290
1303
{
1304
+ ArrayType * v ;
1291
1305
ArrayType * result ;
1292
- void * args [4 ];
1293
1306
char * * values ;
1294
1307
char * elt ;
1295
1308
int * dim ;
@@ -1307,35 +1320,31 @@ array_map(ArrayType *v,
1307
1320
char typalign ;
1308
1321
char * s ;
1309
1322
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 );
1311
1330
1312
1331
/* Large objects not yet supported */
1313
1332
if (ARR_IS_LO (v )== true)
1314
1333
elog (ERROR ,"array_map: large objects not supported" );
1315
1334
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
-
1332
1335
ndim = ARR_NDIM (v );
1333
1336
dim = ARR_DIMS (v );
1334
1337
nitems = getNitems (ndim ,dim );
1335
1338
1336
1339
/* Check for empty array */
1337
1340
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 );
1339
1348
1340
1349
/* Allocate temporary array for new values */
1341
1350
values = (char * * )palloc (nitems * sizeof (char * ));
@@ -1374,33 +1383,23 @@ array_map(ArrayType *v,
1374
1383
}
1375
1384
1376
1385
/*
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.
1379
1391
*/
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" );
1399
1398
1400
1399
/* Update values and total result size */
1401
1400
if (typbyval )
1402
1401
{
1403
- values [i ]= ( char * ) p ;
1402
+ values [i ]= p ;
1404
1403
nbytes += typlen ;
1405
1404
}
1406
1405
else
@@ -1414,7 +1413,7 @@ array_map(ArrayType *v,
1414
1413
p = (char * )palloc (len );
1415
1414
memcpy (p ,elt ,len );
1416
1415
}
1417
- values [i ]= ( char * ) p ;
1416
+ values [i ]= p ;
1418
1417
nbytes += len ;
1419
1418
}
1420
1419
}
@@ -1433,7 +1432,7 @@ array_map(ArrayType *v,
1433
1432
ARR_DATA_PTR (result ),nitems ,
1434
1433
typlen ,typalign ,typbyval );
1435
1434
1436
- return result ;
1435
+ PG_RETURN_POINTER ( result ) ;
1437
1436
}
1438
1437
1439
1438
/*-----------------------------------------------------------------------------