PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plpy_main.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "miscadmin.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "plpython.h"
#include "plpy_main.h"
#include "plpy_elog.h"
#include "plpy_exec.h"
#include "plpy_plpymodule.h"
#include "plpy_procedure.h"
#include "plpy_subxactobject.h"
Include dependency graph for plpy_main.c:

Go to the source code of this file.

Functions

void _PG_init (void)
 
 PG_FUNCTION_INFO_V1 (plpython_validator)
 
 PG_FUNCTION_INFO_V1 (plpython_call_handler)
 
 PG_FUNCTION_INFO_V1 (plpython_inline_handler)
 
 PG_FUNCTION_INFO_V1 (plpython2_validator)
 
 PG_FUNCTION_INFO_V1 (plpython2_call_handler)
 
 PG_FUNCTION_INFO_V1 (plpython2_inline_handler)
 
static bool PLy_procedure_is_trigger (Form_pg_proc procStruct)
 
static void plpython_error_callback (void *arg)
 
static void plpython_inline_error_callback (void *arg)
 
static void PLy_init_interp (void)
 
static PLyExecutionContextPLy_push_execution_context (void)
 
static void PLy_pop_execution_context (void)
 
static void PLy_initialize (void)
 
Datum plpython_validator (PG_FUNCTION_ARGS)
 
Datum plpython2_validator (PG_FUNCTION_ARGS)
 
Datum plpython_call_handler (PG_FUNCTION_ARGS)
 
Datum plpython2_call_handler (PG_FUNCTION_ARGS)
 
Datum plpython_inline_handler (PG_FUNCTION_ARGS)
 
Datum plpython2_inline_handler (PG_FUNCTION_ARGS)
 
PLyExecutionContextPLy_current_execution_context (void)
 
MemoryContext PLy_get_scratch_context (PLyExecutionContext *context)
 

Variables

 PG_MODULE_MAGIC
 
static int * plpython_version_bitmask_ptr = NULL
 
static int plpython_version_bitmask = 0
 
PyObject * PLy_interp_globals = NULL
 
static PLyExecutionContextPLy_execution_contexts = NULL
 

Function Documentation

void _PG_init ( void  )

Definition at line 78 of file plpy_main.c.

References find_rendezvous_variable(), pg_bindtextdomain(), plpython_version_bitmask, plpython_version_bitmask_ptr, and TEXTDOMAIN.

79 {
80  int **bitmask_ptr;
81 
82  /*
83  * Set up a shared bitmask variable telling which Python version(s) are
84  * loaded into this process's address space. If there's more than one, we
85  * cannot call into libpython for fear of causing crashes. But postpone
86  * the actual failure for later, so that operations like pg_restore can
87  * load more than one plpython library so long as they don't try to do
88  * anything much with the language.
89  */
90  bitmask_ptr = (int **) find_rendezvous_variable("plpython_version_bitmask");
91  if (!(*bitmask_ptr)) /* am I the first? */
92  *bitmask_ptr = &plpython_version_bitmask;
93  /* Retain pointer to the agreed-on shared variable ... */
94  plpython_version_bitmask_ptr = *bitmask_ptr;
95  /* ... and announce my presence */
96  *plpython_version_bitmask_ptr |= (1 << PY_MAJOR_VERSION);
97 
98  /*
99  * This should be safe even in the presence of conflicting plpythons, and
100  * it's necessary to do it before possibly throwing a conflict error, or
101  * the error message won't get localized.
102  */
104 }
#define TEXTDOMAIN
Definition: elog.h:125
void ** find_rendezvous_variable(const char *varName)
Definition: dfmgr.c:672
static int * plpython_version_bitmask_ptr
Definition: plpy_main.c:67
static int plpython_version_bitmask
Definition: plpy_main.c:68
void pg_bindtextdomain(const char *domain)
Definition: miscinit.c:1502
PG_FUNCTION_INFO_V1 ( plpython_validator  )
PG_FUNCTION_INFO_V1 ( plpython_call_handler  )
PG_FUNCTION_INFO_V1 ( plpython_inline_handler  )
PG_FUNCTION_INFO_V1 ( plpython2_validator  )
PG_FUNCTION_INFO_V1 ( plpython2_call_handler  )
PG_FUNCTION_INFO_V1 ( plpython2_inline_handler  )
Datum plpython2_call_handler ( PG_FUNCTION_ARGS  )

