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