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