22#include "utils/fmgrprotos.h"
58 PyObject *
volatile plargs = NULL;
59 PyObject *
volatile plrv = NULL;
96 if (srfstate == NULL || srfstate->
iter == NULL)
128 if (srfstate->
iter == NULL)
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.")));
144 srfstate->
iter = PyObject_GetIter(plrv);
149 if (srfstate->
iter == NULL)
151 (
errcode(ERRCODE_DATATYPE_MISMATCH),
152 errmsg(
"returned object cannot be iterated"),
153 errdetail(
"PL/Python set-returning functions must return an iterable object.")));
157 plrv = PyIter_Next(srfstate->
iter);
161 bool has_error = (PyErr_Occurred() != NULL);
163 Py_DECREF(srfstate->
iter);
164 srfstate->
iter = NULL;
209 (
errcode(ERRCODE_DATATYPE_MISMATCH),
210 errmsg(
"PL/Python procedure did not return None")));
213 (
errcode(ERRCODE_DATATYPE_MISMATCH),
214 errmsg(
"PL/Python function with return type \"void\" did not return None")));
220 else if (plrv == Py_None &&
221 srfstate && srfstate->
iter == NULL)
244 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
245 errmsg(
"function returning record called in context "
246 "that cannot accept type record")));
271 Py_XDECREF(srfstate->
iter);
272 srfstate->
iter = NULL;
294 if (srfstate->
iter == NULL)
323 PyObject *
volatile plargs = NULL;
324 PyObject *
volatile plrv = NULL;
385 if (PyUnicode_Check(plrv))
390 (
errcode(ERRCODE_DATA_EXCEPTION),
391 errmsg(
"unexpected return value from trigger procedure"),
392 errdetail(
"Expected None or a string.")));
405 (
errmsg(
"PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored")));
414 (
errcode(ERRCODE_DATA_EXCEPTION),
415 errmsg(
"unexpected return value from trigger procedure"),
416 errdetail(
"Expected None, \"OK\", \"SKIP\", or \"MODIFY\".")));
438 PyObject *
volatile pltdata = NULL;
448 pltdata = PyDict_New();
453 PyDict_SetItemString(pltdata,
"event", pltevent);
457 PyDict_SetItemString(pltdata,
"tag", plttag);
477 PyObject *
volatile arg = NULL;
507 if (PyList_SetItem(
args,
i,
arg) == -1)
508 PLy_elog(
ERROR,
"PyList_SetItem() failed, while setting up arguments");
512 PLy_elog(
ERROR,
"PyDict_SetItemString() failed, while setting up arguments");
546 proc->
nargs *
sizeof(PyObject *));
550 result->
args = PyDict_GetItemString(proc->
globals,
"args");
551 Py_XINCREF(result->
args);
556 result->
td = PyDict_GetItemString(proc->
globals,
"TD");
557 Py_XINCREF(result->
td);
591 for (
i = 0;
i < savedargs->
nargs;
i++)
605 PyDict_SetItemString(proc->
globals,
"args", savedargs->
args);
606 Py_DECREF(savedargs->
args);
612 PyDict_SetItemString(proc->
globals,
"TD", savedargs->
td);
613 Py_DECREF(savedargs->
td);
629 for (
i = 0;
i < savedargs->
nargs;
i++)
635 Py_XDECREF(savedargs->
args);
636 Py_XDECREF(savedargs->
td);
726 Py_XDECREF(srfstate->
iter);
727 srfstate->
iter = NULL;
767 pltdata = PyDict_New();
789 PyDict_SetItemString(pltdata,
"name", pltname);
795 PyDict_SetItemString(pltdata,
"relid", pltrelid);
801 PyDict_SetItemString(pltdata,
"table_name", plttablename);
802 Py_DECREF(plttablename);
807 PyDict_SetItemString(pltdata,
"table_schema", plttableschema);
808 Py_DECREF(plttableschema);
822 PyDict_SetItemString(pltdata,
"when", pltwhen);
828 PyDict_SetItemString(pltdata,
"level", pltlevel);
840 PyDict_SetItemString(pltdata,
"old", Py_None);
845 PyDict_SetItemString(pltdata,
"new", pytnew);
853 PyDict_SetItemString(pltdata,
"new", Py_None);
858 PyDict_SetItemString(pltdata,
"old", pytold);
870 PyDict_SetItemString(pltdata,
"new", pytnew);
876 PyDict_SetItemString(pltdata,
"old", pytold);
886 PyDict_SetItemString(pltdata,
"event", pltevent);
892 PyDict_SetItemString(pltdata,
"level", pltlevel);
895 PyDict_SetItemString(pltdata,
"old", Py_None);
896 PyDict_SetItemString(pltdata,
"new", Py_None);
913 PyDict_SetItemString(pltdata,
"event", pltevent);
928 Assert(pltargs && pltargs != Py_None);
937 PyList_SetItem(pltargs,
i, pltarg);
942 Assert(pltargs == Py_None);
944 PyDict_SetItemString(pltdata,
"args", pltargs);
966 PyObject *
volatile plntup;
967 PyObject *
volatile plkeys;
968 PyObject *
volatile plval;
969 Datum *
volatile modvalues;
970 bool *
volatile modnulls;
971 bool *
volatile modrepls;
978 plntup = plkeys = plval = NULL;
989 if ((plntup = PyDict_GetItemString(pltd,
"new")) == NULL)
991 (
errcode(ERRCODE_UNDEFINED_OBJECT),
992 errmsg(
"TD[\"new\"] deleted, cannot modify row")));
994 if (!PyDict_Check(plntup))
996 (
errcode(ERRCODE_DATATYPE_MISMATCH),
997 errmsg(
"TD[\"new\"] is not a dictionary")));
999 plkeys = PyDict_Keys(plntup);
1000 nkeys = PyList_Size(plkeys);
1005 modnulls = (
bool *)
palloc0(tupdesc->
natts *
sizeof(
bool));
1006 modrepls = (
bool *)
palloc0(tupdesc->
natts *
sizeof(
bool));
1008 for (
i = 0;
i < nkeys;
i++)
1015 platt = PyList_GetItem(plkeys,
i);
1016 if (PyUnicode_Check(platt))
1021 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1022 errmsg(
"TD[\"new\"] dictionary key at ordinal position %d is not a string",
i)));
1028 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1029 errmsg(
"key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row",
1033 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1034 errmsg(
"cannot set system attribute \"%s\"",
1038 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1039 errmsg(
"cannot set generated column \"%s\"",
1042 plval = PyDict_GetItem(plntup, platt);
1044 elog(
FATAL,
"Python interpreter is probably corrupted");
1053 &modnulls[attn - 1]);
1054 modrepls[attn - 1] =
true;
1104 PyObject *rv = NULL;
1107 PyDict_SetItemString(proc->
globals, kargs, vargs);
1140 Assert(save_subxact_level >= 0);
1149 (
errmsg(
"forcibly aborting a subtransaction that has not been exited")));
1158 pfree(subtransactiondata);
#define PG_USED_FOR_ASSERTS_ONLY
const char * GetCommandTagName(CommandTag commandTag)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
#define DirectFunctionCall1(func, arg1)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
#define SRF_IS_FIRSTCALL()
#define SRF_RETURN_NEXT_NULL(_funcctx)
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
if(TABLE==NULL||TABLE_index==NULL)
List * list_delete_first(List *list)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
void pfree(void *pointer)
void * palloc0(Size size)
#define IsA(nodeptr, _type_)
Datum oidout(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static int list_length(const List *l)
void PLy_exec_event_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
static void PLy_function_drop_args(PLySavedArgs *savedargs)
static void PLy_global_args_push(PLyProcedure *proc)
struct PLySRFState PLySRFState
Datum PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
static PyObject * PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
static void PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs)
static PyObject * PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs)
static void plpython_trigger_error_callback(void *arg)
static void PLy_global_args_pop(PLyProcedure *proc)
static PyObject * PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *rv)
static HeapTuple PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata, HeapTuple otup)
static void plpython_srf_cleanup_callback(void *arg)
static PLySavedArgs * PLy_function_save_args(PLyProcedure *proc)
static void PLy_abort_open_subtransactions(int save_subxact_level)
static void plpython_return_error_callback(void *arg)
HeapTuple PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
PLyExecutionContext * PLy_current_execution_context(void)
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)
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)
PyObject * PLyUnicode_FromString(const char *s)
int pg_strcasecmp(const char *s1, const char *s2)
static Datum ObjectIdGetDatum(Oid X)
static char * DatumGetCString(Datum X)
#define RelationGetDescr(relation)
ResourceOwner CurrentResourceOwner
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
int SPI_register_trigger_data(TriggerData *tdata)
char * SPI_getnspname(Relation rel)
char * SPI_getrelname(Relation rel)
#define SPI_ERROR_NOATTRIBUTE
struct ErrorContextCallback * previous
void(* callback)(void *arg)
MemoryContext multi_call_memory_ctx
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
MemoryContextCallbackFunction func
MemoryContextCallback callback
struct PLySavedArgs * next
PyObject * namedargs[FLEXIBLE_ARRAY_MEMBER]
SetFunctionReturnMode returnMode
#define TRIGGER_FIRED_FOR_STATEMENT(event)
#define TRIGGER_FIRED_BY_DELETE(event)
#define TRIGGER_FIRED_BEFORE(event)
#define CALLED_AS_TRIGGER(fcinfo)
#define TRIGGER_FIRED_FOR_ROW(event)
#define TRIGGER_FIRED_AFTER(event)
#define TRIGGER_FIRED_BY_TRUNCATE(event)
#define TRIGGER_FIRED_BY_INSERT(event)
#define TRIGGER_FIRED_BY_UPDATE(event)
#define TRIGGER_FIRED_INSTEAD(event)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
void RollbackAndReleaseCurrentSubTransaction(void)