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