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 по дате отправления:

Предыдущее
От: Marc Munro
Дата:
Сообщение: Quoting oddities when defining operators in postgres 8.3
Следующее
От: Tom Lane
Дата:
Сообщение: Re: operator exclusion constraints