PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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  PLySavedArgs
 
struct  PLyProcedure
 
struct  PLyProcedureKey
 
struct  PLyProcedureEntry
 

Typedefs

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

Functions

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

Function Documentation

void init_procedure_caches ( void  )

Definition at line 38 of file plpy_procedure.c.

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

Referenced by PLy_initialize().

39 {
40  HASHCTL hash_ctl;
41 
42  memset(&hash_ctl, 0, sizeof(hash_ctl));
43  hash_ctl.keysize = sizeof(PLyProcedureKey);
44  hash_ctl.entrysize = sizeof(PLyProcedureEntry);
45  PLy_procedure_cache = hash_create("PL/Python procedures", 32, &hash_ctl,
47 }
#define HASH_ELEM
Definition: hsearch.h:87
Size entrysize
Definition: hsearch.h:73
struct PLyProcedureEntry PLyProcedureEntry
#define HASH_BLOBS
Definition: hsearch.h:88
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
Size keysize
Definition: hsearch.h:72
struct PLyProcedureKey PLyProcedureKey
static HTAB * PLy_procedure_cache
void PLy_procedure_compile ( PLyProcedure proc,
const char *  src 
)

Definition at line 370 of file plpy_procedure.c.

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

Referenced by plpython_inline_handler(), and PLy_procedure_create().

371 {
372  PyObject *crv = NULL;
373  char *msrc;
374 
375  proc->globals = PyDict_Copy(PLy_interp_globals);
376 
377  /*
378  * SD is private preserved data between calls. GD is global data shared by
379  * all functions
380  */
381  proc->statics = PyDict_New();
382  PyDict_SetItemString(proc->globals, "SD", proc->statics);
383 
384  /*
385  * insert the function code into the interpreter
386  */
387  msrc = PLy_procedure_munge_source(proc->pyname, src);
388  /* Save the mangled source for later inclusion in tracebacks */
389  proc->src = MemoryContextStrdup(proc->mcxt, msrc);
390  crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);
391  pfree(msrc);
392 
393  if (crv != NULL)
394  {
395  int clen;
396  char call[NAMEDATALEN + 256];
397 
398  Py_DECREF(crv);
399 
400  /*
401  * compile a call to the function
402  */
403  clen = snprintf(call, sizeof(call), "%s()", proc->pyname);
404  if (clen < 0 || clen >= sizeof(call))
405  elog(ERROR, "string would overflow buffer");
406  proc->code = Py_CompileString(call, "<string>", Py_eval_input);
407  if (proc->code != NULL)
408  return;
409  }
410 
411  if (proc->proname)
412  PLy_elog(ERROR, "could not compile PL/Python function \"%s\"",
413  proc->proname);
414  else
415  PLy_elog(ERROR, "could not compile anonymous PL/Python code block");
416 }
static char * PLy_procedure_munge_source(const char *name, const char *src)
void PLy_elog(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define NAMEDATALEN
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
MemoryContext mcxt
PyObject * PLy_interp_globals
Definition: plpy_main.c:71
PyObject * statics
PyObject * code
#define NULL
Definition: c.h:229
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1064
#define elog
Definition: elog.h:219
PyObject * globals
void PLy_procedure_delete ( PLyProcedure proc)

Definition at line 419 of file plpy_procedure.c.

References PLyProcedure::code, PLyProcedure::globals, PLyProcedure::mcxt, MemoryContextDelete(), and PLyProcedure::statics.

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

420 {
421  Py_XDECREF(proc->code);
422  Py_XDECREF(proc->statics);
423  Py_XDECREF(proc->globals);
424  MemoryContextDelete(proc->mcxt);
425 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
MemoryContext mcxt
PyObject * statics
PyObject * code
PyObject * globals
PLyProcedure* PLy_procedure_get ( Oid  fn_oid,
Oid  fn_rel,
bool  is_trigger 
)

Definition at line 77 of file plpy_procedure.c.

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

Referenced by plpython_call_handler(), and plpython_validator().

78 {
79  bool use_cache = !(is_trigger && fn_rel == InvalidOid);
80  HeapTuple procTup;
81  PLyProcedureKey key;
82  PLyProcedureEntry *volatile entry = NULL;
83  PLyProcedure *volatile proc = NULL;
84  bool found = false;
85 
86  procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid));
87  if (!HeapTupleIsValid(procTup))
88  elog(ERROR, "cache lookup failed for function %u", fn_oid);
89 
90  /*
91  * Look for the function in the cache, unless we don't have the necessary
92  * information (e.g. during validation). In that case we just don't cache
93  * anything.
94  */
95  if (use_cache)
96  {
97  key.fn_oid = fn_oid;
98  key.fn_rel = fn_rel;
99  entry = hash_search(PLy_procedure_cache, &key, HASH_ENTER, &found);
100  proc = entry->proc;
101  }
102 
103  PG_TRY();
104  {
105  if (!found)
106  {
107  /* Haven't found it, create a new procedure */
108  proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
109  if (use_cache)
110  entry->proc = proc;
111  }
112  else if (!PLy_procedure_valid(proc, procTup))
113  {
114  /* Found it, but it's invalid, free and reuse the cache entry */
115  entry->proc = NULL;
116  if (proc)
117  PLy_procedure_delete(proc);
118  proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
119  entry->proc = proc;
120  }
121  /* Found it and it's valid, it's fine to use it */
122  }
123  PG_CATCH();
124  {
125  /* Do not leave an uninitialized entry in the cache */
126  if (use_cache)
128  PG_RE_THROW();
129  }
130  PG_END_TRY();
131 
132  ReleaseSysCache(procTup);
133 
134  return proc;
135 }
void PLy_procedure_delete(PLyProcedure *proc)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static bool PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup)
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
#define InvalidOid
Definition: postgres_ext.h:36
static PLyProcedure * PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
#define PG_CATCH()
Definition: elog.h:293
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define PG_RE_THROW()
Definition: elog.h:314
PLyProcedure * proc
static HTAB * PLy_procedure_cache
#define elog
Definition: elog.h:219
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
char* PLy_procedure_name ( PLyProcedure proc)

Definition at line 57 of file plpy_procedure.c.

References NULL, and PLyProcedure::proname.

Referenced by plpython_error_callback(), and PLy_traceback().

58 {
59  if (proc == NULL)
60  return "<unknown procedure>";
61  return proc->proname;
62 }
#define NULL
Definition: c.h:229