aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c53
1 files changed, 21 insertions, 32 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index eedc3990fa4..9c9d3541e1e 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.100.2.2 2004/12/17 20:58:36 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.100.2.3 2005/03/24 21:51:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1195,6 +1195,7 @@ array_length_coerce(PG_FUNCTION_ARGS)
{
Oid elemtype;
FmgrInfo coerce_finfo;
+ ArrayMapState amstate;
} alc_extra;
alc_extra *my_extra;
FunctionCallInfoData locfcinfo;
@@ -1211,10 +1212,9 @@ array_length_coerce(PG_FUNCTION_ARGS)
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))
@@ -1251,7 +1251,8 @@ array_length_coerce(PG_FUNCTION_ARGS)
locfcinfo.arg[1] = Int32GetDatum(len);
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);
}
/*-----------------------------------------------------------------------------
@@ -2015,13 +2016,20 @@ array_set_slice(ArrayType *array,
* 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;
@@ -2039,12 +2047,6 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
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;
@@ -2076,22 +2078,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
* 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)
{
@@ -2898,6 +2886,7 @@ array_type_coerce(PG_FUNCTION_ARGS)
Oid srctype;
Oid desttype;
FmgrInfo coerce_finfo;
+ ArrayMapState amstate;
} atc_extra;
atc_extra *my_extra;
FunctionCallInfoData locfcinfo;
@@ -2910,10 +2899,9 @@ array_type_coerce(PG_FUNCTION_ARGS)
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)
@@ -2981,7 +2969,8 @@ array_type_coerce(PG_FUNCTION_ARGS)
locfcinfo.nargs = 1;
locfcinfo.arg[0] = PointerGetDatum(src);
- return array_map(&locfcinfo, my_extra->srctype, my_extra->desttype);
+ return array_map(&locfcinfo, my_extra->srctype, my_extra->desttype,
+ &my_extra->amstate);
}
/*