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