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