Line data Source code
1 : /*
2 : * executing Python code
3 : *
4 : * src/pl/plpython/plpy_exec.c
5 : */
6 :
7 : #include "postgres.h"
8 :
9 : #include "access/htup_details.h"
10 : #include "access/xact.h"
11 : #include "catalog/pg_type.h"
12 : #include "commands/event_trigger.h"
13 : #include "commands/trigger.h"
14 : #include "executor/spi.h"
15 : #include "funcapi.h"
16 : #include "plpy_elog.h"
17 : #include "plpy_exec.h"
18 : #include "plpy_main.h"
19 : #include "plpy_procedure.h"
20 : #include "plpy_subxactobject.h"
21 : #include "plpy_util.h"
22 : #include "utils/fmgrprotos.h"
23 : #include "utils/rel.h"
24 :
25 : /* saved state for a set-returning function */
26 : typedef struct PLySRFState
27 : {
28 : PyObject *iter; /* Python iterator producing results */
29 : PLySavedArgs *savedargs; /* function argument values */
30 : MemoryContextCallback callback; /* for releasing refcounts when done */
31 : } PLySRFState;
32 :
33 : static PyObject *PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc);
34 : static PLySavedArgs *PLy_function_save_args(PLyProcedure *proc);
35 : static void PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs);
36 : static void PLy_function_drop_args(PLySavedArgs *savedargs);
37 : static void PLy_global_args_push(PLyProcedure *proc);
38 : static void PLy_global_args_pop(PLyProcedure *proc);
39 : static void plpython_srf_cleanup_callback(void *arg);
40 : static void plpython_return_error_callback(void *arg);
41 :
42 : static PyObject *PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc,
43 : HeapTuple *rv);
44 : static HeapTuple PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd,
45 : TriggerData *tdata, HeapTuple otup);
46 : static void plpython_trigger_error_callback(void *arg);
47 :
48 : static PyObject *PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs);
49 : static void PLy_abort_open_subtransactions(int save_subxact_level);
50 :
51 :
52 : /* function subhandler */
53 : Datum
54 660 : PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
55 : {
56 660 : bool is_setof = proc->is_setof;
57 : Datum rv;
58 660 : PyObject *volatile plargs = NULL;
59 660 : PyObject *volatile plrv = NULL;
60 660 : FuncCallContext *volatile funcctx = NULL;
61 660 : PLySRFState *volatile srfstate = NULL;
62 : ErrorContextCallback plerrcontext;
63 :
64 : /*
65 : * If the function is called recursively, we must push outer-level
66 : * arguments into the stack. This must be immediately before the PG_TRY
67 : * to ensure that the corresponding pop happens.
68 : */
69 660 : PLy_global_args_push(proc);
70 :
71 660 : PG_TRY();
72 : {
73 660 : if (is_setof)
74 : {
75 : /* First Call setup */
76 200 : if (SRF_IS_FIRSTCALL())
77 : {
78 53 : funcctx = SRF_FIRSTCALL_INIT();
79 53 : srfstate = (PLySRFState *)
80 53 : MemoryContextAllocZero(funcctx->multi_call_memory_ctx,
81 : sizeof(PLySRFState));
82 : /* Immediately register cleanup callback */
83 53 : srfstate->callback.func = plpython_srf_cleanup_callback;
84 53 : srfstate->callback.arg = srfstate;
85 53 : MemoryContextRegisterResetCallback(funcctx->multi_call_memory_ctx,
86 53 : &srfstate->callback);
87 53 : funcctx->user_fctx = srfstate;
88 : }
89 : /* Every call setup */
90 200 : funcctx = SRF_PERCALL_SETUP();
91 : Assert(funcctx != NULL);
92 200 : srfstate = (PLySRFState *) funcctx->user_fctx;
93 : Assert(srfstate != NULL);
94 : }
95 :
96 660 : if (srfstate == NULL || srfstate->iter == NULL)
97 : {
98 : /*
99 : * Non-SETOF function or first time for SETOF function: build
100 : * args, then actually execute the function.
101 : */
102 513 : plargs = PLy_function_build_args(fcinfo, proc);
103 513 : plrv = PLy_procedure_call(proc, "args", plargs);
104 459 : Assert(plrv != NULL);
105 : }
106 : else
107 : {
108 : /*
109 : * Second or later call for a SETOF function: restore arguments in
110 : * globals dict to what they were when we left off. We must do
111 : * this in case multiple evaluations of the same SETOF function
112 : * are interleaved. It's a bit annoying, since the iterator may
113 : * not look at the arguments at all, but we have no way to know
114 : * that. Fortunately this isn't terribly expensive.
115 : */
116 147 : if (srfstate->savedargs)
117 147 : PLy_function_restore_args(proc, srfstate->savedargs);
118 147 : srfstate->savedargs = NULL; /* deleted by restore_args */
119 : }
120 :
121 : /*
122 : * If it returns a set, call the iterator to get the next return item.
123 : * We stay in the SPI context while doing this, because PyIter_Next()
124 : * calls back into Python code which might contain SPI calls.
125 : */
126 606 : if (is_setof)
127 : {
128 199 : if (srfstate->iter == NULL)
129 : {
130 : /* first time -- do checks and setup */
131 52 : ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
132 :
133 52 : if (!rsi || !IsA(rsi, ReturnSetInfo) ||
134 52 : (rsi->allowedModes & SFRM_ValuePerCall) == 0)
135 : {
136 0 : ereport(ERROR,
137 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
138 : errmsg("unsupported set function return mode"),
139 : errdetail("PL/Python set-returning functions only support returning one value per call.")));
140 : }
141 52 : rsi->returnMode = SFRM_ValuePerCall;
142 :
143 : /* Make iterator out of returned object */
144 52 : srfstate->iter = PyObject_GetIter(plrv);
145 :
146 52 : Py_DECREF(plrv);
147 52 : plrv = NULL;
148 :
149 52 : if (srfstate->iter == NULL)
150 1 : ereport(ERROR,
151 : (errcode(ERRCODE_DATATYPE_MISMATCH),
152 : errmsg("returned object cannot be iterated"),
153 : errdetail("PL/Python set-returning functions must return an iterable object.")));
154 : }
155 :
156 : /* Fetch next from iterator */
157 198 : plrv = PyIter_Next(srfstate->iter);
158 198 : if (plrv == NULL)
159 : {
160 : /* Iterator is exhausted or error happened */
161 49 : bool has_error = (PyErr_Occurred() != NULL);
162 :
163 49 : Py_DECREF(srfstate->iter);
164 49 : srfstate->iter = NULL;
165 :
166 49 : if (has_error)
167 1 : PLy_elog(ERROR, "error fetching next item from iterator");
168 :
169 : /* Pass a null through the data-returning steps below */
170 : Py_INCREF(Py_None);
171 48 : plrv = Py_None;
172 : }
173 : else
174 : {
175 : /*
176 : * This won't be last call, so save argument values. We do
177 : * this again each time in case the iterator is changing those
178 : * values.
179 : */
180 149 : srfstate->savedargs = PLy_function_save_args(proc);
181 : }
182 : }
183 :
184 : /*
185 : * Disconnect from SPI manager and then create the return values datum
186 : * (if the input function does a palloc for it this must not be
187 : * allocated in the SPI memory context because SPI_finish would free
188 : * it).
189 : */
190 604 : if (SPI_finish() != SPI_OK_FINISH)
191 0 : elog(ERROR, "SPI_finish failed");
192 :
193 604 : plerrcontext.callback = plpython_return_error_callback;
194 604 : plerrcontext.previous = error_context_stack;
195 604 : error_context_stack = &plerrcontext;
196 :
197 : /*
198 : * For a procedure or function declared to return void, the Python
199 : * return value must be None. For void-returning functions, we also
200 : * treat a None return value as a special "void datum" rather than
201 : * NULL (as is the case for non-void-returning functions).
202 : */
203 604 : if (proc->result.typoid == VOIDOID)
204 : {
205 29 : if (plrv != Py_None)
206 : {
207 2 : if (proc->is_procedure)
208 1 : ereport(ERROR,
209 : (errcode(ERRCODE_DATATYPE_MISMATCH),
210 : errmsg("PL/Python procedure did not return None")));
211 : else
212 1 : ereport(ERROR,
213 : (errcode(ERRCODE_DATATYPE_MISMATCH),
214 : errmsg("PL/Python function with return type \"void\" did not return None")));
215 : }
216 :
217 27 : fcinfo->isnull = false;
218 27 : rv = (Datum) 0;
219 : }
220 575 : else if (plrv == Py_None &&
221 55 : srfstate && srfstate->iter == NULL)
222 : {
223 : /*
224 : * In a SETOF function, the iteration-ending null isn't a real
225 : * value; don't pass it through the input function, which might
226 : * complain.
227 : */
228 48 : fcinfo->isnull = true;
229 48 : rv = (Datum) 0;
230 : }
231 : else
232 : {
233 : /*
234 : * Normal conversion of result. However, if the result is of type
235 : * RECORD, we have to set up for that each time through, since it
236 : * might be different from last time.
237 : */
238 527 : if (proc->result.typoid == RECORDOID)
239 : {
240 : TupleDesc desc;
241 :
242 134 : if (get_call_result_type(fcinfo, NULL, &desc) != TYPEFUNC_COMPOSITE)
243 0 : ereport(ERROR,
244 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
245 : errmsg("function returning record called in context "
246 : "that cannot accept type record")));
247 134 : PLy_output_setup_record(&proc->result, desc, proc);
248 : }
249 :
250 527 : rv = PLy_output_convert(&proc->result, plrv,
251 : &fcinfo->isnull);
252 : }
253 : }
254 92 : PG_CATCH();
255 : {
256 : /* Pop old arguments from the stack if they were pushed above */
257 92 : PLy_global_args_pop(proc);
258 :
259 92 : Py_XDECREF(plargs);
260 92 : Py_XDECREF(plrv);
261 :
262 : /*
263 : * If there was an error within a SRF, the iterator might not have
264 : * been exhausted yet. Clear it so the next invocation of the
265 : * function will start the iteration again. (This code is probably
266 : * unnecessary now; plpython_srf_cleanup_callback should take care of
267 : * cleanup. But it doesn't hurt anything to do it here.)
268 : */
269 92 : if (srfstate)
270 : {
271 5 : Py_XDECREF(srfstate->iter);
272 5 : srfstate->iter = NULL;
273 : /* And drop any saved args; we won't need them */
274 5 : if (srfstate->savedargs)
275 2 : PLy_function_drop_args(srfstate->savedargs);
276 5 : srfstate->savedargs = NULL;
277 : }
278 :
279 92 : PG_RE_THROW();
280 : }
281 568 : PG_END_TRY();
282 :
283 568 : error_context_stack = plerrcontext.previous;
284 :
285 : /* Pop old arguments from the stack if they were pushed above */
286 568 : PLy_global_args_pop(proc);
287 :
288 568 : Py_XDECREF(plargs);
289 568 : Py_DECREF(plrv);
290 :
291 568 : if (srfstate)
292 : {
293 : /* We're in a SRF, exit appropriately */
294 195 : if (srfstate->iter == NULL)
295 : {
296 : /* Iterator exhausted, so we're done */
297 48 : SRF_RETURN_DONE(funcctx);
298 : }
299 147 : else if (fcinfo->isnull)
300 7 : SRF_RETURN_NEXT_NULL(funcctx);
301 : else
302 140 : SRF_RETURN_NEXT(funcctx, rv);
303 : }
304 :
305 : /* Plain function, just return the Datum value (possibly null) */
306 373 : return rv;
307 : }
308 :
309 : /*
310 : * trigger subhandler
311 : *
312 : * the python function is expected to return Py_None if the tuple is
313 : * acceptable and unmodified. Otherwise it should return a PyUnicode
314 : * object who's value is SKIP, or MODIFY. SKIP means don't perform
315 : * this action. MODIFY means the tuple has been modified, so update
316 : * tuple and perform action. SKIP and MODIFY assume the trigger fires
317 : * BEFORE the event and is ROW level. postgres expects the function
318 : * to take no arguments and return an argument of type trigger.
319 : */
320 : HeapTuple
321 49 : PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
322 : {
323 49 : HeapTuple rv = NULL;
324 49 : PyObject *volatile plargs = NULL;
325 49 : PyObject *volatile plrv = NULL;
326 : TriggerData *tdata;
327 : TupleDesc rel_descr;
328 :
329 : Assert(CALLED_AS_TRIGGER(fcinfo));
330 49 : tdata = (TriggerData *) fcinfo->context;
331 :
332 : /*
333 : * Input/output conversion for trigger tuples. We use the result and
334 : * result_in fields to store the tuple conversion info. We do this over
335 : * again on each call to cover the possibility that the relation's tupdesc
336 : * changed since the trigger was last called. The PLy_xxx_setup_func
337 : * calls should only happen once, but PLy_input_setup_tuple and
338 : * PLy_output_setup_tuple are responsible for not doing repetitive work.
339 : */
340 49 : rel_descr = RelationGetDescr(tdata->tg_relation);
341 49 : if (proc->result.typoid != rel_descr->tdtypeid)
342 26 : PLy_output_setup_func(&proc->result, proc->mcxt,
343 : rel_descr->tdtypeid,
344 : rel_descr->tdtypmod,
345 : proc);
346 49 : if (proc->result_in.typoid != rel_descr->tdtypeid)
347 26 : PLy_input_setup_func(&proc->result_in, proc->mcxt,
348 : rel_descr->tdtypeid,
349 : rel_descr->tdtypmod,
350 : proc);
351 49 : PLy_output_setup_tuple(&proc->result, rel_descr, proc);
352 49 : PLy_input_setup_tuple(&proc->result_in, rel_descr, proc);
353 :
354 : /*
355 : * If the trigger is called recursively, we must push outer-level
356 : * arguments into the stack. This must be immediately before the PG_TRY
357 : * to ensure that the corresponding pop happens.
358 : */
359 49 : PLy_global_args_push(proc);
360 :
361 49 : PG_TRY();
362 : {
363 : int rc PG_USED_FOR_ASSERTS_ONLY;
364 :
365 49 : rc = SPI_register_trigger_data(tdata);
366 : Assert(rc >= 0);
367 :
368 49 : plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
369 49 : plrv = PLy_procedure_call(proc, "TD", plargs);
370 :
371 : Assert(plrv != NULL);
372 :
373 : /*
374 : * Disconnect from SPI manager
375 : */
376 49 : if (SPI_finish() != SPI_OK_FINISH)
377 0 : elog(ERROR, "SPI_finish failed");
378 :
379 : /*
380 : * return of None means we're happy with the tuple
381 : */
382 49 : if (plrv != Py_None)
383 : {
384 : char *srv;
385 :
386 25 : if (PyUnicode_Check(plrv))
387 24 : srv = PLyUnicode_AsString(plrv);
388 : else
389 : {
390 1 : ereport(ERROR,
391 : (errcode(ERRCODE_DATA_EXCEPTION),
392 : errmsg("unexpected return value from trigger procedure"),
393 : errdetail("Expected None or a string.")));
394 : srv = NULL; /* keep compiler quiet */
395 : }
396 :
397 24 : if (pg_strcasecmp(srv, "SKIP") == 0)
398 1 : rv = NULL;
399 23 : else if (pg_strcasecmp(srv, "MODIFY") == 0)
400 : {
401 21 : if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event) ||
402 9 : TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
403 20 : rv = PLy_modify_tuple(proc, plargs, tdata, rv);
404 : else
405 1 : ereport(WARNING,
406 : (errmsg("PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored")));
407 : }
408 2 : else if (pg_strcasecmp(srv, "OK") != 0)
409 : {
410 : /*
411 : * accept "OK" as an alternative to None; otherwise, raise an
412 : * error
413 : */
414 2 : ereport(ERROR,
415 : (errcode(ERRCODE_DATA_EXCEPTION),
416 : errmsg("unexpected return value from trigger procedure"),
417 : errdetail("Expected None, \"OK\", \"SKIP\", or \"MODIFY\".")));
418 : }
419 : }
420 : }
421 9 : PG_FINALLY();
422 : {
423 49 : PLy_global_args_pop(proc);
424 49 : Py_XDECREF(plargs);
425 49 : Py_XDECREF(plrv);
426 : }
427 49 : PG_END_TRY();
428 :
429 40 : return rv;
430 : }
431 :
432 : /*
433 : * event trigger subhandler
434 : */
435 : void
436 10 : PLy_exec_event_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
437 : {
438 : EventTriggerData *tdata;
439 10 : PyObject *volatile pltdata = NULL;
440 :
441 : Assert(CALLED_AS_EVENT_TRIGGER(fcinfo));
442 10 : tdata = (EventTriggerData *) fcinfo->context;
443 :
444 10 : PG_TRY();
445 : {
446 : PyObject *pltevent,
447 : *plttag;
448 :
449 10 : pltdata = PyDict_New();
450 10 : if (!pltdata)
451 0 : PLy_elog(ERROR, NULL);
452 :
453 10 : pltevent = PLyUnicode_FromString(tdata->event);
454 10 : PyDict_SetItemString(pltdata, "event", pltevent);
455 : Py_DECREF(pltevent);
456 :
457 10 : plttag = PLyUnicode_FromString(GetCommandTagName(tdata->tag));
458 10 : PyDict_SetItemString(pltdata, "tag", plttag);
459 : Py_DECREF(plttag);
460 :
461 10 : PLy_procedure_call(proc, "TD", pltdata);
462 :
463 10 : if (SPI_finish() != SPI_OK_FINISH)
464 0 : elog(ERROR, "SPI_finish() failed");
465 : }
466 0 : PG_FINALLY();
467 : {
468 10 : Py_XDECREF(pltdata);
469 : }
470 10 : PG_END_TRY();
471 10 : }
472 :
473 : /* helper functions for Python code execution */
474 :
475 : static PyObject *
476 513 : PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
477 : {
478 513 : PyObject *volatile arg = NULL;
479 : PyObject *args;
480 : int i;
481 :
482 : /*
483 : * Make any Py*_New() calls before the PG_TRY block so that we can quickly
484 : * return NULL on failure. We can't return within the PG_TRY block, else
485 : * we'd miss unwinding the exception stack.
486 : */
487 513 : args = PyList_New(proc->nargs);
488 513 : if (!args)
489 0 : return NULL;
490 :
491 513 : PG_TRY();
492 : {
493 1228 : for (i = 0; i < proc->nargs; i++)
494 : {
495 715 : PLyDatumToOb *arginfo = &proc->args[i];
496 :
497 715 : if (fcinfo->args[i].isnull)
498 121 : arg = NULL;
499 : else
500 594 : arg = PLy_input_convert(arginfo, fcinfo->args[i].value);
501 :
502 715 : if (arg == NULL)
503 : {
504 : Py_INCREF(Py_None);
505 121 : arg = Py_None;
506 : }
507 :
508 715 : if (PyList_SetItem(args, i, arg) == -1)
509 0 : PLy_elog(ERROR, "PyList_SetItem() failed, while setting up arguments");
510 :
511 715 : if (proc->argnames && proc->argnames[i] &&
512 712 : PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1)
513 0 : PLy_elog(ERROR, "PyDict_SetItemString() failed, while setting up arguments");
514 715 : arg = NULL;
515 : }
516 : }
517 0 : PG_CATCH();
518 : {
519 0 : Py_XDECREF(arg);
520 0 : Py_XDECREF(args);
521 :
522 0 : PG_RE_THROW();
523 : }
524 513 : PG_END_TRY();
525 :
526 513 : return args;
527 : }
528 :
529 : /*
530 : * Construct a PLySavedArgs struct representing the current values of the
531 : * procedure's arguments in its globals dict. This can be used to restore
532 : * those values when exiting a recursive call level or returning control to a
533 : * set-returning function.
534 : *
535 : * This would not be necessary except for an ancient decision to make args
536 : * available via the proc's globals :-( ... but we're stuck with that now.
537 : */
538 : static PLySavedArgs *
539 160 : PLy_function_save_args(PLyProcedure *proc)
540 : {
541 : PLySavedArgs *result;
542 :
543 : /* saved args are always allocated in procedure's context */
544 : result = (PLySavedArgs *)
545 160 : MemoryContextAllocZero(proc->mcxt,
546 160 : offsetof(PLySavedArgs, namedargs) +
547 160 : proc->nargs * sizeof(PyObject *));
548 160 : result->nargs = proc->nargs;
549 :
550 : /* Fetch the "args" list */
551 160 : result->args = PyDict_GetItemString(proc->globals, "args");
552 160 : Py_XINCREF(result->args);
553 :
554 : /* If it's a trigger, also save "TD" */
555 160 : if (proc->is_trigger == PLPY_TRIGGER)
556 : {
557 1 : result->td = PyDict_GetItemString(proc->globals, "TD");
558 1 : Py_XINCREF(result->td);
559 : }
560 :
561 : /* Fetch all the named arguments */
562 160 : if (proc->argnames)
563 : {
564 : int i;
565 :
566 313 : for (i = 0; i < result->nargs; i++)
567 : {
568 216 : if (proc->argnames[i])
569 : {
570 432 : result->namedargs[i] = PyDict_GetItemString(proc->globals,
571 216 : proc->argnames[i]);
572 216 : Py_XINCREF(result->namedargs[i]);
573 : }
574 : }
575 : }
576 :
577 160 : return result;
578 : }
579 :
580 : /*
581 : * Restore procedure's arguments from a PLySavedArgs struct,
582 : * then free the struct.
583 : */
584 : static void
585 158 : PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs)
586 : {
587 : /* Restore named arguments into their slots in the globals dict */
588 158 : if (proc->argnames)
589 : {
590 : int i;
591 :
592 313 : for (i = 0; i < savedargs->nargs; i++)
593 : {
594 216 : if (proc->argnames[i] && savedargs->namedargs[i])
595 : {
596 216 : PyDict_SetItemString(proc->globals, proc->argnames[i],
597 : savedargs->namedargs[i]);
598 216 : Py_DECREF(savedargs->namedargs[i]);
599 : }
600 : }
601 : }
602 :
603 : /* Restore the "args" object, too */
604 158 : if (savedargs->args)
605 : {
606 157 : PyDict_SetItemString(proc->globals, "args", savedargs->args);
607 157 : Py_DECREF(savedargs->args);
608 : }
609 :
610 : /* Restore the "TD" object, too */
611 158 : if (savedargs->td)
612 : {
613 1 : PyDict_SetItemString(proc->globals, "TD", savedargs->td);
614 1 : Py_DECREF(savedargs->td);
615 : }
616 :
617 : /* And free the PLySavedArgs struct */
618 158 : pfree(savedargs);
619 158 : }
620 :
621 : /*
622 : * Free a PLySavedArgs struct without restoring the values.
623 : */
624 : static void
625 2 : PLy_function_drop_args(PLySavedArgs *savedargs)
626 : {
627 : int i;
628 :
629 : /* Drop references for named args */
630 2 : for (i = 0; i < savedargs->nargs; i++)
631 : {
632 0 : Py_XDECREF(savedargs->namedargs[i]);
633 : }
634 :
635 : /* Drop refs to the "args" and "TD" objects, too */
636 2 : Py_XDECREF(savedargs->args);
637 2 : Py_XDECREF(savedargs->td);
638 :
639 : /* And free the PLySavedArgs struct */
640 2 : pfree(savedargs);
641 2 : }
642 :
643 : /*
644 : * Save away any existing arguments for the given procedure, so that we can
645 : * install new values for a recursive call. This should be invoked before
646 : * doing PLy_function_build_args() or PLy_trigger_build_args().
647 : *
648 : * NB: callers must ensure that PLy_global_args_pop gets invoked once, and
649 : * only once, per successful completion of PLy_global_args_push. Otherwise
650 : * we'll end up out-of-sync between the actual call stack and the contents
651 : * of proc->argstack.
652 : */
653 : static void
654 709 : PLy_global_args_push(PLyProcedure *proc)
655 : {
656 : /* We only need to push if we are already inside some active call */
657 709 : if (proc->calldepth > 0)
658 : {
659 : PLySavedArgs *node;
660 :
661 : /* Build a struct containing current argument values */
662 11 : node = PLy_function_save_args(proc);
663 :
664 : /*
665 : * Push the saved argument values into the procedure's stack. Once we
666 : * modify either proc->argstack or proc->calldepth, we had better
667 : * return without the possibility of error.
668 : */
669 11 : node->next = proc->argstack;
670 11 : proc->argstack = node;
671 : }
672 709 : proc->calldepth++;
673 709 : }
674 :
675 : /*
676 : * Pop old arguments when exiting a recursive call.
677 : *
678 : * Note: the idea here is to adjust the proc's callstack state before doing
679 : * anything that could possibly fail. In event of any error, we want the
680 : * callstack to look like we've done the pop. Leaking a bit of memory is
681 : * tolerable.
682 : */
683 : static void
684 709 : PLy_global_args_pop(PLyProcedure *proc)
685 : {
686 : Assert(proc->calldepth > 0);
687 : /* We only need to pop if we were already inside some active call */
688 709 : if (proc->calldepth > 1)
689 : {
690 11 : PLySavedArgs *ptr = proc->argstack;
691 :
692 : /* Pop the callstack */
693 : Assert(ptr != NULL);
694 11 : proc->argstack = ptr->next;
695 11 : proc->calldepth--;
696 :
697 : /* Restore argument values, then free ptr */
698 11 : PLy_function_restore_args(proc, ptr);
699 : }
700 : else
701 : {
702 : /* Exiting call depth 1 */
703 : Assert(proc->argstack == NULL);
704 698 : proc->calldepth--;
705 :
706 : /*
707 : * We used to delete the named arguments (but not "args") from the
708 : * proc's globals dict when exiting the outermost call level for a
709 : * function. This seems rather pointless though: nothing can see the
710 : * dict until the function is called again, at which time we'll
711 : * overwrite those dict entries. So don't bother with that.
712 : */
713 : }
714 709 : }
715 :
716 : /*
717 : * Memory context deletion callback for cleaning up a PLySRFState.
718 : * We need this in case execution of the SRF is terminated early,
719 : * due to error or the caller simply not running it to completion.
720 : */
721 : static void
722 53 : plpython_srf_cleanup_callback(void *arg)
723 : {
724 53 : PLySRFState *srfstate = (PLySRFState *) arg;
725 :
726 : /* Release refcount on the iter, if we still have one */
727 53 : Py_XDECREF(srfstate->iter);
728 53 : srfstate->iter = NULL;
729 : /* And drop any saved args; we won't need them */
730 53 : if (srfstate->savedargs)
731 0 : PLy_function_drop_args(srfstate->savedargs);
732 53 : srfstate->savedargs = NULL;
733 53 : }
734 :
735 : static void
736 37 : plpython_return_error_callback(void *arg)
737 : {
738 37 : PLyExecutionContext *exec_ctx = PLy_current_execution_context();
739 :
740 37 : if (exec_ctx->curr_proc &&
741 37 : !exec_ctx->curr_proc->is_procedure)
742 36 : errcontext("while creating return value");
743 37 : }
744 :
745 : static PyObject *
746 49 : PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *rv)
747 : {
748 49 : TriggerData *tdata = (TriggerData *) fcinfo->context;
749 49 : TupleDesc rel_descr = RelationGetDescr(tdata->tg_relation);
750 : PyObject *pltname,
751 : *pltevent,
752 : *pltwhen,
753 : *pltlevel,
754 : *pltrelid,
755 : *plttablename,
756 : *plttableschema,
757 : *pltargs,
758 : *pytnew,
759 : *pytold,
760 : *pltdata;
761 : char *stroid;
762 :
763 : /*
764 : * Make any Py*_New() calls before the PG_TRY block so that we can quickly
765 : * return NULL on failure. We can't return within the PG_TRY block, else
766 : * we'd miss unwinding the exception stack.
767 : */
768 49 : pltdata = PyDict_New();
769 49 : if (!pltdata)
770 0 : return NULL;
771 :
772 49 : if (tdata->tg_trigger->tgnargs)
773 : {
774 16 : pltargs = PyList_New(tdata->tg_trigger->tgnargs);
775 16 : if (!pltargs)
776 : {
777 : Py_DECREF(pltdata);
778 0 : return NULL;
779 : }
780 : }
781 : else
782 : {
783 : Py_INCREF(Py_None);
784 33 : pltargs = Py_None;
785 : }
786 :
787 49 : PG_TRY();
788 : {
789 49 : pltname = PLyUnicode_FromString(tdata->tg_trigger->tgname);
790 49 : PyDict_SetItemString(pltdata, "name", pltname);
791 : Py_DECREF(pltname);
792 :
793 49 : stroid = DatumGetCString(DirectFunctionCall1(oidout,
794 : ObjectIdGetDatum(tdata->tg_relation->rd_id)));
795 49 : pltrelid = PLyUnicode_FromString(stroid);
796 49 : PyDict_SetItemString(pltdata, "relid", pltrelid);
797 : Py_DECREF(pltrelid);
798 49 : pfree(stroid);
799 :
800 49 : stroid = SPI_getrelname(tdata->tg_relation);
801 49 : plttablename = PLyUnicode_FromString(stroid);
802 49 : PyDict_SetItemString(pltdata, "table_name", plttablename);
803 : Py_DECREF(plttablename);
804 49 : pfree(stroid);
805 :
806 49 : stroid = SPI_getnspname(tdata->tg_relation);
807 49 : plttableschema = PLyUnicode_FromString(stroid);
808 49 : PyDict_SetItemString(pltdata, "table_schema", plttableschema);
809 : Py_DECREF(plttableschema);
810 49 : pfree(stroid);
811 :
812 49 : if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
813 36 : pltwhen = PLyUnicode_FromString("BEFORE");
814 13 : else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
815 10 : pltwhen = PLyUnicode_FromString("AFTER");
816 3 : else if (TRIGGER_FIRED_INSTEAD(tdata->tg_event))
817 3 : pltwhen = PLyUnicode_FromString("INSTEAD OF");
818 : else
819 : {
820 0 : elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event);
821 : pltwhen = NULL; /* keep compiler quiet */
822 : }
823 49 : PyDict_SetItemString(pltdata, "when", pltwhen);
824 : Py_DECREF(pltwhen);
825 :
826 49 : if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
827 : {
828 44 : pltlevel = PLyUnicode_FromString("ROW");
829 44 : PyDict_SetItemString(pltdata, "level", pltlevel);
830 : Py_DECREF(pltlevel);
831 :
832 : /*
833 : * Note: In BEFORE trigger, stored generated columns are not
834 : * computed yet, so don't make them accessible in NEW row.
835 : */
836 :
837 44 : if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
838 : {
839 21 : pltevent = PLyUnicode_FromString("INSERT");
840 :
841 21 : PyDict_SetItemString(pltdata, "old", Py_None);
842 42 : pytnew = PLy_input_from_tuple(&proc->result_in,
843 : tdata->tg_trigtuple,
844 : rel_descr,
845 21 : !TRIGGER_FIRED_BEFORE(tdata->tg_event));
846 21 : PyDict_SetItemString(pltdata, "new", pytnew);
847 : Py_DECREF(pytnew);
848 21 : *rv = tdata->tg_trigtuple;
849 : }
850 23 : else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
851 : {
852 6 : pltevent = PLyUnicode_FromString("DELETE");
853 :
854 6 : PyDict_SetItemString(pltdata, "new", Py_None);
855 6 : pytold = PLy_input_from_tuple(&proc->result_in,
856 : tdata->tg_trigtuple,
857 : rel_descr,
858 : true);
859 6 : PyDict_SetItemString(pltdata, "old", pytold);
860 : Py_DECREF(pytold);
861 6 : *rv = tdata->tg_trigtuple;
862 : }
863 17 : else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
864 : {
865 17 : pltevent = PLyUnicode_FromString("UPDATE");
866 :
867 34 : pytnew = PLy_input_from_tuple(&proc->result_in,
868 : tdata->tg_newtuple,
869 : rel_descr,
870 17 : !TRIGGER_FIRED_BEFORE(tdata->tg_event));
871 17 : PyDict_SetItemString(pltdata, "new", pytnew);
872 : Py_DECREF(pytnew);
873 17 : pytold = PLy_input_from_tuple(&proc->result_in,
874 : tdata->tg_trigtuple,
875 : rel_descr,
876 : true);
877 17 : PyDict_SetItemString(pltdata, "old", pytold);
878 : Py_DECREF(pytold);
879 17 : *rv = tdata->tg_newtuple;
880 : }
881 : else
882 : {
883 0 : elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
884 : pltevent = NULL; /* keep compiler quiet */
885 : }
886 :
887 44 : PyDict_SetItemString(pltdata, "event", pltevent);
888 : Py_DECREF(pltevent);
889 : }
890 5 : else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
891 : {
892 5 : pltlevel = PLyUnicode_FromString("STATEMENT");
893 5 : PyDict_SetItemString(pltdata, "level", pltlevel);
894 : Py_DECREF(pltlevel);
895 :
896 5 : PyDict_SetItemString(pltdata, "old", Py_None);
897 5 : PyDict_SetItemString(pltdata, "new", Py_None);
898 5 : *rv = NULL;
899 :
900 5 : if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
901 1 : pltevent = PLyUnicode_FromString("INSERT");
902 4 : else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
903 1 : pltevent = PLyUnicode_FromString("DELETE");
904 3 : else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
905 2 : pltevent = PLyUnicode_FromString("UPDATE");
906 1 : else if (TRIGGER_FIRED_BY_TRUNCATE(tdata->tg_event))
907 1 : pltevent = PLyUnicode_FromString("TRUNCATE");
908 : else
909 : {
910 0 : elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
911 : pltevent = NULL; /* keep compiler quiet */
912 : }
913 :
914 5 : PyDict_SetItemString(pltdata, "event", pltevent);
915 : Py_DECREF(pltevent);
916 : }
917 : else
918 0 : elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event);
919 :
920 49 : if (tdata->tg_trigger->tgnargs)
921 : {
922 : /*
923 : * all strings...
924 : */
925 : int i;
926 : PyObject *pltarg;
927 :
928 : /* pltargs should have been allocated before the PG_TRY block. */
929 : Assert(pltargs && pltargs != Py_None);
930 :
931 45 : for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
932 : {
933 29 : pltarg = PLyUnicode_FromString(tdata->tg_trigger->tgargs[i]);
934 :
935 : /*
936 : * stolen, don't Py_DECREF
937 : */
938 29 : PyList_SetItem(pltargs, i, pltarg);
939 : }
940 : }
941 : else
942 : {
943 : Assert(pltargs == Py_None);
944 : }
945 49 : PyDict_SetItemString(pltdata, "args", pltargs);
946 : Py_DECREF(pltargs);
947 : }
948 0 : PG_CATCH();
949 : {
950 0 : Py_XDECREF(pltargs);
951 0 : Py_XDECREF(pltdata);
952 0 : PG_RE_THROW();
953 : }
954 49 : PG_END_TRY();
955 :
956 49 : return pltdata;
957 : }
958 :
959 : /*
960 : * Apply changes requested by a MODIFY return from a trigger function.
961 : */
962 : static HeapTuple
963 20 : PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
964 : HeapTuple otup)
965 : {
966 : HeapTuple rtup;
967 : PyObject *volatile plntup;
968 : PyObject *volatile plkeys;
969 : PyObject *volatile plval;
970 : Datum *volatile modvalues;
971 : bool *volatile modnulls;
972 : bool *volatile modrepls;
973 : ErrorContextCallback plerrcontext;
974 :
975 20 : plerrcontext.callback = plpython_trigger_error_callback;
976 20 : plerrcontext.previous = error_context_stack;
977 20 : error_context_stack = &plerrcontext;
978 :
979 20 : plntup = plkeys = plval = NULL;
980 20 : modvalues = NULL;
981 20 : modnulls = NULL;
982 20 : modrepls = NULL;
983 :
984 20 : PG_TRY();
985 : {
986 : TupleDesc tupdesc;
987 : int nkeys,
988 : i;
989 :
990 20 : if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL)
991 1 : ereport(ERROR,
992 : (errcode(ERRCODE_UNDEFINED_OBJECT),
993 : errmsg("TD[\"new\"] deleted, cannot modify row")));
994 19 : Py_INCREF(plntup);
995 19 : if (!PyDict_Check(plntup))
996 1 : ereport(ERROR,
997 : (errcode(ERRCODE_DATATYPE_MISMATCH),
998 : errmsg("TD[\"new\"] is not a dictionary")));
999 :
1000 18 : plkeys = PyDict_Keys(plntup);
1001 18 : nkeys = PyList_Size(plkeys);
1002 :
1003 18 : tupdesc = RelationGetDescr(tdata->tg_relation);
1004 :
1005 18 : modvalues = (Datum *) palloc0(tupdesc->natts * sizeof(Datum));
1006 18 : modnulls = (bool *) palloc0(tupdesc->natts * sizeof(bool));
1007 18 : modrepls = (bool *) palloc0(tupdesc->natts * sizeof(bool));
1008 :
1009 45 : for (i = 0; i < nkeys; i++)
1010 : {
1011 : PyObject *platt;
1012 : char *plattstr;
1013 : int attn;
1014 : PLyObToDatum *att;
1015 :
1016 31 : platt = PyList_GetItem(plkeys, i);
1017 31 : if (PyUnicode_Check(platt))
1018 30 : plattstr = PLyUnicode_AsString(platt);
1019 : else
1020 : {
1021 1 : ereport(ERROR,
1022 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1023 : errmsg("TD[\"new\"] dictionary key at ordinal position %d is not a string", i)));
1024 : plattstr = NULL; /* keep compiler quiet */
1025 : }
1026 30 : attn = SPI_fnumber(tupdesc, plattstr);
1027 30 : if (attn == SPI_ERROR_NOATTRIBUTE)
1028 2 : ereport(ERROR,
1029 : (errcode(ERRCODE_UNDEFINED_COLUMN),
1030 : errmsg("key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row",
1031 : plattstr)));
1032 28 : if (attn <= 0)
1033 0 : ereport(ERROR,
1034 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1035 : errmsg("cannot set system attribute \"%s\"",
1036 : plattstr)));
1037 28 : if (TupleDescAttr(tupdesc, attn - 1)->attgenerated)
1038 1 : ereport(ERROR,
1039 : (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1040 : errmsg("cannot set generated column \"%s\"",
1041 : plattstr)));
1042 :
1043 27 : plval = PyDict_GetItem(plntup, platt);
1044 27 : if (plval == NULL)
1045 0 : elog(FATAL, "Python interpreter is probably corrupted");
1046 :
1047 27 : Py_INCREF(plval);
1048 :
1049 : /* We assume proc->result is set up to convert tuples properly */
1050 27 : att = &proc->result.tuple.atts[attn - 1];
1051 :
1052 54 : modvalues[attn - 1] = PLy_output_convert(att,
1053 : plval,
1054 27 : &modnulls[attn - 1]);
1055 27 : modrepls[attn - 1] = true;
1056 :
1057 27 : Py_DECREF(plval);
1058 27 : plval = NULL;
1059 : }
1060 :
1061 14 : rtup = heap_modify_tuple(otup, tupdesc, modvalues, modnulls, modrepls);
1062 : }
1063 6 : PG_CATCH();
1064 : {
1065 6 : Py_XDECREF(plntup);
1066 6 : Py_XDECREF(plkeys);
1067 6 : Py_XDECREF(plval);
1068 :
1069 6 : if (modvalues)
1070 4 : pfree(modvalues);
1071 6 : if (modnulls)
1072 4 : pfree(modnulls);
1073 6 : if (modrepls)
1074 4 : pfree(modrepls);
1075 :
1076 6 : PG_RE_THROW();
1077 : }
1078 14 : PG_END_TRY();
1079 :
1080 14 : Py_DECREF(plntup);
1081 14 : Py_DECREF(plkeys);
1082 :
1083 14 : pfree(modvalues);
1084 14 : pfree(modnulls);
1085 14 : pfree(modrepls);
1086 :
1087 14 : error_context_stack = plerrcontext.previous;
1088 :
1089 14 : return rtup;
1090 : }
1091 :
1092 : static void
1093 6 : plpython_trigger_error_callback(void *arg)
1094 : {
1095 6 : PLyExecutionContext *exec_ctx = PLy_current_execution_context();
1096 :
1097 6 : if (exec_ctx->curr_proc)
1098 6 : errcontext("while modifying trigger row");
1099 6 : }
1100 :
1101 : /* execute Python code, propagate Python errors to the backend */
1102 : static PyObject *
1103 572 : PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs)
1104 : {
1105 572 : PyObject *rv = NULL;
1106 572 : int volatile save_subxact_level = list_length(explicit_subtransactions);
1107 :
1108 572 : PyDict_SetItemString(proc->globals, kargs, vargs);
1109 :
1110 572 : PG_TRY();
1111 : {
1112 572 : rv = PyEval_EvalCode(proc->code, proc->globals, proc->globals);
1113 :
1114 : /*
1115 : * Since plpy will only let you close subtransactions that you
1116 : * started, you cannot *unnest* subtransactions, only *nest* them
1117 : * without closing.
1118 : */
1119 : Assert(list_length(explicit_subtransactions) >= save_subxact_level);
1120 : }
1121 0 : PG_FINALLY();
1122 : {
1123 572 : PLy_abort_open_subtransactions(save_subxact_level);
1124 : }
1125 572 : PG_END_TRY();
1126 :
1127 : /* If the Python code returned an error, propagate it */
1128 572 : if (rv == NULL)
1129 54 : PLy_elog(ERROR, NULL);
1130 :
1131 518 : return rv;
1132 : }
1133 :
1134 : /*
1135 : * Abort lingering subtransactions that have been explicitly started
1136 : * by plpy.subtransaction().start() and not properly closed.
1137 : */
1138 : static void
1139 572 : PLy_abort_open_subtransactions(int save_subxact_level)
1140 : {
1141 : Assert(save_subxact_level >= 0);
1142 :
1143 578 : while (list_length(explicit_subtransactions) > save_subxact_level)
1144 : {
1145 : PLySubtransactionData *subtransactiondata;
1146 :
1147 : Assert(explicit_subtransactions != NIL);
1148 :
1149 6 : ereport(WARNING,
1150 : (errmsg("forcibly aborting a subtransaction that has not been exited")));
1151 :
1152 6 : RollbackAndReleaseCurrentSubTransaction();
1153 :
1154 6 : subtransactiondata = (PLySubtransactionData *) linitial(explicit_subtransactions);
1155 6 : explicit_subtransactions = list_delete_first(explicit_subtransactions);
1156 :
1157 6 : MemoryContextSwitchTo(subtransactiondata->oldcontext);
1158 6 : CurrentResourceOwner = subtransactiondata->oldowner;
1159 6 : pfree(subtransactiondata);
1160 : }
1161 572 : }
|