PostgreSQL Source Code git master
Loading...
Searching...
No Matches
plpy_exec.c
Go to the documentation of this file.
1/*
2 * executing Python code
3 *
4 * src/pl/plpython/plpy_exec.c
5 */
6
7#include "postgres.h"
8
10#include "access/xact.h"
11#include "catalog/pg_type.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 */
26typedef struct PLySRFState
27{
28 PyObject *iter; /* Python iterator producing results */
29 PLySavedArgs *savedargs; /* function argument values */
30 MemoryContextCallback callback; /* for releasing refcounts when done */
32
35static void PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs);
36static void PLy_function_drop_args(PLySavedArgs *savedargs);
37static void PLy_global_args_push(PLyProcedure *proc);
38static void PLy_global_args_pop(PLyProcedure *proc);
39static void plpython_srf_cleanup_callback(void *arg);
40static void plpython_return_error_callback(void *arg);
41
43 HeapTuple *rv);
46static void plpython_trigger_error_callback(void *arg);
47
48static PyObject *PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs);
50
51
52/* function subhandler */
55{
56 bool is_setof = proc->is_setof;
57 Datum rv;
58 PyObject *volatile plargs = NULL;
59 PyObject *volatile plrv = NULL;
60 FuncCallContext *volatile funcctx = NULL;
61 PLySRFState *volatile srfstate = NULL;
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 */
70
71 PG_TRY();
72 {
73 if (is_setof)
74 {
75 /* First Call setup */
76 if (SRF_IS_FIRSTCALL())
77 {
80 MemoryContextAllocZero(funcctx->multi_call_memory_ctx,
81 sizeof(PLySRFState));
82 /* Immediately register cleanup callback */
84 srfstate->callback.arg = srfstate;
85 MemoryContextRegisterResetCallback(funcctx->multi_call_memory_ctx,
86 &srfstate->callback);
87 funcctx->user_fctx = srfstate;
88 }
89 /* Every call setup */
92 srfstate = (PLySRFState *) funcctx->user_fctx;
94 }
95
96 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 plargs = PLy_function_build_args(fcinfo, proc);
103 plrv = PLy_procedure_call(proc, "args", plargs);
104 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 if (srfstate->savedargs)
117 PLy_function_restore_args(proc, srfstate->savedargs);
118 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 if (is_setof)
127 {
128 if (srfstate->iter == NULL)
129 {
130 /* first time -- do checks and setup */
131 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
132
133 if (!rsi || !IsA(rsi, ReturnSetInfo) ||
134 (rsi->allowedModes & SFRM_ValuePerCall) == 0)
135 {
138 errmsg("unsupported set function return mode"),
139 errdetail("PL/Python set-returning functions only support returning one value per call.")));
140 }
142
143 /* Make iterator out of returned object */
145
147 plrv = NULL;
148
149 if (srfstate->iter == NULL)
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 plrv = PyIter_Next(srfstate->iter);
158 if (plrv == NULL)
159 {
160 /* Iterator is exhausted or error happened */
161 bool has_error = (PyErr_Occurred() != NULL);
162
163 Py_DECREF(srfstate->iter);
164 srfstate->iter = NULL;
165
166 if (has_error)
167 PLy_elog(ERROR, "error fetching next item from iterator");
168
169 /* Pass a null through the data-returning steps below */
171 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 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 if (SPI_finish() != SPI_OK_FINISH)
191 elog(ERROR, "SPI_finish failed");
192
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 if (proc->result.typoid == VOIDOID)
204 {
205 if (plrv != Py_None)
206 {
207 if (proc->is_procedure)
210 errmsg("PL/Python procedure did not return None")));
211 else
214 errmsg("PL/Python function with return type \"void\" did not return None")));
215 }
216
217 fcinfo->isnull = false;
218 rv = (Datum) 0;
219 }
220 else if (plrv == Py_None &&
221 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 fcinfo->isnull = true;
229 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 if (proc->result.typoid == RECORDOID)
239 {
240 TupleDesc desc;
241
242 if (get_call_result_type(fcinfo, NULL, &desc) != TYPEFUNC_COMPOSITE)
245 errmsg("function returning record called in context "
246 "that cannot accept type record")));
247 PLy_output_setup_record(&proc->result, desc, proc);
248 }
249
250 rv = PLy_output_convert(&proc->result, plrv,
251 &fcinfo->isnull);
252 }
253 }
254 PG_CATCH();
255 {
256 /* Pop old arguments from the stack if they were pushed above */
258
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 if (srfstate)
270 {
271 Py_XDECREF(srfstate->iter);
272 srfstate->iter = NULL;
273 /* And drop any saved args; we won't need them */
274 if (srfstate->savedargs)
276 srfstate->savedargs = NULL;
277 }
278
279 PG_RE_THROW();
280 }
281 PG_END_TRY();
282
284
285 /* Pop old arguments from the stack if they were pushed above */
287
290
291 if (srfstate)
292 {
293 /* We're in a SRF, exit appropriately */
294 if (srfstate->iter == NULL)
295 {
296 /* Iterator exhausted, so we're done */
298 }
299 else if (fcinfo->isnull)
301 else
303 }
304
305 /* Plain function, just return the Datum value (possibly null) */
306 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 */
322{
323 HeapTuple rv = NULL;
324 PyObject *volatile plargs = NULL;
325 PyObject *volatile plrv = NULL;
328
329 Assert(CALLED_AS_TRIGGER(fcinfo));
330 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 rel_descr = RelationGetDescr(tdata->tg_relation);
341 if (proc->result.typoid != rel_descr->tdtypeid)
342 PLy_output_setup_func(&proc->result, proc->mcxt,
343 rel_descr->tdtypeid,
344 rel_descr->tdtypmod,
345 proc);
346 if (proc->result_in.typoid != rel_descr->tdtypeid)
347 PLy_input_setup_func(&proc->result_in, proc->mcxt,
348 rel_descr->tdtypeid,
349 rel_descr->tdtypmod,
350 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 */
360
361 PG_TRY();
362 {
364
366 Assert(rc >= 0);
367
368 plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
369 plrv = PLy_procedure_call(proc, "TD", plargs);
370
371 Assert(plrv != NULL);
372
373 /*
374 * Disconnect from SPI manager
375 */
376 if (SPI_finish() != SPI_OK_FINISH)
377 elog(ERROR, "SPI_finish failed");
378
379 /*
380 * return of None means we're happy with the tuple
381 */
382 if (plrv != Py_None)
383 {
384 char *srv;
385
388 else
389 {
392 errmsg("unexpected return value from trigger procedure"),
393 errdetail("Expected None or a string.")));
394 srv = NULL; /* keep compiler quiet */
395 }
396
397 if (pg_strcasecmp(srv, "SKIP") == 0)
398 rv = NULL;
399 else if (pg_strcasecmp(srv, "MODIFY") == 0)
400 {
401 if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event) ||
403 rv = PLy_modify_tuple(proc, plargs, tdata, rv);
404 else
406 (errmsg("PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored")));
407 }
408 else if (pg_strcasecmp(srv, "OK") != 0)
409 {
410 /*
411 * accept "OK" as an alternative to None; otherwise, raise an
412 * error
413 */
416 errmsg("unexpected return value from trigger procedure"),
417 errdetail("Expected None, \"OK\", \"SKIP\", or \"MODIFY\".")));
418 }
419 }
420 }
421 PG_FINALLY();
422 {
426 }
427 PG_END_TRY();
428
429 return rv;
430}
431
432/*
433 * event trigger subhandler
434 */
435void
437{
439 PyObject *volatile pltdata = NULL;
440
442 tdata = (EventTriggerData *) fcinfo->context;
443
444 PG_TRY();
445 {
447 *plttag;
448
450 if (!pltdata)
452
456
460
461 PLy_procedure_call(proc, "TD", pltdata);
462
463 if (SPI_finish() != SPI_OK_FINISH)
464 elog(ERROR, "SPI_finish() failed");
465 }
466 PG_FINALLY();
467 {
469 }
470 PG_END_TRY();
471}
472
473/* helper functions for Python code execution */
474
475static PyObject *
477{
478 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 args = PyList_New(proc->nargs);
488 if (!args)
489 return NULL;
490
491 PG_TRY();
492 {
493 for (i = 0; i < proc->nargs; i++)
494 {
495 PLyDatumToOb *arginfo = &proc->args[i];
496
497 if (fcinfo->args[i].isnull)
498 arg = NULL;
499 else
501
502 if (arg == NULL)
503 {
505 arg = Py_None;
506 }
507
508 if (PyList_SetItem(args, i, arg) == -1)
509 PLy_elog(ERROR, "PyList_SetItem() failed, while setting up arguments");
510
511 if (proc->argnames && proc->argnames[i] &&
512 PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1)
513 PLy_elog(ERROR, "PyDict_SetItemString() failed, while setting up arguments");
514 arg = NULL;
515 }
516 }
517 PG_CATCH();
518 {
520 Py_XDECREF(args);
521
522 PG_RE_THROW();
523 }
524 PG_END_TRY();
525
526 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 */
538static PLySavedArgs *
540{
542
543 /* saved args are always allocated in procedure's context */
544 result = (PLySavedArgs *)
546 offsetof(PLySavedArgs, namedargs) +
547 proc->nargs * sizeof(PyObject *));
548 result->nargs = proc->nargs;
549
550 /* Fetch the "args" list */
551 result->args = PyDict_GetItemString(proc->globals, "args");
552 Py_XINCREF(result->args);
553
554 /* If it's a trigger, also save "TD" */
555 if (proc->is_trigger == PLPY_TRIGGER)
556 {
557 result->td = PyDict_GetItemString(proc->globals, "TD");
558 Py_XINCREF(result->td);
559 }
560
561 /* Fetch all the named arguments */
562 if (proc->argnames)
563 {
564 int i;
565
566 for (i = 0; i < result->nargs; i++)
567 {
568 if (proc->argnames[i])
569 {
570 result->namedargs[i] = PyDict_GetItemString(proc->globals,
571 proc->argnames[i]);
572 Py_XINCREF(result->namedargs[i]);
573 }
574 }
575 }
576
577 return result;
578}
579
580/*
581 * Restore procedure's arguments from a PLySavedArgs struct,
582 * then free the struct.
583 */
584static void
586{
587 /* Restore named arguments into their slots in the globals dict */
588 if (proc->argnames)
589 {
590 int i;
591
592 for (i = 0; i < savedargs->nargs; i++)
593 {
594 if (proc->argnames[i] && savedargs->namedargs[i])
595 {
597 savedargs->namedargs[i]);
598 Py_DECREF(savedargs->namedargs[i]);
599 }
600 }
601 }
602
603 /* Restore the "args" object, too */
604 if (savedargs->args)
605 {
606 PyDict_SetItemString(proc->globals, "args", savedargs->args);
607 Py_DECREF(savedargs->args);
608 }
609
610 /* Restore the "TD" object, too */
611 if (savedargs->td)
612 {
613 PyDict_SetItemString(proc->globals, "TD", savedargs->td);
614 Py_DECREF(savedargs->td);
615 }
616
617 /* And free the PLySavedArgs struct */
618 pfree(savedargs);
619}
620
621/*
622 * Free a PLySavedArgs struct without restoring the values.
623 */
624static void
626{
627 int i;
628
629 /* Drop references for named args */
630 for (i = 0; i < savedargs->nargs; i++)
631 {
632 Py_XDECREF(savedargs->namedargs[i]);
633 }
634
635 /* Drop refs to the "args" and "TD" objects, too */
636 Py_XDECREF(savedargs->args);
637 Py_XDECREF(savedargs->td);
638
639 /* And free the PLySavedArgs struct */
640 pfree(savedargs);
641}
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 */
653static void
655{
656 /* We only need to push if we are already inside some active call */
657 if (proc->calldepth > 0)
658 {
659 PLySavedArgs *node;
660
661 /* Build a struct containing current argument values */
662 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 node->next = proc->argstack;
670 proc->argstack = node;
671 }
672 proc->calldepth++;
673}
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 */
683static void
685{
686 Assert(proc->calldepth > 0);
687 /* We only need to pop if we were already inside some active call */
688 if (proc->calldepth > 1)
689 {
690 PLySavedArgs *ptr = proc->argstack;
691
692 /* Pop the callstack */
693 Assert(ptr != NULL);
694 proc->argstack = ptr->next;
695 proc->calldepth--;
696
697 /* Restore argument values, then free ptr */
698 PLy_function_restore_args(proc, ptr);
699 }
700 else
701 {
702 /* Exiting call depth 1 */
703 Assert(proc->argstack == NULL);
704 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}
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 */
721static void
723{
725
726 /* Release refcount on the iter, if we still have one */
727 Py_XDECREF(srfstate->iter);
728 srfstate->iter = NULL;
729 /* And drop any saved args; we won't need them */
730 if (srfstate->savedargs)
732 srfstate->savedargs = NULL;
733}
734
735static void
737{
739
740 if (exec_ctx->curr_proc &&
741 !exec_ctx->curr_proc->is_procedure)
742 errcontext("while creating return value");
743}
744
745static PyObject *
747{
748 TriggerData *tdata = (TriggerData *) fcinfo->context;
751 *pltevent,
752 *pltwhen,
753 *pltlevel,
754 *pltrelid,
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 */
769 if (!pltdata)
770 return NULL;
771
772 if (tdata->tg_trigger->tgnargs)
773 {
774 pltargs = PyList_New(tdata->tg_trigger->tgnargs);
775 if (!pltargs)
776 {
778 return NULL;
779 }
780 }
781 else
782 {
785 }
786
787 PG_TRY();
788 {
789 pltname = PLyUnicode_FromString(tdata->tg_trigger->tgname);
792
794 ObjectIdGetDatum(tdata->tg_relation->rd_id)));
798 pfree(stroid);
799
800 stroid = SPI_getrelname(tdata->tg_relation);
804 pfree(stroid);
805
806 stroid = SPI_getnspname(tdata->tg_relation);
810 pfree(stroid);
811
812 if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
813 pltwhen = PLyUnicode_FromString("BEFORE");
814 else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
816 else if (TRIGGER_FIRED_INSTEAD(tdata->tg_event))
817 pltwhen = PLyUnicode_FromString("INSTEAD OF");
818 else
819 {
820 elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event);
821 pltwhen = NULL; /* keep compiler quiet */
822 }
825
826 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
827 {
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 if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
838 {
840
843 tdata->tg_trigtuple,
844 rel_descr,
845 !TRIGGER_FIRED_BEFORE(tdata->tg_event));
848 *rv = tdata->tg_trigtuple;
849 }
850 else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
851 {
853
856 tdata->tg_trigtuple,
857 rel_descr,
858 true);
861 *rv = tdata->tg_trigtuple;
862 }
863 else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
864 {
866
868 tdata->tg_newtuple,
869 rel_descr,
870 !TRIGGER_FIRED_BEFORE(tdata->tg_event));
874 tdata->tg_trigtuple,
875 rel_descr,
876 true);
879 *rv = tdata->tg_newtuple;
880 }
881 else
882 {
883 elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
884 pltevent = NULL; /* keep compiler quiet */
885 }
886
889 }
890 else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
891 {
892 pltlevel = PLyUnicode_FromString("STATEMENT");
895
898 *rv = NULL;
899
900 if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
902 else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
904 else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
906 else if (TRIGGER_FIRED_BY_TRUNCATE(tdata->tg_event))
907 pltevent = PLyUnicode_FromString("TRUNCATE");
908 else
909 {
910 elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
911 pltevent = NULL; /* keep compiler quiet */
912 }
913
916 }
917 else
918 elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event);
919
920 if (tdata->tg_trigger->tgnargs)
921 {
922 /*
923 * all strings...
924 */
925 int i;
927
928 /* pltargs should have been allocated before the PG_TRY block. */
930
931 for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
932 {
933 pltarg = PLyUnicode_FromString(tdata->tg_trigger->tgargs[i]);
934
935 /*
936 * stolen, don't Py_DECREF
937 */
939 }
940 }
941 else
942 {
944 }
947 }
948 PG_CATCH();
949 {
952 PG_RE_THROW();
953 }
954 PG_END_TRY();
955
956 return pltdata;
957}
958
959/*
960 * Apply changes requested by a MODIFY return from a trigger function.
961 */
962static HeapTuple
965{
967 PyObject *volatile plntup;
968 PyObject *volatile plkeys;
969 PyObject *volatile plval;
970 Datum *volatile modvalues;
971 bool *volatile modnulls;
972 bool *volatile modrepls;
974
978
979 plntup = plkeys = plval = NULL;
980 modvalues = NULL;
981 modnulls = NULL;
982 modrepls = NULL;
983
984 PG_TRY();
985 {
986 TupleDesc tupdesc;
987 int nkeys,
988 i;
989
990 if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL)
993 errmsg("TD[\"new\"] deleted, cannot modify row")));
995 if (!PyDict_Check(plntup))
998 errmsg("TD[\"new\"] is not a dictionary")));
999
1001 nkeys = PyList_Size(plkeys);
1002
1003 tupdesc = RelationGetDescr(tdata->tg_relation);
1004
1005 modvalues = (Datum *) palloc0(tupdesc->natts * sizeof(Datum));
1006 modnulls = (bool *) palloc0(tupdesc->natts * sizeof(bool));
1007 modrepls = (bool *) palloc0(tupdesc->natts * sizeof(bool));
1008
1009 for (i = 0; i < nkeys; i++)
1010 {
1011 PyObject *platt;
1012 char *plattstr;
1013 int attn;
1014 PLyObToDatum *att;
1015
1019 else
1020 {
1021 ereport(ERROR,
1023 errmsg("TD[\"new\"] dictionary key at ordinal position %d is not a string", i)));
1024 plattstr = NULL; /* keep compiler quiet */
1025 }
1026 attn = SPI_fnumber(tupdesc, plattstr);
1028 ereport(ERROR,
1030 errmsg("key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row",
1031 plattstr)));
1032 if (attn <= 0)
1033 ereport(ERROR,
1035 errmsg("cannot set system attribute \"%s\"",
1036 plattstr)));
1037 if (TupleDescAttr(tupdesc, attn - 1)->attgenerated)
1038 ereport(ERROR,
1040 errmsg("cannot set generated column \"%s\"",
1041 plattstr)));
1042
1044 if (plval == NULL)
1045 elog(FATAL, "Python interpreter is probably corrupted");
1046
1048
1049 /* We assume proc->result is set up to convert tuples properly */
1050 att = &proc->result.tuple.atts[attn - 1];
1051
1053 plval,
1054 &modnulls[attn - 1]);
1055 modrepls[attn - 1] = true;
1056
1058 plval = NULL;
1059 }
1060
1062 }
1063 PG_CATCH();
1064 {
1068
1069 if (modvalues)
1071 if (modnulls)
1072 pfree(modnulls);
1073 if (modrepls)
1074 pfree(modrepls);
1075
1076 PG_RE_THROW();
1077 }
1078 PG_END_TRY();
1079
1082
1084 pfree(modnulls);
1085 pfree(modrepls);
1086
1088
1089 return rtup;
1090}
1091
1092static void
1094{
1096
1097 if (exec_ctx->curr_proc)
1098 errcontext("while modifying trigger row");
1099}
1100
1101/* execute Python code, propagate Python errors to the backend */
1102static PyObject *
1104{
1105 PyObject *rv = NULL;
1107
1109
1110 PG_TRY();
1111 {
1112 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 */
1120 }
1121 PG_FINALLY();
1122 {
1124 }
1125 PG_END_TRY();
1126
1127 /* If the Python code returned an error, propagate it */
1128 if (rv == NULL)
1130
1131 return rv;
1132}
1133
1134/*
1135 * Abort lingering subtransactions that have been explicitly started
1136 * by plpy.subtransaction().start() and not properly closed.
1137 */
1138static void
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:249
#define Assert(condition)
Definition c.h:943
uint32 result
const char * GetCommandTagName(CommandTag commandTag)
Definition cmdtag.c:47
Datum arg
Definition elog.c:1323
ErrorContextCallback * error_context_stack
Definition elog.c:100
int errcode(int sqlerrcode)
Definition elog.c:875
#define PG_RE_THROW()
Definition elog.h:407
#define errcontext
Definition elog.h:200
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:42
#define PG_TRY(...)
Definition elog.h:374
#define WARNING
Definition elog.h:37
#define PG_END_TRY(...)
Definition elog.h:399
#define ERROR
Definition elog.h:40
#define PG_CATCH(...)
Definition elog.h:384
#define elog(elevel,...)
Definition elog.h:228
#define PG_FINALLY(...)
Definition elog.h:391
#define ereport(elevel,...)
Definition elog.h:152
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
@ SFRM_ValuePerCall
Definition execnodes.h:354
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:688
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_RETURN_NEXT_NULL(_funcctx)
Definition funcapi.h:319
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1118
int i
Definition isn.c:77
#define PLy_elog
List * list_delete_first(List *list)
Definition list.c:943
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1269
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
Definition mcxt.c:585
void pfree(void *pointer)
Definition mcxt.c:1619
void * palloc0(Size size)
Definition mcxt.c:1420
#define IsA(nodeptr, _type_)
Definition nodes.h:164
static char * errmsg
Datum oidout(PG_FUNCTION_ARGS)
Definition oid.c:47
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define linitial(l)
Definition pg_list.h:178
void PLy_exec_event_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition plpy_exec.c:436
static void PLy_function_drop_args(PLySavedArgs *savedargs)
Definition plpy_exec.c:625
static void PLy_global_args_push(PLyProcedure *proc)
Definition plpy_exec.c:654
Datum PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition plpy_exec.c:54
static PyObject * PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition plpy_exec.c:476
static void PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs)
Definition plpy_exec.c:585
static PyObject * PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs)
Definition plpy_exec.c:1103
static void plpython_trigger_error_callback(void *arg)
Definition plpy_exec.c:1093
static void PLy_global_args_pop(PLyProcedure *proc)
Definition plpy_exec.c:684
static PyObject * PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *rv)
Definition plpy_exec.c:746
static HeapTuple PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata, HeapTuple otup)
Definition plpy_exec.c:963
static void plpython_srf_cleanup_callback(void *arg)
Definition plpy_exec.c:722
static PLySavedArgs * PLy_function_save_args(PLyProcedure *proc)
Definition plpy_exec.c:539
static void PLy_abort_open_subtransactions(int save_subxact_level)
Definition plpy_exec.c:1139
static void plpython_return_error_callback(void *arg)
Definition plpy_exec.c:736
HeapTuple PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
Definition plpy_exec.c:321
PLyExecutionContext * PLy_current_execution_context(void)
Definition plpy_main.c:336
@ PLPY_TRIGGER
List * explicit_subtransactions
void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
PyObject * PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated)
void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, PLyProcedure *proc)
PyObject * PLy_input_convert(PLyDatumToOb *arg, Datum val)
Definition plpy_typeio.c:81
void PLy_output_setup_record(PLyObToDatum *arg, TupleDesc desc, PLyProcedure *proc)
void PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, PLyProcedure *proc)
Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, bool *isnull)
char * PLyUnicode_AsString(PyObject *unicode)
Definition plpy_util.c:81
PyObject * PLyUnicode_FromString(const char *s)
Definition plpy_util.c:116
int pg_strcasecmp(const char *s1, const char *s2)
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static char * DatumGetCString(Datum X)
Definition postgres.h:365
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
#define RelationGetDescr(relation)
Definition rel.h:542
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
Definition spi.c:1176
int SPI_finish(void)
Definition spi.c:183
int SPI_register_trigger_data(TriggerData *tdata)
Definition spi.c:3364
char * SPI_getnspname(Relation rel)
Definition spi.c:1333
char * SPI_getrelname(Relation rel)
Definition spi.c:1327
#define SPI_ERROR_NOATTRIBUTE
Definition spi.h:76
#define SPI_OK_FINISH
Definition spi.h:83
struct ErrorContextCallback * previous
Definition elog.h:299
void(* callback)(void *arg)
Definition elog.h:300
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition fmgr.h:95
Datum value
Definition postgres.h:87
PLyObToTuple tuple
PLyObToDatum * atts
PLyDatumToOb * args
PLyTrigType is_trigger
PLyObToDatum result
PyObject * code
PLyDatumToOb result_in
PLySavedArgs * argstack
MemoryContext mcxt
PyObject * globals
MemoryContextCallback callback
Definition plpy_exec.c:30
PLySavedArgs * savedargs
Definition plpy_exec.c:29
PyObject * iter
Definition plpy_exec.c:28
PyObject * args
struct PLySavedArgs * next
PyObject * namedargs[FLEXIBLE_ARRAY_MEMBER]
PyObject * td
SetFunctionReturnMode returnMode
Definition execnodes.h:374
#define TRIGGER_FIRED_FOR_STATEMENT(event)
Definition trigger.h:127
#define TRIGGER_FIRED_BY_DELETE(event)
Definition trigger.h:115
#define TRIGGER_FIRED_BEFORE(event)
Definition trigger.h:130
#define CALLED_AS_TRIGGER(fcinfo)
Definition trigger.h:26
#define TRIGGER_FIRED_FOR_ROW(event)
Definition trigger.h:124
#define TRIGGER_FIRED_AFTER(event)
Definition trigger.h:133
#define TRIGGER_FIRED_BY_TRUNCATE(event)
Definition trigger.h:121
#define TRIGGER_FIRED_BY_INSERT(event)
Definition trigger.h:112
#define TRIGGER_FIRED_BY_UPDATE(event)
Definition trigger.h:118
#define TRIGGER_FIRED_INSTEAD(event)
Definition trigger.h:136
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4847