|
|
|
|
@ -29,7 +29,7 @@ |
|
|
|
|
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
|
|
|
|
* |
|
|
|
|
* IDENTIFICATION |
|
|
|
|
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.4 2006/02/20 20:10:41 neilc Exp $ |
|
|
|
|
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.5 2007/11/23 01:47:12 alvherre Exp $ |
|
|
|
|
* |
|
|
|
|
********************************************************************* |
|
|
|
|
*/ |
|
|
|
|
@ -48,6 +48,7 @@ |
|
|
|
|
#include "commands/trigger.h" |
|
|
|
|
#include "executor/spi.h" |
|
|
|
|
#include "fmgr.h" |
|
|
|
|
#include "lib/stringinfo.h" |
|
|
|
|
#include "nodes/makefuncs.h" |
|
|
|
|
#include "parser/parse_type.h" |
|
|
|
|
#include "tcop/tcopprot.h" |
|
|
|
|
@ -204,11 +205,8 @@ static char *PLy_procedure_name(PLyProcedure *); |
|
|
|
|
*/ |
|
|
|
|
static void PLy_elog(int, const char *,...); |
|
|
|
|
static char *PLy_traceback(int *); |
|
|
|
|
static char *PLy_vprintf(const char *fmt, va_list ap); |
|
|
|
|
static char *PLy_printf(const char *fmt,...); |
|
|
|
|
|
|
|
|
|
static void *PLy_malloc(size_t); |
|
|
|
|
static void *PLy_realloc(void *, size_t); |
|
|
|
|
static void PLy_free(void *); |
|
|
|
|
|
|
|
|
|
/* sub handlers for functions and triggers
|
|
|
|
|
@ -2478,35 +2476,44 @@ PLy_exception_set(PyObject * exc, const char *fmt,...) |
|
|
|
|
static void |
|
|
|
|
PLy_elog(int elevel, const char *fmt,...) |
|
|
|
|
{ |
|
|
|
|
va_list ap; |
|
|
|
|
char *xmsg, |
|
|
|
|
*emsg; |
|
|
|
|
char *xmsg; |
|
|
|
|
int xlevel; |
|
|
|
|
StringInfoData emsg; |
|
|
|
|
|
|
|
|
|
xmsg = PLy_traceback(&xlevel); |
|
|
|
|
|
|
|
|
|
va_start(ap, fmt); |
|
|
|
|
emsg = PLy_vprintf(fmt, ap); |
|
|
|
|
va_end(ap); |
|
|
|
|
initStringInfo(&emsg); |
|
|
|
|
for (;;) |
|
|
|
|
{ |
|
|
|
|
va_list ap; |
|
|
|
|
bool success; |
|
|
|
|
|
|
|
|
|
va_start(ap, fmt); |
|
|
|
|
success = appendStringInfoVA(&emsg, fmt, ap); |
|
|
|
|
va_end(ap); |
|
|
|
|
if (success) |
|
|
|
|
break; |
|
|
|
|
enlargeStringInfo(&emsg, emsg.maxlen); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PG_TRY(); |
|
|
|
|
{ |
|
|
|
|
ereport(elevel, |
|
|
|
|
(errmsg("plpython: %s", emsg), |
|
|
|
|
(errmsg("plpython: %s", emsg.data), |
|
|
|
|
(xmsg) ? errdetail("%s", xmsg) : 0)); |
|
|
|
|
} |
|
|
|
|
PG_CATCH(); |
|
|
|
|
{ |
|
|
|
|
PLy_free(emsg); |
|
|
|
|
pfree(emsg.data); |
|
|
|
|
if (xmsg) |
|
|
|
|
PLy_free(xmsg); |
|
|
|
|
pfree(xmsg); |
|
|
|
|
PG_RE_THROW(); |
|
|
|
|
} |
|
|
|
|
PG_END_TRY(); |
|
|
|
|
|
|
|
|
|
PLy_free(emsg); |
|
|
|
|
pfree(emsg.data); |
|
|
|
|
if (xmsg) |
|
|
|
|
PLy_free(xmsg); |
|
|
|
|
pfree(xmsg); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char * |
|
|
|
|
@ -2518,8 +2525,8 @@ PLy_traceback(int *xlevel) |
|
|
|
|
PyObject *eob, |
|
|
|
|
*vob = NULL; |
|
|
|
|
char *vstr, |
|
|
|
|
*estr, |
|
|
|
|
*xstr = NULL; |
|
|
|
|
*estr; |
|
|
|
|
StringInfoData xstr; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* get the current exception |
|
|
|
|
@ -2551,7 +2558,8 @@ PLy_traceback(int *xlevel) |
|
|
|
|
* Assert() be more appropriate? |
|
|
|
|
*/ |
|
|
|
|
estr = eob ? PyString_AsString(eob) : "Unknown Exception"; |
|
|
|
|
xstr = PLy_printf("%s: %s", estr, vstr); |
|
|
|
|
initStringInfo(&xstr); |
|
|
|
|
appendStringInfo(&xstr, "%s: %s", estr, vstr); |
|
|
|
|
|
|
|
|
|
Py_DECREF(eob); |
|
|
|
|
Py_XDECREF(vob); |
|
|
|
|
@ -2568,49 +2576,7 @@ PLy_traceback(int *xlevel) |
|
|
|
|
*xlevel = ERROR; |
|
|
|
|
|
|
|
|
|
Py_DECREF(e); |
|
|
|
|
return xstr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char * |
|
|
|
|
PLy_printf(const char *fmt,...) |
|
|
|
|
{ |
|
|
|
|
va_list ap; |
|
|
|
|
char *emsg; |
|
|
|
|
|
|
|
|
|
va_start(ap, fmt); |
|
|
|
|
emsg = PLy_vprintf(fmt, ap); |
|
|
|
|
va_end(ap); |
|
|
|
|
return emsg; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char * |
|
|
|
|
PLy_vprintf(const char *fmt, va_list ap) |
|
|
|
|
{ |
|
|
|
|
size_t blen; |
|
|
|
|
int bchar, |
|
|
|
|
tries = 2; |
|
|
|
|
char *buf; |
|
|
|
|
|
|
|
|
|
blen = strlen(fmt) * 2; |
|
|
|
|
if (blen < 256) |
|
|
|
|
blen = 256; |
|
|
|
|
buf = PLy_malloc(blen * sizeof(char)); |
|
|
|
|
|
|
|
|
|
while (1) |
|
|
|
|
{ |
|
|
|
|
bchar = vsnprintf(buf, blen, fmt, ap); |
|
|
|
|
if ((bchar > 0) && (bchar < blen)) |
|
|
|
|
return buf; |
|
|
|
|
if (tries-- <= 0) |
|
|
|
|
break; |
|
|
|
|
if (blen > 0) |
|
|
|
|
blen = bchar + 1; |
|
|
|
|
else |
|
|
|
|
blen *= 2; |
|
|
|
|
buf = PLy_realloc(buf, blen); |
|
|
|
|
} |
|
|
|
|
PLy_free(buf); |
|
|
|
|
return NULL; |
|
|
|
|
return xstr.data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* python module code
|
|
|
|
|
@ -2632,18 +2598,6 @@ PLy_malloc(size_t bytes) |
|
|
|
|
return ptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void * |
|
|
|
|
PLy_realloc(void *optr, size_t bytes) |
|
|
|
|
{ |
|
|
|
|
void *nptr = realloc(optr, bytes); |
|
|
|
|
|
|
|
|
|
if (nptr == NULL) |
|
|
|
|
ereport(FATAL, |
|
|
|
|
(errcode(ERRCODE_OUT_OF_MEMORY), |
|
|
|
|
errmsg("out of memory"))); |
|
|
|
|
return nptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* define this away
|
|
|
|
|
*/ |
|
|
|
|
static void |
|
|
|
|
|