Re: plperl and inline functions -- first draft
От | Andrew Dunstan |
---|---|
Тема | Re: plperl and inline functions -- first draft |
Дата | |
Msg-id | 4AF4B342.6030605@dunslane.net обсуждение исходный текст |
Ответ на | Re: plperl and inline functions -- first draft (Andrew Dunstan <andrew@dunslane.net>) |
Ответы |
Re: plperl and inline functions -- first draft
Re: plperl and inline functions -- first draft |
Список | pgsql-hackers |
I wrote: > > Ok, I have a handle on the trusted/nontrusted issue. But I think the > piece that's missing here is that it needs to save the calling context > etc. and use PG_TRY() and friends, just like plperl_call_handler(). > I'll work on that. > > OK, I committed the previously discussed change to store the language trusted flag in the InlineCodeBlock structure. Following that, here is my reworking of Josh's patch for DO blocks for plperl. Missing are docs and regression tests. cheers andrew Index: src/include/catalog/pg_pltemplate.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_pltemplate.h,v retrieving revision 1.8 diff -c -r1.8 pg_pltemplate.h *** src/include/catalog/pg_pltemplate.h 22 Sep 2009 23:43:41 -0000 1.8 --- src/include/catalog/pg_pltemplate.h 6 Nov 2009 23:28:37 -0000 *************** *** 70,77 **** DATA(insert ( "plpgsql" t t "plpgsql_call_handler" "plpgsql_inline_handler" "plpgsql_validator" "$libdir/plpgsql"_null_ )); DATA(insert ( "pltcl" t t "pltcl_call_handler" _null_ _null_ "$libdir/pltcl" _null_ )); DATA(insert ( "pltclu" f f "pltclu_call_handler" _null_ _null_ "$libdir/pltcl" _null_ )); ! DATA(insert ( "plperl" t t "plperl_call_handler" _null_ "plperl_validator" "$libdir/plperl" _null_ )); ! DATA(insert ( "plperlu" f f "plperl_call_handler" _null_ "plperl_validator" "$libdir/plperl" _null_ )); DATA(insert ( "plpythonu" f f "plpython_call_handler" _null_ _null_ "$libdir/plpython" _null_ )); #endif /* PG_PLTEMPLATE_H */ --- 70,77 ---- DATA(insert ( "plpgsql" t t "plpgsql_call_handler" "plpgsql_inline_handler" "plpgsql_validator" "$libdir/plpgsql"_null_ )); DATA(insert ( "pltcl" t t "pltcl_call_handler" _null_ _null_ "$libdir/pltcl" _null_ )); DATA(insert ( "pltclu" f f "pltclu_call_handler" _null_ _null_ "$libdir/pltcl" _null_ )); ! DATA(insert ( "plperl" t t "plperl_call_handler" "plperl_inline_handler" "plperl_validator" "$libdir/plperl" _null_)); ! DATA(insert ( "plperlu" f f "plperl_call_handler" "plperl_inline_handler" "plperl_validator" "$libdir/plperl" _null_)); DATA(insert ( "plpythonu" f f "plpython_call_handler" _null_ _null_ "$libdir/plpython" _null_ )); #endif /* PG_PLTEMPLATE_H */ Index: src/pl/plperl/plperl.c =================================================================== RCS file: /cvsroot/pgsql/src/pl/plperl/plperl.c,v retrieving revision 1.153 diff -c -r1.153 plperl.c *** src/pl/plperl/plperl.c 31 Oct 2009 18:11:59 -0000 1.153 --- src/pl/plperl/plperl.c 6 Nov 2009 23:28:37 -0000 *************** *** 144,149 **** --- 144,150 ---- * Forward declarations **********************************************************************/ Datum plperl_call_handler(PG_FUNCTION_ARGS); + Datum plperl_inline_handler(PG_FUNCTION_ARGS); Datum plperl_validator(PG_FUNCTION_ARGS); void _PG_init(void); *************** *** 862,870 **** /* ! * This is the only externally-visible part of the plperl call interface. ! * The Postgres function and trigger managers call it to execute a ! * perl function. */ PG_FUNCTION_INFO_V1(plperl_call_handler); --- 863,872 ---- /* ! * plperl_call_handler and plperl_inline_handler are the only ! * externally-visible parts of the plperl call interface. The Postgres function ! * and trigger managers call plperl_call_handler to execute a perl function, and ! * call plperl_inline_handler to execute plperl code in a DO statement. */ PG_FUNCTION_INFO_V1(plperl_call_handler); *************** *** 895,900 **** --- 897,960 ---- return retval; } + PG_FUNCTION_INFO_V1(plperl_inline_handler); + + Datum + plperl_inline_handler(PG_FUNCTION_ARGS) + { + InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0)); + FunctionCallInfoData fake_fcinfo; + FmgrInfo flinfo; + plperl_proc_desc desc; + HeapTuple langTup; + Form_pg_language langStruct; + plperl_call_data *save_call_data = current_call_data; + bool oldcontext = trusted_context; + + MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo)); + MemSet(&flinfo, 0, sizeof(flinfo)); + MemSet(&desc, 0, sizeof(desc)); + fake_fcinfo.flinfo = &flinfo; + flinfo.fn_oid = InvalidOid; + flinfo.fn_mcxt = CurrentMemoryContext; + + desc.proname = "Do Inline Block"; + desc.fn_readonly = false; + + desc.lanpltrusted = codeblock->langIsTrusted; + + check_interp(desc.lanpltrusted); + + + desc.fn_retistuple = false; + desc.fn_retisset = false; + desc.fn_retisarray = false; + desc.result_oid = VOIDOID; + desc.nargs = 0; + + PG_TRY(); + { + + desc.reference = plperl_create_sub("DO Inline Block", + codeblock->source_text, + desc.lanpltrusted); + + plperl_call_perl_func(&desc, &fake_fcinfo); + } + PG_CATCH(); + { + current_call_data = save_call_data; + restore_context(oldcontext); + PG_RE_THROW(); + } + PG_END_TRY(); + + current_call_data = save_call_data; + restore_context(oldcontext); + + PG_RETURN_VOID(); + } + /* * This is the other externally visible function - it is called when CREATE * FUNCTION is issued to validate the function being created/replaced.
В списке pgsql-hackers по дате отправления: