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