]> granicus.if.org Git - postgresql/blob - src/pl/plpython/plpython.c
Add table_name and table_schema to plpython trigger data, plus docs and regression...
[postgresql] / src / pl / plpython / plpython.c
1 /**********************************************************************
2  * plpython.c - python as a procedural language for PostgreSQL
3  *
4  *      $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.80 2006/05/26 19:23:09 adunstan Exp $
5  *
6  *********************************************************************
7  */
8
9 #include <Python.h>
10 #include "postgres.h"
11
12 /* system stuff */
13 #include <unistd.h>
14 #include <fcntl.h>
15
16 /* postgreSQL stuff */
17 #include "access/heapam.h"
18 #include "catalog/pg_proc.h"
19 #include "catalog/pg_type.h"
20 #include "commands/trigger.h"
21 #include "executor/spi.h"
22 #include "fmgr.h"
23 #include "nodes/makefuncs.h"
24 #include "parser/parse_type.h"
25 #include "tcop/tcopprot.h"
26 #include "utils/builtins.h"
27 #include "utils/lsyscache.h"
28 #include "utils/memutils.h"
29 #include "utils/syscache.h"
30 #include "utils/typcache.h"
31
32 #include <compile.h>
33 #include <eval.h>
34
35 /* convert Postgresql Datum or tuple into a PyObject.
36  * input to Python.  Tuples are converted to dictionary
37  * objects.
38  */
39
40 typedef PyObject *(*PLyDatumToObFunc) (const char *);
41
42 typedef struct PLyDatumToOb
43 {
44         PLyDatumToObFunc func;
45         FmgrInfo        typfunc;
46         Oid                     typioparam;
47         bool            typbyval;
48 }       PLyDatumToOb;
49
50 typedef struct PLyTupleToOb
51 {
52         PLyDatumToOb *atts;
53         int                     natts;
54 }       PLyTupleToOb;
55
56 typedef union PLyTypeInput
57 {
58         PLyDatumToOb d;
59         PLyTupleToOb r;
60 }       PLyTypeInput;
61
62 /* convert PyObject to a Postgresql Datum or tuple.
63  * output from Python
64  */
65 typedef struct PLyObToDatum
66 {
67         FmgrInfo        typfunc;                /* The type's input function */
68         Oid                     typoid;                 /* The OID of the type */
69         Oid                     typioparam;
70         bool            typbyval;
71 }       PLyObToDatum;
72
73 typedef struct PLyObToTuple
74 {
75         PLyObToDatum *atts;
76         int                     natts;
77 }       PLyObToTuple;
78
79 typedef union PLyTypeOutput
80 {
81         PLyObToDatum d;
82         PLyObToTuple r;
83 }       PLyTypeOutput;
84
85 /* all we need to move Postgresql data to Python objects,
86  * and vis versa
87  */
88 typedef struct PLyTypeInfo
89 {
90         PLyTypeInput in;
91         PLyTypeOutput out;
92         int                     is_rowtype;
93
94         /*
95          * is_rowtype can be: -1  not known yet (initial state) 0  scalar datatype
96          * 1  rowtype 2  rowtype, but I/O functions not set up yet
97          */
98 }       PLyTypeInfo;
99
100
101 /* cached procedure data */
102 typedef struct PLyProcedure
103 {
104         char       *proname;            /* SQL name of procedure */
105         char       *pyname;                     /* Python name of procedure */
106         TransactionId fn_xmin;
107         CommandId       fn_cmin;
108         bool            fn_readonly;
109         PLyTypeInfo result;                     /* also used to store info for trigger tuple
110                                                                  * type */
111         PLyTypeInfo args[FUNC_MAX_ARGS];
112         int                     nargs;
113         PyObject   *code;                       /* compiled procedure code */
114         PyObject   *statics;            /* data saved across calls, local scope */
115         PyObject   *globals;            /* data saved across calls, global scope */
116         PyObject   *me;                         /* PyCObject containing pointer to this
117                                                                  * PLyProcedure */
118 }       PLyProcedure;
119
120
121 /* Python objects */
122 typedef struct PLyPlanObject
123 {
124         PyObject_HEAD
125         void       *plan;                       /* return of an SPI_saveplan */
126         int                     nargs;
127         Oid                *types;
128         Datum      *values;
129         PLyTypeInfo *args;
130 }       PLyPlanObject;
131
132 typedef struct PLyResultObject
133 {
134         PyObject_HEAD
135         /* HeapTuple *tuples; */
136         PyObject   *nrows;                      /* number of rows returned by query */
137         PyObject   *rows;                       /* data rows, or None if no data returned */
138         PyObject   *status;                     /* query status, SPI_OK_*, or SPI_ERR_* */
139 }       PLyResultObject;
140
141
142 /* function declarations */
143
144 /* Two exported functions: first is the magic telling Postgresql
145  * what function call interface it implements. Second allows
146  * preinitialization of the interpreter during postmaster startup.
147  */
148 Datum           plpython_call_handler(PG_FUNCTION_ARGS);
149 void            plpython_init(void);
150
151 PG_FUNCTION_INFO_V1(plpython_call_handler);
152
153 /* most of the remaining of the declarations, all static */
154
155 /* these should only be called once at the first call
156  * of plpython_call_handler.  initialize the python interpreter
157  * and global data.
158  */
159 static void PLy_init_all(void);
160 static void PLy_init_interp(void);
161 static void PLy_init_plpy(void);
162
163 /* call PyErr_SetString with a vprint interface */
164 static void
165 PLy_exception_set(PyObject *, const char *,...)
166 __attribute__((format(printf, 2, 3)));
167
168 /* Get the innermost python procedure called from the backend */
169 static char *PLy_procedure_name(PLyProcedure *);
170
171 /* some utility functions */
172 static void PLy_elog(int, const char *,...);
173 static char *PLy_traceback(int *);
174 static char *PLy_vprintf(const char *fmt, va_list ap);
175 static char *PLy_printf(const char *fmt,...);
176
177 static void *PLy_malloc(size_t);
178 static void *PLy_realloc(void *, size_t);
179 static char *PLy_strdup(const char *);
180 static void PLy_free(void *);
181
182 /* sub handlers for functions and triggers */
183 static Datum PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *);
184 static HeapTuple PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure *);
185
186 static PyObject *PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *);
187 static PyObject *PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *,
188                                            HeapTuple *);
189 static HeapTuple PLy_modify_tuple(PLyProcedure *, PyObject *,
190                                  TriggerData *, HeapTuple);
191
192 static PyObject *PLy_procedure_call(PLyProcedure *, char *, PyObject *);
193
194 static PLyProcedure *PLy_procedure_get(FunctionCallInfo fcinfo,
195                                   Oid tgreloid);
196
197 static PLyProcedure *PLy_procedure_create(FunctionCallInfo fcinfo,
198                                          Oid tgreloid,
199                                          HeapTuple procTup, char *key);
200
201 static void PLy_procedure_compile(PLyProcedure *, const char *);
202 static char *PLy_procedure_munge_source(const char *, const char *);
203 static void PLy_procedure_delete(PLyProcedure *);
204
205 static void PLy_typeinfo_init(PLyTypeInfo *);
206 static void PLy_typeinfo_dealloc(PLyTypeInfo *);
207 static void PLy_output_datum_func(PLyTypeInfo *, HeapTuple);
208 static void PLy_output_datum_func2(PLyObToDatum *, HeapTuple);
209 static void PLy_input_datum_func(PLyTypeInfo *, Oid, HeapTuple);
210 static void PLy_input_datum_func2(PLyDatumToOb *, Oid, HeapTuple);
211 static void PLy_output_tuple_funcs(PLyTypeInfo *, TupleDesc);
212 static void PLy_input_tuple_funcs(PLyTypeInfo *, TupleDesc);
213
214 /* conversion functions */
215 static PyObject *PLyDict_FromTuple(PLyTypeInfo *, HeapTuple, TupleDesc);
216 static PyObject *PLyBool_FromString(const char *);
217 static PyObject *PLyFloat_FromString(const char *);
218 static PyObject *PLyInt_FromString(const char *);
219 static PyObject *PLyLong_FromString(const char *);
220 static PyObject *PLyString_FromString(const char *);
221
222
223 /* global data */
224 static bool     PLy_first_call = true;
225
226 /*
227  * Currently active plpython function
228  */
229 static PLyProcedure *PLy_curr_procedure = NULL;
230
231 /*
232  * When a callback from Python into PG incurs an error, we temporarily store
233  * the error information here, and return NULL to the Python interpreter.
234  * Any further callback attempts immediately fail, and when the Python
235  * interpreter returns to the calling function, we re-throw the error (even if
236  * Python thinks it trapped the error and doesn't return NULL).  Eventually
237  * this ought to be improved to let Python code really truly trap the error,
238  * but that's more of a change from the pre-8.0 semantics than I have time for
239  * now --- it will only be possible if the callback query is executed inside a
240  * subtransaction.
241  */
242 static ErrorData *PLy_error_in_progress = NULL;
243
244 static PyObject *PLy_interp_globals = NULL;
245 static PyObject *PLy_interp_safe_globals = NULL;
246 static PyObject *PLy_procedure_cache = NULL;
247
248 /* Python exceptions */
249 static PyObject *PLy_exc_error = NULL;
250 static PyObject *PLy_exc_fatal = NULL;
251 static PyObject *PLy_exc_spi_error = NULL;
252
253 /* some globals for the python module */
254 static char PLy_plan_doc[] = {
255         "Store a PostgreSQL plan"
256 };
257
258 static char PLy_result_doc[] = {
259         "Results of a PostgreSQL query"
260 };
261
262
263 /*
264  * the function definitions
265  */
266
267 /*
268  * This routine is a crock, and so is everyplace that calls it.  The problem
269  * is that the cached form of plpython functions/queries is allocated permanently
270  * (mostly via malloc()) and never released until backend exit.  Subsidiary
271  * data structures such as fmgr info records therefore must live forever
272  * as well.  A better implementation would store all this stuff in a per-
273  * function memory context that could be reclaimed at need.  In the meantime,
274  * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
275  * it might allocate, and whatever the eventual function might allocate using
276  * fn_mcxt, will live forever too.
277  */
278 static void
279 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
280 {
281         fmgr_info_cxt(functionId, finfo, TopMemoryContext);
282 }
283
284 Datum
285 plpython_call_handler(PG_FUNCTION_ARGS)
286 {
287         Datum           retval;
288         PLyProcedure *save_curr_proc;
289         PLyProcedure *volatile proc = NULL;
290
291         PLy_init_all();
292
293         if (SPI_connect() != SPI_OK_CONNECT)
294                 elog(ERROR, "could not connect to SPI manager");
295
296         save_curr_proc = PLy_curr_procedure;
297
298         PG_TRY();
299         {
300                 if (CALLED_AS_TRIGGER(fcinfo))
301                 {
302                         TriggerData *tdata = (TriggerData *) fcinfo->context;
303                         HeapTuple       trv;
304
305                         proc = PLy_procedure_get(fcinfo,
306                                                                          RelationGetRelid(tdata->tg_relation));
307                         PLy_curr_procedure = proc;
308                         trv = PLy_trigger_handler(fcinfo, proc);
309                         retval = PointerGetDatum(trv);
310                 }
311                 else
312                 {
313                         proc = PLy_procedure_get(fcinfo, InvalidOid);
314                         PLy_curr_procedure = proc;
315                         retval = PLy_function_handler(fcinfo, proc);
316                 }
317         }
318         PG_CATCH();
319         {
320                 PLy_curr_procedure = save_curr_proc;
321                 if (proc)
322                 {
323                         /* note: Py_DECREF needs braces around it, as of 2003/08 */
324                         Py_DECREF(proc->me);
325                 }
326                 PyErr_Clear();
327                 PG_RE_THROW();
328         }
329         PG_END_TRY();
330
331         PLy_curr_procedure = save_curr_proc;
332
333         Py_DECREF(proc->me);
334
335         return retval;
336 }
337
338 /* trigger and function sub handlers
339  *
340  * the python function is expected to return Py_None if the tuple is
341  * acceptable and unmodified.  Otherwise it should return a PyString
342  * object who's value is SKIP, or MODIFY.  SKIP means don't perform
343  * this action.  MODIFY means the tuple has been modified, so update
344  * tuple and perform action.  SKIP and MODIFY assume the trigger fires
345  * BEFORE the event and is ROW level.  postgres expects the function
346  * to take no arguments and return an argument of type trigger.
347  */
348 static HeapTuple
349 PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
350 {
351         HeapTuple       rv = NULL;
352         PyObject   *volatile plargs = NULL;
353         PyObject   *volatile plrv = NULL;
354
355         PG_TRY();
356         {
357                 plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
358                 plrv = PLy_procedure_call(proc, "TD", plargs);
359
360                 Assert(plrv != NULL);
361                 Assert(!PLy_error_in_progress);
362
363                 /*
364                  * Disconnect from SPI manager
365                  */
366                 if (SPI_finish() != SPI_OK_FINISH)
367                         elog(ERROR, "SPI_finish failed");
368
369                 /*
370                  * return of None means we're happy with the tuple
371                  */
372                 if (plrv != Py_None)
373                 {
374                         char       *srv;
375
376                         if (!PyString_Check(plrv))
377                                 ereport(ERROR,
378                                                 (errcode(ERRCODE_DATA_EXCEPTION),
379                                                  errmsg("unexpected return value from trigger procedure"),
380                                                  errdetail("Expected None or a String.")));
381
382                         srv = PyString_AsString(plrv);
383                         if (pg_strcasecmp(srv, "SKIP") == 0)
384                                 rv = NULL;
385                         else if (pg_strcasecmp(srv, "MODIFY") == 0)
386                         {
387                                 TriggerData *tdata = (TriggerData *) fcinfo->context;
388
389                                 if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event) ||
390                                         TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
391                                         rv = PLy_modify_tuple(proc, plargs, tdata, rv);
392                                 else
393                                         elog(WARNING, "ignoring modified tuple in DELETE trigger");
394                         }
395                         else if (pg_strcasecmp(srv, "OK") != 0)
396                         {
397                                 /*
398                                  * accept "OK" as an alternative to None; otherwise,
399                                  * raise an error
400                                  */
401                                 ereport(ERROR,
402                                                 (errcode(ERRCODE_DATA_EXCEPTION),
403                                                  errmsg("unexpected return value from trigger procedure"),
404                                                  errdetail("Expected None, \"OK\", \"SKIP\", or \"MODIFY\".")));
405                         }
406                 }
407         }
408         PG_CATCH();
409         {
410                 Py_XDECREF(plargs);
411                 Py_XDECREF(plrv);
412
413                 PG_RE_THROW();
414         }
415         PG_END_TRY();
416
417         Py_DECREF(plargs);
418         Py_DECREF(plrv);
419
420         return rv;
421 }
422
423 static HeapTuple
424 PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
425                                  HeapTuple otup)
426 {
427         PyObject   *volatile plntup;
428         PyObject   *volatile plkeys;
429         PyObject   *volatile platt;
430         PyObject   *volatile plval;
431         PyObject   *volatile plstr;
432         HeapTuple       rtup;
433         int                     natts,
434                                 i,
435                                 attn,
436                                 atti;
437         int                *volatile modattrs;
438         Datum      *volatile modvalues;
439         char       *volatile modnulls;
440         TupleDesc       tupdesc;
441
442         plntup = plkeys = platt = plval = plstr = NULL;
443         modattrs = NULL;
444         modvalues = NULL;
445         modnulls = NULL;
446
447         PG_TRY();
448         {
449                 if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL)
450                         elog(ERROR, "TD[\"new\"] deleted, unable to modify tuple");
451                 if (!PyDict_Check(plntup))
452                         elog(ERROR, "TD[\"new\"] is not a dictionary object");
453                 Py_INCREF(plntup);
454
455                 plkeys = PyDict_Keys(plntup);
456                 natts = PyList_Size(plkeys);
457
458                 modattrs = (int *) palloc(natts * sizeof(int));
459                 modvalues = (Datum *) palloc(natts * sizeof(Datum));
460                 modnulls = (char *) palloc(natts * sizeof(char));
461
462                 tupdesc = tdata->tg_relation->rd_att;
463
464                 for (i = 0; i < natts; i++)
465                 {
466                         char       *src;
467
468                         platt = PyList_GetItem(plkeys, i);
469                         if (!PyString_Check(platt))
470                                 elog(ERROR, "attribute name is not a string");
471                         attn = SPI_fnumber(tupdesc, PyString_AsString(platt));
472                         if (attn == SPI_ERROR_NOATTRIBUTE)
473                                 elog(ERROR, "invalid attribute \"%s\" in tuple",
474                                          PyString_AsString(platt));
475                         atti = attn - 1;
476
477                         plval = PyDict_GetItem(plntup, platt);
478                         if (plval == NULL)
479                                 elog(FATAL, "python interpreter is probably corrupted");
480
481                         Py_INCREF(plval);
482
483                         modattrs[i] = attn;
484
485                         if (tupdesc->attrs[atti]->attisdropped)
486                         {
487                                 modvalues[i] = (Datum) 0;
488                                 modnulls[i] = 'n';
489                         }
490                         else if (plval != Py_None)
491                         {
492                                 plstr = PyObject_Str(plval);
493                                 if (!plstr)
494                                         PLy_elog(ERROR, "function \"%s\" could not modify tuple",
495                                                          proc->proname);
496                                 src = PyString_AsString(plstr);
497
498                                 modvalues[i] =
499                                         InputFunctionCall(&proc->result.out.r.atts[atti].typfunc,
500                                                                           src,
501                                                                           proc->result.out.r.atts[atti].typioparam,
502                                                                           tupdesc->attrs[atti]->atttypmod);
503                                 modnulls[i] = ' ';
504
505                                 Py_DECREF(plstr);
506                                 plstr = NULL;
507                         }
508                         else
509                         {
510                                 modvalues[i] =
511                                         InputFunctionCall(&proc->result.out.r.atts[atti].typfunc,
512                                                                           NULL,
513                                                                           proc->result.out.r.atts[atti].typioparam,
514                                                                           tupdesc->attrs[atti]->atttypmod);
515                                 modnulls[i] = 'n';
516                         }
517
518                         Py_DECREF(plval);
519                         plval = NULL;
520                 }
521
522                 rtup = SPI_modifytuple(tdata->tg_relation, otup, natts,
523                                                            modattrs, modvalues, modnulls);
524                 if (rtup == NULL)
525                         elog(ERROR, "SPI_modifytuple failed -- error %d", SPI_result);
526         }
527         PG_CATCH();
528         {
529                 Py_XDECREF(plntup);
530                 Py_XDECREF(plkeys);
531                 Py_XDECREF(plval);
532                 Py_XDECREF(plstr);
533
534                 if (modnulls)
535                         pfree(modnulls);
536                 if (modvalues)
537                         pfree(modvalues);
538                 if (modattrs)
539                         pfree(modattrs);
540
541                 PG_RE_THROW();
542         }
543         PG_END_TRY();
544
545         Py_DECREF(plntup);
546         Py_DECREF(plkeys);
547
548         pfree(modattrs);
549         pfree(modvalues);
550         pfree(modnulls);
551
552         return rtup;
553 }
554
555 static PyObject *
556 PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc, HeapTuple *rv)
557 {
558         TriggerData *tdata = (TriggerData *) fcinfo->context;
559         PyObject   *pltname,
560                            *pltevent,
561                            *pltwhen,
562                            *pltlevel,
563                        *pltrelid,
564                        *plttablename,
565                        *plttableschema;
566         PyObject   *pltargs,
567                            *pytnew,
568                            *pytold;
569         PyObject   *volatile pltdata = NULL;
570         char       *stroid;
571
572         PG_TRY();
573         {
574                 pltdata = PyDict_New();
575                 if (!pltdata)
576                         PLy_elog(ERROR, "could not build arguments for trigger procedure");
577
578                 pltname = PyString_FromString(tdata->tg_trigger->tgname);
579                 PyDict_SetItemString(pltdata, "name", pltname);
580                 Py_DECREF(pltname);
581
582                 stroid = DatumGetCString(DirectFunctionCall1(oidout,
583                                                            ObjectIdGetDatum(tdata->tg_relation->rd_id)));
584                 pltrelid = PyString_FromString(stroid);
585                 PyDict_SetItemString(pltdata, "relid", pltrelid);
586                 Py_DECREF(pltrelid);
587                 pfree(stroid);
588
589                 stroid = SPI_getrelname(tdata->tg_relation);
590                 plttablename = PyString_FromString(stroid);
591                 PyDict_SetItemString(pltdata, "table_name", plttablename);
592                 Py_DECREF(plttablename);
593                 pfree(stroid);
594                 
595                 stroid = SPI_getnspname(tdata->tg_relation);
596                 plttableschema = PyString_FromString(stroid);
597                 PyDict_SetItemString(pltdata, "table_schema", plttableschema);
598                 Py_DECREF(plttableschema);
599                 pfree(stroid);
600                 
601
602                 if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
603                         pltwhen = PyString_FromString("BEFORE");
604                 else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
605                         pltwhen = PyString_FromString("AFTER");
606                 else
607                 {
608                         elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event);
609                         pltwhen = NULL;         /* keep compiler quiet */
610                 }
611                 PyDict_SetItemString(pltdata, "when", pltwhen);
612                 Py_DECREF(pltwhen);
613
614                 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
615                 {
616                         pltlevel = PyString_FromString("ROW");
617                         PyDict_SetItemString(pltdata, "level", pltlevel);
618                         Py_DECREF(pltlevel);
619
620                         if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
621                         {
622                                 pltevent = PyString_FromString("INSERT");
623
624                                 PyDict_SetItemString(pltdata, "old", Py_None);
625                                 pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple,
626                                                                                    tdata->tg_relation->rd_att);
627                                 PyDict_SetItemString(pltdata, "new", pytnew);
628                                 Py_DECREF(pytnew);
629                                 *rv = tdata->tg_trigtuple;
630                         }
631                         else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
632                         {
633                                 pltevent = PyString_FromString("DELETE");
634
635                                 PyDict_SetItemString(pltdata, "new", Py_None);
636                                 pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple,
637                                                                                    tdata->tg_relation->rd_att);
638                                 PyDict_SetItemString(pltdata, "old", pytold);
639                                 Py_DECREF(pytold);
640                                 *rv = tdata->tg_trigtuple;
641                         }
642                         else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
643                         {
644                                 pltevent = PyString_FromString("UPDATE");
645
646                                 pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_newtuple,
647                                                                                    tdata->tg_relation->rd_att);
648                                 PyDict_SetItemString(pltdata, "new", pytnew);
649                                 Py_DECREF(pytnew);
650                                 pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple,
651                                                                                    tdata->tg_relation->rd_att);
652                                 PyDict_SetItemString(pltdata, "old", pytold);
653                                 Py_DECREF(pytold);
654                                 *rv = tdata->tg_newtuple;
655                         }
656                         else
657                         {
658                                 elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
659                                 pltevent = NULL;        /* keep compiler quiet */
660                         }
661
662                         PyDict_SetItemString(pltdata, "event", pltevent);
663                         Py_DECREF(pltevent);
664                 }
665                 else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
666                 {
667                         pltlevel = PyString_FromString("STATEMENT");
668                         PyDict_SetItemString(pltdata, "level", pltlevel);
669                         Py_DECREF(pltlevel);
670
671                         PyDict_SetItemString(pltdata, "old", Py_None);
672                         PyDict_SetItemString(pltdata, "new", Py_None);
673                         *rv = NULL;
674
675                         if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
676                                 pltevent = PyString_FromString("INSERT");
677                         else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
678                                 pltevent = PyString_FromString("DELETE");
679                         else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
680                                 pltevent = PyString_FromString("UPDATE");
681                         else
682                         {
683                                 elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
684                                 pltevent = NULL;        /* keep compiler quiet */
685                         }
686
687                         PyDict_SetItemString(pltdata, "event", pltevent);
688                         Py_DECREF(pltevent);
689                 }
690                 else
691                         elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event);
692
693                 if (tdata->tg_trigger->tgnargs)
694                 {
695                         /*
696                          * all strings...
697                          */
698                         int                     i;
699                         PyObject   *pltarg;
700
701                         pltargs = PyList_New(tdata->tg_trigger->tgnargs);
702                         for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
703                         {
704                                 pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]);
705
706                                 /*
707                                  * stolen, don't Py_DECREF
708                                  */
709                                 PyList_SetItem(pltargs, i, pltarg);
710                         }
711                 }
712                 else
713                 {
714                         Py_INCREF(Py_None);
715                         pltargs = Py_None;
716                 }
717                 PyDict_SetItemString(pltdata, "args", pltargs);
718                 Py_DECREF(pltargs);
719         }
720         PG_CATCH();
721         {
722                 Py_XDECREF(pltdata);
723                 PG_RE_THROW();
724         }
725         PG_END_TRY();
726
727         return pltdata;
728 }
729
730
731
732 /* function handler and friends */
733 static Datum
734 PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
735 {
736         Datum           rv;
737         PyObject   *volatile plargs = NULL;
738         PyObject   *volatile plrv = NULL;
739         PyObject   *volatile plrv_so = NULL;
740         char       *plrv_sc;
741
742         PG_TRY();
743         {
744                 plargs = PLy_function_build_args(fcinfo, proc);
745                 plrv = PLy_procedure_call(proc, "args", plargs);
746
747                 Assert(plrv != NULL);
748                 Assert(!PLy_error_in_progress);
749
750                 /*
751                  * Disconnect from SPI manager and then create the return values datum
752                  * (if the input function does a palloc for it this must not be
753                  * allocated in the SPI memory context because SPI_finish would free
754                  * it).
755                  */
756                 if (SPI_finish() != SPI_OK_FINISH)
757                         elog(ERROR, "SPI_finish failed");
758
759                 /*
760                  * If the function is declared to return void, the Python
761                  * return value must be None. For void-returning functions, we
762                  * also treat a None return value as a special "void datum"
763                  * rather than NULL (as is the case for non-void-returning
764                  * functions).
765                  */
766                 if (proc->result.out.d.typoid == VOIDOID)
767                 {
768                         if (plrv != Py_None)
769                                 ereport(ERROR,
770                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
771                                                  errmsg("invalid return value from plpython function"),
772                                                  errdetail("Functions returning type \"void\" must return None.")));
773
774                         fcinfo->isnull = false;
775                         rv = (Datum) 0;
776                 }
777                 else if (plrv == Py_None)
778                 {
779                         fcinfo->isnull = true;
780                         rv = InputFunctionCall(&proc->result.out.d.typfunc,
781                                                                    NULL,
782                                                                    proc->result.out.d.typioparam,
783                                                                    -1);
784                 }
785                 else
786                 {
787                         fcinfo->isnull = false;
788                         plrv_so = PyObject_Str(plrv);
789                         if (!plrv_so)
790                                 PLy_elog(ERROR, "function \"%s\" could not create return value", proc->proname);
791                         plrv_sc = PyString_AsString(plrv_so);
792                         rv = InputFunctionCall(&proc->result.out.d.typfunc,
793                                                                    plrv_sc,
794                                                                    proc->result.out.d.typioparam,
795                                                                    -1);
796                 }
797         }
798         PG_CATCH();
799         {
800                 Py_XDECREF(plargs);
801                 Py_XDECREF(plrv);
802                 Py_XDECREF(plrv_so);
803
804                 PG_RE_THROW();
805         }
806         PG_END_TRY();
807
808         Py_XDECREF(plargs);
809         Py_DECREF(plrv);
810         Py_XDECREF(plrv_so);
811
812         return rv;
813 }
814
815 static PyObject *
816 PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs)
817 {
818         PyObject   *rv;
819
820         PyDict_SetItemString(proc->globals, kargs, vargs);
821         rv = PyEval_EvalCode((PyCodeObject *) proc->code,
822                                                  proc->globals, proc->globals);
823
824         /*
825          * If there was an error in a PG callback, propagate that no matter what
826          * Python claims about its success.
827          */
828         if (PLy_error_in_progress)
829         {
830                 ErrorData  *edata = PLy_error_in_progress;
831
832                 PLy_error_in_progress = NULL;
833                 ReThrowError(edata);
834         }
835
836         if (rv == NULL || PyErr_Occurred())
837         {
838                 Py_XDECREF(rv);
839                 PLy_elog(ERROR, "function \"%s\" failed", proc->proname);
840         }
841
842         return rv;
843 }
844
845 static PyObject *
846 PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
847 {
848         PyObject   *volatile arg = NULL;
849         PyObject   *volatile args = NULL;
850         int                     i;
851
852         PG_TRY();
853         {
854                 args = PyList_New(proc->nargs);
855                 for (i = 0; i < proc->nargs; i++)
856                 {
857                         if (proc->args[i].is_rowtype > 0)
858                         {
859                                 if (fcinfo->argnull[i])
860                                         arg = NULL;
861                                 else
862                                 {
863                                         HeapTupleHeader td;
864                                         Oid                     tupType;
865                                         int32           tupTypmod;
866                                         TupleDesc       tupdesc;
867                                         HeapTupleData tmptup;
868
869                                         td = DatumGetHeapTupleHeader(fcinfo->arg[i]);
870                                         /* Extract rowtype info and find a tupdesc */
871                                         tupType = HeapTupleHeaderGetTypeId(td);
872                                         tupTypmod = HeapTupleHeaderGetTypMod(td);
873                                         tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
874
875                                         /* Set up I/O funcs if not done yet */
876                                         if (proc->args[i].is_rowtype != 1)
877                                                 PLy_input_tuple_funcs(&(proc->args[i]), tupdesc);
878
879                                         /* Build a temporary HeapTuple control structure */
880                                         tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
881                                         tmptup.t_data = td;
882
883                                         arg = PLyDict_FromTuple(&(proc->args[i]), &tmptup, tupdesc);
884                                 }
885                         }
886                         else
887                         {
888                                 if (fcinfo->argnull[i])
889                                         arg = NULL;
890                                 else
891                                 {
892                                         char       *ct;
893
894                                         ct = OutputFunctionCall(&(proc->args[i].in.d.typfunc),
895                                                                                         fcinfo->arg[i]);
896                                         arg = (proc->args[i].in.d.func) (ct);
897                                         pfree(ct);
898                                 }
899                         }
900
901                         if (arg == NULL)
902                         {
903                                 Py_INCREF(Py_None);
904                                 arg = Py_None;
905                         }
906
907                         /*
908                          * FIXME -- error check this
909                          */
910                         PyList_SetItem(args, i, arg);
911                         arg = NULL;
912                 }
913         }
914         PG_CATCH();
915         {
916                 Py_XDECREF(arg);
917                 Py_XDECREF(args);
918
919                 PG_RE_THROW();
920         }
921         PG_END_TRY();
922
923         return args;
924 }
925
926
927 /*
928  * PLyProcedure functions
929  */
930
931 /* PLy_procedure_get: returns a cached PLyProcedure, or creates, stores and
932  * returns a new PLyProcedure.  fcinfo is the call info, tgreloid is the
933  * relation OID when calling a trigger, or InvalidOid (zero) for ordinary
934  * function calls.
935  */
936 static PLyProcedure *
937 PLy_procedure_get(FunctionCallInfo fcinfo, Oid tgreloid)
938 {
939         Oid                     fn_oid;
940         HeapTuple       procTup;
941         char            key[128];
942         PyObject   *plproc;
943         PLyProcedure *proc = NULL;
944         int                     rv;
945
946         fn_oid = fcinfo->flinfo->fn_oid;
947         procTup = SearchSysCache(PROCOID,
948                                                          ObjectIdGetDatum(fn_oid),
949                                                          0, 0, 0);
950         if (!HeapTupleIsValid(procTup))
951                 elog(ERROR, "cache lookup failed for function %u", fn_oid);
952
953         rv = snprintf(key, sizeof(key), "%u_%u", fn_oid, tgreloid);
954         if (rv >= sizeof(key) || rv < 0)
955                 elog(ERROR, "key too long");
956
957         plproc = PyDict_GetItemString(PLy_procedure_cache, key);
958
959         if (plproc != NULL)
960         {
961                 Py_INCREF(plproc);
962                 if (!PyCObject_Check(plproc))
963                         elog(FATAL, "expected a PyCObject, didn't get one");
964
965                 proc = PyCObject_AsVoidPtr(plproc);
966                 if (proc->me != plproc)
967                         elog(FATAL, "proc->me != plproc");
968                 /* did we find an up-to-date cache entry? */
969                 if (proc->fn_xmin != HeapTupleHeaderGetXmin(procTup->t_data) ||
970                         proc->fn_cmin != HeapTupleHeaderGetCmin(procTup->t_data))
971                 {
972                         Py_DECREF(plproc);
973                         proc = NULL;
974                 }
975         }
976
977         if (proc == NULL)
978                 proc = PLy_procedure_create(fcinfo, tgreloid, procTup, key);
979
980         ReleaseSysCache(procTup);
981
982         return proc;
983 }
984
985 static PLyProcedure *
986 PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
987                                          HeapTuple procTup, char *key)
988 {
989         char            procName[NAMEDATALEN + 256];
990         Form_pg_proc procStruct;
991         PLyProcedure *volatile proc;
992         char       *volatile procSource = NULL;
993         Datum           prosrcdatum;
994         bool            isnull;
995         int                     i,
996                                 rv;
997
998         procStruct = (Form_pg_proc) GETSTRUCT(procTup);
999
1000         if (OidIsValid(tgreloid))
1001                 rv = snprintf(procName, sizeof(procName),
1002                                           "__plpython_procedure_%s_%u_trigger_%u",
1003                                           NameStr(procStruct->proname),
1004                                           fcinfo->flinfo->fn_oid,
1005                                           tgreloid);
1006         else
1007                 rv = snprintf(procName, sizeof(procName),
1008                                           "__plpython_procedure_%s_%u",
1009                                           NameStr(procStruct->proname),
1010                                           fcinfo->flinfo->fn_oid);
1011         if (rv >= sizeof(procName) || rv < 0)
1012                 elog(ERROR, "procedure name would overrun buffer");
1013
1014         proc = PLy_malloc(sizeof(PLyProcedure));
1015         proc->proname = PLy_strdup(NameStr(procStruct->proname));
1016         proc->pyname = PLy_strdup(procName);
1017         proc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
1018         proc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
1019         /* Remember if function is STABLE/IMMUTABLE */
1020         proc->fn_readonly =
1021                 (procStruct->provolatile != PROVOLATILE_VOLATILE);
1022         PLy_typeinfo_init(&proc->result);
1023         for (i = 0; i < FUNC_MAX_ARGS; i++)
1024                 PLy_typeinfo_init(&proc->args[i]);
1025         proc->nargs = 0;
1026         proc->code = proc->statics = NULL;
1027         proc->globals = proc->me = NULL;
1028
1029         PG_TRY();
1030         {
1031                 /*
1032                  * get information required for output conversion of the return value,
1033                  * but only if this isn't a trigger.
1034                  */
1035                 if (!CALLED_AS_TRIGGER(fcinfo))
1036                 {
1037                         HeapTuple       rvTypeTup;
1038                         Form_pg_type rvTypeStruct;
1039
1040                         rvTypeTup = SearchSysCache(TYPEOID,
1041                                                                         ObjectIdGetDatum(procStruct->prorettype),
1042                                                                            0, 0, 0);
1043                         if (!HeapTupleIsValid(rvTypeTup))
1044                                 elog(ERROR, "cache lookup failed for type %u",
1045                                          procStruct->prorettype);
1046                         rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup);
1047
1048                         /* Disallow pseudotype result, except for void */
1049                         if (rvTypeStruct->typtype == 'p' &&
1050                                 procStruct->prorettype != VOIDOID)
1051                         {
1052                                 if (procStruct->prorettype == TRIGGEROID)
1053                                         ereport(ERROR,
1054                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1055                                                          errmsg("trigger functions may only be called as triggers")));
1056                                 else
1057                                         ereport(ERROR,
1058                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1059                                                    errmsg("plpython functions cannot return type %s",
1060                                                                   format_type_be(procStruct->prorettype))));
1061                         }
1062
1063                         if (rvTypeStruct->typtype == 'c')
1064                                 ereport(ERROR,
1065                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1066                                          errmsg("plpython functions cannot return tuples yet")));
1067                         else
1068                                 PLy_output_datum_func(&proc->result, rvTypeTup);
1069
1070                         ReleaseSysCache(rvTypeTup);
1071                 }
1072                 else
1073                 {
1074                         /*
1075                          * input/output conversion for trigger tuples.  use the result
1076                          * TypeInfo variable to store the tuple conversion info.
1077                          */
1078                         TriggerData *tdata = (TriggerData *) fcinfo->context;
1079
1080                         PLy_input_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att);
1081                         PLy_output_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att);
1082                 }
1083
1084                 /*
1085                  * now get information required for input conversion of the procedure's
1086                  * arguments.
1087                  */
1088                 proc->nargs = fcinfo->nargs;
1089                 for (i = 0; i < fcinfo->nargs; i++)
1090                 {
1091                         HeapTuple       argTypeTup;
1092                         Form_pg_type argTypeStruct;
1093
1094                         argTypeTup = SearchSysCache(TYPEOID,
1095                                                  ObjectIdGetDatum(procStruct->proargtypes.values[i]),
1096                                                                                 0, 0, 0);
1097                         if (!HeapTupleIsValid(argTypeTup))
1098                                 elog(ERROR, "cache lookup failed for type %u",
1099                                          procStruct->proargtypes.values[i]);
1100                         argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
1101
1102                         /* Disallow pseudotype argument */
1103                         if (argTypeStruct->typtype == 'p')
1104                                 ereport(ERROR,
1105                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1106                                                  errmsg("plpython functions cannot take type %s",
1107                                                 format_type_be(procStruct->proargtypes.values[i]))));
1108
1109                         if (argTypeStruct->typtype != 'c')
1110                                 PLy_input_datum_func(&(proc->args[i]),
1111                                                                          procStruct->proargtypes.values[i],
1112                                                                          argTypeTup);
1113                         else
1114                                 proc->args[i].is_rowtype = 2;   /* still need to set I/O funcs */
1115
1116                         ReleaseSysCache(argTypeTup);
1117                 }
1118
1119
1120                 /*
1121                  * get the text of the function.
1122                  */
1123                 prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
1124                                                                           Anum_pg_proc_prosrc, &isnull);
1125                 if (isnull)
1126                         elog(ERROR, "null prosrc");
1127                 procSource = DatumGetCString(DirectFunctionCall1(textout,
1128                                                                                                                  prosrcdatum));
1129
1130                 PLy_procedure_compile(proc, procSource);
1131
1132                 pfree(procSource);
1133
1134                 proc->me = PyCObject_FromVoidPtr(proc, NULL);
1135                 PyDict_SetItemString(PLy_procedure_cache, key, proc->me);
1136         }
1137         PG_CATCH();
1138         {
1139                 PLy_procedure_delete(proc);
1140                 if (procSource)
1141                         pfree(procSource);
1142
1143                 PG_RE_THROW();
1144         }
1145         PG_END_TRY();
1146
1147         return proc;
1148 }
1149
1150 static void
1151 PLy_procedure_compile(PLyProcedure * proc, const char *src)
1152 {
1153         PyObject   *crv = NULL;
1154         char       *msrc;
1155
1156         proc->globals = PyDict_Copy(PLy_interp_globals);
1157
1158         /*
1159          * SD is private preserved data between calls. GD is global data
1160          * shared by all functions
1161          */
1162         proc->statics = PyDict_New();
1163         PyDict_SetItemString(proc->globals, "SD", proc->statics);
1164
1165         /*
1166          * insert the function code into the interpreter
1167          */
1168         msrc = PLy_procedure_munge_source(proc->pyname, src);
1169         crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);
1170         free(msrc);
1171
1172         if (crv != NULL && (!PyErr_Occurred()))
1173         {
1174                 int                     clen;
1175                 char            call[NAMEDATALEN + 256];
1176
1177                 Py_DECREF(crv);
1178
1179                 /*
1180                  * compile a call to the function
1181                  */
1182                 clen = snprintf(call, sizeof(call), "%s()", proc->pyname);
1183                 if (clen < 0 || clen >= sizeof(call))
1184                         elog(ERROR, "string would overflow buffer");
1185                 proc->code = Py_CompileString(call, "<string>", Py_eval_input);
1186                 if (proc->code != NULL && (!PyErr_Occurred()))
1187                         return;
1188         }
1189         else
1190                 Py_XDECREF(crv);
1191
1192         PLy_elog(ERROR, "could not compile function \"%s\"", proc->proname);
1193 }
1194
1195 static char *
1196 PLy_procedure_munge_source(const char *name, const char *src)
1197 {
1198         char       *mrc,
1199                            *mp;
1200         const char *sp;
1201         size_t          mlen,
1202                                 plen;
1203
1204         /*
1205          * room for function source and the def statement
1206          */
1207         mlen = (strlen(src) * 2) + strlen(name) + 16;
1208
1209         mrc = PLy_malloc(mlen);
1210         plen = snprintf(mrc, mlen, "def %s():\n\t", name);
1211         Assert(plen >= 0 && plen < mlen);
1212
1213         sp = src;
1214         mp = mrc + plen;
1215
1216         while (*sp != '\0')
1217         {
1218                 if (*sp == '\r' && *(sp + 1) == '\n')
1219                         sp++;
1220
1221                 if (*sp == '\n' || *sp == '\r')
1222                 {
1223                         *mp++ = '\n';
1224                         *mp++ = '\t';
1225                         sp++;
1226                 }
1227                 else
1228                         *mp++ = *sp++;
1229         }
1230         *mp++ = '\n';
1231         *mp++ = '\n';
1232         *mp = '\0';
1233
1234         if (mp > (mrc + mlen))
1235                 elog(FATAL, "buffer overrun in PLy_munge_source");
1236
1237         return mrc;
1238 }
1239
1240 static void
1241 PLy_procedure_delete(PLyProcedure * proc)
1242 {
1243         int                     i;
1244
1245         Py_XDECREF(proc->code);
1246         Py_XDECREF(proc->statics);
1247         Py_XDECREF(proc->globals);
1248         Py_XDECREF(proc->me);
1249         if (proc->proname)
1250                 PLy_free(proc->proname);
1251         if (proc->pyname)
1252                 PLy_free(proc->pyname);
1253         for (i = 0; i < proc->nargs; i++)
1254                 if (proc->args[i].is_rowtype == 1)
1255                 {
1256                         if (proc->args[i].in.r.atts)
1257                                 PLy_free(proc->args[i].in.r.atts);
1258                         if (proc->args[i].out.r.atts)
1259                                 PLy_free(proc->args[i].out.r.atts);
1260                 }
1261 }
1262
1263 /* conversion functions.  remember output from python is
1264  * input to postgresql, and vis versa.
1265  */
1266 static void
1267 PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1268 {
1269         int                     i;
1270
1271         if (arg->is_rowtype == 0)
1272                 elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");
1273
1274         arg->is_rowtype = 1;
1275         arg->in.r.natts = desc->natts;
1276         arg->in.r.atts = PLy_malloc(desc->natts * sizeof(PLyDatumToOb));
1277
1278         for (i = 0; i < desc->natts; i++)
1279         {
1280                 HeapTuple       typeTup;
1281
1282                 if (desc->attrs[i]->attisdropped)
1283                         continue;
1284
1285                 typeTup = SearchSysCache(TYPEOID,
1286                                                                  ObjectIdGetDatum(desc->attrs[i]->atttypid),
1287                                                                  0, 0, 0);
1288                 if (!HeapTupleIsValid(typeTup))
1289                         elog(ERROR, "cache lookup failed for type %u",
1290                                  desc->attrs[i]->atttypid);
1291
1292                 PLy_input_datum_func2(&(arg->in.r.atts[i]),
1293                                                           desc->attrs[i]->atttypid,
1294                                                           typeTup);
1295
1296                 ReleaseSysCache(typeTup);
1297         }
1298 }
1299
1300 static void
1301 PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1302 {
1303         int                     i;
1304
1305         if (arg->is_rowtype == 0)
1306                 elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");
1307
1308         arg->is_rowtype = 1;
1309         arg->out.r.natts = desc->natts;
1310         arg->out.r.atts = PLy_malloc(desc->natts * sizeof(PLyDatumToOb));
1311
1312         for (i = 0; i < desc->natts; i++)
1313         {
1314                 HeapTuple       typeTup;
1315
1316                 if (desc->attrs[i]->attisdropped)
1317                         continue;
1318
1319                 typeTup = SearchSysCache(TYPEOID,
1320                                                                  ObjectIdGetDatum(desc->attrs[i]->atttypid),
1321                                                                  0, 0, 0);
1322                 if (!HeapTupleIsValid(typeTup))
1323                         elog(ERROR, "cache lookup failed for type %u",
1324                                  desc->attrs[i]->atttypid);
1325
1326                 PLy_output_datum_func2(&(arg->out.r.atts[i]), typeTup);
1327
1328                 ReleaseSysCache(typeTup);
1329         }
1330 }
1331
1332 static void
1333 PLy_output_datum_func(PLyTypeInfo * arg, HeapTuple typeTup)
1334 {
1335         if (arg->is_rowtype > 0)
1336                 elog(ERROR, "PLyTypeInfo struct is initialized for a Tuple");
1337         arg->is_rowtype = 0;
1338         PLy_output_datum_func2(&(arg->out.d), typeTup);
1339 }
1340
1341 static void
1342 PLy_output_datum_func2(PLyObToDatum * arg, HeapTuple typeTup)
1343 {
1344         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1345
1346         perm_fmgr_info(typeStruct->typinput, &arg->typfunc);
1347         arg->typoid = HeapTupleGetOid(typeTup);
1348         arg->typioparam = getTypeIOParam(typeTup);
1349         arg->typbyval = typeStruct->typbyval;
1350 }
1351
1352 static void
1353 PLy_input_datum_func(PLyTypeInfo * arg, Oid typeOid, HeapTuple typeTup)
1354 {
1355         if (arg->is_rowtype > 0)
1356                 elog(ERROR, "PLyTypeInfo struct is initialized for Tuple");
1357         arg->is_rowtype = 0;
1358         PLy_input_datum_func2(&(arg->in.d), typeOid, typeTup);
1359 }
1360
1361 static void
1362 PLy_input_datum_func2(PLyDatumToOb * arg, Oid typeOid, HeapTuple typeTup)
1363 {
1364         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1365
1366         /* Get the type's conversion information */
1367         perm_fmgr_info(typeStruct->typoutput, &arg->typfunc);
1368         arg->typioparam = getTypeIOParam(typeTup);
1369         arg->typbyval = typeStruct->typbyval;
1370
1371         /* Determine which kind of Python object we will convert to */
1372         switch (typeOid)
1373         {
1374                 case BOOLOID:
1375                         arg->func = PLyBool_FromString;
1376                         break;
1377                 case FLOAT4OID:
1378                 case FLOAT8OID:
1379                 case NUMERICOID:
1380                         arg->func = PLyFloat_FromString;
1381                         break;
1382                 case INT2OID:
1383                 case INT4OID:
1384                         arg->func = PLyInt_FromString;
1385                         break;
1386                 case INT8OID:
1387                         arg->func = PLyLong_FromString;
1388                         break;
1389                 default:
1390                         arg->func = PLyString_FromString;
1391                         break;
1392         }
1393 }
1394
1395 static void
1396 PLy_typeinfo_init(PLyTypeInfo * arg)
1397 {
1398         arg->is_rowtype = -1;
1399         arg->in.r.natts = arg->out.r.natts = 0;
1400         arg->in.r.atts = NULL;
1401         arg->out.r.atts = NULL;
1402 }
1403
1404 static void
1405 PLy_typeinfo_dealloc(PLyTypeInfo * arg)
1406 {
1407         if (arg->is_rowtype == 1)
1408         {
1409                 if (arg->in.r.atts)
1410                         PLy_free(arg->in.r.atts);
1411                 if (arg->out.r.atts)
1412                         PLy_free(arg->out.r.atts);
1413         }
1414 }
1415
1416 /* assumes that a bool is always returned as a 't' or 'f' */
1417 static PyObject *
1418 PLyBool_FromString(const char *src)
1419 {
1420         if (src[0] == 't')
1421                 return PyInt_FromLong(1);
1422         return PyInt_FromLong(0);
1423 }
1424
1425 static PyObject *
1426 PLyFloat_FromString(const char *src)
1427 {
1428         double          v;
1429         char       *eptr;
1430
1431         errno = 0;
1432         v = strtod(src, &eptr);
1433         if (*eptr != '\0' || errno)
1434                 return NULL;
1435         return PyFloat_FromDouble(v);
1436 }
1437
1438 static PyObject *
1439 PLyInt_FromString(const char *src)
1440 {
1441         long            v;
1442         char       *eptr;
1443
1444         errno = 0;
1445         v = strtol(src, &eptr, 0);
1446         if (*eptr != '\0' || errno)
1447                 return NULL;
1448         return PyInt_FromLong(v);
1449 }
1450
1451 static PyObject *
1452 PLyLong_FromString(const char *src)
1453 {
1454         return PyLong_FromString((char *) src, NULL, 0);
1455 }
1456
1457 static PyObject *
1458 PLyString_FromString(const char *src)
1459 {
1460         return PyString_FromString(src);
1461 }
1462
1463 static PyObject *
1464 PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
1465 {
1466         PyObject   *volatile dict;
1467         int                     i;
1468
1469         if (info->is_rowtype != 1)
1470                 elog(ERROR, "PLyTypeInfo structure describes a datum");
1471
1472         dict = PyDict_New();
1473         if (dict == NULL)
1474                 PLy_elog(ERROR, "could not create tuple dictionary");
1475
1476         PG_TRY();
1477         {
1478                 for (i = 0; i < info->in.r.natts; i++)
1479                 {
1480                         char       *key,
1481                                            *vsrc;
1482                         Datum           vattr;
1483                         bool            is_null;
1484                         PyObject   *value;
1485
1486                         if (desc->attrs[i]->attisdropped)
1487                                 continue;
1488
1489                         key = NameStr(desc->attrs[i]->attname);
1490                         vattr = heap_getattr(tuple, (i + 1), desc, &is_null);
1491
1492                         if (is_null || info->in.r.atts[i].func == NULL)
1493                                 PyDict_SetItemString(dict, key, Py_None);
1494                         else
1495                         {
1496                                 vsrc = OutputFunctionCall(&info->in.r.atts[i].typfunc,
1497                                                                                   vattr);
1498
1499                                 /*
1500                                  * no exceptions allowed
1501                                  */
1502                                 value = info->in.r.atts[i].func(vsrc);
1503                                 pfree(vsrc);
1504                                 PyDict_SetItemString(dict, key, value);
1505                                 Py_DECREF(value);
1506                         }
1507                 }
1508         }
1509         PG_CATCH();
1510         {
1511                 Py_DECREF(dict);
1512                 PG_RE_THROW();
1513         }
1514         PG_END_TRY();
1515
1516         return dict;
1517 }
1518
1519 /* initialization, some python variables function declared here */
1520
1521 /* interface to postgresql elog */
1522 static PyObject *PLy_debug(PyObject *, PyObject *);
1523 static PyObject *PLy_log(PyObject *, PyObject *);
1524 static PyObject *PLy_info(PyObject *, PyObject *);
1525 static PyObject *PLy_notice(PyObject *, PyObject *);
1526 static PyObject *PLy_warning(PyObject *, PyObject *);
1527 static PyObject *PLy_error(PyObject *, PyObject *);
1528 static PyObject *PLy_fatal(PyObject *, PyObject *);
1529
1530 /* PLyPlanObject, PLyResultObject and SPI interface */
1531 #define is_PLyPlanObject(x) ((x)->ob_type == &PLy_PlanType)
1532 static PyObject *PLy_plan_new(void);
1533 static void PLy_plan_dealloc(PyObject *);
1534 static PyObject *PLy_plan_getattr(PyObject *, char *);
1535 static PyObject *PLy_plan_status(PyObject *, PyObject *);
1536
1537 static PyObject *PLy_result_new(void);
1538 static void PLy_result_dealloc(PyObject *);
1539 static PyObject *PLy_result_getattr(PyObject *, char *);
1540 static PyObject *PLy_result_nrows(PyObject *, PyObject *);
1541 static PyObject *PLy_result_status(PyObject *, PyObject *);
1542 static int      PLy_result_length(PyObject *);
1543 static PyObject *PLy_result_item(PyObject *, int);
1544 static PyObject *PLy_result_slice(PyObject *, int, int);
1545 static int      PLy_result_ass_item(PyObject *, int, PyObject *);
1546 static int      PLy_result_ass_slice(PyObject *, int, int, PyObject *);
1547
1548
1549 static PyObject *PLy_spi_prepare(PyObject *, PyObject *);
1550 static PyObject *PLy_spi_execute(PyObject *, PyObject *);
1551 static PyObject *PLy_spi_execute_query(char *query, long limit);
1552 static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, long);
1553 static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
1554
1555
1556 static PyTypeObject PLy_PlanType = {
1557         PyObject_HEAD_INIT(NULL)
1558         0,                                                      /* ob_size */
1559         "PLyPlan",                                      /* tp_name */
1560         sizeof(PLyPlanObject),          /* tp_size */
1561         0,                                                      /* tp_itemsize */
1562
1563         /*
1564          * methods
1565          */
1566         (destructor) PLy_plan_dealloc,          /* tp_dealloc */
1567         0,                                                      /* tp_print */
1568         (getattrfunc) PLy_plan_getattr,         /* tp_getattr */
1569         0,                                                      /* tp_setattr */
1570         0,                                                      /* tp_compare */
1571         0,                                                      /* tp_repr */
1572         0,                                                      /* tp_as_number */
1573         0,                                                      /* tp_as_sequence */
1574         0,                                                      /* tp_as_mapping */
1575         0,                                                      /* tp_hash */
1576         0,                                                      /* tp_call */
1577         0,                                                      /* tp_str */
1578         0,                                                      /* tp_getattro */
1579         0,                                                      /* tp_setattro */
1580         0,                                                      /* tp_as_buffer */
1581         0,                                                      /* tp_xxx4 */
1582         PLy_plan_doc,                           /* tp_doc */
1583 };
1584
1585 static PyMethodDef PLy_plan_methods[] = {
1586         {"status", PLy_plan_status, METH_VARARGS, NULL},
1587         {NULL, NULL, 0, NULL}
1588 };
1589
1590
1591 static PySequenceMethods PLy_result_as_sequence = {
1592         (inquiry) PLy_result_length,    /* sq_length */
1593         (binaryfunc) 0,                         /* sq_concat */
1594         (intargfunc) 0,                         /* sq_repeat */
1595         (intargfunc) PLy_result_item,           /* sq_item */
1596         (intintargfunc) PLy_result_slice,       /* sq_slice */
1597         (intobjargproc) PLy_result_ass_item,            /* sq_ass_item */
1598         (intintobjargproc) PLy_result_ass_slice,        /* sq_ass_slice */
1599 };
1600
1601 static PyTypeObject PLy_ResultType = {
1602         PyObject_HEAD_INIT(NULL)
1603         0,                                                      /* ob_size */
1604         "PLyResult",                            /* tp_name */
1605         sizeof(PLyResultObject),        /* tp_size */
1606         0,                                                      /* tp_itemsize */
1607
1608         /*
1609          * methods
1610          */
1611         (destructor) PLy_result_dealloc,        /* tp_dealloc */
1612         0,                                                      /* tp_print */
1613         (getattrfunc) PLy_result_getattr,       /* tp_getattr */
1614         0,                                                      /* tp_setattr */
1615         0,                                                      /* tp_compare */
1616         0,                                                      /* tp_repr */
1617         0,                                                      /* tp_as_number */
1618         &PLy_result_as_sequence,        /* tp_as_sequence */
1619         0,                                                      /* tp_as_mapping */
1620         0,                                                      /* tp_hash */
1621         0,                                                      /* tp_call */
1622         0,                                                      /* tp_str */
1623         0,                                                      /* tp_getattro */
1624         0,                                                      /* tp_setattro */
1625         0,                                                      /* tp_as_buffer */
1626         0,                                                      /* tp_xxx4 */
1627         PLy_result_doc,                         /* tp_doc */
1628 };
1629
1630 static PyMethodDef PLy_result_methods[] = {
1631         {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
1632         {"status", PLy_result_status, METH_VARARGS, NULL},
1633         {NULL, NULL, 0, NULL}
1634 };
1635
1636 static PyMethodDef PLy_methods[] = {
1637         /*
1638          * logging methods
1639          */
1640         {"debug", PLy_debug, METH_VARARGS, NULL},
1641         {"log", PLy_log, METH_VARARGS, NULL},
1642         {"info", PLy_info, METH_VARARGS, NULL},
1643         {"notice", PLy_notice, METH_VARARGS, NULL},
1644         {"warning", PLy_warning, METH_VARARGS, NULL},
1645         {"error", PLy_error, METH_VARARGS, NULL},
1646         {"fatal", PLy_fatal, METH_VARARGS, NULL},
1647
1648         /*
1649          * create a stored plan
1650          */
1651         {"prepare", PLy_spi_prepare, METH_VARARGS, NULL},
1652
1653         /*
1654          * execute a plan or query
1655          */
1656         {"execute", PLy_spi_execute, METH_VARARGS, NULL},
1657
1658         {NULL, NULL, 0, NULL}
1659 };
1660
1661
1662 /* plan object methods */
1663 static PyObject *
1664 PLy_plan_new(void)
1665 {
1666         PLyPlanObject *ob;
1667
1668         if ((ob = PyObject_NEW(PLyPlanObject, &PLy_PlanType)) == NULL)
1669                 return NULL;
1670
1671         ob->plan = NULL;
1672         ob->nargs = 0;
1673         ob->types = NULL;
1674         ob->args = NULL;
1675
1676         return (PyObject *) ob;
1677 }
1678
1679
1680 static void
1681 PLy_plan_dealloc(PyObject * arg)
1682 {
1683         PLyPlanObject *ob = (PLyPlanObject *) arg;
1684
1685         if (ob->plan)
1686                 SPI_freeplan(ob->plan);
1687         if (ob->types)
1688                 PLy_free(ob->types);
1689         if (ob->args)
1690         {
1691                 int                     i;
1692
1693                 for (i = 0; i < ob->nargs; i++)
1694                         PLy_typeinfo_dealloc(&ob->args[i]);
1695                 PLy_free(ob->args);
1696         }
1697
1698         PyMem_DEL(arg);
1699 }
1700
1701
1702 static PyObject *
1703 PLy_plan_getattr(PyObject * self, char *name)
1704 {
1705         return Py_FindMethod(PLy_plan_methods, self, name);
1706 }
1707
1708 static PyObject *
1709 PLy_plan_status(PyObject * self, PyObject * args)
1710 {
1711         if (PyArg_ParseTuple(args, ""))
1712         {
1713                 Py_INCREF(Py_True);
1714                 return Py_True;
1715                 /* return PyInt_FromLong(self->status); */
1716         }
1717         PyErr_SetString(PLy_exc_error, "plan.status() takes no arguments");
1718         return NULL;
1719 }
1720
1721
1722
1723 /* result object methods */
1724
1725 static PyObject *
1726 PLy_result_new(void)
1727 {
1728         PLyResultObject *ob;
1729
1730         if ((ob = PyObject_NEW(PLyResultObject, &PLy_ResultType)) == NULL)
1731                 return NULL;
1732
1733         /* ob->tuples = NULL; */
1734
1735         Py_INCREF(Py_None);
1736         ob->status = Py_None;
1737         ob->nrows = PyInt_FromLong(-1);
1738         ob->rows = PyList_New(0);
1739
1740         return (PyObject *) ob;
1741 }
1742
1743 static void
1744 PLy_result_dealloc(PyObject * arg)
1745 {
1746         PLyResultObject *ob = (PLyResultObject *) arg;
1747
1748         Py_XDECREF(ob->nrows);
1749         Py_XDECREF(ob->rows);
1750         Py_XDECREF(ob->status);
1751
1752         PyMem_DEL(ob);
1753 }
1754
1755 static PyObject *
1756 PLy_result_getattr(PyObject * self, char *name)
1757 {
1758         return Py_FindMethod(PLy_result_methods, self, name);
1759 }
1760
1761 static PyObject *
1762 PLy_result_nrows(PyObject * self, PyObject * args)
1763 {
1764         PLyResultObject *ob = (PLyResultObject *) self;
1765
1766         Py_INCREF(ob->nrows);
1767         return ob->nrows;
1768 }
1769
1770 static PyObject *
1771 PLy_result_status(PyObject * self, PyObject * args)
1772 {
1773         PLyResultObject *ob = (PLyResultObject *) self;
1774
1775         Py_INCREF(ob->status);
1776         return ob->status;
1777 }
1778
1779 static int
1780 PLy_result_length(PyObject * arg)
1781 {
1782         PLyResultObject *ob = (PLyResultObject *) arg;
1783
1784         return PyList_Size(ob->rows);
1785 }
1786
1787 static PyObject *
1788 PLy_result_item(PyObject * arg, int idx)
1789 {
1790         PyObject   *rv;
1791         PLyResultObject *ob = (PLyResultObject *) arg;
1792
1793         rv = PyList_GetItem(ob->rows, idx);
1794         if (rv != NULL)
1795                 Py_INCREF(rv);
1796         return rv;
1797 }
1798
1799 static int
1800 PLy_result_ass_item(PyObject * arg, int idx, PyObject * item)
1801 {
1802         int                     rv;
1803         PLyResultObject *ob = (PLyResultObject *) arg;
1804
1805         Py_INCREF(item);
1806         rv = PyList_SetItem(ob->rows, idx, item);
1807         return rv;
1808 }
1809
1810 static PyObject *
1811 PLy_result_slice(PyObject * arg, int lidx, int hidx)
1812 {
1813         PyObject   *rv;
1814         PLyResultObject *ob = (PLyResultObject *) arg;
1815
1816         rv = PyList_GetSlice(ob->rows, lidx, hidx);
1817         if (rv == NULL)
1818                 return NULL;
1819         Py_INCREF(rv);
1820         return rv;
1821 }
1822
1823 static int
1824 PLy_result_ass_slice(PyObject * arg, int lidx, int hidx, PyObject * slice)
1825 {
1826         int                     rv;
1827         PLyResultObject *ob = (PLyResultObject *) arg;
1828
1829         rv = PyList_SetSlice(ob->rows, lidx, hidx, slice);
1830         return rv;
1831 }
1832
1833 /* SPI interface */
1834 static PyObject *
1835 PLy_spi_prepare(PyObject * self, PyObject * args)
1836 {
1837         PLyPlanObject *plan;
1838         PyObject   *list = NULL;
1839         PyObject   *volatile optr = NULL;
1840         char       *query;
1841         void       *tmpplan;
1842         MemoryContext oldcontext;
1843
1844         /* Can't execute more if we have an unhandled error */
1845         if (PLy_error_in_progress)
1846         {
1847                 PyErr_SetString(PLy_exc_error, "Transaction aborted.");
1848                 return NULL;
1849         }
1850
1851         if (!PyArg_ParseTuple(args, "s|O", &query, &list))
1852         {
1853                 PyErr_SetString(PLy_exc_spi_error,
1854                                                 "Invalid arguments for plpy.prepare()");
1855                 return NULL;
1856         }
1857
1858         if (list && (!PySequence_Check(list)))
1859         {
1860                 PyErr_SetString(PLy_exc_spi_error,
1861                                          "Second argument in plpy.prepare() must be a sequence");
1862                 return NULL;
1863         }
1864
1865         if ((plan = (PLyPlanObject *) PLy_plan_new()) == NULL)
1866                 return NULL;
1867
1868         oldcontext = CurrentMemoryContext;
1869         PG_TRY();
1870         {
1871                 if (list != NULL)
1872                 {
1873                         int                     nargs,
1874                                                 i;
1875
1876                         nargs = PySequence_Length(list);
1877                         if (nargs > 0)
1878                         {
1879                                 plan->nargs = nargs;
1880                                 plan->types = PLy_malloc(sizeof(Oid) * nargs);
1881                                 plan->values = PLy_malloc(sizeof(Datum) * nargs);
1882                                 plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs);
1883
1884                                 /*
1885                                  * the other loop might throw an exception, if PLyTypeInfo
1886                                  * member isn't properly initialized the Py_DECREF(plan) will
1887                                  * go boom
1888                                  */
1889                                 for (i = 0; i < nargs; i++)
1890                                 {
1891                                         PLy_typeinfo_init(&plan->args[i]);
1892                                         plan->values[i] = PointerGetDatum(NULL);
1893                                 }
1894
1895                                 for (i = 0; i < nargs; i++)
1896                                 {
1897                                         char       *sptr;
1898                                         List       *names;
1899                                         HeapTuple       typeTup;
1900                                         Form_pg_type typeStruct;
1901
1902                                         optr = PySequence_GetItem(list, i);
1903                                         if (!PyString_Check(optr))
1904                                                 elog(ERROR, "Type names must be strings.");
1905                                         sptr = PyString_AsString(optr);
1906
1907                                         /*
1908                                          * Parse possibly-qualified type name and look it up in
1909                                          * pg_type
1910                                          */
1911                                         names = stringToQualifiedNameList(sptr,
1912                                                                                                           "PLy_spi_prepare");
1913                                         typeTup = typenameType(NULL,
1914                                                                                    makeTypeNameFromNameList(names));
1915                                         Py_DECREF(optr);
1916                                         optr = NULL;    /* this is important */
1917
1918                                         plan->types[i] = HeapTupleGetOid(typeTup);
1919                                         typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1920                                         if (typeStruct->typtype != 'c')
1921                                                 PLy_output_datum_func(&plan->args[i], typeTup);
1922                                         else
1923                                                 elog(ERROR, "tuples not handled in plpy.prepare, yet.");
1924                                         ReleaseSysCache(typeTup);
1925                                 }
1926                         }
1927                 }
1928
1929                 plan->plan = SPI_prepare(query, plan->nargs, plan->types);
1930                 if (plan->plan == NULL)
1931                         elog(ERROR, "SPI_prepare failed: %s",
1932                                  SPI_result_code_string(SPI_result));
1933
1934                 /* transfer plan from procCxt to topCxt */
1935                 tmpplan = plan->plan;
1936                 plan->plan = SPI_saveplan(tmpplan);
1937                 SPI_freeplan(tmpplan);
1938                 if (plan->plan == NULL)
1939                         elog(ERROR, "SPI_saveplan failed: %s",
1940                                  SPI_result_code_string(SPI_result));
1941         }
1942         PG_CATCH();
1943         {
1944                 MemoryContextSwitchTo(oldcontext);
1945                 PLy_error_in_progress = CopyErrorData();
1946                 FlushErrorState();
1947                 Py_DECREF(plan);
1948                 Py_XDECREF(optr);
1949                 if (!PyErr_Occurred())
1950                         PyErr_SetString(PLy_exc_spi_error,
1951                                                         "Unknown error in PLy_spi_prepare");
1952                 /* XXX this oughta be replaced with errcontext mechanism */
1953                 PLy_elog(WARNING, "in function %s:",
1954                                  PLy_procedure_name(PLy_curr_procedure));
1955                 return NULL;
1956         }
1957         PG_END_TRY();
1958
1959         return (PyObject *) plan;
1960 }
1961
1962 /* execute(query="select * from foo", limit=5)
1963  * execute(plan=plan, values=(foo, bar), limit=5)
1964  */
1965 static PyObject *
1966 PLy_spi_execute(PyObject * self, PyObject * args)
1967 {
1968         char       *query;
1969         PyObject   *plan;
1970         PyObject   *list = NULL;
1971         long            limit = 0;
1972
1973         /* Can't execute more if we have an unhandled error */
1974         if (PLy_error_in_progress)
1975         {
1976                 PyErr_SetString(PLy_exc_error, "Transaction aborted.");
1977                 return NULL;
1978         }
1979
1980         if (PyArg_ParseTuple(args, "s|l", &query, &limit))
1981                 return PLy_spi_execute_query(query, limit);
1982
1983         PyErr_Clear();
1984
1985         if (PyArg_ParseTuple(args, "O|Ol", &plan, &list, &limit) &&
1986                 is_PLyPlanObject(plan))
1987                 return PLy_spi_execute_plan(plan, list, limit);
1988
1989         PyErr_SetString(PLy_exc_error, "Expected a query or plan.");
1990         return NULL;
1991 }
1992
1993 static PyObject *
1994 PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
1995 {
1996         volatile int nargs;
1997         int                     i,
1998                                 rv;
1999         PLyPlanObject *plan;
2000         MemoryContext oldcontext;
2001
2002         if (list != NULL)
2003         {
2004                 if (!PySequence_Check(list) || PyString_Check(list))
2005                 {
2006                         char       *msg = "plpy.execute() takes a sequence as its second argument";
2007
2008                         PyErr_SetString(PLy_exc_spi_error, msg);
2009                         return NULL;
2010                 }
2011                 nargs = PySequence_Length(list);
2012         }
2013         else
2014                 nargs = 0;
2015
2016         plan = (PLyPlanObject *) ob;
2017
2018         if (nargs != plan->nargs)
2019         {
2020                 char       *sv;
2021                 PyObject   *so = PyObject_Str(list);
2022
2023                 if (!so)
2024                         PLy_elog(ERROR, "function \"%s\" could not execute plan",
2025                                          PLy_procedure_name(PLy_curr_procedure));
2026                 sv = PyString_AsString(so);
2027                 PLy_exception_set(PLy_exc_spi_error,
2028                                                   "Expected sequence of %d arguments, got %d. %s",
2029                                                   plan->nargs, nargs, sv);
2030                 Py_DECREF(so);
2031
2032                 return NULL;
2033         }
2034
2035         oldcontext = CurrentMemoryContext;
2036         PG_TRY();
2037         {
2038                 char       *nulls = palloc(nargs * sizeof(char));
2039
2040                 for (i = 0; i < nargs; i++)
2041                 {
2042                         PyObject   *elem,
2043                                            *so;
2044
2045                         elem = PySequence_GetItem(list, i);
2046                         if (elem != Py_None)
2047                         {
2048                                 so = PyObject_Str(elem);
2049                                 if (!so)
2050                                         PLy_elog(ERROR, "function \"%s\" could not execute plan",
2051                                                          PLy_procedure_name(PLy_curr_procedure));
2052                                 Py_DECREF(elem);
2053
2054                                 PG_TRY();
2055                                 {
2056                                         char *sv = PyString_AsString(so);
2057
2058                                         plan->values[i] =
2059                                                 InputFunctionCall(&(plan->args[i].out.d.typfunc),
2060                                                                                   sv,
2061                                                                                   plan->args[i].out.d.typioparam,
2062                                                                                   -1);
2063                                 }
2064                                 PG_CATCH();
2065                                 {
2066                                         Py_DECREF(so);
2067                                         PG_RE_THROW();
2068                                 }
2069                                 PG_END_TRY();
2070
2071                                 Py_DECREF(so);
2072                                 nulls[i] = ' ';
2073                         }
2074                         else
2075                         {
2076                                 Py_DECREF(elem);
2077                                 plan->values[i] =
2078                                         InputFunctionCall(&(plan->args[i].out.d.typfunc),
2079                                                                           NULL,
2080                                                                           plan->args[i].out.d.typioparam,
2081                                                                           -1);
2082                                 nulls[i] = 'n';
2083                         }
2084                 }
2085
2086                 rv = SPI_execute_plan(plan->plan, plan->values, nulls,
2087                                                           PLy_curr_procedure->fn_readonly, limit);
2088
2089                 pfree(nulls);
2090         }
2091         PG_CATCH();
2092         {
2093                 MemoryContextSwitchTo(oldcontext);
2094                 PLy_error_in_progress = CopyErrorData();
2095                 FlushErrorState();
2096
2097                 /*
2098                  * cleanup plan->values array
2099                  */
2100                 for (i = 0; i < nargs; i++)
2101                 {
2102                         if (!plan->args[i].out.d.typbyval &&
2103                                 (plan->values[i] != PointerGetDatum(NULL)))
2104                         {
2105                                 pfree(DatumGetPointer(plan->values[i]));
2106                                 plan->values[i] = PointerGetDatum(NULL);
2107                         }
2108                 }
2109
2110                 if (!PyErr_Occurred())
2111                         PyErr_SetString(PLy_exc_error,
2112                                                         "Unknown error in PLy_spi_execute_plan");
2113                 /* XXX this oughta be replaced with errcontext mechanism */
2114                 PLy_elog(WARNING, "in function %s:",
2115                                  PLy_procedure_name(PLy_curr_procedure));
2116                 return NULL;
2117         }
2118         PG_END_TRY();
2119
2120         for (i = 0; i < nargs; i++)
2121         {
2122                 if (!plan->args[i].out.d.typbyval &&
2123                         (plan->values[i] != PointerGetDatum(NULL)))
2124                 {
2125                         pfree(DatumGetPointer(plan->values[i]));
2126                         plan->values[i] = PointerGetDatum(NULL);
2127                 }
2128         }
2129
2130         if (rv < 0)
2131         {
2132                 PLy_exception_set(PLy_exc_spi_error,
2133                                                   "SPI_execute_plan failed: %s",
2134                                                   SPI_result_code_string(rv));
2135                 return NULL;
2136         }
2137
2138         return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);
2139 }
2140
2141 static PyObject *
2142 PLy_spi_execute_query(char *query, long limit)
2143 {
2144         int                     rv;
2145         MemoryContext oldcontext;
2146
2147         oldcontext = CurrentMemoryContext;
2148         PG_TRY();
2149         {
2150                 rv = SPI_execute(query, PLy_curr_procedure->fn_readonly, limit);
2151         }
2152         PG_CATCH();
2153         {
2154                 MemoryContextSwitchTo(oldcontext);
2155                 PLy_error_in_progress = CopyErrorData();
2156                 FlushErrorState();
2157                 if (!PyErr_Occurred())
2158                         PyErr_SetString(PLy_exc_spi_error,
2159                                                         "Unknown error in PLy_spi_execute_query");
2160                 /* XXX this oughta be replaced with errcontext mechanism */
2161                 PLy_elog(WARNING, "in function %s:",
2162                                  PLy_procedure_name(PLy_curr_procedure));
2163                 return NULL;
2164         }
2165         PG_END_TRY();
2166
2167         if (rv < 0)
2168         {
2169                 PLy_exception_set(PLy_exc_spi_error,
2170                                                   "SPI_execute failed: %s",
2171                                                   SPI_result_code_string(rv));
2172                 return NULL;
2173         }
2174
2175         return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);
2176 }
2177
2178 static PyObject *
2179 PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
2180 {
2181         PLyResultObject *result;
2182         MemoryContext oldcontext;
2183
2184         result = (PLyResultObject *) PLy_result_new();
2185         Py_DECREF(result->status);
2186         result->status = PyInt_FromLong(status);
2187
2188         if (status == SPI_OK_UTILITY)
2189         {
2190                 Py_DECREF(result->nrows);
2191                 result->nrows = PyInt_FromLong(0);
2192         }
2193         else if (status != SPI_OK_SELECT)
2194         {
2195                 Py_DECREF(result->nrows);
2196                 result->nrows = PyInt_FromLong(rows);
2197         }
2198         else
2199         {
2200                 PLyTypeInfo args;
2201                 int                     i;
2202
2203                 PLy_typeinfo_init(&args);
2204                 Py_DECREF(result->nrows);
2205                 result->nrows = PyInt_FromLong(rows);
2206
2207                 oldcontext = CurrentMemoryContext;
2208                 PG_TRY();
2209                 {
2210                         if (rows)
2211                         {
2212                                 Py_DECREF(result->rows);
2213                                 result->rows = PyList_New(rows);
2214
2215                                 PLy_input_tuple_funcs(&args, tuptable->tupdesc);
2216                                 for (i = 0; i < rows; i++)
2217                                 {
2218                                         PyObject   *row = PLyDict_FromTuple(&args, tuptable->vals[i],
2219                                                                                                                 tuptable->tupdesc);
2220
2221                                         PyList_SetItem(result->rows, i, row);
2222                                 }
2223                                 PLy_typeinfo_dealloc(&args);
2224
2225                                 SPI_freetuptable(tuptable);
2226                         }
2227                 }
2228                 PG_CATCH();
2229                 {
2230                         MemoryContextSwitchTo(oldcontext);
2231                         PLy_error_in_progress = CopyErrorData();
2232                         FlushErrorState();
2233                         if (!PyErr_Occurred())
2234                                 PyErr_SetString(PLy_exc_error,
2235                                                         "Unknown error in PLy_spi_execute_fetch_result");
2236                         Py_DECREF(result);
2237                         PLy_typeinfo_dealloc(&args);
2238                         return NULL;
2239                 }
2240                 PG_END_TRY();
2241         }
2242
2243         return (PyObject *) result;
2244 }
2245
2246
2247 /*
2248  * language handler and interpreter initialization
2249  */
2250
2251 /*
2252  * plpython_init()                      - Initialize everything that can be
2253  *                                                        safely initialized during postmaster
2254  *                                                        startup.
2255  *
2256  * DO NOT make this static --- it has to be callable by preload
2257  */
2258 void
2259 plpython_init(void)
2260 {
2261         static volatile bool init_active = false;
2262
2263         /* Do initialization only once */
2264         if (!PLy_first_call)
2265                 return;
2266
2267         if (init_active)
2268                 elog(FATAL, "initialization of language module failed");
2269         init_active = true;
2270
2271         Py_Initialize();
2272         PLy_init_interp();
2273         PLy_init_plpy();
2274         if (PyErr_Occurred())
2275                 PLy_elog(FATAL, "untrapped error in initialization");
2276         PLy_procedure_cache = PyDict_New();
2277         if (PLy_procedure_cache == NULL)
2278                 PLy_elog(ERROR, "could not create procedure cache");
2279
2280         PLy_first_call = false;
2281 }
2282
2283 static void
2284 PLy_init_all(void)
2285 {
2286         /* Execute postmaster-startup safe initialization */
2287         if (PLy_first_call)
2288                 plpython_init();
2289
2290         /*
2291          * Any other initialization that must be done each time a new backend
2292          * starts -- currently none
2293          */
2294 }
2295
2296 static void
2297 PLy_init_interp(void)
2298 {
2299         PyObject   *mainmod;
2300
2301         mainmod = PyImport_AddModule("__main__");
2302         if (mainmod == NULL || PyErr_Occurred())
2303                 PLy_elog(ERROR, "could not import \"__main__\" module.");
2304         Py_INCREF(mainmod);
2305         PLy_interp_globals = PyModule_GetDict(mainmod);
2306         PLy_interp_safe_globals = PyDict_New();
2307         PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
2308         Py_DECREF(mainmod);
2309         if (PLy_interp_globals == NULL || PyErr_Occurred())
2310                 PLy_elog(ERROR, "could not initialize globals");
2311 }
2312
2313 static void
2314 PLy_init_plpy(void)
2315 {
2316         PyObject   *main_mod,
2317                            *main_dict,
2318                            *plpy_mod;
2319         PyObject   *plpy,
2320                            *plpy_dict;
2321
2322         /*
2323          * initialize plpy module
2324          */
2325         PLy_PlanType.ob_type = PLy_ResultType.ob_type = &PyType_Type;
2326         plpy = Py_InitModule("plpy", PLy_methods);
2327         plpy_dict = PyModule_GetDict(plpy);
2328
2329         /* PyDict_SetItemString(plpy, "PlanType", (PyObject *) &PLy_PlanType); */
2330
2331         PLy_exc_error = PyErr_NewException("plpy.Error", NULL, NULL);
2332         PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);
2333         PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);
2334         PyDict_SetItemString(plpy_dict, "Error", PLy_exc_error);
2335         PyDict_SetItemString(plpy_dict, "Fatal", PLy_exc_fatal);
2336         PyDict_SetItemString(plpy_dict, "SPIError", PLy_exc_spi_error);
2337
2338         /*
2339          * initialize main module, and add plpy
2340          */
2341         main_mod = PyImport_AddModule("__main__");
2342         main_dict = PyModule_GetDict(main_mod);
2343         plpy_mod = PyImport_AddModule("plpy");
2344         PyDict_SetItemString(main_dict, "plpy", plpy_mod);
2345         if (PyErr_Occurred())
2346                 elog(ERROR, "could not init plpy");
2347 }
2348
2349 /* the python interface to the elog function
2350  * don't confuse these with PLy_elog
2351  */
2352 static PyObject *PLy_output(int, PyObject *, PyObject *);
2353
2354 static PyObject *
2355 PLy_debug(PyObject * self, PyObject * args)
2356 {
2357         return PLy_output(DEBUG2, self, args);
2358 }
2359
2360 static PyObject *
2361 PLy_log(PyObject * self, PyObject * args)
2362 {
2363         return PLy_output(LOG, self, args);
2364 }
2365
2366 static PyObject *
2367 PLy_info(PyObject * self, PyObject * args)
2368 {
2369         return PLy_output(INFO, self, args);
2370 }
2371
2372 static PyObject *
2373 PLy_notice(PyObject * self, PyObject * args)
2374 {
2375         return PLy_output(NOTICE, self, args);
2376 }
2377
2378 static PyObject *
2379 PLy_warning(PyObject * self, PyObject * args)
2380 {
2381         return PLy_output(WARNING, self, args);
2382 }
2383
2384 static PyObject *
2385 PLy_error(PyObject * self, PyObject * args)
2386 {
2387         return PLy_output(ERROR, self, args);
2388 }
2389
2390 static PyObject *
2391 PLy_fatal(PyObject * self, PyObject * args)
2392 {
2393         return PLy_output(FATAL, self, args);
2394 }
2395
2396
2397 static PyObject *
2398 PLy_output(volatile int level, PyObject * self, PyObject * args)
2399 {
2400         PyObject   *so;
2401         char       *volatile sv;
2402         MemoryContext oldcontext;
2403
2404         so = PyObject_Str(args);
2405         if (so == NULL || ((sv = PyString_AsString(so)) == NULL))
2406         {
2407                 level = ERROR;
2408                 sv = "Unable to parse error message in `plpy.elog'";
2409         }
2410
2411         oldcontext = CurrentMemoryContext;
2412         PG_TRY();
2413         {
2414                 elog(level, "%s", sv);
2415         }
2416         PG_CATCH();
2417         {
2418                 MemoryContextSwitchTo(oldcontext);
2419                 PLy_error_in_progress = CopyErrorData();
2420                 FlushErrorState();
2421                 Py_XDECREF(so);
2422
2423                 /*
2424                  * returning NULL here causes the python interpreter to bail. when
2425                  * control passes back to PLy_procedure_call, we check for PG
2426                  * exceptions and re-throw the error.
2427                  */
2428                 PyErr_SetString(PLy_exc_error, sv);
2429                 return NULL;
2430         }
2431         PG_END_TRY();
2432
2433         Py_XDECREF(so);
2434
2435         /*
2436          * return a legal object so the interpreter will continue on its merry way
2437          */
2438         Py_INCREF(Py_None);
2439         return Py_None;
2440 }
2441
2442
2443 /*
2444  * Get the name of the last procedure called by the backend (the
2445  * innermost, if a plpython procedure call calls the backend and the
2446  * backend calls another plpython procedure).
2447  *
2448  * NB: this returns the SQL name, not the internal Python procedure name
2449  */
2450 static char *
2451 PLy_procedure_name(PLyProcedure * proc)
2452 {
2453         if (proc == NULL)
2454                 return "<unknown procedure>";
2455         return proc->proname;
2456 }
2457
2458 /* output a python traceback/exception via the postgresql elog
2459  * function.  not pretty.
2460  */
2461 static void
2462 PLy_exception_set(PyObject * exc, const char *fmt,...)
2463 {
2464         char            buf[1024];
2465         va_list         ap;
2466
2467         va_start(ap, fmt);
2468         vsnprintf(buf, sizeof(buf), fmt, ap);
2469         va_end(ap);
2470
2471         PyErr_SetString(exc, buf);
2472 }
2473
2474 /* Emit a PG error or notice, together with any available info about the
2475  * current Python error.  This should be used to propagate Python errors
2476  * into PG.
2477  */
2478 static void
2479 PLy_elog(int elevel, const char *fmt,...)
2480 {
2481         va_list         ap;
2482         char       *xmsg,
2483                            *emsg;
2484         int                     xlevel;
2485
2486         xmsg = PLy_traceback(&xlevel);
2487
2488         va_start(ap, fmt);
2489         emsg = PLy_vprintf(fmt, ap);
2490         va_end(ap);
2491
2492         PG_TRY();
2493         {
2494                 ereport(elevel,
2495                                 (errmsg("plpython: %s", emsg),
2496                                  (xmsg) ? errdetail("%s", xmsg) : 0));
2497         }
2498         PG_CATCH();
2499         {
2500                 PLy_free(emsg);
2501                 if (xmsg)
2502                         PLy_free(xmsg);
2503                 PG_RE_THROW();
2504         }
2505         PG_END_TRY();
2506
2507         PLy_free(emsg);
2508         if (xmsg)
2509                 PLy_free(xmsg);
2510 }
2511
2512 static char *
2513 PLy_traceback(int *xlevel)
2514 {
2515         PyObject   *e,
2516                            *v,
2517                            *tb;
2518         PyObject   *eob,
2519                            *vob = NULL;
2520         char       *vstr,
2521                            *estr,
2522                            *xstr = NULL;
2523
2524         /*
2525          * get the current exception
2526          */
2527         PyErr_Fetch(&e, &v, &tb);
2528
2529         /*
2530          * oops, no exception, return
2531          */
2532         if (e == NULL)
2533         {
2534                 *xlevel = WARNING;
2535                 return NULL;
2536         }
2537
2538         PyErr_NormalizeException(&e, &v, &tb);
2539         Py_XDECREF(tb);
2540
2541         eob = PyObject_Str(e);
2542         if (v && ((vob = PyObject_Str(v)) != NULL))
2543                 vstr = PyString_AsString(vob);
2544         else
2545                 vstr = "Unknown";
2546
2547         /*
2548          * I'm not sure what to do if eob is NULL here -- we can't call PLy_elog
2549          * because that function calls us, so we could end up with infinite
2550          * recursion.  I'm not even sure if eob could be NULL here -- would an
2551          * Assert() be more appropriate?
2552          */
2553         estr = eob ? PyString_AsString(eob) : "Unknown Exception";
2554         xstr = PLy_printf("%s: %s", estr, vstr);
2555
2556         Py_DECREF(eob);
2557         Py_XDECREF(vob);
2558         Py_XDECREF(v);
2559
2560         /*
2561          * intuit an appropriate error level based on the exception type
2562          */
2563         if (PLy_exc_error && PyErr_GivenExceptionMatches(e, PLy_exc_error))
2564                 *xlevel = ERROR;
2565         else if (PLy_exc_fatal && PyErr_GivenExceptionMatches(e, PLy_exc_fatal))
2566                 *xlevel = FATAL;
2567         else
2568                 *xlevel = ERROR;
2569
2570         Py_DECREF(e);
2571         return xstr;
2572 }
2573
2574 static char *
2575 PLy_printf(const char *fmt,...)
2576 {
2577         va_list         ap;
2578         char       *emsg;
2579
2580         va_start(ap, fmt);
2581         emsg = PLy_vprintf(fmt, ap);
2582         va_end(ap);
2583         return emsg;
2584 }
2585
2586 static char *
2587 PLy_vprintf(const char *fmt, va_list ap)
2588 {
2589         size_t          blen;
2590         int                     bchar,
2591                                 tries = 2;
2592         char       *buf;
2593
2594         blen = strlen(fmt) * 2;
2595         if (blen < 256)
2596                 blen = 256;
2597         buf = PLy_malloc(blen * sizeof(char));
2598
2599         while (1)
2600         {
2601                 bchar = vsnprintf(buf, blen, fmt, ap);
2602                 if (bchar > 0 && bchar < blen)
2603                         return buf;
2604                 if (tries-- <= 0)
2605                         break;
2606                 if (blen > 0)
2607                         blen = bchar + 1;
2608                 else
2609                         blen *= 2;
2610                 buf = PLy_realloc(buf, blen);
2611         }
2612         PLy_free(buf);
2613         return NULL;
2614 }
2615
2616 /* python module code */
2617
2618 /* some dumb utility functions */
2619 static void *
2620 PLy_malloc(size_t bytes)
2621 {
2622         void       *ptr = malloc(bytes);
2623
2624         if (ptr == NULL)
2625                 ereport(FATAL,
2626                                 (errcode(ERRCODE_OUT_OF_MEMORY),
2627                                  errmsg("out of memory")));
2628         return ptr;
2629 }
2630
2631 static void *
2632 PLy_realloc(void *optr, size_t bytes)
2633 {
2634         void       *nptr = realloc(optr, bytes);
2635
2636         if (nptr == NULL)
2637                 ereport(FATAL,
2638                                 (errcode(ERRCODE_OUT_OF_MEMORY),
2639                                  errmsg("out of memory")));
2640         return nptr;
2641 }
2642
2643 static char *
2644 PLy_strdup(const char *str)
2645 {
2646         char       *result;
2647         size_t          len;
2648
2649         len = strlen(str) + 1;
2650         result = PLy_malloc(len);
2651         memcpy(result, str, len);
2652
2653         return result;
2654 }
2655
2656 /* define this away */
2657 static void
2658 PLy_free(void *ptr)
2659 {
2660         free(ptr);
2661 }