Header And Logo

| The world's most advanced open source database.

Data Structures | Typedefs | Functions

plpy_procedure.h File Reference

#include "plpy_typeio.h"
Include dependency graph for plpy_procedure.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PLyProcedure
struct  PLyProcedureKey
struct  PLyProcedureEntry


typedef struct PLyProcedure PLyProcedure
typedef struct PLyProcedureKey PLyProcedureKey
typedef struct PLyProcedureEntry PLyProcedureEntry


void init_procedure_caches (void)
char * PLy_procedure_name (PLyProcedure *proc)
PLyProcedurePLy_procedure_get (Oid fn_oid, Oid fn_rel, bool is_trigger)
void PLy_procedure_compile (PLyProcedure *proc, const char *src)
void PLy_procedure_delete (PLyProcedure *proc)

Typedef Documentation

typedef struct PLyProcedure PLyProcedure

Function Documentation

void init_procedure_caches ( void   ) 

Definition at line 35 of file plpy_procedure.c.

References HASHCTL::entrysize, HASHCTL::hash, hash_create(), HASH_ELEM, HASH_FUNCTION, and HASHCTL::keysize.

Referenced by _PG_init().

    HASHCTL     hash_ctl;

    memset(&hash_ctl, 0, sizeof(hash_ctl));
    hash_ctl.keysize = sizeof(PLyProcedureKey);
    hash_ctl.entrysize = sizeof(PLyProcedureEntry);
    hash_ctl.hash = tag_hash;
    PLy_procedure_cache = hash_create("PL/Python procedures", 32, &hash_ctl,
                                      HASH_ELEM | HASH_FUNCTION);

void PLy_procedure_compile ( PLyProcedure proc,
const char *  src 

Definition at line 341 of file plpy_procedure.c.

References PLyProcedure::code, elog, ERROR, PLyProcedure::globals, NAMEDATALEN, NULL, pfree(), PLy_elog(), PLy_interp_globals, PLy_procedure_munge_source(), PLy_strdup(), PLyProcedure::proname, PLyProcedure::pyname, snprintf(), PLyProcedure::src, and PLyProcedure::statics.

Referenced by plpython_inline_handler(), and PLy_procedure_create().

    PyObject   *crv = NULL;
    char       *msrc;

    proc->globals = PyDict_Copy(PLy_interp_globals);

     * SD is private preserved data between calls. GD is global data shared by
     * all functions
    proc->statics = PyDict_New();
    PyDict_SetItemString(proc->globals, "SD", proc->statics);

     * insert the function code into the interpreter
    msrc = PLy_procedure_munge_source(proc->pyname, src);
    /* Save the mangled source for later inclusion in tracebacks */
    proc->src = PLy_strdup(msrc);
    crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);

    if (crv != NULL)
        int         clen;
        char        call[NAMEDATALEN + 256];


         * compile a call to the function
        clen = snprintf(call, sizeof(call), "%s()", proc->pyname);
        if (clen < 0 || clen >= sizeof(call))
            elog(ERROR, "string would overflow buffer");
        proc->code = Py_CompileString(call, "<string>", Py_eval_input);
        if (proc->code != NULL)

    if (proc->proname)
        PLy_elog(ERROR, "could not compile PL/Python function \"%s\"",
        PLy_elog(ERROR, "could not compile anonymous PL/Python code block");

void PLy_procedure_delete ( PLyProcedure proc  ) 

Definition at line 390 of file plpy_procedure.c.

References PLyProcedure::argnames, PLyProcedure::args, PLyObToTuple::atts, PLyTupleToOb::atts, PLyProcedure::code, PLyProcedure::globals, i, PLyTypeInfo::in, PLyTypeInfo::is_rowtype, PLyProcedure::nargs, PLyTypeInfo::out, PLy_free(), PLyProcedure::proname, PLyProcedure::pyname, PLyTypeOutput::r, PLyTypeInput::r, PLyProcedure::src, and PLyProcedure::statics.

Referenced by plpython_inline_handler(), PLy_procedure_create(), and PLy_procedure_get().

    int         i;

    if (proc->proname)
    if (proc->pyname)
    for (i = 0; i < proc->nargs; i++)
        if (proc->args[i].is_rowtype == 1)
            if (proc->args[i].in.r.atts)
            if (proc->args[i].out.r.atts)
        if (proc->argnames && proc->argnames[i])
    if (proc->src)
    if (proc->argnames)

PLyProcedure* PLy_procedure_get ( Oid  fn_oid,
Oid  fn_rel,
bool  is_trigger 

Definition at line 75 of file plpy_procedure.c.

References elog, ERROR, PLyProcedureKey::fn_oid, PLyProcedureKey::fn_rel, HASH_ENTER, HASH_REMOVE, hash_search(), HeapTupleIsValid, NULL, ObjectIdGetDatum, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLy_free(), PLy_procedure_create(), PLy_procedure_delete(), PLy_procedure_valid(), PLyProcedureEntry::proc, PROCOID, ReleaseSysCache(), and SearchSysCache1.

Referenced by plpython_call_handler(), and plpython_validator().

    bool        use_cache = !(is_trigger && fn_rel == InvalidOid);
    HeapTuple   procTup;
    PLyProcedureKey key;
    PLyProcedureEntry *volatile entry = NULL;
    PLyProcedure *volatile proc = NULL;
    bool        found = false;

    procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid));
    if (!HeapTupleIsValid(procTup))
        elog(ERROR, "cache lookup failed for function %u", fn_oid);

     * Look for the function in the cache, unless we don't have the necessary
     * information (e.g. during validation). In that case we just don't cache
     * anything.
    if (use_cache)
        key.fn_oid = fn_oid;
        key.fn_rel = fn_rel;
        entry = hash_search(PLy_procedure_cache, &key, HASH_ENTER, &found);
        proc = entry->proc;

        if (!found)
            /* Haven't found it, create a new procedure */
            proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
            if (use_cache)
                entry->proc = proc;
        else if (!PLy_procedure_valid(proc, procTup))
            /* Found it, but it's invalid, free and reuse the cache entry */
            proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
            entry->proc = proc;
        /* Found it and it's valid, it's fine to use it */
        /* Do not leave an uninitialised entry in the cache */
        if (use_cache)
            hash_search(PLy_procedure_cache, &key, HASH_REMOVE, NULL);


    return proc;

char* PLy_procedure_name ( PLyProcedure proc  ) 

Definition at line 55 of file plpy_procedure.c.

References NULL, and PLyProcedure::proname.

Referenced by plpython_error_callback(), and PLy_traceback().

    if (proc == NULL)
        return "<unknown procedure>";
    return proc->proname;