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