Definition at line 287 of file plpy_main.c.

References plpython_call_handler().

288 {
289  return plpython_call_handler(fcinfo);
290 }
Datum plpython_call_handler(PG_FUNCTION_ARGS)
Definition: plpy_main.c:220
Datum plpython2_inline_handler ( PG_FUNCTION_ARGS  )

Definition at line 367 of file plpy_main.c.

References plpython_inline_handler().

368 {
369  return plpython_inline_handler(fcinfo);
370 }
Datum plpython_inline_handler(PG_FUNCTION_ARGS)
Definition: plpy_main.c:294
Datum plpython2_validator ( PG_FUNCTION_ARGS  )

Definition at line 212 of file plpy_main.c.

References plpython_validator().

213 {
214  /* call plpython validator with our fcinfo so it gets our oid */
215  return plpython_validator(fcinfo);
216 }
Datum plpython_validator(PG_FUNCTION_ARGS)
Definition: plpy_main.c:178
Datum plpython_call_handler ( PG_FUNCTION_ARGS  )

Definition at line 220 of file plpy_main.c.

References ErrorContextCallback::callback, CALLED_AS_TRIGGER, PLyExecutionContext::curr_proc, elog, ERROR, error_context_stack, InvalidOid, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, plpython_error_callback(), PLy_exec_function(), PLy_exec_trigger(), PLy_initialize(), PLy_pop_execution_context(), PLy_procedure_get(), PLy_push_execution_context(), PointerGetDatum, ErrorContextCallback::previous, RelationGetRelid, SPI_connect(), and SPI_OK_CONNECT.

Referenced by plpython2_call_handler().

221 {
222  Datum retval;
223  PLyExecutionContext *exec_ctx;
224  ErrorContextCallback plerrcontext;
225 
226  PLy_initialize();
227 
228  /* Note: SPI_finish() happens in plpy_exec.c, which is dubious design */
229  if (SPI_connect() != SPI_OK_CONNECT)
230  elog(ERROR, "SPI_connect failed");
231 
232  /*
233  * Push execution context onto stack. It is important that this get
234  * popped again, so avoid putting anything that could throw error between
235  * here and the PG_TRY. (plpython_error_callback expects the stack entry
236  * to be there, so we have to make the context first.)
237  */
238  exec_ctx = PLy_push_execution_context();
239 
240  /*
241  * Setup error traceback support for ereport()
242  */
243  plerrcontext.callback = plpython_error_callback;
244  plerrcontext.previous = error_context_stack;
245  error_context_stack = &plerrcontext;
246 
247  PG_TRY();
248  {
249  Oid funcoid = fcinfo->flinfo->fn_oid;
250  PLyProcedure *proc;
251 
252  if (CALLED_AS_TRIGGER(fcinfo))
253  {
254  Relation tgrel = ((TriggerData *) fcinfo->context)->tg_relation;
255  HeapTuple trv;
256 
257  proc = PLy_procedure_get(funcoid, RelationGetRelid(tgrel), true);
258  exec_ctx->curr_proc = proc;
259  trv = PLy_exec_trigger(fcinfo, proc);
260  retval = PointerGetDatum(trv);
261  }
262  else
263  {
264  proc = PLy_procedure_get(funcoid, InvalidOid, false);
265  exec_ctx->curr_proc = proc;
266  retval = PLy_exec_function(fcinfo, proc);
267  }
268  }
269  PG_CATCH();
270  {
272  PyErr_Clear();
273  PG_RE_THROW();
274  }
275  PG_END_TRY();
276 
277  /* Pop the error context stack */
278  error_context_stack = plerrcontext.previous;
279  /* ... and then the execution context */
281 
282  return retval;
283 }
HeapTuple PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition: plpy_exec.c:325
#define SPI_OK_CONNECT
Definition: spi.h:50
int SPI_connect(void)
Definition: spi.c:84
#define PointerGetDatum(X)
Definition: postgres.h:562
unsigned int Oid
Definition: postgres_ext.h:31
struct ErrorContextCallback * previous
Definition: elog.h:238
ErrorContextCallback * error_context_stack
Definition: elog.c:88
PLyProcedure * PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger)
static void PLy_pop_execution_context(void)
Definition: plpy_main.c:436
#define ERROR
Definition: elog.h:43
static void PLy_initialize(void)
Definition: plpy_main.c:111
PLyProcedure * curr_proc
Definition: plpy_main.h:20
uintptr_t Datum
Definition: postgres.h:372
#define InvalidOid
Definition: postgres_ext.h:36
static PLyExecutionContext * PLy_push_execution_context(void)
Definition: plpy_main.c:422
#define PG_CATCH()
Definition: elog.h:293
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
#define PG_RE_THROW()
Definition: elog.h:314
void(* callback)(void *arg)
Definition: elog.h:239
#define elog
Definition: elog.h:219
Datum PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition: plpy_exec.c:58
#define PG_TRY()
Definition: elog.h:284
static void plpython_error_callback(void *arg)
Definition: plpy_main.c:382
#define RelationGetRelid(relation)
Definition: rel.h:416
#define PG_END_TRY()
Definition: elog.h:300
static void plpython_error_callback ( void *  arg)
static

