Re: plperl and inline functions -- first draft - Mailing list pgsql-hackers

From Andrew Dunstan
Subject Re: plperl and inline functions -- first draft
Date
Msg-id 4AF4B342.6030605@dunslane.net
Whole thread Raw
In response to Re: plperl and inline functions -- first draft  (Andrew Dunstan <andrew@dunslane.net>)
Responses Re: plperl and inline functions -- first draft
Re: plperl and inline functions -- first draft
List 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 by date:

Previous
From: Marc Munro
Date:
Subject: Quoting oddities when defining operators in postgres 8.3
Next
From: Tom Lane
Date:
Subject: Re: operator exclusion constraints