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