Header And Logo

PostgreSQL
| The world's most advanced open source database.

plperl.c

Go to the documentation of this file.
00001 /**********************************************************************
00002  * plperl.c - perl as a procedural language for PostgreSQL
00003  *
00004  *    src/pl/plperl/plperl.c
00005  *
00006  **********************************************************************/
00007 
00008 #include "postgres.h"
00009 /* Defined by Perl */
00010 #undef _
00011 
00012 /* system stuff */
00013 #include <ctype.h>
00014 #include <fcntl.h>
00015 #include <unistd.h>
00016 #include <locale.h>
00017 
00018 /* postgreSQL stuff */
00019 #include "access/htup_details.h"
00020 #include "access/xact.h"
00021 #include "catalog/pg_language.h"
00022 #include "catalog/pg_proc.h"
00023 #include "catalog/pg_type.h"
00024 #include "commands/trigger.h"
00025 #include "executor/spi.h"
00026 #include "funcapi.h"
00027 #include "mb/pg_wchar.h"
00028 #include "miscadmin.h"
00029 #include "nodes/makefuncs.h"
00030 #include "parser/parse_type.h"
00031 #include "storage/ipc.h"
00032 #include "tcop/tcopprot.h"
00033 #include "utils/builtins.h"
00034 #include "utils/fmgroids.h"
00035 #include "utils/guc.h"
00036 #include "utils/hsearch.h"
00037 #include "utils/lsyscache.h"
00038 #include "utils/memutils.h"
00039 #include "utils/rel.h"
00040 #include "utils/syscache.h"
00041 #include "utils/typcache.h"
00042 
00043 /* define our text domain for translations */
00044 #undef TEXTDOMAIN
00045 #define TEXTDOMAIN PG_TEXTDOMAIN("plperl")
00046 
00047 /* perl stuff */
00048 #include "plperl.h"
00049 #include "plperl_helpers.h"
00050 
00051 /* string literal macros defining chunks of perl code */
00052 #include "perlchunks.h"
00053 /* defines PLPERL_SET_OPMASK */
00054 #include "plperl_opmask.h"
00055 
00056 EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
00057 EXTERN_C void boot_PostgreSQL__InServer__Util(pTHX_ CV *cv);
00058 EXTERN_C void boot_PostgreSQL__InServer__SPI(pTHX_ CV *cv);
00059 
00060 PG_MODULE_MAGIC;
00061 
00062 
00063 /**********************************************************************
00064  * Information associated with a Perl interpreter.  We have one interpreter
00065  * that is used for all plperlu (untrusted) functions.  For plperl (trusted)
00066  * functions, there is a separate interpreter for each effective SQL userid.
00067  * (This is needed to ensure that an unprivileged user can't inject Perl code
00068  * that'll be executed with the privileges of some other SQL user.)
00069  *
00070  * The plperl_interp_desc structs are kept in a Postgres hash table indexed
00071  * by userid OID, with OID 0 used for the single untrusted interpreter.
00072  * Once created, an interpreter is kept for the life of the process.
00073  *
00074  * We start out by creating a "held" interpreter, which we initialize
00075  * only as far as we can do without deciding if it will be trusted or
00076  * untrusted.  Later, when we first need to run a plperl or plperlu
00077  * function, we complete the initialization appropriately and move the
00078  * PerlInterpreter pointer into the plperl_interp_hash hashtable.  If after
00079  * that we need more interpreters, we create them as needed if we can, or
00080  * fail if the Perl build doesn't support multiple interpreters.
00081  *
00082  * The reason for all the dancing about with a held interpreter is to make
00083  * it possible for people to preload a lot of Perl code at postmaster startup
00084  * (using plperl.on_init) and then use that code in backends.  Of course this
00085  * will only work for the first interpreter created in any backend, but it's
00086  * still useful with that restriction.
00087  **********************************************************************/
00088 typedef struct plperl_interp_desc
00089 {
00090     Oid         user_id;        /* Hash key (must be first!) */
00091     PerlInterpreter *interp;    /* The interpreter */
00092     HTAB       *query_hash;     /* plperl_query_entry structs */
00093 } plperl_interp_desc;
00094 
00095 
00096 /**********************************************************************
00097  * The information we cache about loaded procedures
00098  *
00099  * The refcount field counts the struct's reference from the hash table shown
00100  * below, plus one reference for each function call level that is using the
00101  * struct.  We can release the struct, and the associated Perl sub, when the
00102  * refcount goes to zero.
00103  **********************************************************************/
00104 typedef struct plperl_proc_desc
00105 {
00106     char       *proname;        /* user name of procedure */
00107     TransactionId fn_xmin;      /* xmin/TID of procedure's pg_proc tuple */
00108     ItemPointerData fn_tid;
00109     int         refcount;       /* reference count of this struct */
00110     SV         *reference;      /* CODE reference for Perl sub */
00111     plperl_interp_desc *interp; /* interpreter it's created in */
00112     bool        fn_readonly;    /* is function readonly (not volatile)? */
00113     bool        lanpltrusted;   /* is it plperl, rather than plperlu? */
00114     bool        fn_retistuple;  /* true, if function returns tuple */
00115     bool        fn_retisset;    /* true, if function returns set */
00116     bool        fn_retisarray;  /* true if function returns array */
00117     /* Conversion info for function's result type: */
00118     Oid         result_oid;     /* Oid of result type */
00119     FmgrInfo    result_in_func; /* I/O function and arg for result type */
00120     Oid         result_typioparam;
00121     /* Conversion info for function's argument types: */
00122     int         nargs;
00123     FmgrInfo    arg_out_func[FUNC_MAX_ARGS];
00124     bool        arg_is_rowtype[FUNC_MAX_ARGS];
00125     Oid         arg_arraytype[FUNC_MAX_ARGS];   /* InvalidOid if not an array */
00126 } plperl_proc_desc;
00127 
00128 #define increment_prodesc_refcount(prodesc)  \
00129     ((prodesc)->refcount++)
00130 #define decrement_prodesc_refcount(prodesc)  \
00131     do { \
00132         if (--((prodesc)->refcount) <= 0) \
00133             free_plperl_function(prodesc); \
00134     } while(0)
00135 
00136 /**********************************************************************
00137  * For speedy lookup, we maintain a hash table mapping from
00138  * function OID + trigger flag + user OID to plperl_proc_desc pointers.
00139  * The reason the plperl_proc_desc struct isn't directly part of the hash
00140  * entry is to simplify recovery from errors during compile_plperl_function.
00141  *
00142  * Note: if the same function is called by multiple userIDs within a session,
00143  * there will be a separate plperl_proc_desc entry for each userID in the case
00144  * of plperl functions, but only one entry for plperlu functions, because we
00145  * set user_id = 0 for that case.  If the user redeclares the same function
00146  * from plperl to plperlu or vice versa, there might be multiple
00147  * plperl_proc_ptr entries in the hashtable, but only one is valid.
00148  **********************************************************************/
00149 typedef struct plperl_proc_key
00150 {
00151     Oid         proc_id;        /* Function OID */
00152 
00153     /*
00154      * is_trigger is really a bool, but declare as Oid to ensure this struct
00155      * contains no padding
00156      */
00157     Oid         is_trigger;     /* is it a trigger function? */
00158     Oid         user_id;        /* User calling the function, or 0 */
00159 } plperl_proc_key;
00160 
00161 typedef struct plperl_proc_ptr
00162 {
00163     plperl_proc_key proc_key;   /* Hash key (must be first!) */
00164     plperl_proc_desc *proc_ptr;
00165 } plperl_proc_ptr;
00166 
00167 /*
00168  * The information we cache for the duration of a single call to a
00169  * function.
00170  */
00171 typedef struct plperl_call_data
00172 {
00173     plperl_proc_desc *prodesc;
00174     FunctionCallInfo fcinfo;
00175     Tuplestorestate *tuple_store;
00176     TupleDesc   ret_tdesc;
00177     MemoryContext tmp_cxt;
00178 } plperl_call_data;
00179 
00180 /**********************************************************************
00181  * The information we cache about prepared and saved plans
00182  **********************************************************************/
00183 typedef struct plperl_query_desc
00184 {
00185     char        qname[24];
00186     MemoryContext plan_cxt;     /* context holding this struct */
00187     SPIPlanPtr  plan;
00188     int         nargs;
00189     Oid        *argtypes;
00190     FmgrInfo   *arginfuncs;
00191     Oid        *argtypioparams;
00192 } plperl_query_desc;
00193 
00194 /* hash table entry for query desc  */
00195 
00196 typedef struct plperl_query_entry
00197 {
00198     char        query_name[NAMEDATALEN];
00199     plperl_query_desc *query_data;
00200 } plperl_query_entry;
00201 
00202 /**********************************************************************
00203  * Information for PostgreSQL - Perl array conversion.
00204  **********************************************************************/
00205 typedef struct plperl_array_info
00206 {
00207     int         ndims;
00208     bool        elem_is_rowtype;    /* 't' if element type is a rowtype */
00209     Datum      *elements;
00210     bool       *nulls;
00211     int        *nelems;
00212     FmgrInfo    proc;
00213 } plperl_array_info;
00214 
00215 /**********************************************************************
00216  * Global data
00217  **********************************************************************/
00218 
00219 static HTAB *plperl_interp_hash = NULL;
00220 static HTAB *plperl_proc_hash = NULL;
00221 static plperl_interp_desc *plperl_active_interp = NULL;
00222 
00223 /* If we have an unassigned "held" interpreter, it's stored here */
00224 static PerlInterpreter *plperl_held_interp = NULL;
00225 
00226 /* GUC variables */
00227 static bool plperl_use_strict = false;
00228 static char *plperl_on_init = NULL;
00229 static char *plperl_on_plperl_init = NULL;
00230 static char *plperl_on_plperlu_init = NULL;
00231 
00232 static bool plperl_ending = false;
00233 static OP  *(*pp_require_orig) (pTHX) = NULL;
00234 static char plperl_opmask[MAXO];
00235 
00236 /* this is saved and restored by plperl_call_handler */
00237 static plperl_call_data *current_call_data = NULL;
00238 
00239 /**********************************************************************
00240  * Forward declarations
00241  **********************************************************************/
00242 Datum       plperl_call_handler(PG_FUNCTION_ARGS);
00243 Datum       plperl_inline_handler(PG_FUNCTION_ARGS);
00244 Datum       plperl_validator(PG_FUNCTION_ARGS);
00245 Datum       plperlu_call_handler(PG_FUNCTION_ARGS);
00246 Datum       plperlu_inline_handler(PG_FUNCTION_ARGS);
00247 Datum       plperlu_validator(PG_FUNCTION_ARGS);
00248 void        _PG_init(void);
00249 
00250 static PerlInterpreter *plperl_init_interp(void);
00251 static void plperl_destroy_interp(PerlInterpreter **);
00252 static void plperl_fini(int code, Datum arg);
00253 static void set_interp_require(bool trusted);
00254 
00255 static Datum plperl_func_handler(PG_FUNCTION_ARGS);
00256 static Datum plperl_trigger_handler(PG_FUNCTION_ARGS);
00257 
00258 static void free_plperl_function(plperl_proc_desc *prodesc);
00259 
00260 static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger);
00261 
00262 static SV  *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc);
00263 static SV  *plperl_hash_from_datum(Datum attr);
00264 static SV  *plperl_ref_from_pg_array(Datum arg, Oid typid);
00265 static SV  *split_array(plperl_array_info *info, int first, int last, int nest);
00266 static SV  *make_array_ref(plperl_array_info *info, int first, int last);
00267 static SV  *get_perl_array_ref(SV *sv);
00268 static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod,
00269                    FunctionCallInfo fcinfo,
00270                    FmgrInfo *finfo, Oid typioparam,
00271                    bool *isnull);
00272 static void _sv_to_datum_finfo(Oid typid, FmgrInfo *finfo, Oid *typioparam);
00273 static Datum plperl_array_to_datum(SV *src, Oid typid, int32 typmod);
00274 static ArrayBuildState *array_to_datum_internal(AV *av, ArrayBuildState *astate,
00275                         int *ndims, int *dims, int cur_depth,
00276                         Oid arraytypid, Oid elemtypid, int32 typmod,
00277                         FmgrInfo *finfo, Oid typioparam);
00278 static Datum plperl_hash_to_datum(SV *src, TupleDesc td);
00279 
00280 static void plperl_init_shared_libs(pTHX);
00281 static void plperl_trusted_init(void);
00282 static void plperl_untrusted_init(void);
00283 static HV  *plperl_spi_execute_fetch_result(SPITupleTable *, int, int);
00284 static char *hek2cstr(HE *he);
00285 static SV **hv_store_string(HV *hv, const char *key, SV *val);
00286 static SV **hv_fetch_string(HV *hv, const char *key);
00287 static void plperl_create_sub(plperl_proc_desc *desc, char *s, Oid fn_oid);
00288 static SV  *plperl_call_perl_func(plperl_proc_desc *desc,
00289                       FunctionCallInfo fcinfo);
00290 static void plperl_compile_callback(void *arg);
00291 static void plperl_exec_callback(void *arg);
00292 static void plperl_inline_callback(void *arg);
00293 static char *strip_trailing_ws(const char *msg);
00294 static OP  *pp_require_safe(pTHX);
00295 static void activate_interpreter(plperl_interp_desc *interp_desc);
00296 
00297 #ifdef WIN32
00298 static char *setlocale_perl(int category, char *locale);
00299 #endif
00300 
00301 /*
00302  * convert a HE (hash entry) key to a cstr in the current database encoding
00303  */
00304 static char *
00305 hek2cstr(HE *he)
00306 {
00307     /*-------------------------
00308      * Unfortunately,  while HeUTF8 is true for most things > 256, for values
00309      * 128..255 it's not, but perl will treat them as unicode code points if
00310      * the utf8 flag is not set ( see The "Unicode Bug" in perldoc perlunicode
00311      * for more)
00312      *
00313      * So if we did the expected:
00314      *    if (HeUTF8(he))
00315      *        utf_u2e(key...);
00316      *    else // must be ascii
00317      *        return HePV(he);
00318      * we won't match columns with codepoints from 128..255
00319      *
00320      * For a more concrete example given a column with the name of the unicode
00321      * codepoint U+00ae (registered sign) and a UTF8 database and the perl
00322      * return_next { "\N{U+00ae}=>'text } would always fail as heUTF8 returns
00323      * 0 and HePV() would give us a char * with 1 byte contains the decimal
00324      * value 174
00325      *
00326      * Perl has the brains to know when it should utf8 encode 174 properly, so
00327      * here we force it into an SV so that perl will figure it out and do the
00328      * right thing
00329      *-------------------------
00330      */
00331     SV         *sv = HeSVKEY_force(he);
00332 
00333     if (HeUTF8(he))
00334         SvUTF8_on(sv);
00335     return sv2cstr(sv);
00336 }
00337 
00338 /*
00339  * This routine is a crock, and so is everyplace that calls it.  The problem
00340  * is that the cached form of plperl functions/queries is allocated permanently
00341  * (mostly via malloc()) and never released until backend exit.  Subsidiary
00342  * data structures such as fmgr info records therefore must live forever
00343  * as well.  A better implementation would store all this stuff in a per-
00344  * function memory context that could be reclaimed at need.  In the meantime,
00345  * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
00346  * it might allocate, and whatever the eventual function might allocate using
00347  * fn_mcxt, will live forever too.
00348  */
00349 static void
00350 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
00351 {
00352     fmgr_info_cxt(functionId, finfo, TopMemoryContext);
00353 }
00354 
00355 
00356 /*
00357  * _PG_init()           - library load-time initialization
00358  *
00359  * DO NOT make this static nor change its name!
00360  */
00361 void
00362 _PG_init(void)
00363 {
00364     /*
00365      * Be sure we do initialization only once.
00366      *
00367      * If initialization fails due to, e.g., plperl_init_interp() throwing an
00368      * exception, then we'll return here on the next usage and the user will
00369      * get a rather cryptic: ERROR:  attempt to redefine parameter
00370      * "plperl.use_strict"
00371      */
00372     static bool inited = false;
00373     HASHCTL     hash_ctl;
00374 
00375     if (inited)
00376         return;
00377 
00378     /*
00379      * Support localized messages.
00380      */
00381     pg_bindtextdomain(TEXTDOMAIN);
00382 
00383     /*
00384      * Initialize plperl's GUCs.
00385      */
00386     DefineCustomBoolVariable("plperl.use_strict",
00387                              gettext_noop("If true, trusted and untrusted Perl code will be compiled in strict mode."),
00388                              NULL,
00389                              &plperl_use_strict,
00390                              false,
00391                              PGC_USERSET, 0,
00392                              NULL, NULL, NULL);
00393 
00394     /*
00395      * plperl.on_init is marked PGC_SIGHUP to support the idea that it might
00396      * be executed in the postmaster (if plperl is loaded into the postmaster
00397      * via shared_preload_libraries).  This isn't really right either way,
00398      * though.
00399      */
00400     DefineCustomStringVariable("plperl.on_init",
00401                                gettext_noop("Perl initialization code to execute when a Perl interpreter is initialized."),
00402                                NULL,
00403                                &plperl_on_init,
00404                                NULL,
00405                                PGC_SIGHUP, 0,
00406                                NULL, NULL, NULL);
00407 
00408     /*
00409      * plperl.on_plperl_init is marked PGC_SUSET to avoid issues whereby a
00410      * user who might not even have USAGE privilege on the plperl language
00411      * could nonetheless use SET plperl.on_plperl_init='...' to influence the
00412      * behaviour of any existing plperl function that they can execute (which
00413      * might be SECURITY DEFINER, leading to a privilege escalation).  See
00414      * http://archives.postgresql.org/pgsql-hackers/2010-02/msg00281.php and
00415      * the overall thread.
00416      *
00417      * Note that because plperl.use_strict is USERSET, a nefarious user could
00418      * set it to be applied against other people's functions.  This is judged
00419      * OK since the worst result would be an error.  Your code oughta pass
00420      * use_strict anyway ;-)
00421      */
00422     DefineCustomStringVariable("plperl.on_plperl_init",
00423                                gettext_noop("Perl initialization code to execute once when plperl is first used."),
00424                                NULL,
00425                                &plperl_on_plperl_init,
00426                                NULL,
00427                                PGC_SUSET, 0,
00428                                NULL, NULL, NULL);
00429 
00430     DefineCustomStringVariable("plperl.on_plperlu_init",
00431                                gettext_noop("Perl initialization code to execute once when plperlu is first used."),
00432                                NULL,
00433                                &plperl_on_plperlu_init,
00434                                NULL,
00435                                PGC_SUSET, 0,
00436                                NULL, NULL, NULL);
00437 
00438     EmitWarningsOnPlaceholders("plperl");
00439 
00440     /*
00441      * Create hash tables.
00442      */
00443     memset(&hash_ctl, 0, sizeof(hash_ctl));
00444     hash_ctl.keysize = sizeof(Oid);
00445     hash_ctl.entrysize = sizeof(plperl_interp_desc);
00446     hash_ctl.hash = oid_hash;
00447     plperl_interp_hash = hash_create("PL/Perl interpreters",
00448                                      8,
00449                                      &hash_ctl,
00450                                      HASH_ELEM | HASH_FUNCTION);
00451 
00452     memset(&hash_ctl, 0, sizeof(hash_ctl));
00453     hash_ctl.keysize = sizeof(plperl_proc_key);
00454     hash_ctl.entrysize = sizeof(plperl_proc_ptr);
00455     hash_ctl.hash = tag_hash;
00456     plperl_proc_hash = hash_create("PL/Perl procedures",
00457                                    32,
00458                                    &hash_ctl,
00459                                    HASH_ELEM | HASH_FUNCTION);
00460 
00461     /*
00462      * Save the default opmask.
00463      */
00464     PLPERL_SET_OPMASK(plperl_opmask);
00465 
00466     /*
00467      * Create the first Perl interpreter, but only partially initialize it.
00468      */
00469     plperl_held_interp = plperl_init_interp();
00470 
00471     inited = true;
00472 }
00473 
00474 
00475 static void
00476 set_interp_require(bool trusted)
00477 {
00478     if (trusted)
00479     {
00480         PL_ppaddr[OP_REQUIRE] = pp_require_safe;
00481         PL_ppaddr[OP_DOFILE] = pp_require_safe;
00482     }
00483     else
00484     {
00485         PL_ppaddr[OP_REQUIRE] = pp_require_orig;
00486         PL_ppaddr[OP_DOFILE] = pp_require_orig;
00487     }
00488 }
00489 
00490 /*
00491  * Cleanup perl interpreters, including running END blocks.
00492  * Does not fully undo the actions of _PG_init() nor make it callable again.
00493  */
00494 static void
00495 plperl_fini(int code, Datum arg)
00496 {
00497     HASH_SEQ_STATUS hash_seq;
00498     plperl_interp_desc *interp_desc;
00499 
00500     elog(DEBUG3, "plperl_fini");
00501 
00502     /*
00503      * Indicate that perl is terminating. Disables use of spi_* functions when
00504      * running END/DESTROY code. See check_spi_usage_allowed(). Could be
00505      * enabled in future, with care, using a transaction
00506      * http://archives.postgresql.org/pgsql-hackers/2010-01/msg02743.php
00507      */
00508     plperl_ending = true;
00509 
00510     /* Only perform perl cleanup if we're exiting cleanly */
00511     if (code)
00512     {
00513         elog(DEBUG3, "plperl_fini: skipped");
00514         return;
00515     }
00516 
00517     /* Zap the "held" interpreter, if we still have it */
00518     plperl_destroy_interp(&plperl_held_interp);
00519 
00520     /* Zap any fully-initialized interpreters */
00521     hash_seq_init(&hash_seq, plperl_interp_hash);
00522     while ((interp_desc = hash_seq_search(&hash_seq)) != NULL)
00523     {
00524         if (interp_desc->interp)
00525         {
00526             activate_interpreter(interp_desc);
00527             plperl_destroy_interp(&interp_desc->interp);
00528         }
00529     }
00530 
00531     elog(DEBUG3, "plperl_fini: done");
00532 }
00533 
00534 
00535 /*
00536  * Select and activate an appropriate Perl interpreter.
00537  */
00538 static void
00539 select_perl_context(bool trusted)
00540 {
00541     Oid         user_id;
00542     plperl_interp_desc *interp_desc;
00543     bool        found;
00544     PerlInterpreter *interp = NULL;
00545 
00546     /* Find or create the interpreter hashtable entry for this userid */
00547     if (trusted)
00548         user_id = GetUserId();
00549     else
00550         user_id = InvalidOid;
00551 
00552     interp_desc = hash_search(plperl_interp_hash, &user_id,
00553                               HASH_ENTER,
00554                               &found);
00555     if (!found)
00556     {
00557         /* Initialize newly-created hashtable entry */
00558         interp_desc->interp = NULL;
00559         interp_desc->query_hash = NULL;
00560     }
00561 
00562     /* Make sure we have a query_hash for this interpreter */
00563     if (interp_desc->query_hash == NULL)
00564     {
00565         HASHCTL     hash_ctl;
00566 
00567         memset(&hash_ctl, 0, sizeof(hash_ctl));
00568         hash_ctl.keysize = NAMEDATALEN;
00569         hash_ctl.entrysize = sizeof(plperl_query_entry);
00570         interp_desc->query_hash = hash_create("PL/Perl queries",
00571                                               32,
00572                                               &hash_ctl,
00573                                               HASH_ELEM);
00574     }
00575 
00576     /*
00577      * Quick exit if already have an interpreter
00578      */
00579     if (interp_desc->interp)
00580     {
00581         activate_interpreter(interp_desc);
00582         return;
00583     }
00584 
00585     /*
00586      * adopt held interp if free, else create new one if possible
00587      */
00588     if (plperl_held_interp != NULL)
00589     {
00590         /* first actual use of a perl interpreter */
00591         interp = plperl_held_interp;
00592 
00593         /*
00594          * Reset the plperl_held_interp pointer first; if we fail during init
00595          * we don't want to try again with the partially-initialized interp.
00596          */
00597         plperl_held_interp = NULL;
00598 
00599         if (trusted)
00600             plperl_trusted_init();
00601         else
00602             plperl_untrusted_init();
00603 
00604         /* successfully initialized, so arrange for cleanup */
00605         on_proc_exit(plperl_fini, 0);
00606     }
00607     else
00608     {
00609 #ifdef MULTIPLICITY
00610 
00611         /*
00612          * plperl_init_interp will change Perl's idea of the active
00613          * interpreter.  Reset plperl_active_interp temporarily, so that if we
00614          * hit an error partway through here, we'll make sure to switch back
00615          * to a non-broken interpreter before running any other Perl
00616          * functions.
00617          */
00618         plperl_active_interp = NULL;
00619 
00620         /* Now build the new interpreter */
00621         interp = plperl_init_interp();
00622 
00623         if (trusted)
00624             plperl_trusted_init();
00625         else
00626             plperl_untrusted_init();
00627 #else
00628         elog(ERROR,
00629              "cannot allocate multiple Perl interpreters on this platform");
00630 #endif
00631     }
00632 
00633     set_interp_require(trusted);
00634 
00635     /*
00636      * Since the timing of first use of PL/Perl can't be predicted, any
00637      * database interaction during initialization is problematic. Including,
00638      * but not limited to, security definer issues. So we only enable access
00639      * to the database AFTER on_*_init code has run. See
00640      * http://archives.postgresql.org/pgsql-hackers/2010-01/msg02669.php
00641      */
00642     newXS("PostgreSQL::InServer::SPI::bootstrap",
00643           boot_PostgreSQL__InServer__SPI, __FILE__);
00644 
00645     eval_pv("PostgreSQL::InServer::SPI::bootstrap()", FALSE);
00646     if (SvTRUE(ERRSV))
00647         ereport(ERROR,
00648                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
00649         errcontext("while executing PostgreSQL::InServer::SPI::bootstrap")));
00650 
00651     /* Fully initialized, so mark the hashtable entry valid */
00652     interp_desc->interp = interp;
00653 
00654     /* And mark this as the active interpreter */
00655     plperl_active_interp = interp_desc;
00656 }
00657 
00658 /*
00659  * Make the specified interpreter the active one
00660  *
00661  * A call with NULL does nothing.  This is so that "restoring" to a previously
00662  * null state of plperl_active_interp doesn't result in useless thrashing.
00663  */
00664 static void
00665 activate_interpreter(plperl_interp_desc *interp_desc)
00666 {
00667     if (interp_desc && plperl_active_interp != interp_desc)
00668     {
00669         Assert(interp_desc->interp);
00670         PERL_SET_CONTEXT(interp_desc->interp);
00671         /* trusted iff user_id isn't InvalidOid */
00672         set_interp_require(OidIsValid(interp_desc->user_id));
00673         plperl_active_interp = interp_desc;
00674     }
00675 }
00676 
00677 /*
00678  * Create a new Perl interpreter.
00679  *
00680  * We initialize the interpreter as far as we can without knowing whether
00681  * it will become a trusted or untrusted interpreter; in particular, the
00682  * plperl.on_init code will get executed.  Later, either plperl_trusted_init
00683  * or plperl_untrusted_init must be called to complete the initialization.
00684  */
00685 static PerlInterpreter *
00686 plperl_init_interp(void)
00687 {
00688     PerlInterpreter *plperl;
00689 
00690     static char *embedding[3 + 2] = {
00691         "", "-e", PLC_PERLBOOT
00692     };
00693     int         nargs = 3;
00694 
00695 #ifdef WIN32
00696 
00697     /*
00698      * The perl library on startup does horrible things like call
00699      * setlocale(LC_ALL,""). We have protected against that on most platforms
00700      * by setting the environment appropriately. However, on Windows,
00701      * setlocale() does not consult the environment, so we need to save the
00702      * existing locale settings before perl has a chance to mangle them and
00703      * restore them after its dirty deeds are done.
00704      *
00705      * MSDN ref:
00706      * http://msdn.microsoft.com/library/en-us/vclib/html/_crt_locale.asp
00707      *
00708      * It appears that we only need to do this on interpreter startup, and
00709      * subsequent calls to the interpreter don't mess with the locale
00710      * settings.
00711      *
00712      * We restore them using setlocale_perl(), defined below, so that Perl
00713      * doesn't have a different idea of the locale from Postgres.
00714      *
00715      */
00716 
00717     char       *loc;
00718     char       *save_collate,
00719                *save_ctype,
00720                *save_monetary,
00721                *save_numeric,
00722                *save_time;
00723 
00724     loc = setlocale(LC_COLLATE, NULL);
00725     save_collate = loc ? pstrdup(loc) : NULL;
00726     loc = setlocale(LC_CTYPE, NULL);
00727     save_ctype = loc ? pstrdup(loc) : NULL;
00728     loc = setlocale(LC_MONETARY, NULL);
00729     save_monetary = loc ? pstrdup(loc) : NULL;
00730     loc = setlocale(LC_NUMERIC, NULL);
00731     save_numeric = loc ? pstrdup(loc) : NULL;
00732     loc = setlocale(LC_TIME, NULL);
00733     save_time = loc ? pstrdup(loc) : NULL;
00734 
00735 #define PLPERL_RESTORE_LOCALE(name, saved) \
00736     STMT_START { \
00737         if (saved != NULL) { setlocale_perl(name, saved); pfree(saved); } \
00738     } STMT_END
00739 #endif   /* WIN32 */
00740 
00741     if (plperl_on_init && *plperl_on_init)
00742     {
00743         embedding[nargs++] = "-e";
00744         embedding[nargs++] = plperl_on_init;
00745     }
00746 
00747     /*
00748      * The perl API docs state that PERL_SYS_INIT3 should be called before
00749      * allocating interpreters. Unfortunately, on some platforms this fails in
00750      * the Perl_do_taint() routine, which is called when the platform is using
00751      * the system's malloc() instead of perl's own. Other platforms, notably
00752      * Windows, fail if PERL_SYS_INIT3 is not called. So we call it if it's
00753      * available, unless perl is using the system malloc(), which is true when
00754      * MYMALLOC is set.
00755      */
00756 #if defined(PERL_SYS_INIT3) && !defined(MYMALLOC)
00757     {
00758         static int  perl_sys_init_done;
00759 
00760         /* only call this the first time through, as per perlembed man page */
00761         if (!perl_sys_init_done)
00762         {
00763             char       *dummy_env[1] = {NULL};
00764 
00765             PERL_SYS_INIT3(&nargs, (char ***) &embedding, (char ***) &dummy_env);
00766 
00767             /*
00768              * For unclear reasons, PERL_SYS_INIT3 sets the SIGFPE handler to
00769              * SIG_IGN.  Aside from being extremely unfriendly behavior for a
00770              * library, this is dumb on the grounds that the results of a
00771              * SIGFPE in this state are undefined according to POSIX, and in
00772              * fact you get a forced process kill at least on Linux.  Hence,
00773              * restore the SIGFPE handler to the backend's standard setting.
00774              * (See Perl bug 114574 for more information.)
00775              */
00776             pqsignal(SIGFPE, FloatExceptionHandler);
00777 
00778             perl_sys_init_done = 1;
00779             /* quiet warning if PERL_SYS_INIT3 doesn't use the third argument */
00780             dummy_env[0] = NULL;
00781         }
00782     }
00783 #endif
00784 
00785     plperl = perl_alloc();
00786     if (!plperl)
00787         elog(ERROR, "could not allocate Perl interpreter");
00788 
00789     PERL_SET_CONTEXT(plperl);
00790     perl_construct(plperl);
00791 
00792     /* run END blocks in perl_destruct instead of perl_run */
00793     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
00794 
00795     /*
00796      * Record the original function for the 'require' and 'dofile' opcodes.
00797      * (They share the same implementation.) Ensure it's used for new
00798      * interpreters.
00799      */
00800     if (!pp_require_orig)
00801         pp_require_orig = PL_ppaddr[OP_REQUIRE];
00802     else
00803     {
00804         PL_ppaddr[OP_REQUIRE] = pp_require_orig;
00805         PL_ppaddr[OP_DOFILE] = pp_require_orig;
00806     }
00807 
00808 #ifdef PLPERL_ENABLE_OPMASK_EARLY
00809 
00810     /*
00811      * For regression testing to prove that the PLC_PERLBOOT and PLC_TRUSTED
00812      * code doesn't even compile any unsafe ops. In future there may be a
00813      * valid need for them to do so, in which case this could be softened
00814      * (perhaps moved to plperl_trusted_init()) or removed.
00815      */
00816     PL_op_mask = plperl_opmask;
00817 #endif
00818 
00819     if (perl_parse(plperl, plperl_init_shared_libs,
00820                    nargs, embedding, NULL) != 0)
00821         ereport(ERROR,
00822                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
00823                  errcontext("while parsing Perl initialization")));
00824 
00825     if (perl_run(plperl) != 0)
00826         ereport(ERROR,
00827                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
00828                  errcontext("while running Perl initialization")));
00829 
00830 #ifdef PLPERL_RESTORE_LOCALE
00831     PLPERL_RESTORE_LOCALE(LC_COLLATE, save_collate);
00832     PLPERL_RESTORE_LOCALE(LC_CTYPE, save_ctype);
00833     PLPERL_RESTORE_LOCALE(LC_MONETARY, save_monetary);
00834     PLPERL_RESTORE_LOCALE(LC_NUMERIC, save_numeric);
00835     PLPERL_RESTORE_LOCALE(LC_TIME, save_time);
00836 #endif
00837 
00838     return plperl;
00839 }
00840 
00841 
00842 /*
00843  * Our safe implementation of the require opcode.
00844  * This is safe because it's completely unable to load any code.
00845  * If the requested file/module has already been loaded it'll return true.
00846  * If not, it'll die.
00847  * So now "use Foo;" will work iff Foo has already been loaded.
00848  */
00849 static OP  *
00850 pp_require_safe(pTHX)
00851 {
00852     dVAR;
00853     dSP;
00854     SV         *sv,
00855               **svp;
00856     char       *name;
00857     STRLEN      len;
00858 
00859     sv = POPs;
00860     name = SvPV(sv, len);
00861     if (!(name && len > 0 && *name))
00862         RETPUSHNO;
00863 
00864     svp = hv_fetch(GvHVn(PL_incgv), name, len, 0);
00865     if (svp && *svp != &PL_sv_undef)
00866         RETPUSHYES;
00867 
00868     DIE(aTHX_ "Unable to load %s into plperl", name);
00869     /*
00870      * In most Perl versions, DIE() expands to a return statement, so the next
00871      * line is not necessary.  But in versions between but not including 5.11.1
00872      * and 5.13.3 it does not, so the next line is necessary to avoid a
00873      * "control reaches end of non-void function" warning from gcc.  Other
00874      * compilers such as Solaris Studio will, however, issue a "statement not
00875      * reached" warning instead.
00876      */
00877     return NULL;
00878 }
00879 
00880 
00881 /*
00882  * Destroy one Perl interpreter ... actually we just run END blocks.
00883  *
00884  * Caller must have ensured this interpreter is the active one.
00885  */
00886 static void
00887 plperl_destroy_interp(PerlInterpreter **interp)
00888 {
00889     if (interp && *interp)
00890     {
00891         /*
00892          * Only a very minimal destruction is performed: - just call END
00893          * blocks.
00894          *
00895          * We could call perl_destruct() but we'd need to audit its actions
00896          * very carefully and work-around any that impact us. (Calling
00897          * sv_clean_objs() isn't an option because it's not part of perl's
00898          * public API so isn't portably available.) Meanwhile END blocks can
00899          * be used to perform manual cleanup.
00900          */
00901 
00902         /* Run END blocks - based on perl's perl_destruct() */
00903         if (PL_exit_flags & PERL_EXIT_DESTRUCT_END)
00904         {
00905             dJMPENV;
00906             int         x = 0;
00907 
00908             JMPENV_PUSH(x);
00909             PERL_UNUSED_VAR(x);
00910             if (PL_endav && !PL_minus_c)
00911                 call_list(PL_scopestack_ix, PL_endav);
00912             JMPENV_POP;
00913         }
00914         LEAVE;
00915         FREETMPS;
00916 
00917         *interp = NULL;
00918     }
00919 }
00920 
00921 /*
00922  * Initialize the current Perl interpreter as a trusted interp
00923  */
00924 static void
00925 plperl_trusted_init(void)
00926 {
00927     HV         *stash;
00928     SV         *sv;
00929     char       *key;
00930     I32         klen;
00931 
00932     /* use original require while we set up */
00933     PL_ppaddr[OP_REQUIRE] = pp_require_orig;
00934     PL_ppaddr[OP_DOFILE] = pp_require_orig;
00935 
00936     eval_pv(PLC_TRUSTED, FALSE);
00937     if (SvTRUE(ERRSV))
00938         ereport(ERROR,
00939                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
00940                  errcontext("while executing PLC_TRUSTED")));
00941 
00942     /*
00943      * Force loading of utf8 module now to prevent errors that can arise from
00944      * the regex code later trying to load utf8 modules. See
00945      * http://rt.perl.org/rt3/Ticket/Display.html?id=47576
00946      */
00947     eval_pv("my $a=chr(0x100); return $a =~ /\\xa9/i", FALSE);
00948     if (SvTRUE(ERRSV))
00949         ereport(ERROR,
00950                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
00951                  errcontext("while executing utf8fix")));
00952 
00953     /*
00954      * Lock down the interpreter
00955      */
00956 
00957     /* switch to the safe require/dofile opcode for future code */
00958     PL_ppaddr[OP_REQUIRE] = pp_require_safe;
00959     PL_ppaddr[OP_DOFILE] = pp_require_safe;
00960 
00961     /*
00962      * prevent (any more) unsafe opcodes being compiled PL_op_mask is per
00963      * interpreter, so this only needs to be set once
00964      */
00965     PL_op_mask = plperl_opmask;
00966 
00967     /* delete the DynaLoader:: namespace so extensions can't be loaded */
00968     stash = gv_stashpv("DynaLoader", GV_ADDWARN);
00969     hv_iterinit(stash);
00970     while ((sv = hv_iternextsv(stash, &key, &klen)))
00971     {
00972         if (!isGV_with_GP(sv) || !GvCV(sv))
00973             continue;
00974         SvREFCNT_dec(GvCV(sv)); /* free the CV */
00975         GvCV_set(sv, NULL);     /* prevent call via GV */
00976     }
00977     hv_clear(stash);
00978 
00979     /* invalidate assorted caches */
00980     ++PL_sub_generation;
00981     hv_clear(PL_stashcache);
00982 
00983     /*
00984      * Execute plperl.on_plperl_init in the locked-down interpreter
00985      */
00986     if (plperl_on_plperl_init && *plperl_on_plperl_init)
00987     {
00988         eval_pv(plperl_on_plperl_init, FALSE);
00989         if (SvTRUE(ERRSV))
00990             ereport(ERROR,
00991                     (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
00992                      errcontext("while executing plperl.on_plperl_init")));
00993 
00994     }
00995 }
00996 
00997 
00998 /*
00999  * Initialize the current Perl interpreter as an untrusted interp
01000  */
01001 static void
01002 plperl_untrusted_init(void)
01003 {
01004     /*
01005      * Nothing to do except execute plperl.on_plperlu_init
01006      */
01007     if (plperl_on_plperlu_init && *plperl_on_plperlu_init)
01008     {
01009         eval_pv(plperl_on_plperlu_init, FALSE);
01010         if (SvTRUE(ERRSV))
01011             ereport(ERROR,
01012                     (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV))),
01013                      errcontext("while executing plperl.on_plperlu_init")));
01014     }
01015 }
01016 
01017 
01018 /*
01019  * Perl likes to put a newline after its error messages; clean up such
01020  */
01021 static char *
01022 strip_trailing_ws(const char *msg)
01023 {
01024     char       *res = pstrdup(msg);
01025     int         len = strlen(res);
01026 
01027     while (len > 0 && isspace((unsigned char) res[len - 1]))
01028         res[--len] = '\0';
01029     return res;
01030 }
01031 
01032 
01033 /* Build a tuple from a hash. */
01034 
01035 static HeapTuple
01036 plperl_build_tuple_result(HV *perlhash, TupleDesc td)
01037 {
01038     Datum      *values;
01039     bool       *nulls;
01040     HE         *he;
01041     HeapTuple   tup;
01042 
01043     values = palloc0(sizeof(Datum) * td->natts);
01044     nulls = palloc(sizeof(bool) * td->natts);
01045     memset(nulls, true, sizeof(bool) * td->natts);
01046 
01047     hv_iterinit(perlhash);
01048     while ((he = hv_iternext(perlhash)))
01049     {
01050         SV         *val = HeVAL(he);
01051         char       *key = hek2cstr(he);
01052         int         attn = SPI_fnumber(td, key);
01053 
01054         if (attn <= 0 || td->attrs[attn - 1]->attisdropped)
01055             ereport(ERROR,
01056                     (errcode(ERRCODE_UNDEFINED_COLUMN),
01057                      errmsg("Perl hash contains nonexistent column \"%s\"",
01058                             key)));
01059 
01060         values[attn - 1] = plperl_sv_to_datum(val,
01061                                               td->attrs[attn - 1]->atttypid,
01062                                               td->attrs[attn - 1]->atttypmod,
01063                                               NULL,
01064                                               NULL,
01065                                               InvalidOid,
01066                                               &nulls[attn - 1]);
01067 
01068         pfree(key);
01069     }
01070     hv_iterinit(perlhash);
01071 
01072     tup = heap_form_tuple(td, values, nulls);
01073     pfree(values);
01074     pfree(nulls);
01075     return tup;
01076 }
01077 
01078 /* convert a hash reference to a datum */
01079 static Datum
01080 plperl_hash_to_datum(SV *src, TupleDesc td)
01081 {
01082     HeapTuple   tup = plperl_build_tuple_result((HV *) SvRV(src), td);
01083 
01084     return HeapTupleGetDatum(tup);
01085 }
01086 
01087 /*
01088  * if we are an array ref return the reference. this is special in that if we
01089  * are a PostgreSQL::InServer::ARRAY object we will return the 'magic' array.
01090  */
01091 static SV  *
01092 get_perl_array_ref(SV *sv)
01093 {
01094     if (SvOK(sv) && SvROK(sv))
01095     {
01096         if (SvTYPE(SvRV(sv)) == SVt_PVAV)
01097             return sv;
01098         else if (sv_isa(sv, "PostgreSQL::InServer::ARRAY"))
01099         {
01100             HV         *hv = (HV *) SvRV(sv);
01101             SV        **sav = hv_fetch_string(hv, "array");
01102 
01103             if (*sav && SvOK(*sav) && SvROK(*sav) &&
01104                 SvTYPE(SvRV(*sav)) == SVt_PVAV)
01105                 return *sav;
01106 
01107             elog(ERROR, "could not get array reference from PostgreSQL::InServer::ARRAY object");
01108         }
01109     }
01110     return NULL;
01111 }
01112 
01113 /*
01114  * helper function for plperl_array_to_datum, recurses for multi-D arrays
01115  */
01116 static ArrayBuildState *
01117 array_to_datum_internal(AV *av, ArrayBuildState *astate,
01118                         int *ndims, int *dims, int cur_depth,
01119                         Oid arraytypid, Oid elemtypid, int32 typmod,
01120                         FmgrInfo *finfo, Oid typioparam)
01121 {
01122     int         i;
01123     int         len = av_len(av) + 1;
01124 
01125     for (i = 0; i < len; i++)
01126     {
01127         /* fetch the array element */
01128         SV        **svp = av_fetch(av, i, FALSE);
01129 
01130         /* see if this element is an array, if so get that */
01131         SV         *sav = svp ? get_perl_array_ref(*svp) : NULL;
01132 
01133         /* multi-dimensional array? */
01134         if (sav)
01135         {
01136             AV         *nav = (AV *) SvRV(sav);
01137 
01138             /* dimensionality checks */
01139             if (cur_depth + 1 > MAXDIM)
01140                 ereport(ERROR,
01141                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
01142                          errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
01143                                 cur_depth + 1, MAXDIM)));
01144 
01145             /* set size when at first element in this level, else compare */
01146             if (i == 0 && *ndims == cur_depth)
01147             {
01148                 dims[*ndims] = av_len(nav) + 1;
01149                 (*ndims)++;
01150             }
01151             else if (av_len(nav) + 1 != dims[cur_depth])
01152                 ereport(ERROR,
01153                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
01154                          errmsg("multidimensional arrays must have array expressions with matching dimensions")));
01155 
01156             /* recurse to fetch elements of this sub-array */
01157             astate = array_to_datum_internal(nav, astate,
01158                                              ndims, dims, cur_depth + 1,
01159                                              arraytypid, elemtypid, typmod,
01160                                              finfo, typioparam);
01161         }
01162         else
01163         {
01164             Datum       dat;
01165             bool        isnull;
01166 
01167             /* scalar after some sub-arrays at same level? */
01168             if (*ndims != cur_depth)
01169                 ereport(ERROR,
01170                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
01171                          errmsg("multidimensional arrays must have array expressions with matching dimensions")));
01172 
01173             dat = plperl_sv_to_datum(svp ? *svp : NULL,
01174                                      elemtypid,
01175                                      typmod,
01176                                      NULL,
01177                                      finfo,
01178                                      typioparam,
01179                                      &isnull);
01180 
01181             astate = accumArrayResult(astate, dat, isnull,
01182                                       elemtypid, CurrentMemoryContext);
01183         }
01184     }
01185 
01186     return astate;
01187 }
01188 
01189 /*
01190  * convert perl array ref to a datum
01191  */
01192 static Datum
01193 plperl_array_to_datum(SV *src, Oid typid, int32 typmod)
01194 {
01195     ArrayBuildState *astate;
01196     Oid         elemtypid;
01197     FmgrInfo    finfo;
01198     Oid         typioparam;
01199     int         dims[MAXDIM];
01200     int         lbs[MAXDIM];
01201     int         ndims = 1;
01202     int         i;
01203 
01204     elemtypid = get_element_type(typid);
01205     if (!elemtypid)
01206         ereport(ERROR,
01207                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01208                  errmsg("cannot convert Perl array to non-array type %s",
01209                         format_type_be(typid))));
01210 
01211     _sv_to_datum_finfo(elemtypid, &finfo, &typioparam);
01212 
01213     memset(dims, 0, sizeof(dims));
01214     dims[0] = av_len((AV *) SvRV(src)) + 1;
01215 
01216     astate = array_to_datum_internal((AV *) SvRV(src), NULL,
01217                                      &ndims, dims, 1,
01218                                      typid, elemtypid, typmod,
01219                                      &finfo, typioparam);
01220 
01221     if (!astate)
01222         return PointerGetDatum(construct_empty_array(elemtypid));
01223 
01224     for (i = 0; i < ndims; i++)
01225         lbs[i] = 1;
01226 
01227     return makeMdArrayResult(astate, ndims, dims, lbs,
01228                              CurrentMemoryContext, true);
01229 }
01230 
01231 /* Get the information needed to convert data to the specified PG type */
01232 static void
01233 _sv_to_datum_finfo(Oid typid, FmgrInfo *finfo, Oid *typioparam)
01234 {
01235     Oid         typinput;
01236 
01237     /* XXX would be better to cache these lookups */
01238     getTypeInputInfo(typid,
01239                      &typinput, typioparam);
01240     fmgr_info(typinput, finfo);
01241 }
01242 
01243 /*
01244  * convert Perl SV to PG datum of type typid, typmod typmod
01245  *
01246  * Pass the PL/Perl function's fcinfo when attempting to convert to the
01247  * function's result type; otherwise pass NULL.  This is used when we need to
01248  * resolve the actual result type of a function returning RECORD.
01249  *
01250  * finfo and typioparam should be the results of _sv_to_datum_finfo for the
01251  * given typid, or NULL/InvalidOid to let this function do the lookups.
01252  *
01253  * *isnull is an output parameter.
01254  */
01255 static Datum
01256 plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod,
01257                    FunctionCallInfo fcinfo,
01258                    FmgrInfo *finfo, Oid typioparam,
01259                    bool *isnull)
01260 {
01261     FmgrInfo    tmp;
01262 
01263     /* we might recurse */
01264     check_stack_depth();
01265 
01266     *isnull = false;
01267 
01268     /*
01269      * Return NULL if result is undef, or if we're in a function returning
01270      * VOID.  In the latter case, we should pay no attention to the last Perl
01271      * statement's result, and this is a convenient means to ensure that.
01272      */
01273     if (!sv || !SvOK(sv) || typid == VOIDOID)
01274     {
01275         /* look up type info if they did not pass it */
01276         if (!finfo)
01277         {
01278             _sv_to_datum_finfo(typid, &tmp, &typioparam);
01279             finfo = &tmp;
01280         }
01281         *isnull = true;
01282         /* must call typinput in case it wants to reject NULL */
01283         return InputFunctionCall(finfo, NULL, typioparam, typmod);
01284     }
01285     else if (SvROK(sv))
01286     {
01287         /* handle references */
01288         SV         *sav = get_perl_array_ref(sv);
01289 
01290         if (sav)
01291         {
01292             /* handle an arrayref */
01293             return plperl_array_to_datum(sav, typid, typmod);
01294         }
01295         else if (SvTYPE(SvRV(sv)) == SVt_PVHV)
01296         {
01297             /* handle a hashref */
01298             Datum       ret;
01299             TupleDesc   td;
01300 
01301             if (!type_is_rowtype(typid))
01302                 ereport(ERROR,
01303                         (errcode(ERRCODE_DATATYPE_MISMATCH),
01304                   errmsg("cannot convert Perl hash to non-composite type %s",
01305                          format_type_be(typid))));
01306 
01307             td = lookup_rowtype_tupdesc_noerror(typid, typmod, true);
01308             if (td == NULL)
01309             {
01310                 /* Try to look it up based on our result type */
01311                 if (fcinfo == NULL ||
01312                 get_call_result_type(fcinfo, NULL, &td) != TYPEFUNC_COMPOSITE)
01313                     ereport(ERROR,
01314                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01315                         errmsg("function returning record called in context "
01316                                "that cannot accept type record")));
01317             }
01318 
01319             ret = plperl_hash_to_datum(sv, td);
01320 
01321             /* Release on the result of get_call_result_type is harmless */
01322             ReleaseTupleDesc(td);
01323 
01324             return ret;
01325         }
01326 
01327         /* Reference, but not reference to hash or array ... */
01328         ereport(ERROR,
01329                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01330          errmsg("PL/Perl function must return reference to hash or array")));
01331         return (Datum) 0;       /* shut up compiler */
01332     }
01333     else
01334     {
01335         /* handle a string/number */
01336         Datum       ret;
01337         char       *str = sv2cstr(sv);
01338 
01339         /* did not pass in any typeinfo? look it up */
01340         if (!finfo)
01341         {
01342             _sv_to_datum_finfo(typid, &tmp, &typioparam);
01343             finfo = &tmp;
01344         }
01345 
01346         ret = InputFunctionCall(finfo, str, typioparam, typmod);
01347         pfree(str);
01348 
01349         return ret;
01350     }
01351 }
01352 
01353 /* Convert the perl SV to a string returned by the type output function */
01354 char *
01355 plperl_sv_to_literal(SV *sv, char *fqtypename)
01356 {
01357     Datum       str = CStringGetDatum(fqtypename);
01358     Oid         typid = DirectFunctionCall1(regtypein, str);
01359     Oid         typoutput;
01360     Datum       datum;
01361     bool        typisvarlena,
01362                 isnull;
01363 
01364     if (!OidIsValid(typid))
01365         elog(ERROR, "lookup failed for type %s", fqtypename);
01366 
01367     datum = plperl_sv_to_datum(sv,
01368                                typid, -1,
01369                                NULL, NULL, InvalidOid,
01370                                &isnull);
01371 
01372     if (isnull)
01373         return NULL;
01374 
01375     getTypeOutputInfo(typid,
01376                       &typoutput, &typisvarlena);
01377 
01378     return OidOutputFunctionCall(typoutput, datum);
01379 }
01380 
01381 /*
01382  * Convert PostgreSQL array datum to a perl array reference.
01383  *
01384  * typid is arg's OID, which must be an array type.
01385  */
01386 static SV  *
01387 plperl_ref_from_pg_array(Datum arg, Oid typid)
01388 {
01389     ArrayType  *ar = DatumGetArrayTypeP(arg);
01390     Oid         elementtype = ARR_ELEMTYPE(ar);
01391     int16       typlen;
01392     bool        typbyval;
01393     char        typalign,
01394                 typdelim;
01395     Oid         typioparam;
01396     Oid         typoutputfunc;
01397     int         i,
01398                 nitems,
01399                *dims;
01400     plperl_array_info *info;
01401     SV         *av;
01402     HV         *hv;
01403 
01404     info = palloc(sizeof(plperl_array_info));
01405 
01406     /* get element type information, including output conversion function */
01407     get_type_io_data(elementtype, IOFunc_output,
01408                      &typlen, &typbyval, &typalign,
01409                      &typdelim, &typioparam, &typoutputfunc);
01410 
01411     perm_fmgr_info(typoutputfunc, &info->proc);
01412 
01413     info->elem_is_rowtype = type_is_rowtype(elementtype);
01414 
01415     /* Get the number and bounds of array dimensions */
01416     info->ndims = ARR_NDIM(ar);
01417     dims = ARR_DIMS(ar);
01418 
01419     deconstruct_array(ar, elementtype, typlen, typbyval,
01420                       typalign, &info->elements, &info->nulls,
01421                       &nitems);
01422 
01423     /* Get total number of elements in each dimension */
01424     info->nelems = palloc(sizeof(int) * info->ndims);
01425     info->nelems[0] = nitems;
01426     for (i = 1; i < info->ndims; i++)
01427         info->nelems[i] = info->nelems[i - 1] / dims[i - 1];
01428 
01429     av = split_array(info, 0, nitems, 0);
01430 
01431     hv = newHV();
01432     (void) hv_store(hv, "array", 5, av, 0);
01433     (void) hv_store(hv, "typeoid", 7, newSViv(typid), 0);
01434 
01435     return sv_bless(newRV_noinc((SV *) hv),
01436                     gv_stashpv("PostgreSQL::InServer::ARRAY", 0));
01437 }
01438 
01439 /*
01440  * Recursively form array references from splices of the initial array
01441  */
01442 static SV  *
01443 split_array(plperl_array_info *info, int first, int last, int nest)
01444 {
01445     int         i;
01446     AV         *result;
01447 
01448     /* since this function recurses, it could be driven to stack overflow */
01449     check_stack_depth();
01450 
01451     /*
01452      * Base case, return a reference to a single-dimensional array
01453      */
01454     if (nest >= info->ndims - 1)
01455         return make_array_ref(info, first, last);
01456 
01457     result = newAV();
01458     for (i = first; i < last; i += info->nelems[nest + 1])
01459     {
01460         /* Recursively form references to arrays of lower dimensions */
01461         SV         *ref = split_array(info, i, i + info->nelems[nest + 1], nest + 1);
01462 
01463         av_push(result, ref);
01464     }
01465     return newRV_noinc((SV *) result);
01466 }
01467 
01468 /*
01469  * Create a Perl reference from a one-dimensional C array, converting
01470  * composite type elements to hash references.
01471  */
01472 static SV  *
01473 make_array_ref(plperl_array_info *info, int first, int last)
01474 {
01475     int         i;
01476     AV         *result = newAV();
01477 
01478     for (i = first; i < last; i++)
01479     {
01480         if (info->nulls[i])
01481         {
01482             /*
01483              * We can't use &PL_sv_undef here.  See "AVs, HVs and undefined
01484              * values" in perlguts.
01485              */
01486             av_push(result, newSV(0));
01487         }
01488         else
01489         {
01490             Datum       itemvalue = info->elements[i];
01491 
01492             /* Handle composite type elements */
01493             if (info->elem_is_rowtype)
01494                 av_push(result, plperl_hash_from_datum(itemvalue));
01495             else
01496             {
01497                 char       *val = OutputFunctionCall(&info->proc, itemvalue);
01498 
01499                 av_push(result, cstr2sv(val));
01500             }
01501         }
01502     }
01503     return newRV_noinc((SV *) result);
01504 }
01505 
01506 /* Set up the arguments for a trigger call. */
01507 static SV  *
01508 plperl_trigger_build_args(FunctionCallInfo fcinfo)
01509 {
01510     TriggerData *tdata;
01511     TupleDesc   tupdesc;
01512     int         i;
01513     char       *level;
01514     char       *event;
01515     char       *relid;
01516     char       *when;
01517     HV         *hv;
01518 
01519     hv = newHV();
01520     hv_ksplit(hv, 12);          /* pre-grow the hash */
01521 
01522     tdata = (TriggerData *) fcinfo->context;
01523     tupdesc = tdata->tg_relation->rd_att;
01524 
01525     relid = DatumGetCString(
01526                             DirectFunctionCall1(oidout,
01527                                   ObjectIdGetDatum(tdata->tg_relation->rd_id)
01528                                                 )
01529         );
01530 
01531     hv_store_string(hv, "name", cstr2sv(tdata->tg_trigger->tgname));
01532     hv_store_string(hv, "relid", cstr2sv(relid));
01533 
01534     if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
01535     {
01536         event = "INSERT";
01537         if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
01538             hv_store_string(hv, "new",
01539                             plperl_hash_from_tuple(tdata->tg_trigtuple,
01540                                                    tupdesc));
01541     }
01542     else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
01543     {
01544         event = "DELETE";
01545         if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
01546             hv_store_string(hv, "old",
01547                             plperl_hash_from_tuple(tdata->tg_trigtuple,
01548                                                    tupdesc));
01549     }
01550     else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
01551     {
01552         event = "UPDATE";
01553         if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
01554         {
01555             hv_store_string(hv, "old",
01556                             plperl_hash_from_tuple(tdata->tg_trigtuple,
01557                                                    tupdesc));
01558             hv_store_string(hv, "new",
01559                             plperl_hash_from_tuple(tdata->tg_newtuple,
01560                                                    tupdesc));
01561         }
01562     }
01563     else if (TRIGGER_FIRED_BY_TRUNCATE(tdata->tg_event))
01564         event = "TRUNCATE";
01565     else
01566         event = "UNKNOWN";
01567 
01568     hv_store_string(hv, "event", cstr2sv(event));
01569     hv_store_string(hv, "argc", newSViv(tdata->tg_trigger->tgnargs));
01570 
01571     if (tdata->tg_trigger->tgnargs > 0)
01572     {
01573         AV         *av = newAV();
01574 
01575         av_extend(av, tdata->tg_trigger->tgnargs);
01576         for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
01577             av_push(av, cstr2sv(tdata->tg_trigger->tgargs[i]));
01578         hv_store_string(hv, "args", newRV_noinc((SV *) av));
01579     }
01580 
01581     hv_store_string(hv, "relname",
01582                     cstr2sv(SPI_getrelname(tdata->tg_relation)));
01583 
01584     hv_store_string(hv, "table_name",
01585                     cstr2sv(SPI_getrelname(tdata->tg_relation)));
01586 
01587     hv_store_string(hv, "table_schema",
01588                     cstr2sv(SPI_getnspname(tdata->tg_relation)));
01589 
01590     if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
01591         when = "BEFORE";
01592     else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
01593         when = "AFTER";
01594     else if (TRIGGER_FIRED_INSTEAD(tdata->tg_event))
01595         when = "INSTEAD OF";
01596     else
01597         when = "UNKNOWN";
01598     hv_store_string(hv, "when", cstr2sv(when));
01599 
01600     if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
01601         level = "ROW";
01602     else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
01603         level = "STATEMENT";
01604     else
01605         level = "UNKNOWN";
01606     hv_store_string(hv, "level", cstr2sv(level));
01607 
01608     return newRV_noinc((SV *) hv);
01609 }
01610 
01611 
01612 /* Set up the new tuple returned from a trigger. */
01613 
01614 static HeapTuple
01615 plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
01616 {
01617     SV        **svp;
01618     HV         *hvNew;
01619     HE         *he;
01620     HeapTuple   rtup;
01621     int         slotsused;
01622     int        *modattrs;
01623     Datum      *modvalues;
01624     char       *modnulls;
01625 
01626     TupleDesc   tupdesc;
01627 
01628     tupdesc = tdata->tg_relation->rd_att;
01629 
01630     svp = hv_fetch_string(hvTD, "new");
01631     if (!svp)
01632         ereport(ERROR,
01633                 (errcode(ERRCODE_UNDEFINED_COLUMN),
01634                  errmsg("$_TD->{new} does not exist")));
01635     if (!SvOK(*svp) || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVHV)
01636         ereport(ERROR,
01637                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01638                  errmsg("$_TD->{new} is not a hash reference")));
01639     hvNew = (HV *) SvRV(*svp);
01640 
01641     modattrs = palloc(tupdesc->natts * sizeof(int));
01642     modvalues = palloc(tupdesc->natts * sizeof(Datum));
01643     modnulls = palloc(tupdesc->natts * sizeof(char));
01644     slotsused = 0;
01645 
01646     hv_iterinit(hvNew);
01647     while ((he = hv_iternext(hvNew)))
01648     {
01649         bool        isnull;
01650         char       *key = hek2cstr(he);
01651         SV         *val = HeVAL(he);
01652         int         attn = SPI_fnumber(tupdesc, key);
01653 
01654         if (attn <= 0 || tupdesc->attrs[attn - 1]->attisdropped)
01655             ereport(ERROR,
01656                     (errcode(ERRCODE_UNDEFINED_COLUMN),
01657                      errmsg("Perl hash contains nonexistent column \"%s\"",
01658                             key)));
01659 
01660         modvalues[slotsused] = plperl_sv_to_datum(val,
01661                                           tupdesc->attrs[attn - 1]->atttypid,
01662                                          tupdesc->attrs[attn - 1]->atttypmod,
01663                                                   NULL,
01664                                                   NULL,
01665                                                   InvalidOid,
01666                                                   &isnull);
01667 
01668         modnulls[slotsused] = isnull ? 'n' : ' ';
01669         modattrs[slotsused] = attn;
01670         slotsused++;
01671 
01672         pfree(key);
01673     }
01674     hv_iterinit(hvNew);
01675 
01676     rtup = SPI_modifytuple(tdata->tg_relation, otup, slotsused,
01677                            modattrs, modvalues, modnulls);
01678 
01679     pfree(modattrs);
01680     pfree(modvalues);
01681     pfree(modnulls);
01682 
01683     if (rtup == NULL)
01684         elog(ERROR, "SPI_modifytuple failed: %s",
01685              SPI_result_code_string(SPI_result));
01686 
01687     return rtup;
01688 }
01689 
01690 
01691 /*
01692  * There are three externally visible pieces to plperl: plperl_call_handler,
01693  * plperl_inline_handler, and plperl_validator.
01694  */
01695 
01696 /*
01697  * The call handler is called to run normal functions (including trigger
01698  * functions) that are defined in pg_proc.
01699  */
01700 PG_FUNCTION_INFO_V1(plperl_call_handler);
01701 
01702 Datum
01703 plperl_call_handler(PG_FUNCTION_ARGS)
01704 {
01705     Datum       retval;
01706     plperl_call_data *save_call_data = current_call_data;
01707     plperl_interp_desc *oldinterp = plperl_active_interp;
01708     plperl_call_data this_call_data;
01709 
01710     /* Initialize current-call status record */
01711     MemSet(&this_call_data, 0, sizeof(this_call_data));
01712     this_call_data.fcinfo = fcinfo;
01713 
01714     PG_TRY();
01715     {
01716         current_call_data = &this_call_data;
01717         if (CALLED_AS_TRIGGER(fcinfo))
01718             retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
01719         else
01720             retval = plperl_func_handler(fcinfo);
01721     }
01722     PG_CATCH();
01723     {
01724         if (this_call_data.prodesc)
01725             decrement_prodesc_refcount(this_call_data.prodesc);
01726         current_call_data = save_call_data;
01727         activate_interpreter(oldinterp);
01728         PG_RE_THROW();
01729     }
01730     PG_END_TRY();
01731 
01732     if (this_call_data.prodesc)
01733         decrement_prodesc_refcount(this_call_data.prodesc);
01734     current_call_data = save_call_data;
01735     activate_interpreter(oldinterp);
01736     return retval;
01737 }
01738 
01739 /*
01740  * The inline handler runs anonymous code blocks (DO blocks).
01741  */
01742 PG_FUNCTION_INFO_V1(plperl_inline_handler);
01743 
01744 Datum
01745 plperl_inline_handler(PG_FUNCTION_ARGS)
01746 {
01747     InlineCodeBlock *codeblock = (InlineCodeBlock *) PG_GETARG_POINTER(0);
01748     FunctionCallInfoData fake_fcinfo;
01749     FmgrInfo    flinfo;
01750     plperl_proc_desc desc;
01751     plperl_call_data *save_call_data = current_call_data;
01752     plperl_interp_desc *oldinterp = plperl_active_interp;
01753     plperl_call_data this_call_data;
01754     ErrorContextCallback pl_error_context;
01755 
01756     /* Initialize current-call status record */
01757     MemSet(&this_call_data, 0, sizeof(this_call_data));
01758 
01759     /* Set up a callback for error reporting */
01760     pl_error_context.callback = plperl_inline_callback;
01761     pl_error_context.previous = error_context_stack;
01762     pl_error_context.arg = (Datum) 0;
01763     error_context_stack = &pl_error_context;
01764 
01765     /*
01766      * Set up a fake fcinfo and descriptor with just enough info to satisfy
01767      * plperl_call_perl_func().  In particular note that this sets things up
01768      * with no arguments passed, and a result type of VOID.
01769      */
01770     MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));
01771     MemSet(&flinfo, 0, sizeof(flinfo));
01772     MemSet(&desc, 0, sizeof(desc));
01773     fake_fcinfo.flinfo = &flinfo;
01774     flinfo.fn_oid = InvalidOid;
01775     flinfo.fn_mcxt = CurrentMemoryContext;
01776 
01777     desc.proname = "inline_code_block";
01778     desc.fn_readonly = false;
01779 
01780     desc.lanpltrusted = codeblock->langIsTrusted;
01781 
01782     desc.fn_retistuple = false;
01783     desc.fn_retisset = false;
01784     desc.fn_retisarray = false;
01785     desc.result_oid = VOIDOID;
01786     desc.nargs = 0;
01787     desc.reference = NULL;
01788 
01789     this_call_data.fcinfo = &fake_fcinfo;
01790     this_call_data.prodesc = &desc;
01791     /* we do not bother with refcounting the fake prodesc */
01792 
01793     PG_TRY();
01794     {
01795         SV         *perlret;
01796 
01797         current_call_data = &this_call_data;
01798 
01799         if (SPI_connect() != SPI_OK_CONNECT)
01800             elog(ERROR, "could not connect to SPI manager");
01801 
01802         select_perl_context(desc.lanpltrusted);
01803 
01804         plperl_create_sub(&desc, codeblock->source_text, 0);
01805 
01806         if (!desc.reference)    /* can this happen? */
01807             elog(ERROR, "could not create internal procedure for anonymous code block");
01808 
01809         perlret = plperl_call_perl_func(&desc, &fake_fcinfo);
01810 
01811         SvREFCNT_dec(perlret);
01812 
01813         if (SPI_finish() != SPI_OK_FINISH)
01814             elog(ERROR, "SPI_finish() failed");
01815     }
01816     PG_CATCH();
01817     {
01818         if (desc.reference)
01819             SvREFCNT_dec(desc.reference);
01820         current_call_data = save_call_data;
01821         activate_interpreter(oldinterp);
01822         PG_RE_THROW();
01823     }
01824     PG_END_TRY();
01825 
01826     if (desc.reference)
01827         SvREFCNT_dec(desc.reference);
01828 
01829     current_call_data = save_call_data;
01830     activate_interpreter(oldinterp);
01831 
01832     error_context_stack = pl_error_context.previous;
01833 
01834     PG_RETURN_VOID();
01835 }
01836 
01837 /*
01838  * The validator is called during CREATE FUNCTION to validate the function
01839  * being created/replaced. The precise behavior of the validator may be
01840  * modified by the check_function_bodies GUC.
01841  */
01842 PG_FUNCTION_INFO_V1(plperl_validator);
01843 
01844 Datum
01845 plperl_validator(PG_FUNCTION_ARGS)
01846 {
01847     Oid         funcoid = PG_GETARG_OID(0);
01848     HeapTuple   tuple;
01849     Form_pg_proc proc;
01850     char        functyptype;
01851     int         numargs;
01852     Oid        *argtypes;
01853     char      **argnames;
01854     char       *argmodes;
01855     bool        istrigger = false;
01856     int         i;
01857 
01858     /* Get the new function's pg_proc entry */
01859     tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
01860     if (!HeapTupleIsValid(tuple))
01861         elog(ERROR, "cache lookup failed for function %u", funcoid);
01862     proc = (Form_pg_proc) GETSTRUCT(tuple);
01863 
01864     functyptype = get_typtype(proc->prorettype);
01865 
01866     /* Disallow pseudotype result */
01867     /* except for TRIGGER, RECORD, or VOID */
01868     if (functyptype == TYPTYPE_PSEUDO)
01869     {
01870         /* we assume OPAQUE with no arguments means a trigger */
01871         if (proc->prorettype == TRIGGEROID ||
01872             (proc->prorettype == OPAQUEOID && proc->pronargs == 0))
01873             istrigger = true;
01874         else if (proc->prorettype != RECORDOID &&
01875                  proc->prorettype != VOIDOID)
01876             ereport(ERROR,
01877                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01878                      errmsg("PL/Perl functions cannot return type %s",
01879                             format_type_be(proc->prorettype))));
01880     }
01881 
01882     /* Disallow pseudotypes in arguments (either IN or OUT) */
01883     numargs = get_func_arg_info(tuple,
01884                                 &argtypes, &argnames, &argmodes);
01885     for (i = 0; i < numargs; i++)
01886     {
01887         if (get_typtype(argtypes[i]) == TYPTYPE_PSEUDO &&
01888             argtypes[i] != RECORDOID)
01889             ereport(ERROR,
01890                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01891                      errmsg("PL/Perl functions cannot accept type %s",
01892                             format_type_be(argtypes[i]))));
01893     }
01894 
01895     ReleaseSysCache(tuple);
01896 
01897     /* Postpone body checks if !check_function_bodies */
01898     if (check_function_bodies)
01899     {
01900         (void) compile_plperl_function(funcoid, istrigger);
01901     }
01902 
01903     /* the result of a validator is ignored */
01904     PG_RETURN_VOID();
01905 }
01906 
01907 
01908 /*
01909  * plperlu likewise requires three externally visible functions:
01910  * plperlu_call_handler, plperlu_inline_handler, and plperlu_validator.
01911  * These are currently just aliases that send control to the plperl
01912  * handler functions, and we decide whether a particular function is
01913  * trusted or not by inspecting the actual pg_language tuple.
01914  */
01915 
01916 PG_FUNCTION_INFO_V1(plperlu_call_handler);
01917 
01918 Datum
01919 plperlu_call_handler(PG_FUNCTION_ARGS)
01920 {
01921     return plperl_call_handler(fcinfo);
01922 }
01923 
01924 PG_FUNCTION_INFO_V1(plperlu_inline_handler);
01925 
01926 Datum
01927 plperlu_inline_handler(PG_FUNCTION_ARGS)
01928 {
01929     return plperl_inline_handler(fcinfo);
01930 }
01931 
01932 PG_FUNCTION_INFO_V1(plperlu_validator);
01933 
01934 Datum
01935 plperlu_validator(PG_FUNCTION_ARGS)
01936 {
01937     return plperl_validator(fcinfo);
01938 }
01939 
01940 
01941 /*
01942  * Uses mksafefunc/mkunsafefunc to create a subroutine whose text is
01943  * supplied in s, and returns a reference to it
01944  */
01945 static void
01946 plperl_create_sub(plperl_proc_desc *prodesc, char *s, Oid fn_oid)
01947 {
01948     dSP;
01949     char        subname[NAMEDATALEN + 40];
01950     HV         *pragma_hv = newHV();
01951     SV         *subref = NULL;
01952     int         count;
01953 
01954     sprintf(subname, "%s__%u", prodesc->proname, fn_oid);
01955 
01956     if (plperl_use_strict)
01957         hv_store_string(pragma_hv, "strict", (SV *) newAV());
01958 
01959     ENTER;
01960     SAVETMPS;
01961     PUSHMARK(SP);
01962     EXTEND(SP, 4);
01963     PUSHs(sv_2mortal(cstr2sv(subname)));
01964     PUSHs(sv_2mortal(newRV_noinc((SV *) pragma_hv)));
01965 
01966     /*
01967      * Use 'false' for $prolog in mkfunc, which is kept for compatibility in
01968      * case a module such as PostgreSQL::PLPerl::NYTprof replaces the function
01969      * compiler.
01970      */
01971     PUSHs(&PL_sv_no);
01972     PUSHs(sv_2mortal(cstr2sv(s)));
01973     PUTBACK;
01974 
01975     /*
01976      * G_KEEPERR seems to be needed here, else we don't recognize compile
01977      * errors properly.  Perhaps it's because there's another level of eval
01978      * inside mksafefunc?
01979      */
01980     count = perl_call_pv("PostgreSQL::InServer::mkfunc",
01981                          G_SCALAR | G_EVAL | G_KEEPERR);
01982     SPAGAIN;
01983 
01984     if (count == 1)
01985     {
01986         SV         *sub_rv = (SV *) POPs;
01987 
01988         if (sub_rv && SvROK(sub_rv) && SvTYPE(SvRV(sub_rv)) == SVt_PVCV)
01989         {
01990             subref = newRV_inc(SvRV(sub_rv));
01991         }
01992     }
01993 
01994     PUTBACK;
01995     FREETMPS;
01996     LEAVE;
01997 
01998     if (SvTRUE(ERRSV))
01999         ereport(ERROR,
02000                 (errcode(ERRCODE_SYNTAX_ERROR),
02001                  errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV)))));
02002 
02003     if (!subref)
02004         ereport(ERROR,
02005         (errmsg("didn't get a CODE reference from compiling function \"%s\"",
02006                 prodesc->proname)));
02007 
02008     prodesc->reference = subref;
02009 
02010     return;
02011 }
02012 
02013 
02014 /**********************************************************************
02015  * plperl_init_shared_libs()        -
02016  **********************************************************************/
02017 
02018 static void
02019 plperl_init_shared_libs(pTHX)
02020 {
02021     char       *file = __FILE__;
02022 
02023     newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
02024     newXS("PostgreSQL::InServer::Util::bootstrap",
02025           boot_PostgreSQL__InServer__Util, file);
02026     /* newXS for...::SPI::bootstrap is in select_perl_context() */
02027 }
02028 
02029 
02030 static SV  *
02031 plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
02032 {
02033     dSP;
02034     SV         *retval;
02035     int         i;
02036     int         count;
02037 
02038     ENTER;
02039     SAVETMPS;
02040 
02041     PUSHMARK(SP);
02042     EXTEND(sp, desc->nargs);
02043 
02044     for (i = 0; i < desc->nargs; i++)
02045     {
02046         if (fcinfo->argnull[i])
02047             PUSHs(&PL_sv_undef);
02048         else if (desc->arg_is_rowtype[i])
02049         {
02050             SV         *sv = plperl_hash_from_datum(fcinfo->arg[i]);
02051 
02052             PUSHs(sv_2mortal(sv));
02053         }
02054         else
02055         {
02056             SV         *sv;
02057 
02058             if (OidIsValid(desc->arg_arraytype[i]))
02059                 sv = plperl_ref_from_pg_array(fcinfo->arg[i], desc->arg_arraytype[i]);
02060             else
02061             {
02062                 char       *tmp;
02063 
02064                 tmp = OutputFunctionCall(&(desc->arg_out_func[i]),
02065                                          fcinfo->arg[i]);
02066                 sv = cstr2sv(tmp);
02067                 pfree(tmp);
02068             }
02069 
02070             PUSHs(sv_2mortal(sv));
02071         }
02072     }
02073     PUTBACK;
02074 
02075     /* Do NOT use G_KEEPERR here */
02076     count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);
02077 
02078     SPAGAIN;
02079 
02080     if (count != 1)
02081     {
02082         PUTBACK;
02083         FREETMPS;
02084         LEAVE;
02085         elog(ERROR, "didn't get a return item from function");
02086     }
02087 
02088     if (SvTRUE(ERRSV))
02089     {
02090         (void) POPs;
02091         PUTBACK;
02092         FREETMPS;
02093         LEAVE;
02094         /* XXX need to find a way to assign an errcode here */
02095         ereport(ERROR,
02096                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV)))));
02097     }
02098 
02099     retval = newSVsv(POPs);
02100 
02101     PUTBACK;
02102     FREETMPS;
02103     LEAVE;
02104 
02105     return retval;
02106 }
02107 
02108 
02109 static SV  *
02110 plperl_call_perl_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo,
02111                               SV *td)
02112 {
02113     dSP;
02114     SV         *retval,
02115                *TDsv;
02116     int         i,
02117                 count;
02118     Trigger    *tg_trigger = ((TriggerData *) fcinfo->context)->tg_trigger;
02119 
02120     ENTER;
02121     SAVETMPS;
02122 
02123     TDsv = get_sv("main::_TD", 0);
02124     if (!TDsv)
02125         elog(ERROR, "couldn't fetch $_TD");
02126 
02127     save_item(TDsv);            /* local $_TD */
02128     sv_setsv(TDsv, td);
02129 
02130     PUSHMARK(sp);
02131     EXTEND(sp, tg_trigger->tgnargs);
02132 
02133     for (i = 0; i < tg_trigger->tgnargs; i++)
02134         PUSHs(sv_2mortal(cstr2sv(tg_trigger->tgargs[i])));
02135     PUTBACK;
02136 
02137     /* Do NOT use G_KEEPERR here */
02138     count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);
02139 
02140     SPAGAIN;
02141 
02142     if (count != 1)
02143     {
02144         PUTBACK;
02145         FREETMPS;
02146         LEAVE;
02147         elog(ERROR, "didn't get a return item from trigger function");
02148     }
02149 
02150     if (SvTRUE(ERRSV))
02151     {
02152         (void) POPs;
02153         PUTBACK;
02154         FREETMPS;
02155         LEAVE;
02156         /* XXX need to find a way to assign an errcode here */
02157         ereport(ERROR,
02158                 (errmsg("%s", strip_trailing_ws(sv2cstr(ERRSV)))));
02159     }
02160 
02161     retval = newSVsv(POPs);
02162 
02163     PUTBACK;
02164     FREETMPS;
02165     LEAVE;
02166 
02167     return retval;
02168 }
02169 
02170 
02171 static Datum
02172 plperl_func_handler(PG_FUNCTION_ARGS)
02173 {
02174     plperl_proc_desc *prodesc;
02175     SV         *perlret;
02176     Datum       retval = 0;
02177     ReturnSetInfo *rsi;
02178     ErrorContextCallback pl_error_context;
02179 
02180     if (SPI_connect() != SPI_OK_CONNECT)
02181         elog(ERROR, "could not connect to SPI manager");
02182 
02183     prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, false);
02184     current_call_data->prodesc = prodesc;
02185     increment_prodesc_refcount(prodesc);
02186 
02187     /* Set a callback for error reporting */
02188     pl_error_context.callback = plperl_exec_callback;
02189     pl_error_context.previous = error_context_stack;
02190     pl_error_context.arg = prodesc->proname;
02191     error_context_stack = &pl_error_context;
02192 
02193     rsi = (ReturnSetInfo *) fcinfo->resultinfo;
02194 
02195     if (prodesc->fn_retisset)
02196     {
02197         /* Check context before allowing the call to go through */
02198         if (!rsi || !IsA(rsi, ReturnSetInfo) ||
02199             (rsi->allowedModes & SFRM_Materialize) == 0 ||
02200             rsi->expectedDesc == NULL)
02201             ereport(ERROR,
02202                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02203                      errmsg("set-valued function called in context that "
02204                             "cannot accept a set")));
02205     }
02206 
02207     activate_interpreter(prodesc->interp);
02208 
02209     perlret = plperl_call_perl_func(prodesc, fcinfo);
02210 
02211     /************************************************************
02212      * Disconnect from SPI manager and then create the return
02213      * values datum (if the input function does a palloc for it
02214      * this must not be allocated in the SPI memory context
02215      * because SPI_finish would free it).
02216      ************************************************************/
02217     if (SPI_finish() != SPI_OK_FINISH)
02218         elog(ERROR, "SPI_finish() failed");
02219 
02220     if (prodesc->fn_retisset)
02221     {
02222         SV         *sav;
02223 
02224         /*
02225          * If the Perl function returned an arrayref, we pretend that it
02226          * called return_next() for each element of the array, to handle old
02227          * SRFs that didn't know about return_next(). Any other sort of return
02228          * value is an error, except undef which means return an empty set.
02229          */
02230         sav = get_perl_array_ref(perlret);
02231         if (sav)
02232         {
02233             int         i = 0;
02234             SV        **svp = 0;
02235             AV         *rav = (AV *) SvRV(sav);
02236 
02237             while ((svp = av_fetch(rav, i, FALSE)) != NULL)
02238             {
02239                 plperl_return_next(*svp);
02240                 i++;
02241             }
02242         }
02243         else if (SvOK(perlret))
02244         {
02245             ereport(ERROR,
02246                     (errcode(ERRCODE_DATATYPE_MISMATCH),
02247                      errmsg("set-returning PL/Perl function must return "
02248                             "reference to array or use return_next")));
02249         }
02250 
02251         rsi->returnMode = SFRM_Materialize;
02252         if (current_call_data->tuple_store)
02253         {
02254             rsi->setResult = current_call_data->tuple_store;
02255             rsi->setDesc = current_call_data->ret_tdesc;
02256         }
02257         retval = (Datum) 0;
02258     }
02259     else
02260     {
02261         retval = plperl_sv_to_datum(perlret,
02262                                     prodesc->result_oid,
02263                                     -1,
02264                                     fcinfo,
02265                                     &prodesc->result_in_func,
02266                                     prodesc->result_typioparam,
02267                                     &fcinfo->isnull);
02268 
02269         if (fcinfo->isnull && rsi && IsA(rsi, ReturnSetInfo))
02270             rsi->isDone = ExprEndResult;
02271     }
02272 
02273     /* Restore the previous error callback */
02274     error_context_stack = pl_error_context.previous;
02275 
02276     SvREFCNT_dec(perlret);
02277 
02278     return retval;
02279 }
02280 
02281 
02282 static Datum
02283 plperl_trigger_handler(PG_FUNCTION_ARGS)
02284 {
02285     plperl_proc_desc *prodesc;
02286     SV         *perlret;
02287     Datum       retval;
02288     SV         *svTD;
02289     HV         *hvTD;
02290     ErrorContextCallback pl_error_context;
02291 
02292     /* Connect to SPI manager */
02293     if (SPI_connect() != SPI_OK_CONNECT)
02294         elog(ERROR, "could not connect to SPI manager");
02295 
02296     /* Find or compile the function */
02297     prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, true);
02298     current_call_data->prodesc = prodesc;
02299     increment_prodesc_refcount(prodesc);
02300 
02301     /* Set a callback for error reporting */
02302     pl_error_context.callback = plperl_exec_callback;
02303     pl_error_context.previous = error_context_stack;
02304     pl_error_context.arg = prodesc->proname;
02305     error_context_stack = &pl_error_context;
02306 
02307     activate_interpreter(prodesc->interp);
02308 
02309     svTD = plperl_trigger_build_args(fcinfo);
02310     perlret = plperl_call_perl_trigger_func(prodesc, fcinfo, svTD);
02311     hvTD = (HV *) SvRV(svTD);
02312 
02313     /************************************************************
02314     * Disconnect from SPI manager and then create the return
02315     * values datum (if the input function does a palloc for it
02316     * this must not be allocated in the SPI memory context
02317     * because SPI_finish would free it).
02318     ************************************************************/
02319     if (SPI_finish() != SPI_OK_FINISH)
02320         elog(ERROR, "SPI_finish() failed");
02321 
02322     if (perlret == NULL || !SvOK(perlret))
02323     {
02324         /* undef result means go ahead with original tuple */
02325         TriggerData *trigdata = ((TriggerData *) fcinfo->context);
02326 
02327         if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
02328             retval = (Datum) trigdata->tg_trigtuple;
02329         else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
02330             retval = (Datum) trigdata->tg_newtuple;
02331         else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
02332             retval = (Datum) trigdata->tg_trigtuple;
02333         else if (TRIGGER_FIRED_BY_TRUNCATE(trigdata->tg_event))
02334             retval = (Datum) trigdata->tg_trigtuple;
02335         else
02336             retval = (Datum) 0; /* can this happen? */
02337     }
02338     else
02339     {
02340         HeapTuple   trv;
02341         char       *tmp;
02342 
02343         tmp = sv2cstr(perlret);
02344 
02345         if (pg_strcasecmp(tmp, "SKIP") == 0)
02346             trv = NULL;
02347         else if (pg_strcasecmp(tmp, "MODIFY") == 0)
02348         {
02349             TriggerData *trigdata = (TriggerData *) fcinfo->context;
02350 
02351             if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
02352                 trv = plperl_modify_tuple(hvTD, trigdata,
02353                                           trigdata->tg_trigtuple);
02354             else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
02355                 trv = plperl_modify_tuple(hvTD, trigdata,
02356                                           trigdata->tg_newtuple);
02357             else
02358             {
02359                 ereport(WARNING,
02360                         (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
02361                          errmsg("ignoring modified row in DELETE trigger")));
02362                 trv = NULL;
02363             }
02364         }
02365         else
02366         {
02367             ereport(ERROR,
02368                     (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
02369                   errmsg("result of PL/Perl trigger function must be undef, "
02370                          "\"SKIP\", or \"MODIFY\"")));
02371             trv = NULL;
02372         }
02373         retval = PointerGetDatum(trv);
02374         pfree(tmp);
02375     }
02376 
02377     /* Restore the previous error callback */
02378     error_context_stack = pl_error_context.previous;
02379 
02380     SvREFCNT_dec(svTD);
02381     if (perlret)
02382         SvREFCNT_dec(perlret);
02383 
02384     return retval;
02385 }
02386 
02387 
02388 static bool
02389 validate_plperl_function(plperl_proc_ptr *proc_ptr, HeapTuple procTup)
02390 {
02391     if (proc_ptr && proc_ptr->proc_ptr)
02392     {
02393         plperl_proc_desc *prodesc = proc_ptr->proc_ptr;
02394         bool        uptodate;
02395 
02396         /************************************************************
02397          * If it's present, must check whether it's still up to date.
02398          * This is needed because CREATE OR REPLACE FUNCTION can modify the
02399          * function's pg_proc entry without changing its OID.
02400          ************************************************************/
02401         uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
02402                     ItemPointerEquals(&prodesc->fn_tid, &procTup->t_self));
02403 
02404         if (uptodate)
02405             return true;
02406 
02407         /* Otherwise, unlink the obsoleted entry from the hashtable ... */
02408         proc_ptr->proc_ptr = NULL;
02409         /* ... and release the corresponding refcount, probably deleting it */
02410         decrement_prodesc_refcount(prodesc);
02411     }
02412 
02413     return false;
02414 }
02415 
02416 
02417 static void
02418 free_plperl_function(plperl_proc_desc *prodesc)
02419 {
02420     Assert(prodesc->refcount <= 0);
02421     /* Release CODE reference, if we have one, from the appropriate interp */
02422     if (prodesc->reference)
02423     {
02424         plperl_interp_desc *oldinterp = plperl_active_interp;
02425 
02426         activate_interpreter(prodesc->interp);
02427         SvREFCNT_dec(prodesc->reference);
02428         activate_interpreter(oldinterp);
02429     }
02430     /* Get rid of what we conveniently can of our own structs */
02431     /* (FmgrInfo subsidiary info will get leaked ...) */
02432     if (prodesc->proname)
02433         free(prodesc->proname);
02434     free(prodesc);
02435 }
02436 
02437 
02438 static plperl_proc_desc *
02439 compile_plperl_function(Oid fn_oid, bool is_trigger)
02440 {
02441     HeapTuple   procTup;
02442     Form_pg_proc procStruct;
02443     plperl_proc_key proc_key;
02444     plperl_proc_ptr *proc_ptr;
02445     plperl_proc_desc *prodesc = NULL;
02446     int         i;
02447     plperl_interp_desc *oldinterp = plperl_active_interp;
02448     ErrorContextCallback plperl_error_context;
02449 
02450     /* We'll need the pg_proc tuple in any case... */
02451     procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid));
02452     if (!HeapTupleIsValid(procTup))
02453         elog(ERROR, "cache lookup failed for function %u", fn_oid);
02454     procStruct = (Form_pg_proc) GETSTRUCT(procTup);
02455 
02456     /* Set a callback for reporting compilation errors */
02457     plperl_error_context.callback = plperl_compile_callback;
02458     plperl_error_context.previous = error_context_stack;
02459     plperl_error_context.arg = NameStr(procStruct->proname);
02460     error_context_stack = &plperl_error_context;
02461 
02462     /* Try to find function in plperl_proc_hash */
02463     proc_key.proc_id = fn_oid;
02464     proc_key.is_trigger = is_trigger;
02465     proc_key.user_id = GetUserId();
02466 
02467     proc_ptr = hash_search(plperl_proc_hash, &proc_key,
02468                            HASH_FIND, NULL);
02469 
02470     if (validate_plperl_function(proc_ptr, procTup))
02471         prodesc = proc_ptr->proc_ptr;
02472     else
02473     {
02474         /* If not found or obsolete, maybe it's plperlu */
02475         proc_key.user_id = InvalidOid;
02476         proc_ptr = hash_search(plperl_proc_hash, &proc_key,
02477                                HASH_FIND, NULL);
02478         if (validate_plperl_function(proc_ptr, procTup))
02479             prodesc = proc_ptr->proc_ptr;
02480     }
02481 
02482     /************************************************************
02483      * If we haven't found it in the hashtable, we analyze
02484      * the function's arguments and return type and store
02485      * the in-/out-functions in the prodesc block and create
02486      * a new hashtable entry for it.
02487      *
02488      * Then we load the procedure into the Perl interpreter.
02489      ************************************************************/
02490     if (prodesc == NULL)
02491     {
02492         HeapTuple   langTup;
02493         HeapTuple   typeTup;
02494         Form_pg_language langStruct;
02495         Form_pg_type typeStruct;
02496         Datum       prosrcdatum;
02497         bool        isnull;
02498         char       *proc_source;
02499 
02500         /************************************************************
02501          * Allocate a new procedure description block
02502          ************************************************************/
02503         prodesc = (plperl_proc_desc *) malloc(sizeof(plperl_proc_desc));
02504         if (prodesc == NULL)
02505             ereport(ERROR,
02506                     (errcode(ERRCODE_OUT_OF_MEMORY),
02507                      errmsg("out of memory")));
02508         /* Initialize all fields to 0 so free_plperl_function is safe */
02509         MemSet(prodesc, 0, sizeof(plperl_proc_desc));
02510 
02511         prodesc->proname = strdup(NameStr(procStruct->proname));
02512         if (prodesc->proname == NULL)
02513         {
02514             free_plperl_function(prodesc);
02515             ereport(ERROR,
02516                     (errcode(ERRCODE_OUT_OF_MEMORY),
02517                      errmsg("out of memory")));
02518         }
02519         prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
02520         prodesc->fn_tid = procTup->t_self;
02521 
02522         /* Remember if function is STABLE/IMMUTABLE */
02523         prodesc->fn_readonly =
02524             (procStruct->provolatile != PROVOLATILE_VOLATILE);
02525 
02526         /************************************************************
02527          * Lookup the pg_language tuple by Oid
02528          ************************************************************/
02529         langTup = SearchSysCache1(LANGOID,
02530                                   ObjectIdGetDatum(procStruct->prolang));
02531         if (!HeapTupleIsValid(langTup))
02532         {
02533             free_plperl_function(prodesc);
02534             elog(ERROR, "cache lookup failed for language %u",
02535                  procStruct->prolang);
02536         }
02537         langStruct = (Form_pg_language) GETSTRUCT(langTup);
02538         prodesc->lanpltrusted = langStruct->lanpltrusted;
02539         ReleaseSysCache(langTup);
02540 
02541         /************************************************************
02542          * Get the required information for input conversion of the
02543          * return value.
02544          ************************************************************/
02545         if (!is_trigger)
02546         {
02547             typeTup =
02548                 SearchSysCache1(TYPEOID,
02549                                 ObjectIdGetDatum(procStruct->prorettype));
02550             if (!HeapTupleIsValid(typeTup))
02551             {
02552                 free_plperl_function(prodesc);
02553                 elog(ERROR, "cache lookup failed for type %u",
02554                      procStruct->prorettype);
02555             }
02556             typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
02557 
02558             /* Disallow pseudotype result, except VOID or RECORD */
02559             if (typeStruct->typtype == TYPTYPE_PSEUDO)
02560             {
02561                 if (procStruct->prorettype == VOIDOID ||
02562                     procStruct->prorettype == RECORDOID)
02563                      /* okay */ ;
02564                 else if (procStruct->prorettype == TRIGGEROID)
02565                 {
02566                     free_plperl_function(prodesc);
02567                     ereport(ERROR,
02568                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02569                              errmsg("trigger functions can only be called "
02570                                     "as triggers")));
02571                 }
02572                 else
02573                 {
02574                     free_plperl_function(prodesc);
02575                     ereport(ERROR,
02576                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02577                              errmsg("PL/Perl functions cannot return type %s",
02578                                     format_type_be(procStruct->prorettype))));
02579                 }
02580             }
02581 
02582             prodesc->result_oid = procStruct->prorettype;
02583             prodesc->fn_retisset = procStruct->proretset;
02584             prodesc->fn_retistuple = (procStruct->prorettype == RECORDOID ||
02585                                    typeStruct->typtype == TYPTYPE_COMPOSITE);
02586 
02587             prodesc->fn_retisarray =
02588                 (typeStruct->typlen == -1 && typeStruct->typelem);
02589 
02590             perm_fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
02591             prodesc->result_typioparam = getTypeIOParam(typeTup);
02592 
02593             ReleaseSysCache(typeTup);
02594         }
02595 
02596         /************************************************************
02597          * Get the required information for output conversion
02598          * of all procedure arguments
02599          ************************************************************/
02600         if (!is_trigger)
02601         {
02602             prodesc->nargs = procStruct->pronargs;
02603             for (i = 0; i < prodesc->nargs; i++)
02604             {
02605                 typeTup = SearchSysCache1(TYPEOID,
02606                         ObjectIdGetDatum(procStruct->proargtypes.values[i]));
02607                 if (!HeapTupleIsValid(typeTup))
02608                 {
02609                     free_plperl_function(prodesc);
02610                     elog(ERROR, "cache lookup failed for type %u",
02611                          procStruct->proargtypes.values[i]);
02612                 }
02613                 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
02614 
02615                 /* Disallow pseudotype argument */
02616                 if (typeStruct->typtype == TYPTYPE_PSEUDO &&
02617                     procStruct->proargtypes.values[i] != RECORDOID)
02618                 {
02619                     free_plperl_function(prodesc);
02620                     ereport(ERROR,
02621                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02622                              errmsg("PL/Perl functions cannot accept type %s",
02623                         format_type_be(procStruct->proargtypes.values[i]))));
02624                 }
02625 
02626                 if (typeStruct->typtype == TYPTYPE_COMPOSITE ||
02627                     procStruct->proargtypes.values[i] == RECORDOID)
02628                     prodesc->arg_is_rowtype[i] = true;
02629                 else
02630                 {
02631                     prodesc->arg_is_rowtype[i] = false;
02632                     perm_fmgr_info(typeStruct->typoutput,
02633                                    &(prodesc->arg_out_func[i]));
02634                 }
02635 
02636                 /* Identify array attributes */
02637                 if (typeStruct->typelem != 0 && typeStruct->typlen == -1)
02638                     prodesc->arg_arraytype[i] = procStruct->proargtypes.values[i];
02639                 else
02640                     prodesc->arg_arraytype[i] = InvalidOid;
02641 
02642                 ReleaseSysCache(typeTup);
02643             }
02644         }
02645 
02646         /************************************************************
02647          * create the text of the anonymous subroutine.
02648          * we do not use a named subroutine so that we can call directly
02649          * through the reference.
02650          ************************************************************/
02651         prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
02652                                       Anum_pg_proc_prosrc, &isnull);
02653         if (isnull)
02654             elog(ERROR, "null prosrc");
02655         proc_source = TextDatumGetCString(prosrcdatum);
02656 
02657         /************************************************************
02658          * Create the procedure in the appropriate interpreter
02659          ************************************************************/
02660 
02661         select_perl_context(prodesc->lanpltrusted);
02662 
02663         prodesc->interp = plperl_active_interp;
02664 
02665         plperl_create_sub(prodesc, proc_source, fn_oid);
02666 
02667         activate_interpreter(oldinterp);
02668 
02669         pfree(proc_source);
02670         if (!prodesc->reference)    /* can this happen? */
02671         {
02672             free_plperl_function(prodesc);
02673             elog(ERROR, "could not create PL/Perl internal procedure");
02674         }
02675 
02676         /************************************************************
02677          * OK, link the procedure into the correct hashtable entry
02678          ************************************************************/
02679         proc_key.user_id = prodesc->lanpltrusted ? GetUserId() : InvalidOid;
02680 
02681         proc_ptr = hash_search(plperl_proc_hash, &proc_key,
02682                                HASH_ENTER, NULL);
02683         proc_ptr->proc_ptr = prodesc;
02684         increment_prodesc_refcount(prodesc);
02685     }
02686 
02687     /* restore previous error callback */
02688     error_context_stack = plperl_error_context.previous;
02689 
02690     ReleaseSysCache(procTup);
02691 
02692     return prodesc;
02693 }
02694 
02695 /* Build a hash from a given composite/row datum */
02696 static SV  *
02697 plperl_hash_from_datum(Datum attr)
02698 {
02699     HeapTupleHeader td;
02700     Oid         tupType;
02701     int32       tupTypmod;
02702     TupleDesc   tupdesc;
02703     HeapTupleData tmptup;
02704     SV         *sv;
02705 
02706     td = DatumGetHeapTupleHeader(attr);
02707 
02708     /* Extract rowtype info and find a tupdesc */
02709     tupType = HeapTupleHeaderGetTypeId(td);
02710     tupTypmod = HeapTupleHeaderGetTypMod(td);
02711     tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
02712 
02713     /* Build a temporary HeapTuple control structure */
02714     tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
02715     tmptup.t_data = td;
02716 
02717     sv = plperl_hash_from_tuple(&tmptup, tupdesc);
02718     ReleaseTupleDesc(tupdesc);
02719 
02720     return sv;
02721 }
02722 
02723 /* Build a hash from all attributes of a given tuple. */
02724 static SV  *
02725 plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
02726 {
02727     HV         *hv;
02728     int         i;
02729 
02730     /* since this function recurses, it could be driven to stack overflow */
02731     check_stack_depth();
02732 
02733     hv = newHV();
02734     hv_ksplit(hv, tupdesc->natts);      /* pre-grow the hash */
02735 
02736     for (i = 0; i < tupdesc->natts; i++)
02737     {
02738         Datum       attr;
02739         bool        isnull,
02740                     typisvarlena;
02741         char       *attname;
02742         Oid         typoutput;
02743 
02744         if (tupdesc->attrs[i]->attisdropped)
02745             continue;
02746 
02747         attname = NameStr(tupdesc->attrs[i]->attname);
02748         attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
02749 
02750         if (isnull)
02751         {
02752             /*
02753              * Store (attname => undef) and move on.  Note we can't use
02754              * &PL_sv_undef here; see "AVs, HVs and undefined values" in
02755              * perlguts for an explanation.
02756              */
02757             hv_store_string(hv, attname, newSV(0));
02758             continue;
02759         }
02760 
02761         if (type_is_rowtype(tupdesc->attrs[i]->atttypid))
02762         {
02763             SV         *sv = plperl_hash_from_datum(attr);
02764 
02765             hv_store_string(hv, attname, sv);
02766         }
02767         else
02768         {
02769             SV         *sv;
02770 
02771             if (OidIsValid(get_base_element_type(tupdesc->attrs[i]->atttypid)))
02772                 sv = plperl_ref_from_pg_array(attr, tupdesc->attrs[i]->atttypid);
02773             else
02774             {
02775                 char       *outputstr;
02776 
02777                 /* XXX should have a way to cache these lookups */
02778                 getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
02779                                   &typoutput, &typisvarlena);
02780 
02781                 outputstr = OidOutputFunctionCall(typoutput, attr);
02782                 sv = cstr2sv(outputstr);
02783                 pfree(outputstr);
02784             }
02785 
02786             hv_store_string(hv, attname, sv);
02787         }
02788     }
02789     return newRV_noinc((SV *) hv);
02790 }
02791 
02792 
02793 static void
02794 check_spi_usage_allowed()
02795 {
02796     /* see comment in plperl_fini() */
02797     if (plperl_ending)
02798     {
02799         /* simple croak as we don't want to involve PostgreSQL code */
02800         croak("SPI functions can not be used in END blocks");
02801     }
02802 }
02803 
02804 
02805 HV *
02806 plperl_spi_exec(char *query, int limit)
02807 {
02808     HV         *ret_hv;
02809 
02810     /*
02811      * Execute the query inside a sub-transaction, so we can cope with errors
02812      * sanely
02813      */
02814     MemoryContext oldcontext = CurrentMemoryContext;
02815     ResourceOwner oldowner = CurrentResourceOwner;
02816 
02817     check_spi_usage_allowed();
02818 
02819     BeginInternalSubTransaction(NULL);
02820     /* Want to run inside function's memory context */
02821     MemoryContextSwitchTo(oldcontext);
02822 
02823     PG_TRY();
02824     {
02825         int         spi_rv;
02826 
02827         pg_verifymbstr(query, strlen(query), false);
02828 
02829         spi_rv = SPI_execute(query, current_call_data->prodesc->fn_readonly,
02830                              limit);
02831         ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed,
02832                                                  spi_rv);
02833 
02834         /* Commit the inner transaction, return to outer xact context */
02835         ReleaseCurrentSubTransaction();
02836         MemoryContextSwitchTo(oldcontext);
02837         CurrentResourceOwner = oldowner;
02838 
02839         /*
02840          * AtEOSubXact_SPI() should not have popped any SPI context, but just
02841          * in case it did, make sure we remain connected.
02842          */
02843         SPI_restore_connection();
02844     }
02845     PG_CATCH();
02846     {
02847         ErrorData  *edata;
02848 
02849         /* Save error info */
02850         MemoryContextSwitchTo(oldcontext);
02851         edata = CopyErrorData();
02852         FlushErrorState();
02853 
02854         /* Abort the inner transaction */
02855         RollbackAndReleaseCurrentSubTransaction();
02856         MemoryContextSwitchTo(oldcontext);
02857         CurrentResourceOwner = oldowner;
02858 
02859         /*
02860          * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
02861          * have left us in a disconnected state.  We need this hack to return
02862          * to connected state.
02863          */
02864         SPI_restore_connection();
02865 
02866         /* Punt the error to Perl */
02867         croak("%s", edata->message);
02868 
02869         /* Can't get here, but keep compiler quiet */
02870         return NULL;
02871     }
02872     PG_END_TRY();
02873 
02874     return ret_hv;
02875 }
02876 
02877 
02878 static HV  *
02879 plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed,
02880                                 int status)
02881 {
02882     HV         *result;
02883 
02884     check_spi_usage_allowed();
02885 
02886     result = newHV();
02887 
02888     hv_store_string(result, "status",
02889                     cstr2sv(SPI_result_code_string(status)));
02890     hv_store_string(result, "processed",
02891                     newSViv(processed));
02892 
02893     if (status > 0 && tuptable)
02894     {
02895         AV         *rows;
02896         SV         *row;
02897         int         i;
02898 
02899         rows = newAV();
02900         av_extend(rows, processed);
02901         for (i = 0; i < processed; i++)
02902         {
02903             row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc);
02904             av_push(rows, row);
02905         }
02906         hv_store_string(result, "rows",
02907                         newRV_noinc((SV *) rows));
02908     }
02909 
02910     SPI_freetuptable(tuptable);
02911 
02912     return result;
02913 }
02914 
02915 
02916 /*
02917  * Note: plperl_return_next is called both in Postgres and Perl contexts.
02918  * We report any errors in Postgres fashion (via ereport).  If called in
02919  * Perl context, it is SPI.xs's responsibility to catch the error and
02920  * convert to a Perl error.  We assume (perhaps without adequate justification)
02921  * that we need not abort the current transaction if the Perl code traps the
02922  * error.
02923  */
02924 void
02925 plperl_return_next(SV *sv)
02926 {
02927     plperl_proc_desc *prodesc;
02928     FunctionCallInfo fcinfo;
02929     ReturnSetInfo *rsi;
02930     MemoryContext old_cxt;
02931 
02932     if (!sv)
02933         return;
02934 
02935     prodesc = current_call_data->prodesc;
02936     fcinfo = current_call_data->fcinfo;
02937     rsi = (ReturnSetInfo *) fcinfo->resultinfo;
02938 
02939     if (!prodesc->fn_retisset)
02940         ereport(ERROR,
02941                 (errcode(ERRCODE_SYNTAX_ERROR),
02942                  errmsg("cannot use return_next in a non-SETOF function")));
02943 
02944     if (!current_call_data->ret_tdesc)
02945     {
02946         TupleDesc   tupdesc;
02947 
02948         Assert(!current_call_data->tuple_store);
02949 
02950         /*
02951          * This is the first call to return_next in the current PL/Perl
02952          * function call, so memoize some lookups
02953          */
02954         if (prodesc->fn_retistuple)
02955             (void) get_call_result_type(fcinfo, NULL, &tupdesc);
02956         else
02957             tupdesc = rsi->expectedDesc;
02958 
02959         /*
02960          * Make sure the tuple_store and ret_tdesc are sufficiently
02961          * long-lived.
02962          */
02963         old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
02964 
02965         current_call_data->ret_tdesc = CreateTupleDescCopy(tupdesc);
02966         current_call_data->tuple_store =
02967             tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
02968                                   false, work_mem);
02969 
02970         MemoryContextSwitchTo(old_cxt);
02971     }
02972 
02973     /*
02974      * Producing the tuple we want to return requires making plenty of
02975      * palloc() allocations that are not cleaned up. Since this function can
02976      * be called many times before the current memory context is reset, we
02977      * need to do those allocations in a temporary context.
02978      */
02979     if (!current_call_data->tmp_cxt)
02980     {
02981         current_call_data->tmp_cxt =
02982             AllocSetContextCreate(CurrentMemoryContext,
02983                                   "PL/Perl return_next temporary cxt",
02984                                   ALLOCSET_DEFAULT_MINSIZE,
02985                                   ALLOCSET_DEFAULT_INITSIZE,
02986                                   ALLOCSET_DEFAULT_MAXSIZE);
02987     }
02988 
02989     old_cxt = MemoryContextSwitchTo(current_call_data->tmp_cxt);
02990 
02991     if (prodesc->fn_retistuple)
02992     {
02993         HeapTuple   tuple;
02994 
02995         if (!(SvOK(sv) && SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV))
02996             ereport(ERROR,
02997                     (errcode(ERRCODE_DATATYPE_MISMATCH),
02998                      errmsg("SETOF-composite-returning PL/Perl function "
02999                             "must call return_next with reference to hash")));
03000 
03001         tuple = plperl_build_tuple_result((HV *) SvRV(sv),
03002                                           current_call_data->ret_tdesc);
03003         tuplestore_puttuple(current_call_data->tuple_store, tuple);
03004     }
03005     else
03006     {
03007         Datum       ret;
03008         bool        isNull;
03009 
03010         ret = plperl_sv_to_datum(sv,
03011                                  prodesc->result_oid,
03012                                  -1,
03013                                  fcinfo,
03014                                  &prodesc->result_in_func,
03015                                  prodesc->result_typioparam,
03016                                  &isNull);
03017 
03018         tuplestore_putvalues(current_call_data->tuple_store,
03019                              current_call_data->ret_tdesc,
03020                              &ret, &isNull);
03021     }
03022 
03023     MemoryContextSwitchTo(old_cxt);
03024     MemoryContextReset(current_call_data->tmp_cxt);
03025 }
03026 
03027 
03028 SV *
03029 plperl_spi_query(char *query)
03030 {
03031     SV         *cursor;
03032 
03033     /*
03034      * Execute the query inside a sub-transaction, so we can cope with errors
03035      * sanely
03036      */
03037     MemoryContext oldcontext = CurrentMemoryContext;
03038     ResourceOwner oldowner = CurrentResourceOwner;
03039 
03040     check_spi_usage_allowed();
03041 
03042     BeginInternalSubTransaction(NULL);
03043     /* Want to run inside function's memory context */
03044     MemoryContextSwitchTo(oldcontext);
03045 
03046     PG_TRY();
03047     {
03048         SPIPlanPtr  plan;
03049         Portal      portal;
03050 
03051         /* Make sure the query is validly encoded */
03052         pg_verifymbstr(query, strlen(query), false);
03053 
03054         /* Create a cursor for the query */
03055         plan = SPI_prepare(query, 0, NULL);
03056         if (plan == NULL)
03057             elog(ERROR, "SPI_prepare() failed:%s",
03058                  SPI_result_code_string(SPI_result));
03059 
03060         portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
03061         SPI_freeplan(plan);
03062         if (portal == NULL)
03063             elog(ERROR, "SPI_cursor_open() failed:%s",
03064                  SPI_result_code_string(SPI_result));
03065         cursor = cstr2sv(portal->name);
03066 
03067         /* Commit the inner transaction, return to outer xact context */
03068         ReleaseCurrentSubTransaction();
03069         MemoryContextSwitchTo(oldcontext);
03070         CurrentResourceOwner = oldowner;
03071 
03072         /*
03073          * AtEOSubXact_SPI() should not have popped any SPI context, but just
03074          * in case it did, make sure we remain connected.
03075          */
03076         SPI_restore_connection();
03077     }
03078     PG_CATCH();
03079     {
03080         ErrorData  *edata;
03081 
03082         /* Save error info */
03083         MemoryContextSwitchTo(oldcontext);
03084         edata = CopyErrorData();
03085         FlushErrorState();
03086 
03087         /* Abort the inner transaction */
03088         RollbackAndReleaseCurrentSubTransaction();
03089         MemoryContextSwitchTo(oldcontext);
03090         CurrentResourceOwner = oldowner;
03091 
03092         /*
03093          * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
03094          * have left us in a disconnected state.  We need this hack to return
03095          * to connected state.
03096          */
03097         SPI_restore_connection();
03098 
03099         /* Punt the error to Perl */
03100         croak("%s", edata->message);
03101 
03102         /* Can't get here, but keep compiler quiet */
03103         return NULL;
03104     }
03105     PG_END_TRY();
03106 
03107     return cursor;
03108 }
03109 
03110 
03111 SV *
03112 plperl_spi_fetchrow(char *cursor)
03113 {
03114     SV         *row;
03115 
03116     /*
03117      * Execute the FETCH inside a sub-transaction, so we can cope with errors
03118      * sanely
03119      */
03120     MemoryContext oldcontext = CurrentMemoryContext;
03121     ResourceOwner oldowner = CurrentResourceOwner;
03122 
03123     check_spi_usage_allowed();
03124 
03125     BeginInternalSubTransaction(NULL);
03126     /* Want to run inside function's memory context */
03127     MemoryContextSwitchTo(oldcontext);
03128 
03129     PG_TRY();
03130     {
03131         Portal      p = SPI_cursor_find(cursor);
03132 
03133         if (!p)
03134         {
03135             row = &PL_sv_undef;
03136         }
03137         else
03138         {
03139             SPI_cursor_fetch(p, true, 1);
03140             if (SPI_processed == 0)
03141             {
03142                 SPI_cursor_close(p);
03143                 row = &PL_sv_undef;
03144             }
03145             else
03146             {
03147                 row = plperl_hash_from_tuple(SPI_tuptable->vals[0],
03148                                              SPI_tuptable->tupdesc);
03149             }
03150             SPI_freetuptable(SPI_tuptable);
03151         }
03152 
03153         /* Commit the inner transaction, return to outer xact context */
03154         ReleaseCurrentSubTransaction();
03155         MemoryContextSwitchTo(oldcontext);
03156         CurrentResourceOwner = oldowner;
03157 
03158         /*
03159          * AtEOSubXact_SPI() should not have popped any SPI context, but just
03160          * in case it did, make sure we remain connected.
03161          */
03162         SPI_restore_connection();
03163     }
03164     PG_CATCH();
03165     {
03166         ErrorData  *edata;
03167 
03168         /* Save error info */
03169         MemoryContextSwitchTo(oldcontext);
03170         edata = CopyErrorData();
03171         FlushErrorState();
03172 
03173         /* Abort the inner transaction */
03174         RollbackAndReleaseCurrentSubTransaction();
03175         MemoryContextSwitchTo(oldcontext);
03176         CurrentResourceOwner = oldowner;
03177 
03178         /*
03179          * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
03180          * have left us in a disconnected state.  We need this hack to return
03181          * to connected state.
03182          */
03183         SPI_restore_connection();
03184 
03185         /* Punt the error to Perl */
03186         croak("%s", edata->message);
03187 
03188         /* Can't get here, but keep compiler quiet */
03189         return NULL;
03190     }
03191     PG_END_TRY();
03192 
03193     return row;
03194 }
03195 
03196 void
03197 plperl_spi_cursor_close(char *cursor)
03198 {
03199     Portal      p;
03200 
03201     check_spi_usage_allowed();
03202 
03203     p = SPI_cursor_find(cursor);
03204 
03205     if (p)
03206         SPI_cursor_close(p);
03207 }
03208 
03209 SV *
03210 plperl_spi_prepare(char *query, int argc, SV **argv)
03211 {
03212     volatile SPIPlanPtr plan = NULL;
03213     volatile MemoryContext plan_cxt = NULL;
03214     plperl_query_desc *volatile qdesc = NULL;
03215     plperl_query_entry *volatile hash_entry = NULL;
03216     MemoryContext oldcontext = CurrentMemoryContext;
03217     ResourceOwner oldowner = CurrentResourceOwner;
03218     MemoryContext work_cxt;
03219     bool        found;
03220     int         i;
03221 
03222     check_spi_usage_allowed();
03223 
03224     BeginInternalSubTransaction(NULL);
03225     MemoryContextSwitchTo(oldcontext);
03226 
03227     PG_TRY();
03228     {
03229         CHECK_FOR_INTERRUPTS();
03230 
03231         /************************************************************
03232          * Allocate the new querydesc structure
03233          *
03234          * The qdesc struct, as well as all its subsidiary data, lives in its
03235          * plan_cxt.  But note that the SPIPlan does not.
03236          ************************************************************/
03237         plan_cxt = AllocSetContextCreate(TopMemoryContext,
03238                                          "PL/Perl spi_prepare query",
03239                                          ALLOCSET_SMALL_MINSIZE,
03240                                          ALLOCSET_SMALL_INITSIZE,
03241                                          ALLOCSET_SMALL_MAXSIZE);
03242         MemoryContextSwitchTo(plan_cxt);
03243         qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc));
03244         snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
03245         qdesc->plan_cxt = plan_cxt;
03246         qdesc->nargs = argc;
03247         qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid));
03248         qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo));
03249         qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid));
03250         MemoryContextSwitchTo(oldcontext);
03251 
03252         /************************************************************
03253          * Do the following work in a short-lived context so that we don't
03254          * leak a lot of memory in the PL/Perl function's SPI Proc context.
03255          ************************************************************/
03256         work_cxt = AllocSetContextCreate(CurrentMemoryContext,
03257                                          "PL/Perl spi_prepare workspace",
03258                                          ALLOCSET_DEFAULT_MINSIZE,
03259                                          ALLOCSET_DEFAULT_INITSIZE,
03260                                          ALLOCSET_DEFAULT_MAXSIZE);
03261         MemoryContextSwitchTo(work_cxt);
03262 
03263         /************************************************************
03264          * Resolve argument type names and then look them up by oid
03265          * in the system cache, and remember the required information
03266          * for input conversion.
03267          ************************************************************/
03268         for (i = 0; i < argc; i++)
03269         {
03270             Oid         typId,
03271                         typInput,
03272                         typIOParam;
03273             int32       typmod;
03274             char       *typstr;
03275 
03276             typstr = sv2cstr(argv[i]);
03277             parseTypeString(typstr, &typId, &typmod);
03278             pfree(typstr);
03279 
03280             getTypeInputInfo(typId, &typInput, &typIOParam);
03281 
03282             qdesc->argtypes[i] = typId;
03283             fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
03284             qdesc->argtypioparams[i] = typIOParam;
03285         }
03286 
03287         /* Make sure the query is validly encoded */
03288         pg_verifymbstr(query, strlen(query), false);
03289 
03290         /************************************************************
03291          * Prepare the plan and check for errors
03292          ************************************************************/
03293         plan = SPI_prepare(query, argc, qdesc->argtypes);
03294 
03295         if (plan == NULL)
03296             elog(ERROR, "SPI_prepare() failed:%s",
03297                  SPI_result_code_string(SPI_result));
03298 
03299         /************************************************************
03300          * Save the plan into permanent memory (right now it's in the
03301          * SPI procCxt, which will go away at function end).
03302          ************************************************************/
03303         if (SPI_keepplan(plan))
03304             elog(ERROR, "SPI_keepplan() failed");
03305         qdesc->plan = plan;
03306 
03307         /************************************************************
03308          * Insert a hashtable entry for the plan.
03309          ************************************************************/
03310         hash_entry = hash_search(plperl_active_interp->query_hash,
03311                                  qdesc->qname,
03312                                  HASH_ENTER, &found);
03313         hash_entry->query_data = qdesc;
03314 
03315         /* Get rid of workspace */
03316         MemoryContextDelete(work_cxt);
03317 
03318         /* Commit the inner transaction, return to outer xact context */
03319         ReleaseCurrentSubTransaction();
03320         MemoryContextSwitchTo(oldcontext);
03321         CurrentResourceOwner = oldowner;
03322 
03323         /*
03324          * AtEOSubXact_SPI() should not have popped any SPI context, but just
03325          * in case it did, make sure we remain connected.
03326          */
03327         SPI_restore_connection();
03328     }
03329     PG_CATCH();
03330     {
03331         ErrorData  *edata;
03332 
03333         /* Save error info */
03334         MemoryContextSwitchTo(oldcontext);
03335         edata = CopyErrorData();
03336         FlushErrorState();
03337 
03338         /* Drop anything we managed to allocate */
03339         if (hash_entry)
03340             hash_search(plperl_active_interp->query_hash,
03341                         qdesc->qname,
03342                         HASH_REMOVE, NULL);
03343         if (plan_cxt)
03344             MemoryContextDelete(plan_cxt);
03345         if (plan)
03346             SPI_freeplan(plan);
03347 
03348         /* Abort the inner transaction */
03349         RollbackAndReleaseCurrentSubTransaction();
03350         MemoryContextSwitchTo(oldcontext);
03351         CurrentResourceOwner = oldowner;
03352 
03353         /*
03354          * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
03355          * have left us in a disconnected state.  We need this hack to return
03356          * to connected state.
03357          */
03358         SPI_restore_connection();
03359 
03360         /* Punt the error to Perl */
03361         croak("%s", edata->message);
03362 
03363         /* Can't get here, but keep compiler quiet */
03364         return NULL;
03365     }
03366     PG_END_TRY();
03367 
03368     /************************************************************
03369      * Return the query's hash key to the caller.
03370      ************************************************************/
03371     return cstr2sv(qdesc->qname);
03372 }
03373 
03374 HV *
03375 plperl_spi_exec_prepared(char *query, HV *attr, int argc, SV **argv)
03376 {
03377     HV         *ret_hv;
03378     SV        **sv;
03379     int         i,
03380                 limit,
03381                 spi_rv;
03382     char       *nulls;
03383     Datum      *argvalues;
03384     plperl_query_desc *qdesc;
03385     plperl_query_entry *hash_entry;
03386 
03387     /*
03388      * Execute the query inside a sub-transaction, so we can cope with errors
03389      * sanely
03390      */
03391     MemoryContext oldcontext = CurrentMemoryContext;
03392     ResourceOwner oldowner = CurrentResourceOwner;
03393 
03394     check_spi_usage_allowed();
03395 
03396     BeginInternalSubTransaction(NULL);
03397     /* Want to run inside function's memory context */
03398     MemoryContextSwitchTo(oldcontext);
03399 
03400     PG_TRY();
03401     {
03402         /************************************************************
03403          * Fetch the saved plan descriptor, see if it's o.k.
03404          ************************************************************/
03405         hash_entry = hash_search(plperl_active_interp->query_hash, query,
03406                                  HASH_FIND, NULL);
03407         if (hash_entry == NULL)
03408             elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
03409 
03410         qdesc = hash_entry->query_data;
03411         if (qdesc == NULL)
03412             elog(ERROR, "spi_exec_prepared: plperl query_hash value vanished");
03413 
03414         if (qdesc->nargs != argc)
03415             elog(ERROR, "spi_exec_prepared: expected %d argument(s), %d passed",
03416                  qdesc->nargs, argc);
03417 
03418         /************************************************************
03419          * Parse eventual attributes
03420          ************************************************************/
03421         limit = 0;
03422         if (attr != NULL)
03423         {
03424             sv = hv_fetch_string(attr, "limit");
03425             if (sv && *sv && SvIOK(*sv))
03426                 limit = SvIV(*sv);
03427         }
03428         /************************************************************
03429          * Set up arguments
03430          ************************************************************/
03431         if (argc > 0)
03432         {
03433             nulls = (char *) palloc(argc);
03434             argvalues = (Datum *) palloc(argc * sizeof(Datum));
03435         }
03436         else
03437         {
03438             nulls = NULL;
03439             argvalues = NULL;
03440         }
03441 
03442         for (i = 0; i < argc; i++)
03443         {
03444             bool        isnull;
03445 
03446             argvalues[i] = plperl_sv_to_datum(argv[i],
03447                                               qdesc->argtypes[i],
03448                                               -1,
03449                                               NULL,
03450                                               &qdesc->arginfuncs[i],
03451                                               qdesc->argtypioparams[i],
03452                                               &isnull);
03453             nulls[i] = isnull ? 'n' : ' ';
03454         }
03455 
03456         /************************************************************
03457          * go
03458          ************************************************************/
03459         spi_rv = SPI_execute_plan(qdesc->plan, argvalues, nulls,
03460                              current_call_data->prodesc->fn_readonly, limit);
03461         ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed,
03462                                                  spi_rv);
03463         if (argc > 0)
03464         {
03465             pfree(argvalues);
03466             pfree(nulls);
03467         }
03468 
03469         /* Commit the inner transaction, return to outer xact context */
03470         ReleaseCurrentSubTransaction();
03471         MemoryContextSwitchTo(oldcontext);
03472         CurrentResourceOwner = oldowner;
03473 
03474         /*
03475          * AtEOSubXact_SPI() should not have popped any SPI context, but just
03476          * in case it did, make sure we remain connected.
03477          */
03478         SPI_restore_connection();
03479     }
03480     PG_CATCH();
03481     {
03482         ErrorData  *edata;
03483 
03484         /* Save error info */
03485         MemoryContextSwitchTo(oldcontext);
03486         edata = CopyErrorData();
03487         FlushErrorState();
03488 
03489         /* Abort the inner transaction */
03490         RollbackAndReleaseCurrentSubTransaction();
03491         MemoryContextSwitchTo(oldcontext);
03492         CurrentResourceOwner = oldowner;
03493 
03494         /*
03495          * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
03496          * have left us in a disconnected state.  We need this hack to return
03497          * to connected state.
03498          */
03499         SPI_restore_connection();
03500 
03501         /* Punt the error to Perl */
03502         croak("%s", edata->message);
03503 
03504         /* Can't get here, but keep compiler quiet */
03505         return NULL;
03506     }
03507     PG_END_TRY();
03508 
03509     return ret_hv;
03510 }
03511 
03512 SV *
03513 plperl_spi_query_prepared(char *query, int argc, SV **argv)
03514 {
03515     int         i;
03516     char       *nulls;
03517     Datum      *argvalues;
03518     plperl_query_desc *qdesc;
03519     plperl_query_entry *hash_entry;
03520     SV         *cursor;
03521     Portal      portal = NULL;
03522 
03523     /*
03524      * Execute the query inside a sub-transaction, so we can cope with errors
03525      * sanely
03526      */
03527     MemoryContext oldcontext = CurrentMemoryContext;
03528     ResourceOwner oldowner = CurrentResourceOwner;
03529 
03530     check_spi_usage_allowed();
03531 
03532     BeginInternalSubTransaction(NULL);
03533     /* Want to run inside function's memory context */
03534     MemoryContextSwitchTo(oldcontext);
03535 
03536     PG_TRY();
03537     {
03538         /************************************************************
03539          * Fetch the saved plan descriptor, see if it's o.k.
03540          ************************************************************/
03541         hash_entry = hash_search(plperl_active_interp->query_hash, query,
03542                                  HASH_FIND, NULL);
03543         if (hash_entry == NULL)
03544             elog(ERROR, "spi_query_prepared: Invalid prepared query passed");
03545 
03546         qdesc = hash_entry->query_data;
03547         if (qdesc == NULL)
03548             elog(ERROR, "spi_query_prepared: plperl query_hash value vanished");
03549 
03550         if (qdesc->nargs != argc)
03551             elog(ERROR, "spi_query_prepared: expected %d argument(s), %d passed",
03552                  qdesc->nargs, argc);
03553 
03554         /************************************************************
03555          * Set up arguments
03556          ************************************************************/
03557         if (argc > 0)
03558         {
03559             nulls = (char *) palloc(argc);
03560             argvalues = (Datum *) palloc(argc * sizeof(Datum));
03561         }
03562         else
03563         {
03564             nulls = NULL;
03565             argvalues = NULL;
03566         }
03567 
03568         for (i = 0; i < argc; i++)
03569         {
03570             bool        isnull;
03571 
03572             argvalues[i] = plperl_sv_to_datum(argv[i],
03573                                               qdesc->argtypes[i],
03574                                               -1,
03575                                               NULL,
03576                                               &qdesc->arginfuncs[i],
03577                                               qdesc->argtypioparams[i],
03578                                               &isnull);
03579             nulls[i] = isnull ? 'n' : ' ';
03580         }
03581 
03582         /************************************************************
03583          * go
03584          ************************************************************/
03585         portal = SPI_cursor_open(NULL, qdesc->plan, argvalues, nulls,
03586                                  current_call_data->prodesc->fn_readonly);
03587         if (argc > 0)
03588         {
03589             pfree(argvalues);
03590             pfree(nulls);
03591         }
03592         if (portal == NULL)
03593             elog(ERROR, "SPI_cursor_open() failed:%s",
03594                  SPI_result_code_string(SPI_result));
03595 
03596         cursor = cstr2sv(portal->name);
03597 
03598         /* Commit the inner transaction, return to outer xact context */
03599         ReleaseCurrentSubTransaction();
03600         MemoryContextSwitchTo(oldcontext);
03601         CurrentResourceOwner = oldowner;
03602 
03603         /*
03604          * AtEOSubXact_SPI() should not have popped any SPI context, but just
03605          * in case it did, make sure we remain connected.
03606          */
03607         SPI_restore_connection();
03608     }
03609     PG_CATCH();
03610     {
03611         ErrorData  *edata;
03612 
03613         /* Save error info */
03614         MemoryContextSwitchTo(oldcontext);
03615         edata = CopyErrorData();
03616         FlushErrorState();
03617 
03618         /* Abort the inner transaction */
03619         RollbackAndReleaseCurrentSubTransaction();
03620         MemoryContextSwitchTo(oldcontext);
03621         CurrentResourceOwner = oldowner;
03622 
03623         /*
03624          * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
03625          * have left us in a disconnected state.  We need this hack to return
03626          * to connected state.
03627          */
03628         SPI_restore_connection();
03629 
03630         /* Punt the error to Perl */
03631         croak("%s", edata->message);
03632 
03633         /* Can't get here, but keep compiler quiet */
03634         return NULL;
03635     }
03636     PG_END_TRY();
03637 
03638     return cursor;
03639 }
03640 
03641 void
03642 plperl_spi_freeplan(char *query)
03643 {
03644     SPIPlanPtr  plan;
03645     plperl_query_desc *qdesc;
03646     plperl_query_entry *hash_entry;
03647 
03648     check_spi_usage_allowed();
03649 
03650     hash_entry = hash_search(plperl_active_interp->query_hash, query,
03651                              HASH_FIND, NULL);
03652     if (hash_entry == NULL)
03653         elog(ERROR, "spi_freeplan: Invalid prepared query passed");
03654 
03655     qdesc = hash_entry->query_data;
03656     if (qdesc == NULL)
03657         elog(ERROR, "spi_freeplan: plperl query_hash value vanished");
03658     plan = qdesc->plan;
03659 
03660     /*
03661      * free all memory before SPI_freeplan, so if it dies, nothing will be
03662      * left over
03663      */
03664     hash_search(plperl_active_interp->query_hash, query,
03665                 HASH_REMOVE, NULL);
03666 
03667     MemoryContextDelete(qdesc->plan_cxt);
03668 
03669     SPI_freeplan(plan);
03670 }
03671 
03672 /*
03673  * Store an SV into a hash table under a key that is a string assumed to be
03674  * in the current database's encoding.
03675  */
03676 static SV **
03677 hv_store_string(HV *hv, const char *key, SV *val)
03678 {
03679     int32       hlen;
03680     char       *hkey;
03681     SV        **ret;
03682 
03683     hkey = (char *)
03684         pg_do_encoding_conversion((unsigned char *) key, strlen(key),
03685                                   GetDatabaseEncoding(), PG_UTF8);
03686 
03687     /*
03688      * This seems nowhere documented, but under Perl 5.8.0 and up, hv_store()
03689      * recognizes a negative klen parameter as meaning a UTF-8 encoded key. It
03690      * does not appear that hashes track UTF-8-ness of keys at all in Perl
03691      * 5.6.
03692      */
03693     hlen = -(int) strlen(hkey);
03694     ret = hv_store(hv, hkey, hlen, val, 0);
03695 
03696     if (hkey != key)
03697         pfree(hkey);
03698 
03699     return ret;
03700 }
03701 
03702 /*
03703  * Fetch an SV from a hash table under a key that is a string assumed to be
03704  * in the current database's encoding.
03705  */
03706 static SV **
03707 hv_fetch_string(HV *hv, const char *key)
03708 {
03709     int32       hlen;
03710     char       *hkey;
03711     SV        **ret;
03712 
03713     hkey = (char *)
03714         pg_do_encoding_conversion((unsigned char *) key, strlen(key),
03715                                   GetDatabaseEncoding(), PG_UTF8);
03716 
03717     /* See notes in hv_store_string */
03718     hlen = -(int) strlen(hkey);
03719     ret = hv_fetch(hv, hkey, hlen, 0);
03720 
03721     if (hkey != key)
03722         pfree(hkey);
03723 
03724     return ret;
03725 }
03726 
03727 /*
03728  * Provide function name for PL/Perl execution errors
03729  */
03730 static void
03731 plperl_exec_callback(void *arg)
03732 {
03733     char       *procname = (char *) arg;
03734 
03735     if (procname)
03736         errcontext("PL/Perl function \"%s\"", procname);
03737 }
03738 
03739 /*
03740  * Provide function name for PL/Perl compilation errors
03741  */
03742 static void
03743 plperl_compile_callback(void *arg)
03744 {
03745     char       *procname = (char *) arg;
03746 
03747     if (procname)
03748         errcontext("compilation of PL/Perl function \"%s\"", procname);
03749 }
03750 
03751 /*
03752  * Provide error context for the inline handler
03753  */
03754 static void
03755 plperl_inline_callback(void *arg)
03756 {
03757     errcontext("PL/Perl anonymous code block");
03758 }
03759 
03760 
03761 /*
03762  * Perl's own setlocal() copied from POSIX.xs
03763  * (needed because of the calls to new_*())
03764  */
03765 #ifdef WIN32
03766 static char *
03767 setlocale_perl(int category, char *locale)
03768 {
03769     char       *RETVAL = setlocale(category, locale);
03770 
03771     if (RETVAL)
03772     {
03773 #ifdef USE_LOCALE_CTYPE
03774         if (category == LC_CTYPE
03775 #ifdef LC_ALL
03776             || category == LC_ALL
03777 #endif
03778             )
03779         {
03780             char       *newctype;
03781 
03782 #ifdef LC_ALL
03783             if (category == LC_ALL)
03784                 newctype = setlocale(LC_CTYPE, NULL);
03785             else
03786 #endif
03787                 newctype = RETVAL;
03788             new_ctype(newctype);
03789         }
03790 #endif   /* USE_LOCALE_CTYPE */
03791 #ifdef USE_LOCALE_COLLATE
03792         if (category == LC_COLLATE
03793 #ifdef LC_ALL
03794             || category == LC_ALL
03795 #endif
03796             )
03797         {
03798             char       *newcoll;
03799 
03800 #ifdef LC_ALL
03801             if (category == LC_ALL)
03802                 newcoll = setlocale(LC_COLLATE, NULL);
03803             else
03804 #endif
03805                 newcoll = RETVAL;
03806             new_collate(newcoll);
03807         }
03808 #endif   /* USE_LOCALE_COLLATE */
03809 
03810 #ifdef USE_LOCALE_NUMERIC
03811         if (category == LC_NUMERIC
03812 #ifdef LC_ALL
03813             || category == LC_ALL
03814 #endif
03815             )
03816         {
03817             char       *newnum;
03818 
03819 #ifdef LC_ALL
03820             if (category == LC_ALL)
03821                 newnum = setlocale(LC_NUMERIC, NULL);
03822             else
03823 #endif
03824                 newnum = RETVAL;
03825             new_numeric(newnum);
03826         }
03827 #endif   /* USE_LOCALE_NUMERIC */
03828     }
03829 
03830     return RETVAL;
03831 }
03832 
03833 #endif