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