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