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