11/**********************************************************************
22 * plperl.c - perl as a procedural language for PostgreSQL
33 *
4- * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.153 2009/10/31 18:11:59 tgl Exp $
4+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.154 2009/11/29 03:02:27 tgl Exp $
55 *
66 **********************************************************************/
77
@@ -144,6 +144,7 @@ static plperl_call_data *current_call_data = NULL;
144144 * Forward declarations
145145 **********************************************************************/
146146Datum plperl_call_handler (PG_FUNCTION_ARGS );
147+ Datum plperl_inline_handler (PG_FUNCTION_ARGS );
147148Datum plperl_validator (PG_FUNCTION_ARGS );
148149void _PG_init (void );
149150
@@ -160,10 +161,11 @@ static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int);
160161static SV * newSVstring (const char * str );
161162static SV * * hv_store_string (HV * hv ,const char * key ,SV * val );
162163static SV * * hv_fetch_string (HV * hv ,const char * key );
163- static SV * plperl_create_sub (char * proname ,char * s ,bool trusted );
164+ static SV * plperl_create_sub (const char * proname ,const char * s ,bool trusted );
164165static SV * plperl_call_perl_func (plperl_proc_desc * desc ,FunctionCallInfo fcinfo );
165166static void plperl_compile_callback (void * arg );
166167static void plperl_exec_callback (void * arg );
168+ static void plperl_inline_callback (void * arg );
167169
168170/*
169171 * This routine is a crock, and so is everyplace that calls it. The problem
@@ -862,9 +864,13 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
862864
863865
864866/*
865- * This is the only externally-visible part of the plperl call interface.
866- * The Postgres function and trigger managers call it to execute a
867- * perl function.
867+ * There are three externally visible pieces to plperl: plperl_call_handler,
868+ * plperl_inline_handler, and plperl_validator.
869+ */
870+
871+ /*
872+ * The call handler is called to run normal functions (including trigger
873+ * functions) that are defined in pg_proc.
868874 */
869875PG_FUNCTION_INFO_V1 (plperl_call_handler );
870876
@@ -896,8 +902,102 @@ plperl_call_handler(PG_FUNCTION_ARGS)
896902}
897903
898904/*
899- * This is the other externally visible function - it is called when CREATE
900- * FUNCTION is issued to validate the function being created/replaced.
905+ * The inline handler runs anonymous code blocks (DO blocks).
906+ */
907+ PG_FUNCTION_INFO_V1 (plperl_inline_handler );
908+
909+ Datum
910+ plperl_inline_handler (PG_FUNCTION_ARGS )
911+ {
912+ InlineCodeBlock * codeblock = (InlineCodeBlock * )PG_GETARG_POINTER (0 );
913+ FunctionCallInfoData fake_fcinfo ;
914+ FmgrInfo flinfo ;
915+ plperl_proc_desc desc ;
916+ plperl_call_data * save_call_data = current_call_data ;
917+ bool oldcontext = trusted_context ;
918+ ErrorContextCallback pl_error_context ;
919+
920+ /* Set up a callback for error reporting */
921+ pl_error_context .callback = plperl_inline_callback ;
922+ pl_error_context .previous = error_context_stack ;
923+ pl_error_context .arg = (Datum )0 ;
924+ error_context_stack = & pl_error_context ;
925+
926+ /*
927+ * Set up a fake fcinfo and descriptor with just enough info to satisfy
928+ * plperl_call_perl_func(). In particular note that this sets things up
929+ * with no arguments passed, and a result type of VOID.
930+ */
931+ MemSet (& fake_fcinfo ,0 ,sizeof (fake_fcinfo ));
932+ MemSet (& flinfo ,0 ,sizeof (flinfo ));
933+ MemSet (& desc ,0 ,sizeof (desc ));
934+ fake_fcinfo .flinfo = & flinfo ;
935+ flinfo .fn_oid = InvalidOid ;
936+ flinfo .fn_mcxt = CurrentMemoryContext ;
937+
938+ desc .proname = "inline_code_block" ;
939+ desc .fn_readonly = false;
940+
941+ desc .lanpltrusted = codeblock -> langIsTrusted ;
942+
943+ desc .fn_retistuple = false;
944+ desc .fn_retisset = false;
945+ desc .fn_retisarray = false;
946+ desc .result_oid = VOIDOID ;
947+ desc .nargs = 0 ;
948+ desc .reference = NULL ;
949+
950+ current_call_data = (plperl_call_data * )palloc0 (sizeof (plperl_call_data ));
951+ current_call_data -> fcinfo = & fake_fcinfo ;
952+ current_call_data -> prodesc = & desc ;
953+
954+ PG_TRY ();
955+ {
956+ SV * perlret ;
957+
958+ if (SPI_connect ()!= SPI_OK_CONNECT )
959+ elog (ERROR ,"could not connect to SPI manager" );
960+
961+ check_interp (desc .lanpltrusted );
962+
963+ desc .reference = plperl_create_sub (desc .proname ,
964+ codeblock -> source_text ,
965+ desc .lanpltrusted );
966+
967+ if (!desc .reference )/* can this happen? */
968+ elog (ERROR ,"could not create internal procedure for anonymous code block" );
969+
970+ perlret = plperl_call_perl_func (& desc ,& fake_fcinfo );
971+
972+ SvREFCNT_dec (perlret );
973+
974+ if (SPI_finish ()!= SPI_OK_FINISH )
975+ elog (ERROR ,"SPI_finish() failed" );
976+ }
977+ PG_CATCH ();
978+ {
979+ current_call_data = save_call_data ;
980+ restore_context (oldcontext );
981+ if (desc .reference )
982+ SvREFCNT_dec (desc .reference );
983+ PG_RE_THROW ();
984+ }
985+ PG_END_TRY ();
986+
987+ current_call_data = save_call_data ;
988+ restore_context (oldcontext );
989+ if (desc .reference )
990+ SvREFCNT_dec (desc .reference );
991+
992+ error_context_stack = pl_error_context .previous ;
993+
994+ PG_RETURN_VOID ();
995+ }
996+
997+ /*
998+ * The validator is called during CREATE FUNCTION to validate the function
999+ * being created/replaced. The precise behavior of the validator may be
1000+ * modified by the check_function_bodies GUC.
9011001 */
9021002PG_FUNCTION_INFO_V1 (plperl_validator );
9031003
@@ -971,7 +1071,7 @@ plperl_validator(PG_FUNCTION_ARGS)
9711071 * supplied in s, and returns a reference to the closure.
9721072 */
9731073static SV *
974- plperl_create_sub (char * proname ,char * s ,bool trusted )
1074+ plperl_create_sub (const char * proname ,const char * s ,bool trusted )
9751075{
9761076dSP ;
9771077SV * subref ;
@@ -1375,7 +1475,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
13751475
13761476/* Restore the previous error callback */
13771477error_context_stack = pl_error_context .previous ;
1378-
1478+
13791479if (array_ret == NULL )
13801480SvREFCNT_dec (perlret );
13811481
@@ -2716,9 +2816,9 @@ hv_fetch_string(HV *hv, const char *key)
27162816}
27172817
27182818/*
2719- * Provide function name for PL/Perl execution errors
2819+ * Provide function name for PL/Perl execution errors
27202820 */
2721- static void
2821+ static void
27222822plperl_exec_callback (void * arg )
27232823{
27242824char * procname = (char * )arg ;
@@ -2727,7 +2827,7 @@ plperl_exec_callback(void *arg)
27272827}
27282828
27292829/*
2730- * Provide function name for PL/Perl compilation errors
2830+ * Provide function name for PL/Perl compilation errors
27312831 */
27322832static void
27332833plperl_compile_callback (void * arg )
@@ -2736,3 +2836,12 @@ plperl_compile_callback(void *arg)
27362836if (procname )
27372837errcontext ("compilation of PL/Perl function \"%s\"" ,procname );
27382838}
2839+
2840+ /*
2841+ * Provide error context for the inline handler
2842+ */
2843+ static void
2844+ plperl_inline_callback (void * arg )
2845+ {
2846+ errcontext ("PL/Perl anonymous code block" );
2847+ }