CREATE AGGREGATE Rbitmap_union2 (rbitmap) ( sfunc = myfunction, stype = MyType, finalfunc = myfunction_final );
When you write an aggregate function, the same function is called repeatedly for each row, and if the data to be processed is cumulative, then if you do not share the memory space between each call, instead of constantly requesting to release the new memory, the speed becomes very slow, so it is useful to share the memory at this point:
PostgreSQL has the concept of memorycontext, if the normal use of palloc application memory space, the system will apply to Currentmemorycontext, and according to my trial guess, the aggregate function in each call, will switch Currentmemorycontext, so the ordinary palloc is not used.
When using Version 1 calling conventions, there is the following macro definition, Pg_function_args is the actual entry of the function we write:
#define PG_FUNCTION_ARGSFUNCTIONCALLINFO Fcinfo
Functioncallinfo is a pointer to the FUNCTIONCALLINFODATA structure:
/* * This struct was the data actually passed to an fmgr-called function. */typedef struct functioncallinfodata{fmgrinfo *flinfo;/* ptr to lookup info used for this call */fmnodeptrcontext;/* Pass info about the context of call */fmnodeptrresultinfo;/* Pass or return extra info about result */oidfncollation;/* Colla tion for function-*/boolisnull;/* function must set true if result is NULL */shortnargs;/* # arguments actually pas Sed */datumarg[func_max_args];/* Arguments passed to function */boolargnull[func_max_args]; /* T if arg[i] is actually NULL */} Functioncallinfodata;
Where the flinfo points to Fmgrinfo
typedef struct FMGRINFO{PGFUNCTIONFN_ADDR;/* Pointer to function or handler to be called */oidfn_oid;/* oid of function (N OT of handler, if any) */shortfn_nargs;/* number of the input args (0..func_max_args) */boolfn_strict;/* function is "strict" (NULL in = null out) */boolfn_retset;/* function returns a set */unsigned char fn_stats;/* collect stats if Track_func tions > This */<span style= "color: #ff0000;" >void *fn_extra</span>;/* Extra space for use by handler */<span style= "color: #ff0000;" >memorycontext fn_mcxt</span>;/* Memory context to store Fn_extra in */fmnodeptrfn_expr;/* expression parse tree For call, or NULL */} Fmgrinfo;
As long as we apply for memory under FN_MCXT This memorycontext, we can keep it in the whole aggregation process, the request to the memory block pointer, can be stored in Fn_extra, can also be passed as the return value and the entry parameter between each call, and finally use Finalfunc The specified function for final processing.
The function to request memory for the specified MEMORYCONTEXT-FN_MCXT is as follows:
Memorycontextalloc (FCINFO->FLINFO->FN_MCXT, sizeof (Some_type));
It returns a void pointer to the requested memory space.
can refer tosrc/backend/utils/adt/arrayfuncs.c 以及下列文章。
Reference article:
http://stackoverflow.com/questions/30515552/ Can-a-postgres-c-language-function-reference-a-stateful-variable-c-side-possibl
The PostgreSQL aggregate function shares the requested memory space