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