Definition at line 382 of file plpy_main.c.

References PLyExecutionContext::curr_proc, errcontext, PLy_current_execution_context(), and PLy_procedure_name().

Referenced by plpython_call_handler().

383 {
385 
386  if (exec_ctx->curr_proc)
387  errcontext("PL/Python function \"%s\"",
388  PLy_procedure_name(exec_ctx->curr_proc));
389 }
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:398
char * PLy_procedure_name(PLyProcedure *proc)
PLyProcedure * curr_proc
Definition: plpy_main.h:20
#define errcontext
Definition: elog.h:164
static void plpython_inline_error_callback ( void *  arg)
static

Definition at line 392 of file plpy_main.c.

References errcontext.

Referenced by plpython_inline_handler().

393 {
394  errcontext("PL/Python anonymous code block");
395 }
#define errcontext
Definition: elog.h:164
Datum plpython_inline_handler ( PG_FUNCTION_ARGS  )

Definition at line 294 of file plpy_main.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), ErrorContextCallback::callback, PLyExecutionContext::curr_proc, CurrentMemoryContext, PLyTypeOutput::d, DatumGetPointer, elog, ERROR, error_context_stack, FunctionCallInfoData::flinfo, FmgrInfo::fn_mcxt, FmgrInfo::fn_oid, InvalidOid, PLyProcedure::langid, InlineCodeBlock::langOid, PLyProcedure::mcxt, MemoryContextStrdup(), MemSet, PLyTypeInfo::out, PG_CATCH, PG_END_TRY, PG_GETARG_DATUM, PG_RE_THROW, PG_RETURN_VOID, PG_TRY, plpython_inline_error_callback(), PLy_exec_function(), PLy_initialize(), PLy_pop_execution_context(), PLy_procedure_compile(), PLy_procedure_delete(), PLy_push_execution_context(), ErrorContextCallback::previous, PLyProcedure::pyname, PLyProcedure::result, InlineCodeBlock::source_text, SPI_connect(), SPI_OK_CONNECT, TopMemoryContext, PLyObToDatum::typoid, and VOIDOID.

Referenced by plpython2_inline_handler().

