PostgreSQL Source Code  git master
plpy_elog.c File Reference
#include "postgres.h"
#include "lib/stringinfo.h"
#include "plpy_elog.h"
#include "plpy_main.h"
#include "plpy_procedure.h"
#include "plpython.h"
Include dependency graph for plpy_elog.c:

Go to the source code of this file.

Functions

static void PLy_traceback (PyObject *e, PyObject *v, PyObject *tb, char **xmsg, char **tbmsg, int *tb_depth)
 
static void PLy_get_spi_error_data (PyObject *exc, int *sqlerrcode, char **detail, char **hint, char **query, int *position, char **schema_name, char **table_name, char **column_name, char **datatype_name, char **constraint_name)
 
static void PLy_get_error_data (PyObject *exc, int *sqlerrcode, char **detail, char **hint, char **schema_name, char **table_name, char **column_name, char **datatype_name, char **constraint_name)
 
static char * get_source_line (const char *src, int lineno)
 
static void get_string_attr (PyObject *obj, char *attrname, char **str)
 
static bool set_string_attr (PyObject *obj, char *attrname, char *str)
 
void PLy_elog_impl (int elevel, const char *fmt,...)
 
static void PLy_get_sqlerrcode (PyObject *exc, int *sqlerrcode)
 
void PLy_exception_set (PyObject *exc, const char *fmt,...)
 
