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