|
1 | 1 | /**********************************************************************
|
2 | 2 | * plpython.c - python as a procedural language for PostgreSQL
|
3 | 3 | *
|
4 |
| - * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.135 2010/01/16 11:03:51 petere Exp $ |
| 4 | + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.136 2010/01/22 15:45:15 petere Exp $ |
5 | 5 | *
|
6 | 6 | *********************************************************************
|
7 | 7 | */
|
@@ -243,14 +243,13 @@ typedef struct PLyResultObject
|
243 | 243 |
|
244 | 244 | /* function declarations */
|
245 | 245 |
|
246 |
| -/* Two exported functions: first is the magic telling Postgresql |
247 |
| - * what function call interface it implements. Second is for |
248 |
| - * initialization of the interpreter during library load. |
249 |
| - */ |
| 246 | +/* exported functions */ |
250 | 247 | Datum plpython_call_handler(PG_FUNCTION_ARGS);
|
| 248 | +Datum plpython_inline_handler(PG_FUNCTION_ARGS); |
251 | 249 | void _PG_init(void);
|
252 | 250 |
|
253 | 251 | PG_FUNCTION_INFO_V1(plpython_call_handler);
|
| 252 | +PG_FUNCTION_INFO_V1(plpython_inline_handler); |
254 | 253 |
|
255 | 254 | /* most of the remaining of the declarations, all static */
|
256 | 255 |
|
@@ -418,6 +417,12 @@ plpython_error_callback(void *arg)
|
418 | 417 | errcontext("PL/Python function \"%s\"", PLy_procedure_name(PLy_curr_procedure));
|
419 | 418 | }
|
420 | 419 |
|
| 420 | +static void |
| 421 | +plpython_inline_error_callback(void *arg) |
| 422 | +{ |
| 423 | + errcontext("PL/Python anonymous code block"); |
| 424 | +} |
| 425 | + |
421 | 426 | static void
|
422 | 427 | plpython_trigger_error_callback(void *arg)
|
423 | 428 | {
|
@@ -495,6 +500,60 @@ plpython_call_handler(PG_FUNCTION_ARGS)
|
495 | 500 | return retval;
|
496 | 501 | }
|
497 | 502 |
|
| 503 | +Datum |
| 504 | +plpython_inline_handler(PG_FUNCTION_ARGS) |
| 505 | +{ |
| 506 | + InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0)); |
| 507 | + FunctionCallInfoData fake_fcinfo; |
| 508 | + FmgrInfo flinfo; |
| 509 | + PLyProcedure *save_curr_proc; |
| 510 | + PLyProcedure *volatile proc = NULL; |
| 511 | + ErrorContextCallback plerrcontext; |
| 512 | + |
| 513 | + if (SPI_connect() != SPI_OK_CONNECT) |
| 514 | + elog(ERROR, "SPI_connect failed"); |
| 515 | + |
| 516 | + save_curr_proc = PLy_curr_procedure; |
| 517 | + |
| 518 | + /* |
| 519 | + * Setup error traceback support for ereport() |
| 520 | + */ |
| 521 | + plerrcontext.callback = plpython_inline_error_callback; |
| 522 | + plerrcontext.previous = error_context_stack; |
| 523 | + error_context_stack = &plerrcontext; |
| 524 | + |
| 525 | + MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo)); |
| 526 | + MemSet(&flinfo, 0, sizeof(flinfo)); |
| 527 | + fake_fcinfo.flinfo = &flinfo; |
| 528 | + flinfo.fn_oid = InvalidOid; |
| 529 | + flinfo.fn_mcxt = CurrentMemoryContext; |
| 530 | + |
| 531 | + proc = PLy_malloc0(sizeof(PLyProcedure)); |
| 532 | + proc->pyname = PLy_strdup("__plpython_inline_block"); |
| 533 | + proc->result.out.d.typoid = VOIDOID; |
| 534 | + |
| 535 | + PG_TRY(); |
| 536 | + { |
| 537 | + PLy_procedure_compile(proc, codeblock->source_text); |
| 538 | + PLy_curr_procedure = proc; |
| 539 | + PLy_function_handler(&fake_fcinfo, proc); |
| 540 | + } |
| 541 | + PG_CATCH(); |
| 542 | + { |
| 543 | + PLy_curr_procedure = save_curr_proc; |
| 544 | + PyErr_Clear(); |
| 545 | + PG_RE_THROW(); |
| 546 | + } |
| 547 | + PG_END_TRY(); |
| 548 | + |
| 549 | + /* Pop the error context stack */ |
| 550 | + error_context_stack = plerrcontext.previous; |
| 551 | + |
| 552 | + PLy_curr_procedure = save_curr_proc; |
| 553 | + |
| 554 | + PG_RETURN_VOID(); |
| 555 | +} |
| 556 | + |
498 | 557 | /* trigger and function sub handlers
|
499 | 558 | *
|
500 | 559 | * 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)
|
1107 | 1166 | if (rv == NULL || PyErr_Occurred())
|
1108 | 1167 | {
|
1109 | 1168 | Py_XDECREF(rv);
|
1110 |
| - PLy_elog(ERROR, "PL/Python function \"%s\" failed", proc->proname); |
| 1169 | + PLy_elog(ERROR, NULL); |
1111 | 1170 | }
|
1112 | 1171 |
|
1113 | 1172 | return rv;
|
|
0 commit comments