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