void PLy_exception_set_plural (PyObject *exc, const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
 
void PLy_exception_set_with_details (PyObject *excclass, ErrorData *edata)
 

Variables

PyObject * PLy_exc_error = NULL
 
PyObject * PLy_exc_fatal = NULL
 
PyObject * PLy_exc_spi_error = NULL
 

Function Documentation

◆ get_source_line()

static char * get_source_line ( const char *  src,
int  lineno 
)
static

Definition at line 433 of file plpy_elog.c.

434 {
435  const char *s = NULL;
436  const char *next = src;
437  int current = 0;
438 
439  /* sanity check */
440  if (lineno <= 0)
441  return NULL;
442 
443  while (current < lineno)
444  {
445  s = next;
446  next = strchr(s + 1, '\n');
447  current++;
448  if (next == NULL)
449  break;
450  }
451 
452  if (current != lineno)
453  return NULL;
454 
455  while (*s && isspace((unsigned char) *s))
456  s++;
457 
458  if (next == NULL)
459  return pstrdup(s);
460 
461  /*
462  * Sanity check, next < s if the line was all-whitespace, which should
463  * never happen if Python reported a frame created on that line, but check
464  * anyway.
465  */
466  if (next < s)
467  return NULL;
468 
469  return pnstrdup(s, next - s);
470 }
static int32 next
Definition: blutils.c:219
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1635
char * pstrdup(const char *in)
Definition: mcxt.c:1624

References next, pnstrdup(), and pstrdup().

Referenced by PLy_traceback().

◆ get_string_attr()

static void get_string_attr ( PyObject *  obj,
char *  attrname,
char **  str 
)
static

Definition at line 565 of file plpy_elog.c.

566 {
567  PyObject *val;
568 
569  val = PyObject_GetAttrString(obj, attrname);
570  if (val != NULL && val != Py_None)
571  {
573  }
574  Py_XDECREF(val);
575 }
long val
Definition: informix.c:664
char * PLyUnicode_AsString(PyObject *unicode)
Definition: plpy_util.c:83

References PLyUnicode_AsString(), pstrdup(), generate_unaccent_rules::str, and val.

Referenced by PLy_get_error_data().

◆ PLy_elog_impl()

void PLy_elog_impl ( int  elevel,
const char *  fmt,
  ... 
)

Definition at line 43 of file plpy_elog.c.

44 {
45  int save_errno = errno;
46  char *xmsg;
47  char *tbmsg;
48  int tb_depth;
49  StringInfoData emsg;
50  PyObject *exc,
51  *val,
52  *tb;
53  const char *primary = NULL;
54  int sqlerrcode = 0;
55  char *detail = NULL;
56  char *hint = NULL;
57  char *query = NULL;
58  int position = 0;
59  char *schema_name = NULL;
60  char *table_name = NULL;
61  char *column_name = NULL;
62  char *datatype_name = NULL;
63  char *constraint_name = NULL;
64 
65  PyErr_Fetch(&exc, &val, &tb);
66 
67  if (exc != NULL)
68  {
69  PyErr_NormalizeException(&exc, &val, &tb);
70 
71  if (PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
72  PLy_get_spi_error_data(val, &sqlerrcode,
73  &detail, &hint, &query, &position,
74  &schema_name, &table_name, &column_name,
75  &datatype_name, &constraint_name);
76  else if (PyErr_GivenExceptionMatches(val, PLy_exc_error))
77  PLy_get_error_data(val, &sqlerrcode, &detail, &hint,
78  &schema_name, &table_name, &column_name,
79  &datatype_name, &constraint_name);
80  else if (PyErr_GivenExceptionMatches(val, PLy_exc_fatal))
81  elevel = FATAL;
82  }
83 
84  /* this releases our refcount on tb! */
85  PLy_traceback(exc, val, tb,
86  &xmsg, &tbmsg, &tb_depth);
87 
88  if (fmt)
89  {
90  initStringInfo(&emsg);
91  for (;;)
92  {
93  va_list ap;
94  int needed;
95 
96  errno = save_errno;
97  va_start(ap, fmt);
98  needed = appendStringInfoVA(&emsg, dgettext(TEXTDOMAIN, fmt), ap);
99  va_end(ap);
100  if (needed == 0)
101  break;
102  enlargeStringInfo(&emsg, needed);
103  }
104  primary = emsg.data;
105 
106  /* Since we have a format string, we cannot have a SPI detail. */
107  Assert(detail == NULL);
108 
109  /* If there's an exception message, it goes in the detail. */
110  if (xmsg)
111  detail = xmsg;
112  }
113  else
114  {
115  if (xmsg)
116  primary = xmsg;
117  }
118 
119  PG_TRY();
120  {
121  ereport(elevel,
122  (errcode(sqlerrcode ? sqlerrcode : ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
123  errmsg_internal("%s", primary ? primary : "no exception data"),
124  (detail) ? errdetail_internal("%s", detail) : 0,
125  (tb_depth > 0 && tbmsg) ? errcontext("%s", tbmsg) : 0,
126  (hint) ? errhint("%s", hint) : 0,
127  (query) ? internalerrquery(query) : 0,
128  (position) ? internalerrposition(position) : 0,
129  (schema_name) ? err_generic_string(PG_DIAG_SCHEMA_NAME,
130  schema_name) : 0,
131  (table_name) ? err_generic_string(PG_DIAG_TABLE_NAME,
132  table_name) : 0,
133  (column_name) ? err_generic_string(PG_DIAG_COLUMN_NAME,
134  column_name) : 0,
135  (datatype_name) ? err_generic_string(PG_DIAG_DATATYPE_NAME,
136  datatype_name) : 0,
137  (constraint_name) ? err_generic_string(PG_DIAG_CONSTRAINT_NAME,
138  constraint_name) : 0));
139  }
140  PG_FINALLY();
141  {
142  if (fmt)
143  pfree(emsg.data);
144  if (xmsg)
145  pfree(xmsg);
146  if (tbmsg)
147  pfree(tbmsg);
148  Py_XDECREF(exc);
149  Py_XDECREF(val);
150  }
151  PG_END_TRY();
152 }
#define dgettext(d, x)
Definition: c.h:1170
int err_generic_string(int field, const char *str)
Definition: elog.c:1511
int internalerrquery(const char *query)
Definition: elog.c:1481
int internalerrposition(int cursorpos)
Definition: elog.c:1461
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1229
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
#define errcontext
Definition: elog.h:196
#define FATAL
Definition: elog.h:41
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define TEXTDOMAIN
Definition: elog.h:152
#define PG_FINALLY(...)
Definition: elog.h:387
#define ereport(elevel,...)
Definition: elog.h:149
static void const char * fmt
va_end(args)
Assert(fmt[strlen(fmt) - 1] !='\n')
va_start(args, fmt)
void pfree(void *pointer)
Definition: mcxt.c:1436
PyObject * PLy_exc_error
Definition: plpy_elog.c:15
static void PLy_get_error_data(PyObject *exc, int *sqlerrcode, char **detail, char **hint, char **schema_name, char **table_name, char **column_name, char **datatype_name, char **constraint_name)
Definition: plpy_elog.c:415
static void PLy_traceback(PyObject *e, PyObject *v, PyObject *tb, char **xmsg, char **tbmsg, int *tb_depth)
Definition: plpy_elog.c:165
PyObject * PLy_exc_spi_error
Definition: plpy_elog.c:17
static void PLy_get_spi_error_data(PyObject *exc, int *sqlerrcode, char **detail, char **hint, char **query, int *position, char **schema_name, char **table_name, char **column_name, char **datatype_name, char **constraint_name)
Definition: plpy_elog.c:379
PyObject * PLy_exc_fatal
Definition: plpy_elog.c:16
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:64
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:68
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:67
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:66
int appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
Definition: stringinfo.c:133
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:283
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

References appendStringInfoVA(), Assert(), StringInfoData::data, dgettext, enlargeStringInfo(), ereport, err_generic_string(), errcode(), errcontext, errdetail_internal(), errhint(), errmsg_internal(), FATAL, fmt, initStringInfo(), internalerrposition(), internalerrquery(), pfree(), PG_DIAG_COLUMN_NAME, PG_DIAG_CONSTRAINT_NAME, PG_DIAG_DATATYPE_NAME, PG_DIAG_SCHEMA_NAME, PG_DIAG_TABLE_NAME, PG_END_TRY, PG_FINALLY, PG_TRY, PLy_exc_error, PLy_exc_fatal, PLy_exc_spi_error, PLy_get_error_data(), PLy_get_spi_error_data(), PLy_traceback(), TEXTDOMAIN, va_end(), va_start(), and val.

Referenced by _PG_init().

◆ PLy_exception_set()

void PLy_exception_set ( PyObject *  exc,
const char *  fmt,
  ... 
)

Definition at line 475 of file plpy_elog.c.

476 {
477  char buf[1024];
478  va_list ap;
479 
480  va_start(ap, fmt);
481  vsnprintf(buf, sizeof(buf), dgettext(TEXTDOMAIN, fmt), ap);
482  va_end(ap);
483 
484  PyErr_SetString(exc, buf);
485 }
static char * buf
Definition: pg_test_fsync.c:67
#define vsnprintf
Definition: port.h:237

References buf, dgettext, fmt, TEXTDOMAIN, va_end(), va_start(), and vsnprintf.

Referenced by PLy_cursor(), PLy_cursor_close(), PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_cursor_plan(), PLy_output(), PLy_result_colnames(), PLy_result_coltypes(), PLy_result_coltypmods(), PLy_spi_execute(), PLy_spi_execute_plan(), PLy_spi_execute_query(), PLy_spi_prepare(), PLy_subtransaction_enter(), and PLy_subtransaction_exit().

◆ PLy_exception_set_plural()

void PLy_exception_set_plural ( PyObject *  exc,
const char *  fmt_singular,
const char *  fmt_plural,
unsigned long  n,
  ... 
)

Definition at line 489 of file plpy_elog.c.

492 {
493  char buf[1024];
494  va_list ap;
495 
496  va_start(ap, n);
497  vsnprintf(buf, sizeof(buf),
498  dngettext(TEXTDOMAIN, fmt_singular, fmt_plural, n),
499  ap);
500  va_end(ap);
501 
502  PyErr_SetString(exc, buf);
503 }
#define dngettext(d, s, p, n)
Definition: c.h:1172

References buf, dngettext, TEXTDOMAIN, va_end(), va_start(), and vsnprintf.

Referenced by PLy_cursor_plan(), and PLy_spi_execute_plan().

◆ PLy_exception_set_with_details()

void PLy_exception_set_with_details ( PyObject *  excclass,
ErrorData edata 
)

Definition at line 507 of file plpy_elog.c.

508 {
509  PyObject *args = NULL;
510  PyObject *error = NULL;
511 
512  args = Py_BuildValue("(s)", edata->message);
513  if (!args)
514  goto failure;
515 
516  /* create a new exception with the error message as the parameter */
517  error = PyObject_CallObject(excclass, args);
518  if (!error)
519  goto failure;
520 
521  if (!set_string_attr(error, "sqlstate",
522  unpack_sql_state(edata->sqlerrcode)))
523  goto failure;
524 
525  if (!set_string_attr(error, "detail", edata->detail))
526  goto failure;
527 
528  if (!set_string_attr(error, "hint", edata->hint))
529  goto failure;
530 
531  if (!set_string_attr(error, "query", edata->internalquery))
532  goto failure;
533 
534  if (!set_string_attr(error, "schema_name", edata->schema_name))
535  goto failure;
536 
537  if (!set_string_attr(error, "table_name", edata->table_name))
538  goto failure;
539 
540  if (!set_string_attr(error, "column_name", edata->column_name))
541  goto failure;
542 
543  if (!set_string_attr(error, "datatype_name", edata->datatype_name))
544  goto failure;
545 
546  if (!set_string_attr(error, "constraint_name", edata->constraint_name))
547  goto failure;
548 
549  PyErr_SetObject(excclass, error);
550 
551  Py_DECREF(args);
552  Py_DECREF(error);
553 
554  return;
555 
556 failure:
557  Py_XDECREF(args);
558  Py_XDECREF(error);
559 
560  elog(ERROR, "could not convert error to Python exception");
561 }
char * unpack_sql_state(int sql_state)
Definition: elog.c:3124
#define ERROR
Definition: elog.h:39
static bool set_string_attr(PyObject *obj, char *attrname, char *str)
Definition: plpy_elog.c:581
static void error(void)
Definition: sql-dyntest.c:147
char * schema_name
Definition: elog.h:446
char * internalquery
Definition: elog.h:453
int sqlerrcode
Definition: elog.h:438
char * datatype_name
Definition: elog.h:449
char * detail
Definition: elog.h:440
char * table_name
Definition: elog.h:447
char * message
Definition: elog.h:439
char * hint
Definition: elog.h:442
char * constraint_name
Definition: elog.h:450
char * column_name
Definition: elog.h:448

References generate_unaccent_rules::args, ErrorData::column_name, ErrorData::constraint_name, ErrorData::datatype_name, ErrorData::detail, elog(), ERROR, error(), ErrorData::hint, ErrorData::internalquery, ErrorData::message, ErrorData::schema_name, set_string_attr(), ErrorData::sqlerrcode, ErrorData::table_name, and unpack_sql_state().

Referenced by PLy_output().

◆ PLy_get_error_data()

static void PLy_get_error_data ( PyObject *  exc,
int *  sqlerrcode,
char **  detail,
char **  hint,
char **  schema_name,
char **  table_name,
char **  column_name,
char **  datatype_name,
char **  constraint_name 
)
static

Definition at line 415 of file plpy_elog.c.

418 {
419  PLy_get_sqlerrcode(exc, sqlerrcode);
420  get_string_attr(exc, "detail", detail);
421  get_string_attr(exc, "hint", hint);
422  get_string_attr(exc, "schema_name", schema_name);
423  get_string_attr(exc, "table_name", table_name);
424  get_string_attr(exc, "column_name", column_name);
425  get_string_attr(exc, "datatype_name", datatype_name);
426  get_string_attr(exc, "constraint_name", constraint_name);
427 }
static void get_string_attr(PyObject *obj, char *attrname, char **str)
Definition: plpy_elog.c:565
static void PLy_get_sqlerrcode(PyObject *exc, int *sqlerrcode)
Definition: plpy_elog.c:355

References get_string_attr(), and PLy_get_sqlerrcode().

Referenced by PLy_elog_impl().

◆ PLy_get_spi_error_data()

static void PLy_get_spi_error_data ( PyObject *  exc,
int *  sqlerrcode,
char **  detail,
char **  hint,
char **  query,
int *  position,
char **  schema_name,
char **  table_name,
char **  column_name,
char **  datatype_name,
char **  constraint_name 
)
static

Definition at line 379 of file plpy_elog.c.

384 {
385  PyObject *spidata;
386 
387  spidata = PyObject_GetAttrString(exc, "spidata");
388 
389  if (spidata != NULL)
390  {
391  PyArg_ParseTuple(spidata, "izzzizzzzz",
392  sqlerrcode, detail, hint, query, position,
393  schema_name, table_name, column_name,
394  datatype_name, constraint_name);
395  }
396  else
397  {
398  /*
399  * If there's no spidata, at least set the sqlerrcode. This can happen
400  * if someone explicitly raises a SPI exception from Python code.
401  */
402  PLy_get_sqlerrcode(exc, sqlerrcode);
403  }
404 
405  Py_XDECREF(spidata);
406 }

References PLy_get_sqlerrcode().

Referenced by PLy_elog_impl().

◆ PLy_get_sqlerrcode()

static void PLy_get_sqlerrcode ( PyObject *  exc,
int *  sqlerrcode 
)
static

Definition at line 355 of file plpy_elog.c.

356 {
357  PyObject *sqlstate;
358  char *buffer;
359 
360  sqlstate = PyObject_GetAttrString(exc, "sqlstate");
361  if (sqlstate == NULL)
362  return;
363 
364  buffer = PLyUnicode_AsString(sqlstate);
365  if (strlen(buffer) == 5 &&
366  strspn(buffer, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
367  {
368  *sqlerrcode = MAKE_SQLSTATE(buffer[0], buffer[1], buffer[2],
369  buffer[3], buffer[4]);
370  }
371 
372  Py_DECREF(sqlstate);
373 }
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:56

References MAKE_SQLSTATE, and PLyUnicode_AsString().

Referenced by PLy_get_error_data(), and PLy_get_spi_error_data().

◆ PLy_traceback()

static void PLy_traceback ( PyObject *  e,
PyObject *  v,
PyObject *  tb,
char **  xmsg,
char **  tbmsg,
int *  tb_depth 
)
static

Definition at line 165 of file plpy_elog.c.

167 {
168  PyObject *e_type_o;
169  PyObject *e_module_o;
170  char *e_type_s = NULL;
171  char *e_module_s = NULL;
172  PyObject *vob = NULL;
173  char *vstr;
174  StringInfoData xstr;
175  StringInfoData tbstr;
176 
177  /*
178  * if no exception, return nulls
179  */
180  if (e == NULL)
181  {
182  *xmsg = NULL;
183  *tbmsg = NULL;
184  *tb_depth = 0;
185 
186  return;
187  }
188 
189  /*
190  * Format the exception and its value and put it in xmsg.
191  */
192 
193  e_type_o = PyObject_GetAttrString(e, "__name__");
194  e_module_o = PyObject_GetAttrString(e, "__module__");
195  if (e_type_o)
196  e_type_s = PLyUnicode_AsString(e_type_o);
197  if (e_type_s)
198  e_module_s = PLyUnicode_AsString(e_module_o);
199 
200  if (v && ((vob = PyObject_Str(v)) != NULL))
201  vstr = PLyUnicode_AsString(vob);
202  else
203  vstr = "unknown";
204 
205  initStringInfo(&xstr);
206  if (!e_type_s || !e_module_s)
207  {
208  /* shouldn't happen */
209  appendStringInfoString(&xstr, "unrecognized exception");
210  }
211  /* mimics behavior of traceback.format_exception_only */
212  else if (strcmp(e_module_s, "builtins") == 0
213  || strcmp(e_module_s, "__main__") == 0
214  || strcmp(e_module_s, "exceptions") == 0)
215  appendStringInfoString(&xstr, e_type_s);
216  else
217  appendStringInfo(&xstr, "%s.%s", e_module_s, e_type_s);
218  appendStringInfo(&xstr, ": %s", vstr);
219 
220  *xmsg = xstr.data;
221 
222  /*
223  * Now format the traceback and put it in tbmsg.
224  */
225 
226  *tb_depth = 0;
227  initStringInfo(&tbstr);
228  /* Mimic Python traceback reporting as close as possible. */
229  appendStringInfoString(&tbstr, "Traceback (most recent call last):");
230  while (tb != NULL && tb != Py_None)
231  {
232  PyObject *volatile tb_prev = NULL;
233  PyObject *volatile frame = NULL;
234  PyObject *volatile code = NULL;
235  PyObject *volatile name = NULL;
236  PyObject *volatile lineno = NULL;
237  PyObject *volatile filename = NULL;
238 
239  PG_TRY();
240  {
241  lineno = PyObject_GetAttrString(tb, "tb_lineno");
242  if (lineno == NULL)
243  elog(ERROR, "could not get line number from Python traceback");
244 
245  frame = PyObject_GetAttrString(tb, "tb_frame");
246  if (frame == NULL)
247  elog(ERROR, "could not get frame from Python traceback");
248 
249  code = PyObject_GetAttrString(frame, "f_code");
250  if (code == NULL)
251  elog(ERROR, "could not get code object from Python frame");
252 
253  name = PyObject_GetAttrString(code, "co_name");
254  if (name == NULL)
255  elog(ERROR, "could not get function name from Python code object");
256 
257  filename = PyObject_GetAttrString(code, "co_filename");
258  if (filename == NULL)
259  elog(ERROR, "could not get file name from Python code object");
260  }
261  PG_CATCH();
262  {
263  Py_XDECREF(frame);
264  Py_XDECREF(code);
265  Py_XDECREF(name);
266  Py_XDECREF(lineno);
267  Py_XDECREF(filename);
268  PG_RE_THROW();
269  }
270  PG_END_TRY();
271 
272  /* The first frame always points at <module>, skip it. */
273  if (*tb_depth > 0)
274  {
276  char *proname;
277  char *fname;
278  char *line;
279  char *plain_filename;
280  long plain_lineno;
281 
282  /*
283  * The second frame points at the internal function, but to mimic
284  * Python error reporting we want to say <module>.
285  */
286  if (*tb_depth == 1)
287  fname = "<module>";
288  else
289  fname = PLyUnicode_AsString(name);
290 
291  proname = PLy_procedure_name(exec_ctx->curr_proc);
292  plain_filename = PLyUnicode_AsString(filename);
293  plain_lineno = PyLong_AsLong(lineno);
294 
295  if (proname == NULL)
296  appendStringInfo(&tbstr, "\n PL/Python anonymous code block, line %ld, in %s",
297  plain_lineno - 1, fname);
298  else
299  appendStringInfo(&tbstr, "\n PL/Python function \"%s\", line %ld, in %s",
300  proname, plain_lineno - 1, fname);
301 
302  /*
303  * function code object was compiled with "<string>" as the
304  * filename
305  */
306  if (exec_ctx->curr_proc && plain_filename != NULL &&
307  strcmp(plain_filename, "<string>") == 0)
308  {
309  /*
310  * If we know the current procedure, append the exact line
311  * from the source, again mimicking Python's traceback.py
312  * module behavior. We could store the already line-split
313  * source to avoid splitting it every time, but producing a
314  * traceback is not the most important scenario to optimize
315  * for. But we do not go as far as traceback.py in reading
316  * the source of imported modules.
317  */
318  line = get_source_line(exec_ctx->curr_proc->src, plain_lineno);
319  if (line)
320  {
321  appendStringInfo(&tbstr, "\n %s", line);
322  pfree(line);
323  }
324  }
325  }
326 
327  Py_DECREF(frame);
328  Py_DECREF(code);
329  Py_DECREF(name);
330  Py_DECREF(lineno);
331  Py_DECREF(filename);
332 
333  /* Release the current frame and go to the next one. */
334  tb_prev = tb;
335  tb = PyObject_GetAttrString(tb, "tb_next");
336  Assert(tb_prev != Py_None);
337  Py_DECREF(tb_prev);
338  if (tb == NULL)
339  elog(ERROR, "could not traverse Python traceback");
340  (*tb_depth)++;
341  }
342 
343  /* Return the traceback. */
344  *tbmsg = tbstr.data;
345 
346  Py_XDECREF(e_type_o);
347  Py_XDECREF(e_module_o);
348  Py_XDECREF(vob);
349 }
#define PG_RE_THROW()
Definition: elog.h:411
#define PG_CATCH(...)
Definition: elog.h:380
const char * name
Definition: encode.c:571
static char * filename
Definition: pg_dumpall.c:119
NameData proname
Definition: pg_proc.h:35
static char * get_source_line(const char *src, int lineno)
Definition: plpy_elog.c:433
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:367
char * PLy_procedure_name(PLyProcedure *proc)
e
Definition: preproc-init.c:82
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
PLyProcedure * curr_proc
Definition: plpy_main.h:20

References appendStringInfo(), appendStringInfoString(), Assert(), PLyExecutionContext::curr_proc, StringInfoData::data, elog(), ERROR, filename, get_source_line(), initStringInfo(), name, pfree(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLy_current_execution_context(), PLy_procedure_name(), PLyUnicode_AsString(), proname, and PLyProcedure::src.

Referenced by PLy_elog_impl().

◆ set_string_attr()

static bool set_string_attr ( PyObject *  obj,
char *  attrname,
char *  str 
)
static

Definition at line 581 of file plpy_elog.c.

582 {
583  int result;
584  PyObject *val;
585 
586  if (str != NULL)
587  {
589  if (!val)
590  return false;
591  }
592  else
593  {
594  val = Py_None;
595  Py_INCREF(Py_None);
596  }
597 
598  result = PyObject_SetAttrString(obj, attrname, val);
599  Py_DECREF(val);
600 
601  return result != -1;
602 }
PyObject * PLyUnicode_FromString(const char *s)
Definition: plpy_util.c:118

References PLyUnicode_FromString(), generate_unaccent_rules::str, and val.

Referenced by PLy_exception_set_with_details().

Variable Documentation

◆ PLy_exc_error

◆ PLy_exc_fatal

PyObject* PLy_exc_fatal = NULL

Definition at line 16 of file plpy_elog.c.

Referenced by PLy_add_exceptions(), and PLy_elog_impl().

◆ PLy_exc_spi_error