]> granicus.if.org Git - postgresql/blob - src/pl/plpython/plpython.c
Back out /pl memory leak patch. Wait for new version.
[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.24 2002/09/26 05:39:03 momjian 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                         Py_DECREF(proc->me);
412                 RERAISE_EXC();
413         }
414
415         /*
416          * elog(DEBUG3, "PLy_restart_in_progress is %d",
417          * PLy_restart_in_progress);
418          */
419
420         proc = PLy_procedure_get(fcinfo, is_trigger);
421
422         if (is_trigger)
423         {
424                 HeapTuple       trv = PLy_trigger_handler(fcinfo, proc);
425
426                 retval = PointerGetDatum(trv);
427         }
428         else
429                 retval = PLy_function_handler(fcinfo, proc);
430
431         CALL_LEVEL_DEC();
432         RESTORE_EXC();
433
434         Py_DECREF(proc->me);
435         refc(proc->me);
436
437         return retval;
438 }
439
440 /* trigger and function sub handlers
441  *
442  * the python function is expected to return Py_None if the tuple is
443  * acceptable and unmodified.  Otherwise it should return a PyString
444  * object who's value is SKIP, or MODIFY.  SKIP means don't perform
445  * this action.  MODIFY means the tuple has been modified, so update
446  * tuple and perform action.  SKIP and MODIFY assume the trigger fires
447  * BEFORE the event and is ROW level.  postgres expects the function
448  * to take no arguments and return an argument of type trigger.
449  */
450 HeapTuple
451 PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
452 {
453         DECLARE_EXC();
454         HeapTuple       rv = NULL;
455         PyObject   *volatile plargs = NULL;
456         PyObject   *volatile plrv = NULL;
457
458         enter();
459
460         SAVE_EXC();
461         if (TRAP_EXC())
462         {
463                 RESTORE_EXC();
464
465                 Py_XDECREF(plargs);
466                 Py_XDECREF(plrv);
467
468                 RERAISE_EXC();
469         }
470
471         plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
472         plrv = PLy_procedure_call(proc, "TD", plargs);
473
474         /*
475          * Disconnect from SPI manager
476          */
477         if (SPI_finish() != SPI_OK_FINISH)
478                 elog(ERROR, "plpython: SPI_finish failed");
479
480         if (plrv == NULL)
481                 elog(FATAL, "Aiieee, PLy_procedure_call returned NULL");
482
483         if (PLy_restart_in_progress)
484                 elog(FATAL, "Aiieee, restart in progress not expected");
485
486         /*
487          * return of None means we're happy with the tuple
488          */
489         if (plrv != Py_None)
490         {
491                 char       *srv;
492
493                 if (!PyString_Check(plrv))
494                         elog(ERROR, "plpython: Expected trigger to return None or a String");
495
496                 srv = PyString_AsString(plrv);
497                 if (strcasecmp(srv, "SKIP") == 0)
498                         rv = NULL;
499                 else if (strcasecmp(srv, "MODIFY") == 0)
500                 {
501                         TriggerData *tdata = (TriggerData *) fcinfo->context;
502
503                         if ((TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) ||
504                                 (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)))
505                                 rv = PLy_modify_tuple(proc, plargs, tdata, rv);
506                         else
507                                 elog(WARNING, "plpython: Ignoring modified tuple in DELETE trigger");
508                 }
509                 else if (strcasecmp(srv, "OK"))
510                 {
511                         /*
512                          * hmmm, perhaps they only read the pltcl page, not a
513                          * surprising thing since i've written no documentation, so
514                          * accept a belated OK
515                          */
516                         elog(ERROR, "plpython: Expected return to be 'SKIP' or 'MODIFY'");
517                 }
518         }
519
520         Py_DECREF(plargs);
521         Py_DECREF(plrv);
522
523         RESTORE_EXC();
524
525         return rv;
526 }
527
528 HeapTuple
529 PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
530                                  HeapTuple otup)
531 {
532         DECLARE_EXC();
533         PyObject   *volatile plntup;
534         PyObject   *volatile plkeys;
535         PyObject   *volatile platt;
536         PyObject   *volatile plval;
537         PyObject   *volatile plstr;
538         HeapTuple       rtup;
539         int                     natts,
540                                 i,
541                                 j,
542                                 attn,
543                                 atti;
544         int                *volatile modattrs;
545         Datum      *volatile modvalues;
546         char       *volatile modnulls;
547         TupleDesc       tupdesc;
548
549         plntup = plkeys = platt = plval = plstr = NULL;
550         modattrs = NULL;
551         modvalues = NULL;
552         modnulls = NULL;
553
554         enter();
555
556         SAVE_EXC();
557         if (TRAP_EXC())
558         {
559                 RESTORE_EXC();
560
561                 Py_XDECREF(plntup);
562                 Py_XDECREF(plkeys);
563                 Py_XDECREF(platt);
564                 Py_XDECREF(plval);
565                 Py_XDECREF(plstr);
566
567                 if (modnulls)
568                         pfree(modnulls);
569                 if (modvalues)
570                         pfree(modvalues);
571                 if (modattrs)
572                         pfree(modattrs);
573
574                 RERAISE_EXC();
575         }
576
577         if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL)
578                 elog(ERROR, "plpython: TD[\"new\"] deleted, unable to modify tuple");
579         if (!PyDict_Check(plntup))
580                 elog(ERROR, "plpython: TD[\"new\"] is not a dictionary object");
581         Py_INCREF(plntup);
582
583         plkeys = PyDict_Keys(plntup);
584         natts = PyList_Size(plkeys);
585
586         if (natts != proc->result.out.r.natts)
587                 elog(ERROR, "plpython: TD[\"new\"] has an incorrect number of keys.");
588
589         modattrs = palloc(natts * sizeof(int));
590         modvalues = palloc(natts * sizeof(Datum));
591         for (i = 0; i < natts; i++)
592         {
593                 modattrs[i] = i + 1;
594                 modvalues[i] = (Datum) NULL;
595         }
596         modnulls = palloc(natts + 1);
597         memset(modnulls, 'n', natts);
598         modnulls[natts] = '\0';
599
600         tupdesc = tdata->tg_relation->rd_att;
601
602         for (j = 0; j < natts; j++)
603         {
604                 char       *src;
605
606                 platt = PyList_GetItem(plkeys, j);
607                 if (!PyString_Check(platt))
608                         elog(ERROR, "plpython: attribute is not a string");
609                 attn = modattrs[j] = SPI_fnumber(tupdesc, PyString_AsString(platt));
610
611                 if (attn == SPI_ERROR_NOATTRIBUTE)
612                         elog(ERROR, "plpython: invalid attribute `%s' in tuple.",
613                                  PyString_AsString(platt));
614                 atti = attn - 1;
615
616                 plval = PyDict_GetItem(plntup, platt);
617                 if (plval == NULL)
618                         elog(FATAL, "plpython: interpreter is probably corrupted");
619
620                 Py_INCREF(plval);
621
622                 if (plval != Py_None)
623                 {
624                         plstr = PyObject_Str(plval);
625                         src = PyString_AsString(plstr);
626
627                         modvalues[j] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc,
628                                                                                  CStringGetDatum(src),
629                                  ObjectIdGetDatum(proc->result.out.r.atts[atti].typelem),
630                                                         Int32GetDatum(tupdesc->attrs[j]->atttypmod));
631                         modnulls[j] = ' ';
632
633                         Py_DECREF(plstr);
634                         plstr = NULL;
635                 }
636                 Py_DECREF(plval);
637                 plval = NULL;
638
639         }
640         rtup = SPI_modifytuple(tdata->tg_relation, otup, natts, modattrs,
641                                                    modvalues, modnulls);
642
643         /*
644          * FIXME -- these leak if not explicity pfree'd by other elog calls,
645          * no?
646          */
647         pfree(modattrs);
648         pfree(modvalues);
649         pfree(modnulls);
650
651         if (rtup == NULL)
652                 elog(ERROR, "plpython: SPI_modifytuple failed -- error %d", SPI_result);
653
654         Py_DECREF(plntup);
655         Py_DECREF(plkeys);
656
657         RESTORE_EXC();
658
659         return rtup;
660 }
661
662 PyObject *
663 PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc, HeapTuple *rv)
664 {
665         DECLARE_EXC();
666         TriggerData *tdata;
667         PyObject   *pltname,
668                            *pltevent,
669                            *pltwhen,
670                            *pltlevel,
671                            *pltrelid;
672         PyObject   *pltargs,
673                            *pytnew,
674                            *pytold;
675         PyObject   *volatile pltdata = NULL;
676         char       *stroid;
677
678         enter();
679
680         SAVE_EXC();
681         if (TRAP_EXC())
682         {
683                 RESTORE_EXC();
684
685                 Py_XDECREF(pltdata);
686
687                 RERAISE_EXC();
688         }
689
690         tdata = (TriggerData *) fcinfo->context;
691
692         pltdata = PyDict_New();
693         if (!pltdata)
694                 PLy_elog(ERROR, "Unable to build arguments for trigger procedure");
695
696         pltname = PyString_FromString(tdata->tg_trigger->tgname);
697         PyDict_SetItemString(pltdata, "name", pltname);
698         Py_DECREF(pltname);
699
700         stroid = DatumGetCString(DirectFunctionCall1(oidout,
701                                                    ObjectIdGetDatum(tdata->tg_relation->rd_id)));
702         pltrelid = PyString_FromString(stroid);
703         PyDict_SetItemString(pltdata, "relid", pltrelid);
704         Py_DECREF(pltrelid);
705         pfree(stroid);
706
707
708
709         if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
710                 pltwhen = PyString_FromString("BEFORE");
711         else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
712                 pltwhen = PyString_FromString("AFTER");
713         else
714                 pltwhen = PyString_FromString("UNKNOWN");
715         PyDict_SetItemString(pltdata, "when", pltwhen);
716         Py_DECREF(pltwhen);
717
718         if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
719                 pltlevel = PyString_FromString("ROW");
720         else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
721                 pltlevel = PyString_FromString("STATEMENT");
722         else
723                 pltlevel = PyString_FromString("UNKNOWN");
724         PyDict_SetItemString(pltdata, "level", pltlevel);
725         Py_DECREF(pltlevel);
726
727         if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
728         {
729                 pltevent = PyString_FromString("INSERT");
730                 PyDict_SetItemString(pltdata, "old", Py_None);
731                 pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple,
732                                                                    tdata->tg_relation->rd_att);
733                 PyDict_SetItemString(pltdata, "new", pytnew);
734                 Py_DECREF(pytnew);
735                 *rv = tdata->tg_trigtuple;
736         }
737         else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
738         {
739                 pltevent = PyString_FromString("DELETE");
740                 PyDict_SetItemString(pltdata, "new", Py_None);
741                 pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple,
742                                                                    tdata->tg_relation->rd_att);
743                 PyDict_SetItemString(pltdata, "old", pytold);
744                 Py_DECREF(pytold);
745                 *rv = tdata->tg_trigtuple;
746         }
747         else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
748         {
749                 pltevent = PyString_FromString("UPDATE");
750                 pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_newtuple,
751                                                                    tdata->tg_relation->rd_att);
752                 PyDict_SetItemString(pltdata, "new", pytnew);
753                 Py_DECREF(pytnew);
754                 pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple,
755                                                                    tdata->tg_relation->rd_att);
756                 PyDict_SetItemString(pltdata, "old", pytold);
757                 Py_DECREF(pytold);
758                 *rv = tdata->tg_newtuple;
759         }
760         else
761         {
762                 pltevent = PyString_FromString("UNKNOWN");
763                 PyDict_SetItemString(pltdata, "old", Py_None);
764                 PyDict_SetItemString(pltdata, "new", Py_None);
765                 *rv = tdata->tg_trigtuple;
766         }
767         PyDict_SetItemString(pltdata, "event", pltevent);
768         Py_DECREF(pltevent);
769
770         if (tdata->tg_trigger->tgnargs)
771         {
772                 /*
773                  * all strings...
774                  */
775                 int                     i;
776                 PyObject   *pltarg;
777
778                 pltargs = PyList_New(tdata->tg_trigger->tgnargs);
779                 for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
780                 {
781                         pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]);
782
783                         /*
784                          * stolen, don't Py_DECREF
785                          */
786                         PyList_SetItem(pltargs, i, pltarg);
787                 }
788         }
789         else
790         {
791                 Py_INCREF(Py_None);
792                 pltargs = Py_None;
793         }
794         PyDict_SetItemString(pltdata, "args", pltargs);
795         Py_DECREF(pltargs);
796
797         RESTORE_EXC();
798
799         return pltdata;
800 }
801
802
803
804 /* function handler and friends
805  */
806 Datum
807 PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
808 {
809         DECLARE_EXC();
810         Datum           rv;
811         PyObject   *volatile plargs = NULL;
812         PyObject   *volatile plrv = NULL;
813         PyObject   *volatile plrv_so = NULL;
814         char       *plrv_sc;
815
816         enter();
817
818         /*
819          * setup to catch elog in while building function arguments, and
820          * DECREF the plargs if the function call fails
821          */
822         SAVE_EXC();
823         if (TRAP_EXC())
824         {
825                 RESTORE_EXC();
826
827                 Py_XDECREF(plargs);
828                 Py_XDECREF(plrv);
829                 Py_XDECREF(plrv_so);
830
831                 RERAISE_EXC();
832         }
833
834         plargs = PLy_function_build_args(fcinfo, proc);
835         plrv = PLy_procedure_call(proc, "args", plargs);
836
837         /*
838          * Disconnect from SPI manager and then create the return values datum
839          * (if the input function does a palloc for it this must not be
840          * allocated in the SPI memory context because SPI_finish would free
841          * it).
842          */
843         if (SPI_finish() != SPI_OK_FINISH)
844                 elog(ERROR, "plpython: SPI_finish failed");
845
846         if (plrv == NULL)
847         {
848                 elog(FATAL, "Aiieee, PLy_procedure_call returned NULL");
849 #ifdef NOT_USED
850                 if (!PLy_restart_in_progress)
851                         PLy_elog(ERROR, "plpython: Function \"%s\" failed.", proc->proname);
852
853                 /*
854                  * FIXME is this dead code?  i'm pretty sure it is for unnested
855                  * calls, but not for nested calls
856                  */
857                 RAISE_EXC(1);
858 #endif
859         }
860
861         /*
862          * convert the python PyObject to a postgresql Datum FIXME returning a
863          * NULL, ie PG_RETURN_NULL() blows the backend to small messy bits...
864          * it this a bug or expected?  so just call with the string value of
865          * None for now
866          */
867
868         if (plrv == Py_None)
869         {
870                 fcinfo->isnull = true;
871                 rv = (Datum) NULL;
872         }
873         else
874         {
875                 fcinfo->isnull = false;
876                 plrv_so = PyObject_Str(plrv);
877                 plrv_sc = PyString_AsString(plrv_so);
878                 rv = FunctionCall3(&proc->result.out.d.typfunc,
879                                                    PointerGetDatum(plrv_sc),
880                                                    ObjectIdGetDatum(proc->result.out.d.typelem),
881                                                    Int32GetDatum(-1));
882         }
883
884         RESTORE_EXC();
885
886         Py_XDECREF(plargs);
887         Py_DECREF(plrv);
888         Py_XDECREF(plrv_so);
889
890         return rv;
891 }
892
893 PyObject *
894 PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs)
895 {
896         PyObject   *rv;
897         PLyProcedure *current;
898
899         enter();
900
901         current = PLy_last_procedure;
902         PLy_last_procedure = proc;
903         PyDict_SetItemString(proc->globals, kargs, vargs);
904         rv = PyObject_CallFunction(proc->reval, "O", proc->code);
905         PLy_last_procedure = current;
906
907         if ((rv == NULL) || (PyErr_Occurred()))
908         {
909                 Py_XDECREF(rv);
910                 if (!PLy_restart_in_progress)
911                         PLy_elog(ERROR, "Call of function `%s' failed.", proc->proname);
912                 RAISE_EXC(1);
913         }
914
915         return rv;
916 }
917
918 PyObject *
919 PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
920 {
921         DECLARE_EXC();
922         PyObject   *volatile arg = NULL;
923         PyObject   *volatile args = NULL;
924         int                     i;
925
926         enter();
927
928         /*
929          * FIXME -- if the setjmp setup is expensive, add the arg and args
930          * field to the procedure struct and cleanup at the start of the next
931          * call
932          */
933         SAVE_EXC();
934         if (TRAP_EXC())
935         {
936                 RESTORE_EXC();
937                 Py_XDECREF(arg);
938                 Py_XDECREF(args);
939
940                 RERAISE_EXC();
941         }
942
943         args = PyList_New(proc->nargs);
944         for (i = 0; i < proc->nargs; i++)
945         {
946                 if (proc->args[i].is_rel == 1)
947                 {
948                         TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
949
950                         arg = PLyDict_FromTuple(&(proc->args[i]), slot->val,
951                                                                         slot->ttc_tupleDescriptor);
952                 }
953                 else
954                 {
955                         if (!fcinfo->argnull[i])
956                         {
957                                 char       *ct;
958                                 Datum           dt;
959
960                                 dt = FunctionCall3(&(proc->args[i].in.d.typfunc),
961                                                                    fcinfo->arg[i],
962                                                         ObjectIdGetDatum(proc->args[i].in.d.typelem),
963                                                                    Int32GetDatum(-1));
964                                 ct = DatumGetCString(dt);
965                                 arg = (proc->args[i].in.d.func) (ct);
966                                 pfree(ct);
967                         }
968                         else
969                                 arg = NULL;
970                 }
971
972                 if (arg == NULL)
973                 {
974                         Py_INCREF(Py_None);
975                         arg = Py_None;
976                 }
977
978                 /*
979                  * FIXME -- error check this
980                  */
981                 PyList_SetItem(args, i, arg);
982         }
983
984         RESTORE_EXC();
985
986         return args;
987 }
988
989
990 /* PLyProcedure functions
991  */
992 static PLyProcedure *
993 PLy_procedure_get(FunctionCallInfo fcinfo, bool is_trigger)
994 {
995         Oid                     fn_oid;
996         HeapTuple       procTup;
997         char            key[128];
998         PyObject   *plproc;
999         PLyProcedure *proc = NULL;
1000         int                     rv;
1001
1002         enter();
1003
1004         fn_oid = fcinfo->flinfo->fn_oid;
1005         procTup = SearchSysCache(PROCOID,
1006                                                          ObjectIdGetDatum(fn_oid),
1007                                                          0, 0, 0);
1008         if (!HeapTupleIsValid(procTup))
1009                 elog(ERROR, "plpython: cache lookup for procedure %u failed", fn_oid);
1010
1011         rv = snprintf(key, sizeof(key), "%u%s",
1012                                   fn_oid,
1013                                   is_trigger ? "_trigger" : "");
1014         if ((rv >= sizeof(key)) || (rv < 0))
1015                 elog(FATAL, "plpython: Buffer overrun in %s:%d", __FILE__, __LINE__);
1016
1017         plproc = PyDict_GetItemString(PLy_procedure_cache, key);
1018
1019         if (plproc != NULL)
1020         {
1021                 Py_INCREF(plproc);
1022                 if (!PyCObject_Check(plproc))
1023                         elog(FATAL, "plpython: Expected a PyCObject, didn't get one");
1024
1025                 mark();
1026
1027                 proc = PyCObject_AsVoidPtr(plproc);
1028                 if (proc->me != plproc)
1029                         elog(FATAL, "plpython: Aiieee, proc->me != plproc");
1030                 /* did we find an up-to-date cache entry? */
1031                 if (proc->fn_xmin != HeapTupleHeaderGetXmin(procTup->t_data) ||
1032                         proc->fn_cmin != HeapTupleHeaderGetCmin(procTup->t_data))
1033                 {
1034                         Py_DECREF(plproc);
1035                         proc = NULL;
1036                 }
1037         }
1038
1039         if (proc == NULL)
1040                 proc = PLy_procedure_create(fcinfo, is_trigger, procTup, key);
1041
1042         ReleaseSysCache(procTup);
1043
1044         return proc;
1045 }
1046
1047 static PLyProcedure *
1048 PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
1049                                          HeapTuple procTup, char *key)
1050 {
1051         char            procName[256];
1052
1053         DECLARE_EXC();
1054         Form_pg_proc procStruct;
1055         PLyProcedure *volatile proc;
1056         char       *volatile procSource = NULL;
1057         Datum           procDatum;
1058         int                     i,
1059                                 rv;
1060
1061         enter();
1062
1063         procStruct = (Form_pg_proc) GETSTRUCT(procTup);
1064
1065         rv = snprintf(procName, sizeof(procName),
1066                                   "__plpython_procedure_%s_%u%s",
1067                                   NameStr(procStruct->proname),
1068                                   fcinfo->flinfo->fn_oid,
1069                                   is_trigger ? "_trigger" : "");
1070         if ((rv >= sizeof(procName)) || (rv < 0))
1071                 elog(FATAL, "plpython: Procedure name would overrun buffer");
1072
1073         proc = PLy_malloc(sizeof(PLyProcedure));
1074         proc->proname = PLy_malloc(strlen(procName) + 1);
1075         strcpy(proc->proname, procName);
1076         proc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
1077         proc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
1078         PLy_typeinfo_init(&proc->result);
1079         for (i = 0; i < FUNC_MAX_ARGS; i++)
1080                 PLy_typeinfo_init(&proc->args[i]);
1081         proc->nargs = 0;
1082         proc->code = proc->interp = proc->reval = proc->statics = NULL;
1083         proc->globals = proc->me = NULL;
1084
1085         SAVE_EXC();
1086         if (TRAP_EXC())
1087         {
1088                 RESTORE_EXC();
1089                 PLy_procedure_delete(proc);
1090                 if (procSource)
1091                         pfree(procSource);
1092                 RERAISE_EXC();
1093         }
1094
1095         /*
1096          * get information required for output conversion of the return value,
1097          * but only if this isn't a trigger.
1098          */
1099         if (!is_trigger)
1100         {
1101                 HeapTuple       rvTypeTup;
1102                 Form_pg_type rvTypeStruct;
1103                 Datum           rvDatum;
1104
1105                 rvDatum = ObjectIdGetDatum(procStruct->prorettype);
1106                 rvTypeTup = SearchSysCache(TYPEOID, rvDatum, 0, 0, 0);
1107                 if (!HeapTupleIsValid(rvTypeTup))
1108                         elog(ERROR, "plpython: cache lookup for type \"%u\" failed",
1109                                  procStruct->prorettype);
1110
1111                 rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup);
1112                 if (rvTypeStruct->typrelid == InvalidOid)
1113                         PLy_output_datum_func(&proc->result, rvTypeStruct);
1114                 else
1115                         elog(ERROR, "plpython: tuple return types not supported, yet");
1116
1117                 ReleaseSysCache(rvTypeTup);
1118         }
1119         else
1120         {
1121                 /*
1122                  * input/output conversion for trigger tuples.  use the result
1123                  * TypeInfo variable to store the tuple conversion info.
1124                  */
1125                 TriggerData *tdata = (TriggerData *) fcinfo->context;
1126
1127                 PLy_input_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att);
1128                 PLy_output_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att);
1129         }
1130
1131         /*
1132          * now get information required for input conversion of the procedures
1133          * arguments.
1134          */
1135         proc->nargs = fcinfo->nargs;
1136         for (i = 0; i < fcinfo->nargs; i++)
1137         {
1138                 HeapTuple       argTypeTup;
1139                 Form_pg_type argTypeStruct;
1140                 Datum           argDatum;
1141
1142                 argDatum = ObjectIdGetDatum(procStruct->proargtypes[i]);
1143                 argTypeTup = SearchSysCache(TYPEOID, argDatum, 0, 0, 0);
1144                 if (!HeapTupleIsValid(argTypeTup))
1145                         elog(ERROR, "plpython: cache lookup for type \"%u\" failed",
1146                                  procStruct->proargtypes[i]);
1147                 argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
1148
1149                 if (argTypeStruct->typrelid == InvalidOid)
1150                         PLy_input_datum_func(&(proc->args[i]), argTypeStruct);
1151                 else
1152                 {
1153                         TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
1154
1155                         PLy_input_tuple_funcs(&(proc->args[i]),
1156                                                                   slot->ttc_tupleDescriptor);
1157                 }
1158
1159                 ReleaseSysCache(argTypeTup);
1160         }
1161
1162
1163         /*
1164          * get the text of the function.
1165          */
1166         procDatum = DirectFunctionCall1(textout,
1167                                                                         PointerGetDatum(&procStruct->prosrc));
1168         procSource = DatumGetCString(procDatum);
1169
1170         PLy_procedure_compile(proc, procSource);
1171
1172         pfree(procSource);
1173
1174         proc->me = PyCObject_FromVoidPtr(proc, NULL);
1175         PyDict_SetItemString(PLy_procedure_cache, key, proc->me);
1176
1177         RESTORE_EXC();
1178
1179         return proc;
1180 }
1181
1182 void
1183 PLy_procedure_compile(PLyProcedure * proc, const char *src)
1184 {
1185         PyObject   *module,
1186                            *crv = NULL;
1187         char       *msrc;
1188
1189         enter();
1190
1191         /*
1192          * get an instance of rexec.RExec for the function
1193          */
1194         proc->interp = PyObject_CallMethod(PLy_interp_safe, "RExec", NULL);
1195         if ((proc->interp == NULL) || (PyErr_Occurred()))
1196                 PLy_elog(ERROR, "Unable to create rexec.RExec instance");
1197
1198         proc->reval = PyObject_GetAttrString(proc->interp, "r_eval");
1199         if ((proc->reval == NULL) || (PyErr_Occurred()))
1200                 PLy_elog(ERROR, "Unable to get method `r_eval' from rexec.RExec");
1201
1202         /*
1203          * add a __main__ module to the function's interpreter
1204          */
1205         module = PyObject_CallMethod(proc->interp, "add_module", "s", "__main__");
1206         if ((module == NULL) || (PyErr_Occurred()))
1207                 PLy_elog(ERROR, "Unable to get module `__main__' from rexec.RExec");
1208
1209         /*
1210          * add plpy module to the interpreters main dictionary
1211          */
1212         proc->globals = PyModule_GetDict(module);
1213         if ((proc->globals == NULL) || (PyErr_Occurred()))
1214                 PLy_elog(ERROR, "Unable to get `__main__.__dict__' from rexec.RExec");
1215
1216         /*
1217          * why the hell won't r_import or r_exec('import plpy') work?
1218          */
1219         module = PyDict_GetItemString(PLy_interp_globals, "plpy");
1220         if ((module == NULL) || (PyErr_Occurred()))
1221                 PLy_elog(ERROR, "Unable to get `plpy'");
1222         Py_INCREF(module);
1223         PyDict_SetItemString(proc->globals, "plpy", module);
1224
1225         /*
1226          * SD is private preserved data between calls GD is global data shared
1227          * by all functions
1228          */
1229         proc->statics = PyDict_New();
1230         PyDict_SetItemString(proc->globals, "SD", proc->statics);
1231         PyDict_SetItemString(proc->globals, "GD", PLy_interp_safe_globals);
1232
1233         /*
1234          * insert the function code into the interpreter
1235          */
1236         msrc = PLy_procedure_munge_source(proc->proname, src);
1237         crv = PyObject_CallMethod(proc->interp, "r_exec", "s", msrc);
1238         free(msrc);
1239
1240         if ((crv != NULL) && (!PyErr_Occurred()))
1241         {
1242                 int                     clen;
1243                 char            call[256];
1244
1245                 Py_DECREF(crv);
1246
1247                 /*
1248                  * compile a call to the function
1249                  */
1250                 clen = snprintf(call, sizeof(call), "%s()", proc->proname);
1251                 if ((clen < 0) || (clen >= sizeof(call)))
1252                         elog(ERROR, "plpython: string would overflow buffer.");
1253                 proc->code = Py_CompileString(call, "<string>", Py_eval_input);
1254                 if ((proc->code != NULL) && (!PyErr_Occurred()))
1255                         return;
1256         }
1257         else
1258                 Py_XDECREF(crv);
1259
1260         PLy_elog(ERROR, "Unable to compile function %s", proc->proname);
1261 }
1262
1263 char *
1264 PLy_procedure_munge_source(const char *name, const char *src)
1265 {
1266         char       *mrc,
1267                            *mp;
1268         const char *sp;
1269         size_t          mlen,
1270                                 plen;
1271
1272         enter();
1273
1274         /*
1275          * room for function source and the def statement
1276          */
1277         mlen = (strlen(src) * 2) + strlen(name) + 16;
1278
1279         mrc = PLy_malloc(mlen);
1280         plen = snprintf(mrc, mlen, "def %s():\n\t", name);
1281         if ((plen < 0) || (plen >= mlen))
1282                 elog(FATAL, "Aiieee, impossible buffer overrun (or snprintf failure)");
1283
1284         sp = src;
1285         mp = mrc + plen;
1286
1287         while (*sp != '\0')
1288         {
1289                 if (*sp == '\n')
1290                 {
1291                         *mp++ = *sp++;
1292                         *mp++ = '\t';
1293                 }
1294                 else
1295                         *mp++ = *sp++;
1296         }
1297         *mp++ = '\n';
1298         *mp++ = '\n';
1299         *mp = '\0';
1300
1301         if (mp > (mrc + mlen))
1302                 elog(FATAL, "plpython: Buffer overrun in PLy_munge_source");
1303
1304         return mrc;
1305 }
1306
1307 void
1308 PLy_procedure_delete(PLyProcedure * proc)
1309 {
1310         int                     i;
1311
1312         enter();
1313
1314         Py_XDECREF(proc->code);
1315         Py_XDECREF(proc->interp);
1316         Py_XDECREF(proc->reval);
1317         Py_XDECREF(proc->statics);
1318         Py_XDECREF(proc->globals);
1319         Py_XDECREF(proc->me);
1320         if (proc->proname)
1321                 PLy_free(proc->proname);
1322         for (i = 0; i < proc->nargs; i++)
1323                 if (proc->args[i].is_rel == 1)
1324                 {
1325                         if (proc->args[i].in.r.atts)
1326                                 PLy_free(proc->args[i].in.r.atts);
1327                         if (proc->args[i].out.r.atts)
1328                                 PLy_free(proc->args[i].out.r.atts);
1329                 }
1330
1331         leave();
1332 }
1333
1334 /* conversion functions.  remember output from python is
1335  * input to postgresql, and vis versa.
1336  */
1337 void
1338 PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1339 {
1340         int                     i;
1341         Datum           datum;
1342
1343         enter();
1344
1345         if (arg->is_rel == 0)
1346                 elog(FATAL, "plpython: PLyTypeInfo struct is initialized for a Datum");
1347
1348         arg->is_rel = 1;
1349         arg->in.r.natts = desc->natts;
1350         arg->in.r.atts = malloc(desc->natts * sizeof(PLyDatumToOb));
1351
1352         for (i = 0; i < desc->natts; i++)
1353         {
1354                 HeapTuple       typeTup;
1355                 Form_pg_type typeStruct;
1356
1357                 datum = ObjectIdGetDatum(desc->attrs[i]->atttypid);
1358                 typeTup = SearchSysCache(TYPEOID, datum, 0, 0, 0);
1359                 if (!HeapTupleIsValid(typeTup))
1360                 {
1361                         char       *attname = NameStr(desc->attrs[i]->attname);
1362
1363                         elog(ERROR, "plpython: Cache lookup for attribute `%s' type `%u' failed",
1364                                  attname, desc->attrs[i]->atttypid);
1365                 }
1366
1367                 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1368
1369                 PLy_input_datum_func2(&(arg->in.r.atts[i]), typeStruct);
1370
1371                 ReleaseSysCache(typeTup);
1372         }
1373 }
1374
1375 void
1376 PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1377 {
1378         int                     i;
1379         Datum           datum;
1380
1381         enter();
1382
1383         if (arg->is_rel == 0)
1384                 elog(FATAL, "plpython: PLyTypeInfo struct is initialized for a Datum");
1385
1386         arg->is_rel = 1;
1387         arg->out.r.natts = desc->natts;
1388         arg->out.r.atts = malloc(desc->natts * sizeof(PLyDatumToOb));
1389
1390         for (i = 0; i < desc->natts; i++)
1391         {
1392                 HeapTuple       typeTup;
1393                 Form_pg_type typeStruct;
1394
1395                 datum = ObjectIdGetDatum(desc->attrs[i]->atttypid);
1396                 typeTup = SearchSysCache(TYPEOID, datum, 0, 0, 0);
1397                 if (!HeapTupleIsValid(typeTup))
1398                 {
1399                         char       *attname = NameStr(desc->attrs[i]->attname);
1400
1401                         elog(ERROR, "plpython: Cache lookup for attribute `%s' type `%u' failed",
1402                                  attname, desc->attrs[i]->atttypid);
1403                 }
1404
1405                 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1406
1407                 PLy_output_datum_func2(&(arg->out.r.atts[i]), typeStruct);
1408
1409                 ReleaseSysCache(typeTup);
1410         }
1411 }
1412
1413 void
1414 PLy_output_datum_func(PLyTypeInfo * arg, Form_pg_type typeStruct)
1415 {
1416         enter();
1417
1418         if (arg->is_rel == 1)
1419                 elog(FATAL, "plpython: PLyTypeInfo struct is initialized for a Tuple");
1420         arg->is_rel = 0;
1421         PLy_output_datum_func2(&(arg->out.d), typeStruct);
1422 }
1423
1424 void
1425 PLy_output_datum_func2(PLyObToDatum * arg, Form_pg_type typeStruct)
1426 {
1427         enter();
1428
1429         perm_fmgr_info(typeStruct->typinput, &arg->typfunc);
1430         arg->typelem = typeStruct->typelem;
1431         arg->typbyval = typeStruct->typbyval;
1432 }
1433
1434 void
1435 PLy_input_datum_func(PLyTypeInfo * arg, Form_pg_type typeStruct)
1436 {
1437         enter();
1438
1439         if (arg->is_rel == 1)
1440                 elog(FATAL, "plpython: PLyTypeInfo struct is initialized for Tuple");
1441         arg->is_rel = 0;
1442         PLy_input_datum_func2(&(arg->in.d), typeStruct);
1443 }
1444
1445 void
1446 PLy_input_datum_func2(PLyDatumToOb * arg, Form_pg_type typeStruct)
1447 {
1448         char       *type;
1449
1450         perm_fmgr_info(typeStruct->typoutput, &arg->typfunc);
1451         arg->typelem = typeStruct->typelem;
1452         arg->typbyval = typeStruct->typbyval;
1453
1454         /*
1455          * hmmm, wierd.  means this arg will always be converted to a python
1456          * None
1457          */
1458         if (!OidIsValid(typeStruct->typoutput))
1459         {
1460                 elog(ERROR, "plpython: (FIXME) typeStruct->typoutput is invalid");
1461
1462                 arg->func = NULL;
1463                 return;
1464         }
1465
1466         type = NameStr(typeStruct->typname);
1467         switch (type[0])
1468         {
1469                 case 'b':
1470                         {
1471                                 if (strcasecmp("bool", type))
1472                                 {
1473                                         arg->func = PLyBool_FromString;
1474                                         return;
1475                                 }
1476                                 break;
1477                         }
1478                 case 'f':
1479                         {
1480                                 if ((strncasecmp("float", type, 5) == 0) &&
1481                                         ((type[5] == '8') || (type[5] == '4')))
1482                                 {
1483                                         arg->func = PLyFloat_FromString;
1484                                         return;
1485                                 }
1486                                 break;
1487                         }
1488                 case 'i':
1489                         {
1490                                 if ((strncasecmp("int", type, 3) == 0) &&
1491                                         ((type[3] == '4') || (type[3] == '2')) &&
1492                                         (type[4] == '\0'))
1493                                 {
1494                                         arg->func = PLyInt_FromString;
1495                                         return;
1496                                 }
1497                                 else if (strcasecmp("int8", type) == 0)
1498                                         arg->func = PLyLong_FromString;
1499                                 break;
1500                         }
1501                 case 'n':
1502                         {
1503                                 if (strcasecmp("numeric", type) == 0)
1504                                 {
1505                                         arg->func = PLyFloat_FromString;
1506                                         return;
1507                                 }
1508                                 break;
1509                         }
1510                 default:
1511                         break;
1512         }
1513         arg->func = PLyString_FromString;
1514 }
1515
1516 void
1517 PLy_typeinfo_init(PLyTypeInfo * arg)
1518 {
1519         arg->is_rel = -1;
1520         arg->in.r.natts = arg->out.r.natts = 0;
1521         arg->in.r.atts = NULL;
1522         arg->out.r.atts = NULL;
1523 }
1524
1525 void
1526 PLy_typeinfo_dealloc(PLyTypeInfo * arg)
1527 {
1528         if (arg->is_rel == 1)
1529         {
1530                 if (arg->in.r.atts)
1531                         PLy_free(arg->in.r.atts);
1532                 if (arg->out.r.atts)
1533                         PLy_free(arg->out.r.atts);
1534         }
1535 }
1536
1537 /* assumes that a bool is always returned as a 't' or 'f'
1538  */
1539 PyObject *
1540 PLyBool_FromString(const char *src)
1541 {
1542         enter();
1543
1544         if (src[0] == 't')
1545                 return PyInt_FromLong(1);
1546         return PyInt_FromLong(0);
1547 }
1548
1549 PyObject *
1550 PLyFloat_FromString(const char *src)
1551 {
1552         double          v;
1553         char       *eptr;
1554
1555         enter();
1556
1557         errno = 0;
1558         v = strtod(src, &eptr);
1559         if ((*eptr != '\0') || (errno))
1560                 return NULL;
1561         return PyFloat_FromDouble(v);
1562 }
1563
1564 PyObject *
1565 PLyInt_FromString(const char *src)
1566 {
1567         long            v;
1568         char       *eptr;
1569
1570         enter();
1571
1572         errno = 0;
1573         v = strtol(src, &eptr, 0);
1574         if ((*eptr != '\0') || (errno))
1575                 return NULL;
1576         return PyInt_FromLong(v);
1577 }
1578
1579 PyObject *
1580 PLyLong_FromString(const char *src)
1581 {
1582         return PyLong_FromString((char *) src, NULL, 0);
1583 }
1584
1585 PyObject *
1586 PLyString_FromString(const char *src)
1587 {
1588         return PyString_FromString(src);
1589 }
1590
1591 PyObject *
1592 PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
1593 {
1594         DECLARE_EXC();
1595         PyObject   *volatile dict;
1596         int                     i;
1597
1598         enter();
1599
1600         if (info->is_rel != 1)
1601                 elog(FATAL, "plpython: PLyTypeInfo structure describes a datum.");
1602
1603         dict = PyDict_New();
1604         if (dict == NULL)
1605                 PLy_elog(ERROR, "Unable to create tuple dictionary.");
1606
1607         SAVE_EXC();
1608         if (TRAP_EXC())
1609         {
1610                 RESTORE_EXC();
1611                 Py_DECREF(dict);
1612
1613                 RERAISE_EXC();
1614         }
1615
1616         for (i = 0; i < info->in.r.natts; i++)
1617         {
1618                 char       *key,
1619                                    *vsrc;
1620                 Datum           vattr,
1621                                         vdat;
1622                 bool            is_null;
1623                 PyObject   *value;
1624
1625                 key = NameStr(desc->attrs[i]->attname);
1626                 vattr = heap_getattr(tuple, (i + 1), desc, &is_null);
1627
1628                 if ((is_null) || (info->in.r.atts[i].func == NULL))
1629                         PyDict_SetItemString(dict, key, Py_None);
1630                 else
1631                 {
1632                         vdat = FunctionCall3(&info->in.r.atts[i].typfunc,
1633                                                                  vattr,
1634                                                         ObjectIdGetDatum(info->in.r.atts[i].typelem),
1635                                                            Int32GetDatum(desc->attrs[i]->atttypmod));
1636                         vsrc = DatumGetCString(vdat);
1637
1638                         /*
1639                          * no exceptions allowed
1640                          */
1641                         value = info->in.r.atts[i].func(vsrc);
1642                         pfree(vsrc);
1643                         PyDict_SetItemString(dict, key, value);
1644                         Py_DECREF(value);
1645                 }
1646         }
1647
1648         RESTORE_EXC();
1649
1650         return dict;
1651 }
1652
1653 /* initialization, some python variables function declared here
1654  */
1655
1656 /* interface to postgresql elog
1657  */
1658 static PyObject *PLy_debug(PyObject *, PyObject *);
1659 static PyObject *PLy_log(PyObject *, PyObject *);
1660 static PyObject *PLy_info(PyObject *, PyObject *);
1661 static PyObject *PLy_notice(PyObject *, PyObject *);
1662 static PyObject *PLy_warning(PyObject *, PyObject *);
1663 static PyObject *PLy_error(PyObject *, PyObject *);
1664 static PyObject *PLy_fatal(PyObject *, PyObject *);
1665
1666 /* PLyPlanObject, PLyResultObject and SPI interface
1667  */
1668 #define is_PLyPlanObject(x) ((x)->ob_type == &PLy_PlanType)
1669 static PyObject *PLy_plan_new(void);
1670 static void PLy_plan_dealloc(PyObject *);
1671 static PyObject *PLy_plan_getattr(PyObject *, char *);
1672 static PyObject *PLy_plan_status(PyObject *, PyObject *);
1673
1674 static PyObject *PLy_result_new(void);
1675 static void PLy_result_dealloc(PyObject *);
1676 static PyObject *PLy_result_getattr(PyObject *, char *);
1677
1678 #ifdef NOT_USED
1679 /* Appear to be unused */
1680 static PyObject *PLy_result_fetch(PyObject *, PyObject *);
1681 static PyObject *PLy_result_nrows(PyObject *, PyObject *);
1682 static PyObject *PLy_result_status(PyObject *, PyObject *);
1683 #endif
1684 static int      PLy_result_length(PyObject *);
1685 static PyObject *PLy_result_item(PyObject *, int);
1686 static PyObject *PLy_result_slice(PyObject *, int, int);
1687 static int      PLy_result_ass_item(PyObject *, int, PyObject *);
1688 static int      PLy_result_ass_slice(PyObject *, int, int, PyObject *);
1689
1690
1691 static PyObject *PLy_spi_prepare(PyObject *, PyObject *);
1692 static PyObject *PLy_spi_execute(PyObject *, PyObject *);
1693 static const char *PLy_spi_error_string(int);
1694 static PyObject *PLy_spi_execute_query(char *query, int limit);
1695 static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, int);
1696 static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
1697
1698
1699 static PyTypeObject PLy_PlanType = {
1700         PyObject_HEAD_INIT(NULL)
1701         0,                                                      /* ob_size */
1702         "PLyPlan",                                      /* tp_name */
1703         sizeof(PLyPlanObject),          /* tp_size */
1704         0,                                                      /* tp_itemsize */
1705
1706         /*
1707          * methods
1708          */
1709         (destructor) PLy_plan_dealloc,          /* tp_dealloc */
1710         0,                                                      /* tp_print */
1711         (getattrfunc) PLy_plan_getattr,         /* tp_getattr */
1712         0,                                                      /* tp_setattr */
1713         0,                                                      /* tp_compare */
1714         0,                                                      /* tp_repr */
1715         0,                                                      /* tp_as_number */
1716         0,                                                      /* tp_as_sequence */
1717         0,                                                      /* tp_as_mapping */
1718         0,                                                      /* tp_hash */
1719         0,                                                      /* tp_call */
1720         0,                                                      /* tp_str */
1721         0,                                                      /* tp_getattro */
1722         0,                                                      /* tp_setattro */
1723         0,                                                      /* tp_as_buffer */
1724         0,                                                      /* tp_xxx4 */
1725         PLy_plan_doc,                           /* tp_doc */
1726 };
1727
1728 static PyMethodDef PLy_plan_methods[] = {
1729         {"status", (PyCFunction) PLy_plan_status, METH_VARARGS, NULL},
1730         {NULL, NULL, 0, NULL}
1731 };
1732
1733
1734 static PySequenceMethods PLy_result_as_sequence = {
1735         (inquiry) PLy_result_length,    /* sq_length */
1736         (binaryfunc) 0,                         /* sq_concat */
1737         (intargfunc) 0,                         /* sq_repeat */
1738         (intargfunc) PLy_result_item,           /* sq_item */
1739         (intintargfunc) PLy_result_slice,       /* sq_slice */
1740         (intobjargproc) PLy_result_ass_item,            /* sq_ass_item */
1741         (intintobjargproc) PLy_result_ass_slice,        /* sq_ass_slice */
1742 };
1743
1744 static PyTypeObject PLy_ResultType = {
1745         PyObject_HEAD_INIT(NULL)
1746         0,                                                      /* ob_size */
1747         "PLyResult",                            /* tp_name */
1748         sizeof(PLyResultObject),        /* tp_size */
1749         0,                                                      /* tp_itemsize */
1750
1751         /*
1752          * methods
1753          */
1754         (destructor) PLy_result_dealloc,        /* tp_dealloc */
1755         0,                                                      /* tp_print */
1756         (getattrfunc) PLy_result_getattr,       /* tp_getattr */
1757         0,                                                      /* tp_setattr */
1758         0,                                                      /* tp_compare */
1759         0,                                                      /* tp_repr */
1760         0,                                                      /* tp_as_number */
1761         &PLy_result_as_sequence,        /* tp_as_sequence */
1762         0,                                                      /* tp_as_mapping */
1763         0,                                                      /* tp_hash */
1764         0,                                                      /* tp_call */
1765         0,                                                      /* tp_str */
1766         0,                                                      /* tp_getattro */
1767         0,                                                      /* tp_setattro */
1768         0,                                                      /* tp_as_buffer */
1769         0,                                                      /* tp_xxx4 */
1770         PLy_result_doc,                         /* tp_doc */
1771 };
1772
1773 #ifdef NOT_USED
1774 /* Appear to be unused */
1775 static PyMethodDef PLy_result_methods[] = {
1776         {"fetch", (PyCFunction) PLy_result_fetch, METH_VARARGS, NULL,},
1777         {"nrows", (PyCFunction) PLy_result_nrows, METH_VARARGS, NULL},
1778         {"status", (PyCFunction) PLy_result_status, METH_VARARGS, NULL},
1779         {NULL, NULL, 0, NULL}
1780 };
1781 #endif
1782
1783 static PyMethodDef PLy_methods[] = {
1784         /*
1785          * logging methods
1786          */
1787         {"debug", PLy_debug, METH_VARARGS, NULL},
1788         {"log", PLy_log, METH_VARARGS, NULL},
1789         {"info", PLy_info, METH_VARARGS, NULL},
1790         {"notice", PLy_notice, METH_VARARGS, NULL},
1791         {"warning", PLy_warning, METH_VARARGS, NULL},
1792         {"error", PLy_error, METH_VARARGS, NULL},
1793         {"fatal", PLy_fatal, METH_VARARGS, NULL},
1794
1795         /*
1796          * create a stored plan
1797          */
1798         {"prepare", PLy_spi_prepare, METH_VARARGS, NULL},
1799
1800         /*
1801          * execute a plan or query
1802          */
1803         {"execute", PLy_spi_execute, METH_VARARGS, NULL},
1804
1805         {NULL, NULL, 0, NULL}
1806 };
1807
1808
1809 /* plan object methods
1810  */
1811 PyObject *
1812 PLy_plan_new(void)
1813 {
1814         PLyPlanObject *ob;
1815
1816         enter();
1817
1818         if ((ob = PyObject_NEW(PLyPlanObject, &PLy_PlanType)) == NULL)
1819                 return NULL;
1820
1821         ob->plan = NULL;
1822         ob->nargs = 0;
1823         ob->types = NULL;
1824         ob->args = NULL;
1825
1826         return (PyObject *) ob;
1827 }
1828
1829
1830 void
1831 PLy_plan_dealloc(PyObject * arg)
1832 {
1833         PLyPlanObject *ob = (PLyPlanObject *) arg;
1834
1835         enter();
1836
1837         if (ob->plan)
1838         {
1839                 /*
1840                  * free the plan... pfree(ob->plan);
1841                  *
1842                  * FIXME -- leaks saved plan on object destruction.  can this be
1843                  * avoided?
1844                  */
1845         }
1846         if (ob->types)
1847                 PLy_free(ob->types);
1848         if (ob->args)
1849         {
1850                 int                     i;
1851
1852                 for (i = 0; i < ob->nargs; i++)
1853                         PLy_typeinfo_dealloc(&ob->args[i]);
1854                 PLy_free(ob->args);
1855         }
1856
1857         PyMem_DEL(arg);
1858
1859         leave();
1860 }
1861
1862
1863 PyObject *
1864 PLy_plan_getattr(PyObject * self, char *name)
1865 {
1866         return Py_FindMethod(PLy_plan_methods, self, name);
1867 }
1868
1869 PyObject *
1870 PLy_plan_status(PyObject * self, PyObject * args)
1871 {
1872         if (PyArg_ParseTuple(args, ""))
1873         {
1874                 Py_INCREF(Py_True);
1875                 return Py_True;
1876                 /* return PyInt_FromLong(self->status); */
1877         }
1878         PyErr_SetString(PLy_exc_error, "plan.status() takes no arguments");
1879         return NULL;
1880 }
1881
1882
1883
1884 /* result object methods
1885  */
1886
1887 PyObject *
1888 PLy_result_new(void)
1889 {
1890         PLyResultObject *ob;
1891
1892         enter();
1893
1894         if ((ob = PyObject_NEW(PLyResultObject, &PLy_ResultType)) == NULL)
1895                 return NULL;
1896
1897         /* ob->tuples = NULL; */
1898
1899         Py_INCREF(Py_None);
1900         ob->status = Py_None;
1901         ob->nrows = PyInt_FromLong(-1);
1902         ob->rows = PyList_New(0);
1903
1904         return (PyObject *) ob;
1905 }
1906
1907 void
1908 PLy_result_dealloc(PyObject * arg)
1909 {
1910         PLyResultObject *ob = (PLyResultObject *) arg;
1911
1912         enter();
1913
1914         Py_XDECREF(ob->nrows);
1915         Py_XDECREF(ob->rows);
1916         Py_XDECREF(ob->status);
1917
1918         PyMem_DEL(ob);
1919 }
1920
1921 PyObject *
1922 PLy_result_getattr(PyObject * self, char *attr)
1923 {
1924         return NULL;
1925 }
1926
1927 #ifdef NOT_USED
1928 /* Appear to be unused */
1929 PyObject *
1930 PLy_result_fetch(PyObject * self, PyObject * args)
1931 {
1932         return NULL;
1933 }
1934
1935 PyObject *
1936 PLy_result_nrows(PyObject * self, PyObject * args)
1937 {
1938         PLyResultObject *ob = (PLyResultObject *) self;
1939
1940         Py_INCREF(ob->nrows);
1941         return ob->nrows;
1942 }
1943
1944 PyObject *
1945 PLy_result_status(PyObject * self, PyObject * args)
1946 {
1947         PLyResultObject *ob = (PLyResultObject *) self;
1948
1949         Py_INCREF(ob->status);
1950         return ob->status;
1951 }
1952 #endif
1953 int
1954 PLy_result_length(PyObject * arg)
1955 {
1956         PLyResultObject *ob = (PLyResultObject *) arg;
1957
1958         return PyList_Size(ob->rows);
1959 }
1960
1961 PyObject *
1962 PLy_result_item(PyObject * arg, int idx)
1963 {
1964         PyObject   *rv;
1965         PLyResultObject *ob = (PLyResultObject *) arg;
1966
1967         rv = PyList_GetItem(ob->rows, idx);
1968         if (rv != NULL)
1969                 Py_INCREF(rv);
1970         return rv;
1971 }
1972
1973 int
1974 PLy_result_ass_item(PyObject * arg, int idx, PyObject * item)
1975 {
1976         int                     rv;
1977         PLyResultObject *ob = (PLyResultObject *) arg;
1978
1979         Py_INCREF(item);
1980         rv = PyList_SetItem(ob->rows, idx, item);
1981         return rv;
1982 }
1983
1984 PyObject *
1985 PLy_result_slice(PyObject * arg, int lidx, int hidx)
1986 {
1987         PyObject   *rv;
1988         PLyResultObject *ob = (PLyResultObject *) arg;
1989
1990         rv = PyList_GetSlice(ob->rows, lidx, hidx);
1991         if (rv == NULL)
1992                 return NULL;
1993         Py_INCREF(rv);
1994         return rv;
1995 }
1996
1997 int
1998 PLy_result_ass_slice(PyObject * arg, int lidx, int hidx, PyObject * slice)
1999 {
2000         int                     rv;
2001         PLyResultObject *ob = (PLyResultObject *) arg;
2002
2003         rv = PyList_SetSlice(ob->rows, lidx, hidx, slice);
2004         return rv;
2005 }
2006
2007 /* SPI interface
2008  */
2009 PyObject *
2010 PLy_spi_prepare(PyObject * self, PyObject * args)
2011 {
2012         DECLARE_EXC();
2013         PLyPlanObject *plan;
2014         PyObject   *list = NULL;
2015         PyObject   *volatile optr = NULL;
2016         char       *query;
2017
2018         enter();
2019
2020         if (!PyArg_ParseTuple(args, "s|O", &query, &list))
2021         {
2022                 PyErr_SetString(PLy_exc_spi_error,
2023                                                 "Invalid arguments for plpy.prepare()");
2024                 return NULL;
2025         }
2026
2027         if ((list) && (!PySequence_Check(list)))
2028         {
2029                 PyErr_SetString(PLy_exc_spi_error,
2030                                  "Second argument in plpy.prepare() must be a sequence");
2031                 return NULL;
2032         }
2033
2034
2035         if ((plan = (PLyPlanObject *) PLy_plan_new()) == NULL)
2036                 return NULL;
2037
2038         SAVE_EXC();
2039         if (TRAP_EXC())
2040         {
2041                 RESTORE_EXC();
2042                 Py_DECREF(plan);
2043                 Py_XDECREF(optr);
2044                 if (!PyErr_Occurred())
2045                         PyErr_SetString(PLy_exc_spi_error,
2046                                                         "Unknown error in PLy_spi_prepare.");
2047                 PLy_elog(WARNING, "in function %s:", PLy_procedure_name(PLy_last_procedure));
2048                 RERAISE_EXC();
2049         }
2050
2051         if (list != NULL)
2052         {
2053                 int                     nargs,
2054                                         i;
2055
2056
2057                 nargs = PySequence_Length(list);
2058                 if (nargs > 0)
2059                 {
2060                         plan->nargs = nargs;
2061                         plan->types = PLy_malloc(sizeof(Oid) * nargs);
2062                         plan->values = PLy_malloc(sizeof(Datum) * nargs);
2063                         plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs);
2064
2065                         /*
2066                          * the other loop might throw an exception, if PLyTypeInfo
2067                          * member isn't properly initialized the Py_DECREF(plan) will
2068                          * go boom
2069                          */
2070                         for (i = 0; i < nargs; i++)
2071                         {
2072                                 PLy_typeinfo_init(&plan->args[i]);
2073                                 plan->values[i] = (Datum) NULL;
2074                         }
2075
2076                         for (i = 0; i < nargs; i++)
2077                         {
2078                                 char       *sptr;
2079                                 HeapTuple       typeTup;
2080                                 Form_pg_type typeStruct;
2081
2082                                 optr = PySequence_GetItem(list, i);
2083                                 if (!PyString_Check(optr))
2084                                 {
2085                                         PyErr_SetString(PLy_exc_spi_error,
2086                                                                         "Type names must be strings.");
2087                                         RAISE_EXC(1);
2088                                 }
2089                                 sptr = PyString_AsString(optr);
2090                                 /* XXX should extend this to allow qualified type names */
2091                                 typeTup = typenameType(makeTypeName(sptr));
2092                                 Py_DECREF(optr);
2093                                 optr = NULL;    /* this is important */
2094
2095                                 plan->types[i] = HeapTupleGetOid(typeTup);
2096                                 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2097                                 if (typeStruct->typrelid == InvalidOid)
2098                                         PLy_output_datum_func(&plan->args[i], typeStruct);
2099                                 else
2100                                 {
2101                                         PyErr_SetString(PLy_exc_spi_error,
2102                                                          "tuples not handled in plpy.prepare, yet.");
2103                                         RAISE_EXC(1);
2104                                 }
2105                                 ReleaseSysCache(typeTup);
2106                         }
2107                 }
2108         }
2109
2110         plan->plan = SPI_prepare(query, plan->nargs, plan->types);
2111         if (plan->plan == NULL)
2112         {
2113                 PLy_exception_set(PLy_exc_spi_error,
2114                                          "Unable to prepare plan. SPI_prepare failed -- %s.",
2115                                                   PLy_spi_error_string(SPI_result));
2116                 RAISE_EXC(1);
2117         }
2118
2119         plan->plan = SPI_saveplan(plan->plan);
2120         if (plan->plan == NULL)
2121         {
2122                 PLy_exception_set(PLy_exc_spi_error,
2123                                            "Unable to save plan. SPI_saveplan failed -- %s.",
2124                                                   PLy_spi_error_string(SPI_result));
2125                 RAISE_EXC(1);
2126         }
2127
2128         RESTORE_EXC();
2129
2130         return (PyObject *) plan;
2131 }
2132
2133 /* execute(query="select * from foo", limit=5)
2134  * execute(plan=plan, values=(foo, bar), limit=5)
2135  */
2136 PyObject *
2137 PLy_spi_execute(PyObject * self, PyObject * args)
2138 {
2139         char       *query;
2140         PyObject   *plan;
2141         PyObject   *list = NULL;
2142         int                     limit = 0;
2143
2144         enter();
2145
2146 #ifdef NOT_USED
2147
2148         /*
2149          * there should - hahaha - be an python exception set so just return
2150          * NULL.  FIXME -- is this needed?
2151          */
2152         if (PLy_restart_in_progress)
2153                 return NULL;
2154 #endif
2155
2156         if (PyArg_ParseTuple(args, "s|i", &query, &limit))
2157                 return PLy_spi_execute_query(query, limit);
2158
2159         PyErr_Clear();
2160
2161         if ((PyArg_ParseTuple(args, "O|Oi", &plan, &list, &limit)) &&
2162                 (is_PLyPlanObject(plan)))
2163         {
2164                 PyObject   *rv = PLy_spi_execute_plan(plan, list, limit);
2165
2166                 return rv;
2167         }
2168
2169         PyErr_SetString(PLy_exc_error, "Expected a query or plan.");
2170         return NULL;
2171 }
2172
2173 PyObject *
2174 PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit)
2175 {
2176         DECLARE_EXC();
2177         volatile int nargs;
2178         int                     i,
2179                                 rv;
2180         PLyPlanObject *plan;
2181
2182         enter();
2183
2184         if (list != NULL)
2185         {
2186                 if ((!PySequence_Check(list)) || (PyString_Check(list)))
2187                 {
2188                         char       *msg = "plpy.execute() takes a sequence as its second argument";
2189
2190                         PyErr_SetString(PLy_exc_spi_error, msg);
2191                         return NULL;
2192                 }
2193                 nargs = PySequence_Length(list);
2194         }
2195         else
2196                 nargs = 0;
2197
2198         plan = (PLyPlanObject *) ob;
2199
2200         if (nargs != plan->nargs)
2201         {
2202                 char       *sv;
2203
2204                 PyObject   *so = PyObject_Str(list);
2205
2206                 sv = PyString_AsString(so);
2207                 PLy_exception_set(PLy_exc_spi_error,
2208                                                   "Expected sequence of %d arguments, got %d. %s",
2209                                                   plan->nargs, nargs, sv);
2210                 Py_DECREF(so);
2211
2212                 return NULL;
2213         }
2214
2215         SAVE_EXC();
2216         if (TRAP_EXC())
2217         {
2218                 RESTORE_EXC();
2219
2220                 /*
2221                  * cleanup plan->values array
2222                  */
2223                 for (i = 0; i < nargs; i++)
2224                 {
2225                         if (!plan->args[i].out.d.typbyval &&
2226                                 (plan->values[i] != (Datum) NULL))
2227                         {
2228                                 pfree(DatumGetPointer(plan->values[i]));
2229                                 plan->values[i] = (Datum) NULL;
2230                         }
2231                 }
2232
2233                 if (!PyErr_Occurred())
2234                         PyErr_SetString(PLy_exc_error,
2235                                                         "Unknown error in PLy_spi_execute_plan");
2236                 PLy_elog(WARNING, "in function %s:", PLy_procedure_name(PLy_last_procedure));
2237                 RERAISE_EXC();
2238         }
2239
2240         if (nargs)
2241         {
2242                 for (i = 0; i < nargs; i++)
2243                 {
2244                         PyObject   *elem,
2245                                            *so;
2246                         char       *sv;
2247
2248                         elem = PySequence_GetItem(list, i);
2249                         so = PyObject_Str(elem);
2250                         sv = PyString_AsString(so);
2251
2252                         /*
2253                          * FIXME -- if this can elog, we have leak
2254                          */
2255                         plan->values[i] = FunctionCall3(&(plan->args[i].out.d.typfunc),
2256                                                                                         CStringGetDatum(sv),
2257                                                    ObjectIdGetDatum(plan->args[i].out.d.typelem),
2258                                                                                         Int32GetDatum(-1));
2259
2260                         Py_DECREF(so);
2261                         Py_DECREF(elem);
2262                 }
2263         }
2264
2265         rv = SPI_execp(plan->plan, plan->values, NULL, limit);
2266         RESTORE_EXC();
2267
2268         for (i = 0; i < nargs; i++)
2269         {
2270                 if (!plan->args[i].out.d.typbyval &&
2271                         (plan->values[i] != (Datum) NULL))
2272                 {
2273                         pfree(DatumGetPointer(plan->values[i]));
2274                         plan->values[i] = (Datum) NULL;
2275                 }
2276         }
2277
2278         if (rv < 0)
2279         {
2280                 PLy_exception_set(PLy_exc_spi_error,
2281                                            "Unable to execute plan.  SPI_execp failed -- %s",
2282                                                   PLy_spi_error_string(rv));
2283                 return NULL;
2284         }
2285
2286         return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);
2287 }
2288
2289 PyObject *
2290 PLy_spi_execute_query(char *query, int limit)
2291 {
2292         DECLARE_EXC();
2293         int                     rv;
2294
2295         SAVE_EXC();
2296         if (TRAP_EXC())
2297         {
2298                 RESTORE_EXC();
2299                 if ((!PLy_restart_in_progress) && (!PyErr_Occurred()))
2300                         PyErr_SetString(PLy_exc_spi_error,
2301                                                         "Unknown error in PLy_spi_execute_query.");
2302                 PLy_elog(WARNING, "in function %s:", PLy_procedure_name(PLy_last_procedure));
2303                 RERAISE_EXC();
2304         }
2305
2306         rv = SPI_exec(query, limit);
2307         RESTORE_EXC();
2308         if (rv < 0)
2309         {
2310                 PLy_exception_set(PLy_exc_spi_error,
2311                                            "Unable to execute query.  SPI_exec failed -- %s",
2312                                                   PLy_spi_error_string(rv));
2313                 return NULL;
2314         }
2315
2316         return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);
2317 }
2318
2319 PyObject *
2320 PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
2321 {
2322         PLyResultObject *result;
2323
2324         enter();
2325
2326         result = (PLyResultObject *) PLy_result_new();
2327         Py_DECREF(result->status);
2328         result->status = PyInt_FromLong(status);
2329
2330         if (status == SPI_OK_UTILITY)
2331         {
2332                 Py_DECREF(result->nrows);
2333                 result->nrows = PyInt_FromLong(0);
2334         }
2335         else if (status != SPI_OK_SELECT)
2336         {
2337                 Py_DECREF(result->nrows);
2338                 result->nrows = PyInt_FromLong(rows);
2339         }
2340         else
2341         {
2342                 DECLARE_EXC();
2343                 PLyTypeInfo args;
2344                 int                     i;
2345
2346                 PLy_typeinfo_init(&args);
2347                 Py_DECREF(result->nrows);
2348                 result->nrows = PyInt_FromLong(rows);
2349
2350                 SAVE_EXC();
2351                 if (TRAP_EXC())
2352                 {
2353                         RESTORE_EXC();
2354
2355                         if (!PyErr_Occurred())
2356                                 PyErr_SetString(PLy_exc_error,
2357                                                 "Unknown error in PLy_spi_execute_fetch_result");
2358                         Py_DECREF(result);
2359                         PLy_typeinfo_dealloc(&args);
2360                         RERAISE_EXC();
2361                 }
2362
2363                 if (rows)
2364                 {
2365                         Py_DECREF(result->rows);
2366                         result->rows = PyList_New(rows);
2367
2368                         PLy_input_tuple_funcs(&args, tuptable->tupdesc);
2369                         for (i = 0; i < rows; i++)
2370                         {
2371                                 PyObject   *row = PLyDict_FromTuple(&args, tuptable->vals[i],
2372                                                                                                         tuptable->tupdesc);
2373
2374                                 PyList_SetItem(result->rows, i, row);
2375                         }
2376                         PLy_typeinfo_dealloc(&args);
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, 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 }