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