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