Обсуждение: C-language functions: SRF question
Hello, I need to code a set-returning function, but it's my first time, and I'm not sure if my point is the right one. I'd like to know your opinion: My function will return an array of structs. Then, In the first call (SRF_IS_FIRSTCALL() is true), I get the array from another function. For the next calls, I'll need to access a position of this array, so, I'll need to store it, and the position needed, in any place. The place should be the user_fctx field of the FuncCallContext. I've created a struct that will store my array of structs and an int value, a index. In the first call, this index is 0. In next calls, I can recover data from FuncCallContext, get the struct indexed by the index value, build my tuple, return it and increment the index. Is this a good way of doing it? Is it possible? And another small question: if the memory for my array of structs is allocated inside the function that provides me the array, should I deallocate it in the SRF? Using pfree? It wasn't allocated by palloc... Thanks in advance, and best regards, Jorge -- http://www.gis4free.org/blog
On Thu, Apr 8, 2010 at 11:40 AM, Jorge Arevalo <jorgearevalo@gis4free.org> wrote: > Is this a good way of doing it? Is it possible? And another small > question: if the memory for my array of structs is allocated inside > the function that provides me the array, should I deallocate it in the > SRF? Using pfree? It wasn't allocated by palloc... why didn't you use palloc? external library? postgresql guarantees that memory allocated w/palloc is cleaned up. you pretty much have to assume any backend api calls can bounce you out of the transaction in which case you will leak if you alloc'd with non palloc allocator. do not call pfree on any memory allocated by anything else than palloc. every malloc needs a free. if the array construction code is also yours you may want to consider reworking it to take an allocator. the more you use palloc the less problems you will have (and as a bonus, you get to worry less about pfree'ing stuff). if you must use malloc and don't want to be cavalier about leaking memory, try and keep allocations as short lived as possible or at very specific points, like a static pointer. be sure to review the memory manager readme in src/backend/utils/mmgr/README merlin
On Thu, Apr 8, 2010 at 6:18 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > On Thu, Apr 8, 2010 at 11:40 AM, Jorge Arevalo > <jorgearevalo@gis4free.org> wrote: >> Is this a good way of doing it? Is it possible? And another small >> question: if the memory for my array of structs is allocated inside >> the function that provides me the array, should I deallocate it in the >> SRF? Using pfree? It wasn't allocated by palloc... > > why didn't you use palloc? external library? postgresql guarantees > that memory allocated w/palloc is cleaned up. you pretty much have to > assume any backend api calls can bounce you out of the transaction in > which case you will leak if you alloc'd with non palloc allocator. do > not call pfree on any memory allocated by anything else than palloc. > every malloc needs a free. > > if the array construction code is also yours you may want to consider > reworking it to take an allocator. the more you use palloc the less > problems you will have (and as a bonus, you get to worry less about > pfree'ing stuff). > > if you must use malloc and don't want to be cavalier about leaking > memory, try and keep allocations as short lived as possible or at very > specific points, like a static pointer. > The memory is allocated in a function of an external library. But I can force this library to allocate memory in a valid context (the one pointed by fcinfo->flinfo->fn_mcxt, actually). If I do that, I suppose I can call pfree. Or even better, I don't need to worry about that, am I right? BTW, this code is for WKT Raster. A PostGIS extension. We can use the memory context I said (fcinfo->flinfo->fn_mcxt) to allocate memory when we need to call one of our functions from a standard "version 1" function, but is this the right context? I mean, the context we should use for a whole-plugin-lifetime persistence. > be sure to review the memory manager readme in src/backend/utils/mmgr/README > Excelent reading! Thanks for the info. And sorry if my questions are very basic. Best regards, Jorge > merlin >
Jorge Arevalo <jorgearevalo@gis4free.org> writes: > BTW, this code is for WKT Raster. A PostGIS extension. We can use the > memory context I said (fcinfo->flinfo->fn_mcxt) to allocate memory > when we need to call one of our functions from a standard "version 1" > function, but is this the right context? I mean, the context we should > use for a whole-plugin-lifetime persistence. fn_mcxt will typically point at a query-lifespan context. If you need to allocate storage that will live as long as the session, there's not that much reason not to use malloc, except perhaps that you have to remember to do your own out-of-memory-failure checks. The typical coding pattern in the backend for session-lifespan storage is to use TopMemoryContext, or possibly make your own context (as a child of TopMemoryContext) so that you can easily identify how much storage you're using for this purpose. regards, tom lane