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