PostgreSQL Source Code  git master
plpy_plpymodule.c
Go to the documentation of this file.
1 /*
2  * the plpy module
3  *
4  * src/pl/plpython/plpy_plpymodule.c
5  */
6 
7 #include "postgres.h"
8 
9 #include "access/xact.h"
10 #include "mb/pg_wchar.h"
11 #include "plpy_cursorobject.h"
12 #include "plpy_elog.h"
13 #include "plpy_main.h"
14 #include "plpy_planobject.h"
15 #include "plpy_plpymodule.h"
16 #include "plpy_resultobject.h"
17 #include "plpy_spi.h"
18 #include "plpy_subxactobject.h"
19 #include "plpython.h"
20 #include "utils/builtins.h"
21 #include "utils/snapmgr.h"
22 
24 
25 
26 static void PLy_add_exceptions(PyObject *plpy);
27 static PyObject *PLy_create_exception(char *name,
28  PyObject *base, PyObject *dict,
29  const char *modname, PyObject *mod);
30 static void PLy_generate_spi_exceptions(PyObject *mod, PyObject *base);
31 
32 /* module functions */
33 static PyObject *PLy_debug(PyObject *self, PyObject *args, PyObject *kw);
34 static PyObject *PLy_log(PyObject *self, PyObject *args, PyObject *kw);
35 static PyObject *PLy_info(PyObject *self, PyObject *args, PyObject *kw);
36 static PyObject *PLy_notice(PyObject *self, PyObject *args, PyObject *kw);
37 static PyObject *PLy_warning(PyObject *self, PyObject *args, PyObject *kw);
38 static PyObject *PLy_error(PyObject *self, PyObject *args, PyObject *kw);
39 static PyObject *PLy_fatal(PyObject *self, PyObject *args, PyObject *kw);
40 static PyObject *PLy_quote_literal(PyObject *self, PyObject *args);
41 static PyObject *PLy_quote_nullable(PyObject *self, PyObject *args);
42 static PyObject *PLy_quote_ident(PyObject *self, PyObject *args);
43 static PyObject *PLy_commit(PyObject *self, PyObject *args);
44 static PyObject *PLy_rollback(PyObject *self, PyObject *args);
45 
46 
47 /* A list of all known exceptions, generated from backend/utils/errcodes.txt */
48 typedef struct ExceptionMap
49 {
50  char *name;
51  char *classname;
52  int sqlstate;
53 } ExceptionMap;
54 
55 static const ExceptionMap exception_map[] = {
56 #include "spiexceptions.h"
57  {NULL, NULL, 0}
58 };
59 
60 static PyMethodDef PLy_methods[] = {
61  /*
62  * logging methods
63  */
64  {"debug", (PyCFunction) (pg_funcptr_t) PLy_debug, METH_VARARGS | METH_KEYWORDS, NULL},
65  {"log", (PyCFunction) (pg_funcptr_t) PLy_log, METH_VARARGS | METH_KEYWORDS, NULL},
66  {"info", (PyCFunction) (pg_funcptr_t) PLy_info, METH_VARARGS | METH_KEYWORDS, NULL},
67  {"notice", (PyCFunction) (pg_funcptr_t) PLy_notice, METH_VARARGS | METH_KEYWORDS, NULL},
68  {"warning", (PyCFunction) (pg_funcptr_t) PLy_warning, METH_VARARGS | METH_KEYWORDS, NULL},
69  {"error", (PyCFunction) (pg_funcptr_t) PLy_error, METH_VARARGS | METH_KEYWORDS, NULL},
70  {"fatal", (PyCFunction) (pg_funcptr_t) PLy_fatal, METH_VARARGS | METH_KEYWORDS, NULL},
71 
72  /*
73  * create a stored plan
74  */
75  {"prepare", PLy_spi_prepare, METH_VARARGS, NULL},
76 
77  /*
78  * execute a plan or query
79  */
80  {"execute", PLy_spi_execute, METH_VARARGS, NULL},
81 
82  /*
83  * escaping strings
84  */
85  {"quote_literal", PLy_quote_literal, METH_VARARGS, NULL},
86  {"quote_nullable", PLy_quote_nullable, METH_VARARGS, NULL},
87  {"quote_ident", PLy_quote_ident, METH_VARARGS, NULL},
88 
89  /*
90  * create the subtransaction context manager
91  */
92  {"subtransaction", PLy_subtransaction_new, METH_NOARGS, NULL},
93 
94  /*
95  * create a cursor
96  */
97  {"cursor", PLy_cursor, METH_VARARGS, NULL},
98 
99  /*
100  * transaction control
101  */
102  {"commit", PLy_commit, METH_NOARGS, NULL},
103  {"rollback", PLy_rollback, METH_NOARGS, NULL},
104 
105  {NULL, NULL, 0, NULL}
106 };
107 
108 static PyMethodDef PLy_exc_methods[] = {
109  {NULL, NULL, 0, NULL}
110 };
111 
112 #if PY_MAJOR_VERSION >= 3
113 static PyModuleDef PLy_module = {
114  PyModuleDef_HEAD_INIT,
115  .m_name = "plpy",
116  .m_size = -1,
117  .m_methods = PLy_methods,
118 };
119 
120 static PyModuleDef PLy_exc_module = {
121  PyModuleDef_HEAD_INIT,
122  .m_name = "spiexceptions",
123  .m_size = -1,
124  .m_methods = PLy_exc_methods,
125 };
126 
127 /*
128  * Must have external linkage, because PyMODINIT_FUNC does dllexport on
129  * Windows-like platforms.
130  */
131 PyMODINIT_FUNC
132 PyInit_plpy(void)
133 {
134  PyObject *m;
135 
136  m = PyModule_Create(&PLy_module);
137  if (m == NULL)
138  return NULL;
139 
141 
142  return m;
143 }
144 #endif /* PY_MAJOR_VERSION >= 3 */
145 
146 void
148 {
149  PyObject *main_mod,
150  *main_dict,
151  *plpy_mod;
152 
153 #if PY_MAJOR_VERSION < 3
154  PyObject *plpy;
155 #endif
156 
157  /*
158  * initialize plpy module
159  */
164 
165 #if PY_MAJOR_VERSION >= 3
166  PyModule_Create(&PLy_module);
167  /* for Python 3 we initialized the exceptions in PyInit_plpy */
168 #else
169  plpy = Py_InitModule("plpy", PLy_methods);
170  PLy_add_exceptions(plpy);
171 #endif
172 
173  /* PyDict_SetItemString(plpy, "PlanType", (PyObject *) &PLy_PlanType); */
174 
175  /*
176  * initialize main module, and add plpy
177  */
178  main_mod = PyImport_AddModule("__main__");
179  main_dict = PyModule_GetDict(main_mod);
180  plpy_mod = PyImport_AddModule("plpy");
181  if (plpy_mod == NULL)
182  PLy_elog(ERROR, "could not import \"plpy\" module");
183  PyDict_SetItemString(main_dict, "plpy", plpy_mod);
184  if (PyErr_Occurred())
185  PLy_elog(ERROR, "could not import \"plpy\" module");
186 }
187 
188 static void
189 PLy_add_exceptions(PyObject *plpy)
190 {
191  PyObject *excmod;
192  HASHCTL hash_ctl;
193 
194 #if PY_MAJOR_VERSION < 3
195  excmod = Py_InitModule("spiexceptions", PLy_exc_methods);
196 #else
197  excmod = PyModule_Create(&PLy_exc_module);
198 #endif
199  if (excmod == NULL)
200  PLy_elog(ERROR, "could not create the spiexceptions module");
201 
202  /*
203  * PyModule_AddObject does not add a refcount to the object, for some odd
204  * reason; we must do that.
205  */
206  Py_INCREF(excmod);
207  if (PyModule_AddObject(plpy, "spiexceptions", excmod) < 0)
208  PLy_elog(ERROR, "could not add the spiexceptions module");
209 
210  PLy_exc_error = PLy_create_exception("plpy.Error", NULL, NULL,
211  "Error", plpy);
212  PLy_exc_fatal = PLy_create_exception("plpy.Fatal", NULL, NULL,
213  "Fatal", plpy);
214  PLy_exc_spi_error = PLy_create_exception("plpy.SPIError", NULL, NULL,
215  "SPIError", plpy);
216 
217  hash_ctl.keysize = sizeof(int);
218  hash_ctl.entrysize = sizeof(PLyExceptionEntry);
219  PLy_spi_exceptions = hash_create("PL/Python SPI exceptions", 256,
220  &hash_ctl, HASH_ELEM | HASH_BLOBS);
221 
223 }
224 
225 /*
226  * Create an exception object and add it to the module
227  */
228 static PyObject *
229 PLy_create_exception(char *name, PyObject *base, PyObject *dict,
230  const char *modname, PyObject *mod)
231 {
232  PyObject *exc;
233 
234  exc = PyErr_NewException(name, base, dict);
235  if (exc == NULL)
236  PLy_elog(ERROR, NULL);
237 
238  /*
239  * PyModule_AddObject does not add a refcount to the object, for some odd
240  * reason; we must do that.
241  */
242  Py_INCREF(exc);
243  PyModule_AddObject(mod, modname, exc);
244 
245  /*
246  * The caller will also store a pointer to the exception object in some
247  * permanent variable, so add another ref to account for that. This is
248  * probably excessively paranoid, but let's be sure.
249  */
250  Py_INCREF(exc);
251  return exc;
252 }
253 
254 /*
255  * Add all the autogenerated exceptions as subclasses of SPIError
256  */
257 static void
258 PLy_generate_spi_exceptions(PyObject *mod, PyObject *base)
259 {
260  int i;
261 
262  for (i = 0; exception_map[i].name != NULL; i++)
263  {
264  bool found;
265  PyObject *exc;
266  PLyExceptionEntry *entry;
267  PyObject *sqlstate;
268  PyObject *dict = PyDict_New();
269 
270  if (dict == NULL)
271  PLy_elog(ERROR, NULL);
272 
273  sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate));
274  if (sqlstate == NULL)
275  PLy_elog(ERROR, "could not generate SPI exceptions");
276 
277  PyDict_SetItemString(dict, "sqlstate", sqlstate);
278  Py_DECREF(sqlstate);
279 
280  exc = PLy_create_exception(exception_map[i].name, base, dict,
281  exception_map[i].classname, mod);
282 
283  entry = hash_search(PLy_spi_exceptions, &exception_map[i].sqlstate,
284  HASH_ENTER, &found);
285  Assert(!found);
286  entry->exc = exc;
287  }
288 }
289 
290 
291 /*
292  * the python interface to the elog function
293  * don't confuse these with PLy_elog
294  */
295 static PyObject *PLy_output(volatile int level, PyObject *self,
296  PyObject *args, PyObject *kw);
297 
298 static PyObject *
299 PLy_debug(PyObject *self, PyObject *args, PyObject *kw)
300 {
301  return PLy_output(DEBUG2, self, args, kw);
302 }
303 
304 static PyObject *
305 PLy_log(PyObject *self, PyObject *args, PyObject *kw)
306 {
307  return PLy_output(LOG, self, args, kw);
308 }
309 
310 static PyObject *
311 PLy_info(PyObject *self, PyObject *args, PyObject *kw)
312 {
313  return PLy_output(INFO, self, args, kw);
314 }
315 
316 static PyObject *
317 PLy_notice(PyObject *self, PyObject *args, PyObject *kw)
318 {
319  return PLy_output(NOTICE, self, args, kw);
320 }
321 
322 static PyObject *
323 PLy_warning(PyObject *self, PyObject *args, PyObject *kw)
324 {
325  return PLy_output(WARNING, self, args, kw);
326 }
327 
328 static PyObject *
329 PLy_error(PyObject *self, PyObject *args, PyObject *kw)
330 {
331  return PLy_output(ERROR, self, args, kw);
332 }
333 
334 static PyObject *
335 PLy_fatal(PyObject *self, PyObject *args, PyObject *kw)
336 {
337  return PLy_output(FATAL, self, args, kw);
338 }
339 
340 static PyObject *
341 PLy_quote_literal(PyObject *self, PyObject *args)
342 {
343  const char *str;
344  char *quoted;
345  PyObject *ret;
346 
347  if (!PyArg_ParseTuple(args, "s:quote_literal", &str))
348  return NULL;
349 
350  quoted = quote_literal_cstr(str);
351  ret = PyString_FromString(quoted);
352  pfree(quoted);
353 
354  return ret;
355 }
356 
357 static PyObject *
358 PLy_quote_nullable(PyObject *self, PyObject *args)
359 {
360  const char *str;
361  char *quoted;
362  PyObject *ret;
363 
364  if (!PyArg_ParseTuple(args, "z:quote_nullable", &str))
365  return NULL;
366 
367  if (str == NULL)
368  return PyString_FromString("NULL");
369 
370  quoted = quote_literal_cstr(str);
371  ret = PyString_FromString(quoted);
372  pfree(quoted);
373 
374  return ret;
375 }
376 
377 static PyObject *
378 PLy_quote_ident(PyObject *self, PyObject *args)
379 {
380  const char *str;
381  const char *quoted;
382  PyObject *ret;
383 
384  if (!PyArg_ParseTuple(args, "s:quote_ident", &str))
385  return NULL;
386 
387  quoted = quote_identifier(str);
388  ret = PyString_FromString(quoted);
389 
390  return ret;
391 }
392 
393 /* enforce cast of object to string */
394 static char *
395 object_to_string(PyObject *obj)
396 {
397  if (obj)
398  {
399  PyObject *so = PyObject_Str(obj);
400 
401  if (so != NULL)
402  {
403  char *str;
404 
405  str = pstrdup(PyString_AsString(so));
406  Py_DECREF(so);
407 
408  return str;
409  }
410  }
411 
412  return NULL;
413 }
414 
415 static PyObject *
416 PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw)
417 {
418  int sqlstate = 0;
419  char *volatile sqlstatestr = NULL;
420  char *volatile message = NULL;
421  char *volatile detail = NULL;
422  char *volatile hint = NULL;
423  char *volatile column_name = NULL;
424  char *volatile constraint_name = NULL;
425  char *volatile datatype_name = NULL;
426  char *volatile table_name = NULL;
427  char *volatile schema_name = NULL;
428  volatile MemoryContext oldcontext;
429  PyObject *key,
430  *value;
431  PyObject *volatile so;
432  Py_ssize_t pos = 0;
433 
434  if (PyTuple_Size(args) == 1)
435  {
436  /*
437  * Treat single argument specially to avoid undesirable ('tuple',)
438  * decoration.
439  */
440  PyObject *o;
441 
442  if (!PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o))
443  PLy_elog(ERROR, "could not unpack arguments in plpy.elog");
444  so = PyObject_Str(o);
445  }
446  else
447  so = PyObject_Str(args);
448 
449  if (so == NULL || ((message = PyString_AsString(so)) == NULL))
450  {
451  level = ERROR;
452  message = dgettext(TEXTDOMAIN, "could not parse error message in plpy.elog");
453  }
454  message = pstrdup(message);
455 
456  Py_XDECREF(so);
457 
458  if (kw != NULL)
459  {
460  while (PyDict_Next(kw, &pos, &key, &value))
461  {
462  char *keyword = PyString_AsString(key);
463 
464  if (strcmp(keyword, "message") == 0)
465  {
466  /* the message should not be overwritten */
467  if (PyTuple_Size(args) != 0)
468  {
469  PLy_exception_set(PyExc_TypeError, "argument 'message' given by name and position");
470  return NULL;
471  }
472 
473  if (message)
474  pfree(message);
475  message = object_to_string(value);
476  }
477  else if (strcmp(keyword, "detail") == 0)
478  detail = object_to_string(value);
479  else if (strcmp(keyword, "hint") == 0)
480  hint = object_to_string(value);
481  else if (strcmp(keyword, "sqlstate") == 0)
482  sqlstatestr = object_to_string(value);
483  else if (strcmp(keyword, "schema_name") == 0)
484  schema_name = object_to_string(value);
485  else if (strcmp(keyword, "table_name") == 0)
486  table_name = object_to_string(value);
487  else if (strcmp(keyword, "column_name") == 0)
488  column_name = object_to_string(value);
489  else if (strcmp(keyword, "datatype_name") == 0)
490  datatype_name = object_to_string(value);
491  else if (strcmp(keyword, "constraint_name") == 0)
492  constraint_name = object_to_string(value);
493  else
494  {
495  PLy_exception_set(PyExc_TypeError,
496  "'%s' is an invalid keyword argument for this function",
497  keyword);
498  return NULL;
499  }
500  }
501  }
502 
503  if (sqlstatestr != NULL)
504  {
505  if (strlen(sqlstatestr) != 5)
506  {
507  PLy_exception_set(PyExc_ValueError, "invalid SQLSTATE code");
508  return NULL;
509  }
510 
511  if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
512  {
513  PLy_exception_set(PyExc_ValueError, "invalid SQLSTATE code");
514  return NULL;
515  }
516 
517  sqlstate = MAKE_SQLSTATE(sqlstatestr[0],
518  sqlstatestr[1],
519  sqlstatestr[2],
520  sqlstatestr[3],
521  sqlstatestr[4]);
522  }
523 
524  oldcontext = CurrentMemoryContext;
525  PG_TRY();
526  {
527  if (message != NULL)
528  pg_verifymbstr(message, strlen(message), false);
529  if (detail != NULL)
530  pg_verifymbstr(detail, strlen(detail), false);
531  if (hint != NULL)
532  pg_verifymbstr(hint, strlen(hint), false);
533  if (schema_name != NULL)
534  pg_verifymbstr(schema_name, strlen(schema_name), false);
535  if (table_name != NULL)
536  pg_verifymbstr(table_name, strlen(table_name), false);
537  if (column_name != NULL)
538  pg_verifymbstr(column_name, strlen(column_name), false);
539  if (datatype_name != NULL)
540  pg_verifymbstr(datatype_name, strlen(datatype_name), false);
541  if (constraint_name != NULL)
542  pg_verifymbstr(constraint_name, strlen(constraint_name), false);
543 
544  ereport(level,
545  ((sqlstate != 0) ? errcode(sqlstate) : 0,
546  (message != NULL) ? errmsg_internal("%s", message) : 0,
547  (detail != NULL) ? errdetail_internal("%s", detail) : 0,
548  (hint != NULL) ? errhint("%s", hint) : 0,
549  (column_name != NULL) ?
550  err_generic_string(PG_DIAG_COLUMN_NAME, column_name) : 0,
551  (constraint_name != NULL) ?
552  err_generic_string(PG_DIAG_CONSTRAINT_NAME, constraint_name) : 0,
553  (datatype_name != NULL) ?
554  err_generic_string(PG_DIAG_DATATYPE_NAME, datatype_name) : 0,
555  (table_name != NULL) ?
556  err_generic_string(PG_DIAG_TABLE_NAME, table_name) : 0,
557  (schema_name != NULL) ?
558  err_generic_string(PG_DIAG_SCHEMA_NAME, schema_name) : 0));
559  }
560  PG_CATCH();
561  {
562  ErrorData *edata;
563 
564  MemoryContextSwitchTo(oldcontext);
565  edata = CopyErrorData();
566  FlushErrorState();
567 
569  FreeErrorData(edata);
570 
571  return NULL;
572  }
573  PG_END_TRY();
574 
575  /*
576  * return a legal object so the interpreter will continue on its merry way
577  */
578  Py_RETURN_NONE;
579 }
580 
581 static PyObject *
582 PLy_commit(PyObject *self, PyObject *args)
583 {
585 
586  SPI_commit();
588 
589  /* was cleared at transaction end, reset pointer */
590  exec_ctx->scratch_ctx = NULL;
591 
592  Py_RETURN_NONE;
593 }
594 
595 static PyObject *
596 PLy_rollback(PyObject *self, PyObject *args)
597 {
599 
600  SPI_rollback();
602 
603  /* was cleared at transaction end, reset pointer */
604  exec_ctx->scratch_ctx = NULL;
605 
606  Py_RETURN_NONE;
607 }
static PyObject * PLy_quote_nullable(PyObject *self, PyObject *args)
MemoryContext scratch_ctx
Definition: plpy_main.h:21
static PyObject * PLy_rollback(PyObject *self, PyObject *args)
static PyObject * PLy_quote_literal(PyObject *self, PyObject *args)
static PyObject * PLy_warning(PyObject *self, PyObject *args, PyObject *kw)
void PLy_plan_init_type(void)
int errhint(const char *fmt,...)
Definition: elog.c:1162
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:102
PyObject * PLy_cursor(PyObject *self, PyObject *args)
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:65
#define HASH_ELEM
Definition: hsearch.h:95
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10933
#define TEXTDOMAIN
Definition: elog.h:158
ErrorData * CopyErrorData(void)
Definition: elog.c:1565
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:67
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
char * pstrdup(const char *in)
Definition: mcxt.c:1187
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:66
char * unpack_sql_state(int sql_state)
Definition: elog.c:2979
static struct @144 value
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Size entrysize
Definition: hsearch.h:76
static PyObject * PLy_notice(PyObject *self, PyObject *args, PyObject *kw)
int errcode(int sqlerrcode)
Definition: elog.c:704
#define INFO
Definition: elog.h:33
PyObject * PLy_exc_error
Definition: plpy_elog.c:15
static PyObject * PLy_log(PyObject *self, PyObject *args, PyObject *kw)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:954
#define LOG
Definition: elog.h:26
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:408
void PLy_exception_set(PyObject *exc, const char *fmt,...)
Definition: plpy_elog.c:479
void SPI_rollback(void)
Definition: spi.c:340
static PyObject * PLy_info(PyObject *self, PyObject *args, PyObject *kw)
void FlushErrorState(void)
Definition: elog.c:1659
static void PLy_generate_spi_exceptions(PyObject *mod, PyObject *base)
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1075
static void PLy_add_exceptions(PyObject *plpy)
Definition: dynahash.c:219
void pfree(void *pointer)
Definition: mcxt.c:1057
void FreeErrorData(ErrorData *edata)
Definition: elog.c:1621
#define ERROR
Definition: elog.h:45
void PLy_cursor_init_type(void)
void PLy_subtransaction_init_type(void)
#define FATAL
Definition: elog.h:54
struct ExceptionMap ExceptionMap
#define PLy_elog
#define DEBUG2
Definition: elog.h:24
void PLy_exception_set_with_details(PyObject *excclass, ErrorData *edata)
Definition: plpy_elog.c:511
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:349
static PyObject * PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw)
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static PyObject * PLy_error(PyObject *self, PyObject *args, PyObject *kw)
void SPI_commit(void)
Definition: spi.c:285
static PyObject * PLy_fatal(PyObject *self, PyObject *args, PyObject *kw)
#define WARNING
Definition: elog.h:40
static const ExceptionMap exception_map[]
static PyObject * PLy_create_exception(char *name, PyObject *base, PyObject *dict, const char *modname, PyObject *mod)
#define HASH_BLOBS
Definition: hsearch.h:97
static PyObject * PLy_commit(PyObject *self, PyObject *args)
#define dgettext(d, x)
Definition: c.h:1169
Size keysize
Definition: hsearch.h:75
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:68
static PyMethodDef PLy_exc_methods[]
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:69
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1446
#define ereport(elevel,...)
Definition: elog.h:155
#define NOTICE
Definition: elog.h:37
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1002
#define PG_CATCH()
Definition: elog.h:319
PyObject * PLy_exc_fatal
Definition: plpy_elog.c:16
#define Assert(condition)
Definition: c.h:792
PyObject * PLy_spi_execute(PyObject *self, PyObject *args)
Definition: plpy_spi.c:156
struct PLyExceptionEntry PLyExceptionEntry
HTAB * PLy_spi_exceptions
const char * name
Definition: encode.c:515
static PyObject * PLy_quote_ident(PyObject *self, PyObject *args)
void PLy_result_init_type(void)
void PLy_init_plpy(void)
int i
void(* pg_funcptr_t)(void)
Definition: c.h:328
void SPI_start_transaction(void)
Definition: spi.c:219
int err_generic_string(int field, const char *str)
Definition: elog.c:1356
PyObject * PLy_subtransaction_new(PyObject *self, PyObject *unused)
#define PG_TRY()
Definition: elog.h:309
static PyObject * PLy_debug(PyObject *self, PyObject *args, PyObject *kw)
PyObject * exc
Definition: plpy_spi.h:18
PyObject * PLy_exc_spi_error
Definition: plpy_elog.c:17
static char * object_to_string(PyObject *obj)
#define PG_END_TRY()
Definition: elog.h:334
PyObject * PLy_spi_prepare(PyObject *self, PyObject *args)
Definition: plpy_spi.c:39
static PyMethodDef PLy_methods[]