295 {
297  FunctionCallInfoData fake_fcinfo;
298  FmgrInfo flinfo;
299  PLyProcedure proc;
300  PLyExecutionContext *exec_ctx;
301  ErrorContextCallback plerrcontext;
302 
303  PLy_initialize();
304 
305  /* Note: SPI_finish() happens in plpy_exec.c, which is dubious design */
306  if (SPI_connect() != SPI_OK_CONNECT)
307  elog(ERROR, "SPI_connect failed");
308 
309  MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));
310  MemSet(&flinfo, 0, sizeof(flinfo));
311  fake_fcinfo.flinfo = &flinfo;
312  flinfo.fn_oid = InvalidOid;
313  flinfo.fn_mcxt = CurrentMemoryContext;
314 
315  MemSet(&proc, 0, sizeof(PLyProcedure));
317  "__plpython_inline_block",
319  proc.pyname = MemoryContextStrdup(proc.mcxt, "__plpython_inline_block");
320  proc.langid = codeblock->langOid;
321  proc.result.out.d.typoid = VOIDOID;
322 
323  /*
324  * Push execution context onto stack. It is important that this get
325  * popped again, so avoid putting anything that could throw error between
326  * here and the PG_TRY. (plpython_inline_error_callback doesn't currently
327  * need the stack entry, but for consistency with plpython_call_handler we
328  * do it in this order.)
329  */
330  exec_ctx = PLy_push_execution_context();
331 
332  /*
333  * Setup error traceback support for ereport()
334  */
336  plerrcontext.previous = error_context_stack;
337  error_context_stack = &plerrcontext;
338 
339  PG_TRY();
340  {
341  PLy_procedure_compile(&proc, codeblock->source_text);
342  exec_ctx->curr_proc = &proc;
343  PLy_exec_function(&fake_fcinfo, &proc);
344  }
345  PG_CATCH();
346  {
348  PLy_procedure_delete(&proc);
349  PyErr_Clear();
350  PG_RE_THROW();
351  }
352  PG_END_TRY();
353 
354  /* Pop the error context stack */
355  error_context_stack = plerrcontext.previous;
356  /* ... and then the execution context */
358 
359  /* Now clean up the transient procedure we made */
360  PLy_procedure_delete(&proc);
361 
362  PG_RETURN_VOID();
363 }
#define SPI_OK_CONNECT
Definition: spi.h:50
Definition: fmgr.h:56
MemoryContext fn_mcxt
Definition: fmgr.h:65
int SPI_connect(void)
Definition: spi.c:84
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
void PLy_procedure_delete(PLyProcedure *proc)
void PLy_procedure_compile(PLyProcedure *proc, const char *src)
#define MemSet(start, val, len)
Definition: c.h:857
struct ErrorContextCallback * previous
Definition: elog.h:238
ErrorContextCallback * error_context_stack
Definition: elog.c:88
PLyTypeInfo result
FmgrInfo * flinfo
Definition: fmgr.h:79
static void PLy_pop_execution_context(void)
Definition: plpy_main.c:436
#define VOIDOID
Definition: pg_type.h:690
#define ERROR
Definition: elog.h:43
PLyObToDatum d
Definition: plpy_typeio.h:77
MemoryContext mcxt
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
PLyTypeOutput out
Definition: plpy_typeio.h:87
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
MemoryContext TopMemoryContext
Definition: mcxt.c:43
static void PLy_initialize(void)
Definition: plpy_main.c:111
static void plpython_inline_error_callback(void *arg)
Definition: plpy_main.c:392
PLyProcedure * curr_proc
Definition: plpy_main.h:20
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:59
static PLyExecutionContext * PLy_push_execution_context(void)
Definition: plpy_main.c:422
#define PG_RETURN_VOID()
Definition: fmgr.h:309
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
#define DatumGetPointer(X)
Definition: postgres.h:555
void(* callback)(void *arg)
Definition: elog.h:239
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1064
char * source_text
Definition: parsenodes.h:2774
#define elog
Definition: elog.h:219
Datum PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition: plpy_exec.c:58
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
Datum plpython_validator ( PG_FUNCTION_ARGS  )

Definition at line 178 of file plpy_main.c.

References check_function_bodies, CheckFunctionValidatorAccess(), elog, ERROR, GETSTRUCT, HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_VOID, PLy_initialize(), PLy_procedure_get(), PLy_procedure_is_trigger(), PROCOID, ReleaseSysCache(), and SearchSysCache1.

Referenced by plpython2_validator().

179 {
180  Oid funcoid = PG_GETARG_OID(0);
181  HeapTuple tuple;
182  Form_pg_proc procStruct;
183  bool is_trigger;
184 
185  if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
186  PG_RETURN_VOID();
187 
189  PG_RETURN_VOID();
190 
191  /* Do this only after making sure we need to do something */
192  PLy_initialize();
193 
194  /* Get the new function's pg_proc entry */
195  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
196  if (!HeapTupleIsValid(tuple))
197  elog(ERROR, "cache lookup failed for function %u", funcoid);
198  procStruct = (Form_pg_proc) GETSTRUCT(tuple);
199 
200  is_trigger = PLy_procedure_is_trigger(procStruct);
201 
202  ReleaseSysCache(tuple);
203 
204  /* We can't validate triggers against any particular table ... */
205  PLy_procedure_get(funcoid, InvalidOid, is_trigger);
206 
207  PG_RETURN_VOID();
208 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool check_function_bodies
Definition: guc.c:447
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
PLyProcedure * PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger)
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
Definition: fmgr.c:2101
static bool PLy_procedure_is_trigger(Form_pg_proc procStruct)
Definition: plpy_main.c:374
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static void PLy_initialize(void)
Definition: plpy_main.c:111
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_VOID()
Definition: fmgr.h:309
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
PLyExecutionContext* PLy_current_execution_context ( void  )

Definition at line 398 of file plpy_main.c.

References elog, ERROR, NULL, and PLy_execution_contexts.

Referenced by plpython_error_callback(), plpython_return_error_callback(), plpython_trigger_error_callback(), PLy_cursor_plan(), PLy_cursor_query(), PLy_input_tuple_funcs(), PLy_output_tuple_funcs(), PLy_spi_execute_plan(), PLy_spi_execute_query(), PLy_spi_prepare(), PLy_traceback(), PLyDict_FromTuple(), and PLyString_ToComposite().

399 {
401  elog(ERROR, "no Python function is currently executing");
402 
403  return PLy_execution_contexts;
404 }
#define ERROR
Definition: elog.h:43
#define NULL
Definition: c.h:229
static PLyExecutionContext * PLy_execution_contexts
Definition: plpy_main.c:74
#define elog
Definition: elog.h:219
MemoryContext PLy_get_scratch_context ( PLyExecutionContext context)

Definition at line 407 of file plpy_main.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), NULL, PLyExecutionContext::scratch_ctx, and TopTransactionContext.

Referenced by PLyDict_FromTuple().

408 {
409  /*
410  * A scratch context might never be needed in a given plpython procedure,
411  * so allocate it on first request.
412  */
413  if (context->scratch_ctx == NULL)
414  context->scratch_ctx =
416  "PL/Python scratch context",
418  return context->scratch_ctx;
419 }
MemoryContext scratch_ctx
Definition: plpy_main.h:21
MemoryContext TopTransactionContext
Definition: mcxt.c:48
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
#define NULL
Definition: c.h:229
static void PLy_init_interp ( void  )
static

Definition at line 158 of file plpy_main.c.

References ERROR, NULL, PLy_elog(), and PLy_interp_globals.

Referenced by PLy_initialize().

159 {
160  static PyObject *PLy_interp_safe_globals = NULL;
161  PyObject *mainmod;
162 
163  mainmod = PyImport_AddModule("__main__");
164  if (mainmod == NULL || PyErr_Occurred())
165  PLy_elog(ERROR, "could not import \"__main__\" module");
166  Py_INCREF(mainmod);
167  PLy_interp_globals = PyModule_GetDict(mainmod);
168  PLy_interp_safe_globals = PyDict_New();
169  if (PLy_interp_safe_globals == NULL)
170  PLy_elog(ERROR, "could not create globals");
171  PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
172  Py_DECREF(mainmod);
173  if (PLy_interp_globals == NULL || PyErr_Occurred())
174  PLy_elog(ERROR, "could not initialize globals");
175 }
void PLy_elog(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
#define ERROR
Definition: elog.h:43
PyObject * PLy_interp_globals
Definition: plpy_main.c:71
#define NULL
Definition: c.h:229
static void PLy_initialize ( void  )
static

Definition at line 111 of file plpy_main.c.

References ereport, errdetail(), errmsg(), explicit_subtransactions, FATAL, init_procedure_caches(), NIL, NULL, plpython_version_bitmask_ptr, PLy_elog(), PLy_init_interp(), and PLy_init_plpy().

Referenced by plpython_call_handler(), plpython_inline_handler(), and plpython_validator().

112 {
113  static bool inited = false;
114 
115  /*
116  * Check for multiple Python libraries before actively doing anything with
117  * libpython. This must be repeated on each entry to PL/Python, in case a
118  * conflicting library got loaded since we last looked.
119  *
120  * It is attractive to weaken this error from FATAL to ERROR, but there
121  * would be corner cases, so it seems best to be conservative.
122  */
123  if (*plpython_version_bitmask_ptr != (1 << PY_MAJOR_VERSION))
124  ereport(FATAL,
125  (errmsg("multiple Python libraries are present in session"),
126  errdetail("Only one Python major version can be used in one session.")));
127 
128  /* The rest should only be done once per session */
129  if (inited)
130  return;
131 
132 #if PY_MAJOR_VERSION >= 3
133  PyImport_AppendInittab("plpy", PyInit_plpy);
134 #endif
135  Py_Initialize();
136 #if PY_MAJOR_VERSION >= 3
137  PyImport_ImportModule("plpy");
138 #endif
139  PLy_init_interp();
140  PLy_init_plpy();
141  if (PyErr_Occurred())
142  PLy_elog(FATAL, "untrapped error in initialization");
143 
145 
147 
149 
150  inited = true;
151 }
#define NIL
Definition: pg_list.h:69
static void PLy_init_interp(void)
Definition: plpy_main.c:158
void PLy_elog(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
void init_procedure_caches(void)
static int * plpython_version_bitmask_ptr
Definition: plpy_main.c:67
#define FATAL
Definition: elog.h:52
int errdetail(const char *fmt,...)
Definition: elog.c:873
List * explicit_subtransactions
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
static PLyExecutionContext * PLy_execution_contexts
Definition: plpy_main.c:74
int errmsg(const char *fmt,...)
Definition: elog.c:797
void PLy_init_plpy(void)
static void PLy_pop_execution_context ( void  )
static

Definition at line 436 of file plpy_main.c.

References elog, ERROR, MemoryContextDelete(), PLyExecutionContext::next, NULL, pfree(), PLy_execution_contexts, and PLyExecutionContext::scratch_ctx.

Referenced by plpython_call_handler(), and plpython_inline_handler().

437 {
439 
440  if (context == NULL)
441  elog(ERROR, "no Python function is currently executing");
442 
443  PLy_execution_contexts = context->next;
444 
445  if (context->scratch_ctx)
447  pfree(context);
448 }
MemoryContext scratch_ctx
Definition: plpy_main.h:21
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
#define NULL
Definition: c.h:229
static PLyExecutionContext * PLy_execution_contexts
Definition: plpy_main.c:74
struct PLyExecutionContext * next
Definition: plpy_main.h:22
#define elog
Definition: elog.h:219
static bool PLy_procedure_is_trigger ( Form_pg_proc  procStruct)
static

Definition at line 374 of file plpy_main.c.

References OPAQUEOID, and TRIGGEROID.

Referenced by plpython_validator().

375 {
376  return (procStruct->prorettype == TRIGGEROID ||
377  (procStruct->prorettype == OPAQUEOID &&
378  procStruct->pronargs == 0));
379 }
#define OPAQUEOID
Definition: pg_type.h:700
#define TRIGGEROID
Definition: pg_type.h:692
static PLyExecutionContext * PLy_push_execution_context ( void  )
static

Definition at line 422 of file plpy_main.c.

References PLyExecutionContext::curr_proc, MemoryContextAlloc(), PLyExecutionContext::next, NULL, PLy_execution_contexts, PLyExecutionContext::scratch_ctx, and TopTransactionContext.

Referenced by plpython_call_handler(), and plpython_inline_handler().

423 {
424  PLyExecutionContext *context;
425 
426  context = (PLyExecutionContext *)
428  context->curr_proc = NULL;
429  context->scratch_ctx = NULL;
430  context->next = PLy_execution_contexts;
431  PLy_execution_contexts = context;
432  return context;
433 }
MemoryContext scratch_ctx
Definition: plpy_main.h:21
MemoryContext TopTransactionContext
Definition: mcxt.c:48
PLyProcedure * curr_proc
Definition: plpy_main.h:20
#define NULL
Definition: c.h:229
static PLyExecutionContext * PLy_execution_contexts
Definition: plpy_main.c:74
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
struct PLyExecutionContext * next
Definition: plpy_main.h:22

Variable Documentation

PG_MODULE_MAGIC

Definition at line 44 of file plpy_main.c.

int plpython_version_bitmask = 0
static

Definition at line 68 of file plpy_main.c.

Referenced by _PG_init().

int* plpython_version_bitmask_ptr = NULL
static

Definition at line 67 of file plpy_main.c.

Referenced by _PG_init(), and PLy_initialize().

PLyExecutionContext* PLy_execution_contexts = NULL
static
PyObject* PLy_interp_globals = NULL

Definition at line 71 of file plpy_main.c.

Referenced by PLy_init_interp(), and PLy_procedure_compile().