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