Search Postgresql Archives

Re: Set Returning C-Function with cache over multiple calls (with different arguments)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear list,

I solved my own problem - as so often, once you write it down and press the send button you get the idea.

The problem was:

> Currently I am working on a user C-Function which should create a cache object on the first call and afterwards return a 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_extra for my pointer to the data. This is now used by the FuncCallContext structure. This structure is destroyed every time SRF_RETURN_DONE is called, thus user_fctx also is not the way to go.

My solution:

--------------------------------------------------- snip ---------------------------------------------------
struct myData {
	FuncCallContext *funcctx; 
	// own Data
	int cachedObject;
} myData

PG_FUNCTION_INFO_V1(test);
Datum test(PG_FUNCTION_ARGS) 
{
	MemoryContext old_context;
	FuncCallContext     *funcctx;
	myData *str;
	
	// Get fn_extra
	str = fcinfo->flinfo->fn_extra; 
	if ( ! str) {
		elog(NOTICE, "create new");
		
		old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
		// Fill str with data around here ...
		MemoryContextSwitchTo(old_context);
		str->funcctx = NULL;
	}
	
	// This is the situation the SRF-macros expect:
	fcinfo->flinfo->fn_extra = str->funcctx; 

	if (SRF_IS_FIRSTCALL()) {
		funcctx = SRF_FIRSTCALL_INIT();
	
		// Your commands
	}
	funcctx = SRF_PERCALL_SETUP();
	
	// This is the macro SRF_RETURN_DONE(funcctx); 
	// Before we finally return we save our str in fn_extra and fn_extra in str->funcctx.
	do { 
		ReturnSetInfo *rsi; 
		end_MultiFuncCall(fcinfo, funcctx); 
		rsi = (ReturnSetInfo *) fcinfo->resultinfo; 
		rsi->isDone = ExprEndResult; 
		// -- Modify macro here --
		str->funcctx = fcinfo->flinfo->fn_extra; 
		fcinfo->flinfo->fn_extra = str; 
		// -- End modification --
		PG_RETURN_NULL(); 
	} while (0);

	// Of course, SRF_RETURN_DATUM has to be adapted the same way!
}
--------------------------------------------------- snip ---------------------------------------------------

Regards,
Thilo Schneider
-- 
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux