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