Re: Set Returning C-Function with cache over multiple calls (with different arguments)
От | Merlin Moncure |
---|---|
Тема | Re: Set Returning C-Function with cache over multiple calls (with different arguments) |
Дата | |
Msg-id | b42b73151001110658l38397ff1i442fe47151a183a7@mail.gmail.com обсуждение исходный текст |
Ответ на | Set Returning C-Function with cache over multiple calls (with different arguments) (Thilo Schneider <Thilo.Schneider@math.uni-giessen.de>) |
Список | pgsql-general |
On Mon, Jan 11, 2010 at 2:45 AM, Thilo Schneider <Thilo.Schneider@math.uni-giessen.de> wrote: > Dear list, > > Currently I am working on a user C-Function which should create a cache object on the first call and afterwards returna set of computed values for each argument combination it is called with. > > My Problem is how to get the cache object saved over multiple calls. Without the SRF I could use fcinfo->flinfo->fn_extrafor my pointer to the data. This is now used by the FuncCallContext structure. This structure isdestroyed every time SRF_RETURN_DONE is called, thus user_fctx also is not the way to go. > > As a minimal example look at the function provided below. > > --------------------------------------------------- snip --------------------------------------------------- > PG_FUNCTION_INFO_V1(test); > Datum test(PG_FUNCTION_ARGS) > { > MemoryContext old_context; > FuncCallContext *funcctx; > > > if (SRF_IS_FIRSTCALL()) { > funcctx = SRF_FIRSTCALL_INIT(); > > // This is the structure potentially generated in previous calls > str = funcctx->user_fctx; > > // If the structure does not exist or the geometry array has changed, it has to be created. > if ( ! str) { > elog(NOTICE, "create new"); > > old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); > > // Fill str with data around here ... > > MemoryContextSwitchTo(old_context); > > funcctx->user_fctx = str; > } > > } > funcctx = SRF_PERCALL_SETUP(); > SRF_RETURN_DONE(funcctx); > } > --------------------------------------------------- snip --------------------------------------------------- > > To make the problem perfectly clear the SQL-Code this should work with: > > --------------------------------------------------- snip --------------------------------------------------- > CREATE OR REPLACE FUNCTION test(int, int[] ) > RETURNS SETOF int AS 'myfunc', 'test' > LANGUAGE 'c' IMMUTABLE STRICT > COST 1; > > SELECT test(number, array(SELECT integers FROM another_table)) FROM numbers; > --------------------------------------------------- snip --------------------------------------------------- > > As creating the cache object is by far the most expensive part in the desired function, it should be possible to createthe cache only once over the whole query - using only the arguments in the array, which do not change over multiplecalls. > > Is there a way around this problem? Another pointer I could use and do not know of yet? have you ruled out simply keeping a static pointer around and using malloc()? merlin
В списке pgsql-general по дате отправления: