Ensure the previous Perl interpreter selection is restored upon exit from
authorTom Lane <[email protected]>
Sat, 31 Oct 2009 18:12:05 +0000 (18:12 +0000)
committerTom Lane <[email protected]>
Sat, 31 Oct 2009 18:12:05 +0000 (18:12 +0000)
plperl_call_handler, in both the normal and error-exit paths.  Per report
from Alexey Klyukin.

src/pl/plperl/plperl.c

index 33e06e8c9639999d75000bc60ebfde23f6b0307e..d2ea5b58833d939932df512f9d4dda7b5155888c 100644 (file)
@@ -1,7 +1,7 @@
 /**********************************************************************
  * plperl.c - perl as a procedural language for PostgreSQL
  *
- *   $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.150.2.1 2009/09/28 17:30:56 adunstan Exp $
+ *   $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.150.2.2 2009/10/31 18:12:05 tgl Exp $
  *
  **********************************************************************/
 
@@ -150,8 +150,8 @@ void        _PG_init(void);
 static void plperl_init_interp(void);
 
 static Datum plperl_func_handler(PG_FUNCTION_ARGS);
-
 static Datum plperl_trigger_handler(PG_FUNCTION_ARGS);
+
 static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger);
 
 static SV  *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc);
@@ -378,11 +378,13 @@ check_interp(bool trusted)
    }
 }
 
-
+/*
+ * Restore previous interpreter selection, if two are active
+ */
 static void
 restore_context(bool old_context)
 {
-   if (trusted_context != old_context)
+   if (interp_state == INTERP_BOTH && trusted_context != old_context)
    {
        if (old_context)
            PERL_SET_CONTEXT(plperl_trusted_interp);
@@ -868,9 +870,9 @@ Datum
 plperl_call_handler(PG_FUNCTION_ARGS)
 {
    Datum       retval;
-   plperl_call_data *save_call_data;
+   plperl_call_data *save_call_data = current_call_data;
+   bool        oldcontext = trusted_context;
 
-   save_call_data = current_call_data;
    PG_TRY();
    {
        if (CALLED_AS_TRIGGER(fcinfo))
@@ -881,11 +883,13 @@ plperl_call_handler(PG_FUNCTION_ARGS)
    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);
    return retval;
 }
 
@@ -1230,7 +1234,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
    Datum       retval;
    ReturnSetInfo *rsi;
    SV         *array_ret = NULL;
-   bool        oldcontext = trusted_context;
 
    /*
     * Create the call_data beforing connecting to SPI, so that it is not
@@ -1370,9 +1373,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
    if (array_ret == NULL)
        SvREFCNT_dec(perlret);
 
-   current_call_data = NULL;
-   restore_context(oldcontext);
-
    return retval;
 }
 
@@ -1385,7 +1385,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
    Datum       retval;
    SV         *svTD;
    HV         *hvTD;
-   bool        oldcontext = trusted_context;
 
    /*
     * Create the call_data beforing connecting to SPI, so that it is not
@@ -1475,8 +1474,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
    if (perlret)
        SvREFCNT_dec(perlret);
 
-   current_call_data = NULL;
-   restore_context(oldcontext);
    return retval;
 }