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