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