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