Re: New PL/Perl failure with Safe 2.2x due to recursion (8.x & 9.0) - Mailing list pgsql-bugs

From Alex Hunsaker
Subject Re: New PL/Perl failure with Safe 2.2x due to recursion (8.x & 9.0)
Date
Msg-id 34d269d41002241900r6a451349ybbfd41dd1e7cbc74@mail.gmail.com
Whole thread Raw
In response to Re: New PL/Perl failure with Safe 2.2x due to recursion (8.x & 9.0)  (Alex Hunsaker <badalex@gmail.com>)
Responses Re: New PL/Perl failure with Safe 2.2x due to recursion (8.x & 9.0)  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
On Wed, Feb 24, 2010 at 19:17, Alex Hunsaker <badalex@gmail.com> wrote:
> On Tue, Feb 23, 2010 at 15:23, Tim Bunce <Tim.Bunce@pobox.com> wrote:
>
>> I believe (but haven't yet confirmed) that the problem here is recursion.
>> This affects all versions of PostgreSQL.

> Ill keep digging.

Ok I understand now, basically the problem is (as Tim also described elsewhere):

postgres->plperl_call_perl_func->SPI->postgres->plperl_create_sub

On that last call to plperl_create_sub we are still executing under
Safe (as its the same interpreter).   And so it fails when it tries to
compile a new sub.

ISTM the easiest and safest fix would be to not allow recursive plperl
creations.  You could still call plperl functions within functions,
just not if they are not defined.  This limitation really blows so im
hoping someone else has a better idea?  Alternately we could also
break out of the safe, compile the sub and then go back to it as Tim
suggested up-thread.  I think this could work as long as its not to
nasty (which Tim does not seem to think it would be).

Thoughts? Better Ideas?

[ patch against 8.3/8.4 ]
----
*** a/src/pl/plperl/plperl.c
--- b/src/pl/plperl/plperl.c
***************
*** 126,131 **** static HTAB *plperl_proc_hash = NULL;
--- 126,132 ----
  static HTAB *plperl_query_hash = NULL;

  static bool plperl_use_strict = false;
+ static bool plperl_executing = false;

  /* this is saved and restored by plperl_call_handler */
  static plperl_call_data *current_call_data = NULL;
***************
*** 1117,1125 **** plperl_call_perl_func(plperl_proc_desc *desc,
FunctionCallInfo fcinfo)
--- 1118,1132 ----
      }
      PUTBACK;

+     if (desc->lanpltrusted)
+         plperl_executing = true;
+
      /* Do NOT use G_KEEPERR here */
      count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);

+     if (desc->lanpltrusted)
+         plperl_executing = false;
+
      SPAGAIN;

      if (count != 1)
***************
*** 1697,1702 **** compile_plperl_function(Oid fn_oid, bool is_trigger)
--- 1704,1721 ----

          check_interp(prodesc->lanpltrusted);

+         /************************************************************
+          * Dont let us recursively create a plperl function from a plperl function
+          * as plperl_create_sub gets called we are running under Safe and fails.
+          * TODO: We could break out of the safe via Safe::HOLE or some such.
+          ************************************************************/
+         if (prodesc->lanpltrusted && plperl_executing)
+             ereport(ERROR,
+                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                  errmsg("could not create plperl function \"%s\"", prodesc->proname),
+                  errdetail("plperl functions can not recursivley define other
plperl functions"),
+                  errhint("try calling the function first")));
+
          prodesc->reference = plperl_create_sub(prodesc->proname,
                                                 proc_source,
                                                 prodesc->lanpltrusted);

pgsql-bugs by date:

Previous
From: Alex Hunsaker
Date:
Subject: Re: New PL/Perl failure with Safe 2.2x due to recursion (8.x & 9.0)
Next
From: Tom Lane
Date:
Subject: Re: New PL/Perl failure with Safe 2.2x due to recursion (8.x & 9.0)