*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.116 2005/02/28 03:45:21 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.117 2005/03/24 21:50:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* or binary-compatible with, the first argument type of fn().
* * retType: OID of element type of output array. This must be the same as,
* or binary-compatible with, the result type of fn().
+ * * amstate: workspace for array_map. Must be zeroed by caller before
+ * first call, and not touched after that.
+ *
+ * It is legitimate to pass a freshly-zeroed ArrayMapState on each call,
+ * but better performance can be had if the state can be preserved across
+ * a series of calls.
*
* NB: caller must assure that input array is not NULL. Currently,
* any additional parameters passed to fn() may not be specified as NULL
* either.
*/
Datum
-array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
+array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType,
+ ArrayMapState *amstate)
{
ArrayType *v;
ArrayType *result;
bool typbyval;
char typalign;
char *s;
- typedef struct
- {
- ArrayMetaState inp_extra;
- ArrayMetaState ret_extra;
- } am_extra;
- am_extra *my_extra;
ArrayMetaState *inp_extra;
ArrayMetaState *ret_extra;
* only once per series of calls, assuming the element type doesn't
* change underneath us.
*/
- my_extra = (am_extra *) fcinfo->flinfo->fn_extra;
- if (my_extra == NULL)
- {
- fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
- sizeof(am_extra));
- my_extra = (am_extra *) fcinfo->flinfo->fn_extra;
- inp_extra = &my_extra->inp_extra;
- inp_extra->element_type = InvalidOid;
- ret_extra = &my_extra->ret_extra;
- ret_extra->element_type = InvalidOid;
- }
- else
- {
- inp_extra = &my_extra->inp_extra;
- ret_extra = &my_extra->ret_extra;
- }
+ inp_extra = &amstate->inp_extra;
+ ret_extra = &amstate->ret_extra;
if (inp_extra->element_type != inpType)
{
Oid srctype;
Oid desttype;
FmgrInfo coerce_finfo;
+ ArrayMapState amstate;
} atc_extra;
atc_extra *my_extra;
FunctionCallInfoData locfcinfo;
my_extra = (atc_extra *) fmgr_info->fn_extra;
if (my_extra == NULL)
{
- fmgr_info->fn_extra = MemoryContextAlloc(fmgr_info->fn_mcxt,
- sizeof(atc_extra));
+ fmgr_info->fn_extra = MemoryContextAllocZero(fmgr_info->fn_mcxt,
+ sizeof(atc_extra));
my_extra = (atc_extra *) fmgr_info->fn_extra;
- my_extra->srctype = InvalidOid;
}
if (my_extra->srctype != src_elem_type)
locfcinfo.arg[1] = Int32GetDatum(desttypmod);
locfcinfo.arg[2] = BoolGetDatum(isExplicit);
- return array_map(&locfcinfo, my_extra->srctype, my_extra->desttype);
+ return array_map(&locfcinfo, my_extra->srctype, my_extra->desttype,
+ &my_extra->amstate);
}
/*
{
Oid elemtype;
FmgrInfo coerce_finfo;
+ ArrayMapState amstate;
} alc_extra;
alc_extra *my_extra;
FunctionCallInfoData locfcinfo;
my_extra = (alc_extra *) fmgr_info->fn_extra;
if (my_extra == NULL)
{
- fmgr_info->fn_extra = MemoryContextAlloc(fmgr_info->fn_mcxt,
- sizeof(alc_extra));
+ fmgr_info->fn_extra = MemoryContextAllocZero(fmgr_info->fn_mcxt,
+ sizeof(alc_extra));
my_extra = (alc_extra *) fmgr_info->fn_extra;
- my_extra->elemtype = InvalidOid;
}
if (my_extra->elemtype != ARR_ELEMTYPE(v))
locfcinfo.arg[1] = Int32GetDatum(desttypmod);
locfcinfo.arg[2] = BoolGetDatum(isExplicit);
- return array_map(&locfcinfo, ARR_ELEMTYPE(v), ARR_ELEMTYPE(v));
+ return array_map(&locfcinfo, ARR_ELEMTYPE(v), ARR_ELEMTYPE(v),
+ &my_extra->amstate);
}
/*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.52 2005/02/28 03:45:23 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.53 2005/03/24 21:50:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
FmgrInfo proc;
} ArrayMetaState;
+/*
+ * private state needed by array_map (here because caller must provide it)
+ */
+typedef struct ArrayMapState
+{
+ ArrayMetaState inp_extra;
+ ArrayMetaState ret_extra;
+} ArrayMapState;
+
/*
* fmgr macros for array objects
*/
int arraylen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
-extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType);
+extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType,
+ ArrayMapState *amstate);
extern ArrayType *construct_array(Datum *elems, int nelems,
Oid elmtype,