1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

PL/Python DO handler

Also cleaned up some redundancies between the primary error messages and the
error context in PL/Python.

Hannu Valtonen
This commit is contained in:
Peter Eisentraut
2010-01-22 15:45:15 +00:00
parent 306a4287c3
commit adb7764030
8 changed files with 102 additions and 16 deletions

View File

@ -1,7 +1,7 @@
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.135 2010/01/16 11:03:51 petere Exp $
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.136 2010/01/22 15:45:15 petere Exp $
*
*********************************************************************
*/
@ -243,14 +243,13 @@ typedef struct PLyResultObject
/* function declarations */
/* Two exported functions: first is the magic telling Postgresql
* what function call interface it implements. Second is for
* initialization of the interpreter during library load.
*/
/* exported functions */
Datum plpython_call_handler(PG_FUNCTION_ARGS);
Datum plpython_inline_handler(PG_FUNCTION_ARGS);
void _PG_init(void);
PG_FUNCTION_INFO_V1(plpython_call_handler);
PG_FUNCTION_INFO_V1(plpython_inline_handler);
/* most of the remaining of the declarations, all static */
@ -418,6 +417,12 @@ plpython_error_callback(void *arg)
errcontext("PL/Python function \"%s\"", PLy_procedure_name(PLy_curr_procedure));
}
static void
plpython_inline_error_callback(void *arg)
{
errcontext("PL/Python anonymous code block");
}
static void
plpython_trigger_error_callback(void *arg)
{
@ -495,6 +500,60 @@ plpython_call_handler(PG_FUNCTION_ARGS)
return retval;
}
Datum
plpython_inline_handler(PG_FUNCTION_ARGS)
{
InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0));
FunctionCallInfoData fake_fcinfo;
FmgrInfo flinfo;
PLyProcedure *save_curr_proc;
PLyProcedure *volatile proc = NULL;
ErrorContextCallback plerrcontext;
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect failed");
save_curr_proc = PLy_curr_procedure;
/*
* Setup error traceback support for ereport()
*/
plerrcontext.callback = plpython_inline_error_callback;
plerrcontext.previous = error_context_stack;
error_context_stack = &plerrcontext;
MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));
MemSet(&flinfo, 0, sizeof(flinfo));
fake_fcinfo.flinfo = &flinfo;
flinfo.fn_oid = InvalidOid;
flinfo.fn_mcxt = CurrentMemoryContext;
proc = PLy_malloc0(sizeof(PLyProcedure));
proc->pyname = PLy_strdup("__plpython_inline_block");
proc->result.out.d.typoid = VOIDOID;
PG_TRY();
{
PLy_procedure_compile(proc, codeblock->source_text);
PLy_curr_procedure = proc;
PLy_function_handler(&fake_fcinfo, proc);
}
PG_CATCH();
{
PLy_curr_procedure = save_curr_proc;
PyErr_Clear();
PG_RE_THROW();
}
PG_END_TRY();
/* Pop the error context stack */
error_context_stack = plerrcontext.previous;
PLy_curr_procedure = save_curr_proc;
PG_RETURN_VOID();
}
/* trigger and function sub handlers
*
* the python function is expected to return Py_None if the tuple is
@ -1107,7 +1166,7 @@ PLy_procedure_call(PLyProcedure *proc, char *kargs, PyObject *vargs)
if (rv == NULL || PyErr_Occurred())
{
Py_XDECREF(rv);
PLy_elog(ERROR, "PL/Python function \"%s\" failed", proc->proname);
PLy_elog(ERROR, NULL);
}
return rv;