]> granicus.if.org Git - postgresql/blob - src/pl/plpython/plpython.c
20177d62e1bb5d3a1ec58f8df6ef60a014776e49
[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.107 2008/03/25 22:42:45 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(TextDatumGetCString(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 = TextDatumGetCString(prosrcdatum);
1312
1313                 PLy_procedure_compile(proc, procSource);
1314
1315                 pfree(procSource);
1316
1317                 proc->me = PyCObject_FromVoidPtr(proc, NULL);
1318                 PyDict_SetItemString(PLy_procedure_cache, key, proc->me);
1319         }
1320         PG_CATCH();
1321         {
1322                 PLy_procedure_delete(proc);
1323                 if (procSource)
1324                         pfree(procSource);
1325
1326                 PG_RE_THROW();
1327         }
1328         PG_END_TRY();
1329
1330         return proc;
1331 }
1332
1333 static void
1334 PLy_procedure_compile(PLyProcedure * proc, const char *src)
1335 {
1336         PyObject   *crv = NULL;
1337         char       *msrc;
1338
1339         proc->globals = PyDict_Copy(PLy_interp_globals);
1340
1341         /*
1342          * SD is private preserved data between calls. GD is global data shared by
1343          * all functions
1344          */
1345         proc->statics = PyDict_New();
1346         PyDict_SetItemString(proc->globals, "SD", proc->statics);
1347
1348         /*
1349          * insert the function code into the interpreter
1350          */
1351         msrc = PLy_procedure_munge_source(proc->pyname, src);
1352         crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);
1353         free(msrc);
1354
1355         if (crv != NULL && (!PyErr_Occurred()))
1356         {
1357                 int                     clen;
1358                 char            call[NAMEDATALEN + 256];
1359
1360                 Py_DECREF(crv);
1361
1362                 /*
1363                  * compile a call to the function
1364                  */
1365                 clen = snprintf(call, sizeof(call), "%s()", proc->pyname);
1366                 if (clen < 0 || clen >= sizeof(call))
1367                         elog(ERROR, "string would overflow buffer");
1368                 proc->code = Py_CompileString(call, "<string>", Py_eval_input);
1369                 if (proc->code != NULL && (!PyErr_Occurred()))
1370                         return;
1371         }
1372         else
1373                 Py_XDECREF(crv);
1374
1375         PLy_elog(ERROR, "could not compile function \"%s\"", proc->proname);
1376 }
1377
1378 static char *
1379 PLy_procedure_munge_source(const char *name, const char *src)
1380 {
1381         char       *mrc,
1382                            *mp;
1383         const char *sp;
1384         size_t          mlen,
1385                                 plen;
1386
1387         /*
1388          * room for function source and the def statement
1389          */
1390         mlen = (strlen(src) * 2) + strlen(name) + 16;
1391
1392         mrc = PLy_malloc(mlen);
1393         plen = snprintf(mrc, mlen, "def %s():\n\t", name);
1394         Assert(plen >= 0 && plen < mlen);
1395
1396         sp = src;
1397         mp = mrc + plen;
1398
1399         while (*sp != '\0')
1400         {
1401                 if (*sp == '\r' && *(sp + 1) == '\n')
1402                         sp++;
1403
1404                 if (*sp == '\n' || *sp == '\r')
1405                 {
1406                         *mp++ = '\n';
1407                         *mp++ = '\t';
1408                         sp++;
1409                 }
1410                 else
1411                         *mp++ = *sp++;
1412         }
1413         *mp++ = '\n';
1414         *mp++ = '\n';
1415         *mp = '\0';
1416
1417         if (mp > (mrc + mlen))
1418                 elog(FATAL, "buffer overrun in PLy_munge_source");
1419
1420         return mrc;
1421 }
1422
1423 static void
1424 PLy_procedure_delete(PLyProcedure * proc)
1425 {
1426         int                     i;
1427
1428         Py_XDECREF(proc->code);
1429         Py_XDECREF(proc->statics);
1430         Py_XDECREF(proc->globals);
1431         Py_XDECREF(proc->me);
1432         if (proc->proname)
1433                 PLy_free(proc->proname);
1434         if (proc->pyname)
1435                 PLy_free(proc->pyname);
1436         for (i = 0; i < proc->nargs; i++)
1437         {
1438                 if (proc->args[i].is_rowtype == 1)
1439                 {
1440                         if (proc->args[i].in.r.atts)
1441                                 PLy_free(proc->args[i].in.r.atts);
1442                         if (proc->args[i].out.r.atts)
1443                                 PLy_free(proc->args[i].out.r.atts);
1444                 }
1445                 if (proc->argnames && proc->argnames[i])
1446                         PLy_free(proc->argnames[i]);
1447         }
1448         if (proc->argnames)
1449                 PLy_free(proc->argnames);
1450 }
1451
1452 /* conversion functions.  remember output from python is
1453  * input to postgresql, and vis versa.
1454  */
1455 static void
1456 PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1457 {
1458         int                     i;
1459
1460         if (arg->is_rowtype == 0)
1461                 elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");
1462         arg->is_rowtype = 1;
1463
1464         if (arg->in.r.natts != desc->natts)
1465         {
1466                 if (arg->in.r.atts)
1467                         PLy_free(arg->in.r.atts);
1468                 arg->in.r.natts = desc->natts;
1469                 arg->in.r.atts = PLy_malloc0(desc->natts * sizeof(PLyDatumToOb));
1470         }
1471
1472         for (i = 0; i < desc->natts; i++)
1473         {
1474                 HeapTuple       typeTup;
1475
1476                 if (desc->attrs[i]->attisdropped)
1477                         continue;
1478
1479                 if (arg->in.r.atts[i].typoid == desc->attrs[i]->atttypid)
1480                         continue;                       /* already set up this entry */
1481
1482                 typeTup = SearchSysCache(TYPEOID,
1483                                                                  ObjectIdGetDatum(desc->attrs[i]->atttypid),
1484                                                                  0, 0, 0);
1485                 if (!HeapTupleIsValid(typeTup))
1486                         elog(ERROR, "cache lookup failed for type %u",
1487                                  desc->attrs[i]->atttypid);
1488
1489                 PLy_input_datum_func2(&(arg->in.r.atts[i]),
1490                                                           desc->attrs[i]->atttypid,
1491                                                           typeTup);
1492
1493                 ReleaseSysCache(typeTup);
1494         }
1495 }
1496
1497 static void
1498 PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1499 {
1500         int                     i;
1501
1502         if (arg->is_rowtype == 0)
1503                 elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");
1504         arg->is_rowtype = 1;
1505
1506         if (arg->out.r.natts != desc->natts)
1507         {
1508                 if (arg->out.r.atts)
1509                         PLy_free(arg->out.r.atts);
1510                 arg->out.r.natts = desc->natts;
1511                 arg->out.r.atts = PLy_malloc0(desc->natts * sizeof(PLyDatumToOb));
1512         }
1513
1514         for (i = 0; i < desc->natts; i++)
1515         {
1516                 HeapTuple       typeTup;
1517
1518                 if (desc->attrs[i]->attisdropped)
1519                         continue;
1520
1521                 if (arg->out.r.atts[i].typoid == desc->attrs[i]->atttypid)
1522                         continue;                       /* already set up this entry */
1523
1524                 typeTup = SearchSysCache(TYPEOID,
1525                                                                  ObjectIdGetDatum(desc->attrs[i]->atttypid),
1526                                                                  0, 0, 0);
1527                 if (!HeapTupleIsValid(typeTup))
1528                         elog(ERROR, "cache lookup failed for type %u",
1529                                  desc->attrs[i]->atttypid);
1530
1531                 PLy_output_datum_func2(&(arg->out.r.atts[i]), typeTup);
1532
1533                 ReleaseSysCache(typeTup);
1534         }
1535 }
1536
1537 static void
1538 PLy_output_datum_func(PLyTypeInfo * arg, HeapTuple typeTup)
1539 {
1540         if (arg->is_rowtype > 0)
1541                 elog(ERROR, "PLyTypeInfo struct is initialized for a Tuple");
1542         arg->is_rowtype = 0;
1543         PLy_output_datum_func2(&(arg->out.d), typeTup);
1544 }
1545
1546 static void
1547 PLy_output_datum_func2(PLyObToDatum * arg, HeapTuple typeTup)
1548 {
1549         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1550
1551         perm_fmgr_info(typeStruct->typinput, &arg->typfunc);
1552         arg->typoid = HeapTupleGetOid(typeTup);
1553         arg->typioparam = getTypeIOParam(typeTup);
1554         arg->typbyval = typeStruct->typbyval;
1555 }
1556
1557 static void
1558 PLy_input_datum_func(PLyTypeInfo * arg, Oid typeOid, HeapTuple typeTup)
1559 {
1560         if (arg->is_rowtype > 0)
1561                 elog(ERROR, "PLyTypeInfo struct is initialized for Tuple");
1562         arg->is_rowtype = 0;
1563         PLy_input_datum_func2(&(arg->in.d), typeOid, typeTup);
1564 }
1565
1566 static void
1567 PLy_input_datum_func2(PLyDatumToOb * arg, Oid typeOid, HeapTuple typeTup)
1568 {
1569         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1570
1571         /* Get the type's conversion information */
1572         perm_fmgr_info(typeStruct->typoutput, &arg->typfunc);
1573         arg->typoid = HeapTupleGetOid(typeTup);
1574         arg->typioparam = getTypeIOParam(typeTup);
1575         arg->typbyval = typeStruct->typbyval;
1576
1577         /* Determine which kind of Python object we will convert to */
1578         switch (typeOid)
1579         {
1580                 case BOOLOID:
1581                         arg->func = PLyBool_FromString;
1582                         break;
1583                 case FLOAT4OID:
1584                 case FLOAT8OID:
1585                 case NUMERICOID:
1586                         arg->func = PLyFloat_FromString;
1587                         break;
1588                 case INT2OID:
1589                 case INT4OID:
1590                         arg->func = PLyInt_FromString;
1591                         break;
1592                 case INT8OID:
1593                         arg->func = PLyLong_FromString;
1594                         break;
1595                 default:
1596                         arg->func = PLyString_FromString;
1597                         break;
1598         }
1599 }
1600
1601 static void
1602 PLy_typeinfo_init(PLyTypeInfo * arg)
1603 {
1604         arg->is_rowtype = -1;
1605         arg->in.r.natts = arg->out.r.natts = 0;
1606         arg->in.r.atts = NULL;
1607         arg->out.r.atts = NULL;
1608 }
1609
1610 static void
1611 PLy_typeinfo_dealloc(PLyTypeInfo * arg)
1612 {
1613         if (arg->is_rowtype == 1)
1614         {
1615                 if (arg->in.r.atts)
1616                         PLy_free(arg->in.r.atts);
1617                 if (arg->out.r.atts)
1618                         PLy_free(arg->out.r.atts);
1619         }
1620 }
1621
1622 /* assumes that a bool is always returned as a 't' or 'f' */
1623 static PyObject *
1624 PLyBool_FromString(const char *src)
1625 {
1626         /*
1627          * We would like to use Py_RETURN_TRUE and Py_RETURN_FALSE here for
1628          * generating SQL from trigger functions, but those are only supported in
1629          * Python >= 2.3, and we support older versions.
1630          * http://docs.python.org/api/boolObjects.html
1631          */
1632         if (src[0] == 't')
1633                 return PyBool_FromLong(1);
1634         return PyBool_FromLong(0);
1635 }
1636
1637 static PyObject *
1638 PLyFloat_FromString(const char *src)
1639 {
1640         double          v;
1641         char       *eptr;
1642
1643         errno = 0;
1644         v = strtod(src, &eptr);
1645         if (*eptr != '\0' || errno)
1646                 return NULL;
1647         return PyFloat_FromDouble(v);
1648 }
1649
1650 static PyObject *
1651 PLyInt_FromString(const char *src)
1652 {
1653         long            v;
1654         char       *eptr;
1655
1656         errno = 0;
1657         v = strtol(src, &eptr, 0);
1658         if (*eptr != '\0' || errno)
1659                 return NULL;
1660         return PyInt_FromLong(v);
1661 }
1662
1663 static PyObject *
1664 PLyLong_FromString(const char *src)
1665 {
1666         return PyLong_FromString((char *) src, NULL, 0);
1667 }
1668
1669 static PyObject *
1670 PLyString_FromString(const char *src)
1671 {
1672         return PyString_FromString(src);
1673 }
1674
1675 static PyObject *
1676 PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
1677 {
1678         PyObject   *volatile dict;
1679         int                     i;
1680
1681         if (info->is_rowtype != 1)
1682                 elog(ERROR, "PLyTypeInfo structure describes a datum");
1683
1684         dict = PyDict_New();
1685         if (dict == NULL)
1686                 PLy_elog(ERROR, "could not create tuple dictionary");
1687
1688         PG_TRY();
1689         {
1690                 for (i = 0; i < info->in.r.natts; i++)
1691                 {
1692                         char       *key,
1693                                            *vsrc;
1694                         Datum           vattr;
1695                         bool            is_null;
1696                         PyObject   *value;
1697
1698                         if (desc->attrs[i]->attisdropped)
1699                                 continue;
1700
1701                         key = NameStr(desc->attrs[i]->attname);
1702                         vattr = heap_getattr(tuple, (i + 1), desc, &is_null);
1703
1704                         if (is_null || info->in.r.atts[i].func == NULL)
1705                                 PyDict_SetItemString(dict, key, Py_None);
1706                         else
1707                         {
1708                                 vsrc = OutputFunctionCall(&info->in.r.atts[i].typfunc,
1709                                                                                   vattr);
1710
1711                                 /*
1712                                  * no exceptions allowed
1713                                  */
1714                                 value = info->in.r.atts[i].func(vsrc);
1715                                 pfree(vsrc);
1716                                 PyDict_SetItemString(dict, key, value);
1717                                 Py_DECREF(value);
1718                         }
1719                 }
1720         }
1721         PG_CATCH();
1722         {
1723                 Py_DECREF(dict);
1724                 PG_RE_THROW();
1725         }
1726         PG_END_TRY();
1727
1728         return dict;
1729 }
1730
1731
1732 static HeapTuple
1733 PLyMapping_ToTuple(PLyTypeInfo * info, PyObject * mapping)
1734 {
1735         TupleDesc       desc;
1736         HeapTuple       tuple;
1737         Datum      *values;
1738         char       *nulls;
1739         volatile int i;
1740
1741         Assert(PyMapping_Check(mapping));
1742
1743         desc = lookup_rowtype_tupdesc(info->out.d.typoid, -1);
1744         if (info->is_rowtype == 2)
1745                 PLy_output_tuple_funcs(info, desc);
1746         Assert(info->is_rowtype == 1);
1747
1748         /* Build tuple */
1749         values = palloc(sizeof(Datum) * desc->natts);
1750         nulls = palloc(sizeof(char) * desc->natts);
1751         for (i = 0; i < desc->natts; ++i)
1752         {
1753                 char       *key;
1754                 PyObject   *volatile value,
1755                                    *volatile so;
1756
1757                 key = NameStr(desc->attrs[i]->attname);
1758                 value = so = NULL;
1759                 PG_TRY();
1760                 {
1761                         value = PyMapping_GetItemString(mapping, key);
1762                         if (value == Py_None)
1763                         {
1764                                 values[i] = (Datum) NULL;
1765                                 nulls[i] = 'n';
1766                         }
1767                         else if (value)
1768                         {
1769                                 char       *valuestr;
1770
1771                                 so = PyObject_Str(value);
1772                                 if (so == NULL)
1773                                         PLy_elog(ERROR, "cannot convert mapping type");
1774                                 valuestr = PyString_AsString(so);
1775
1776                                 values[i] = InputFunctionCall(&info->out.r.atts[i].typfunc
1777                                                                                           ,valuestr
1778                                                                                           ,info->out.r.atts[i].typioparam
1779                                                                                           ,-1);
1780                                 Py_DECREF(so);
1781                                 so = NULL;
1782                                 nulls[i] = ' ';
1783                         }
1784                         else
1785                                 ereport(ERROR,
1786                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
1787                                                  errmsg("no mapping found with key \"%s\"", key),
1788                                                  errhint("to return null in specific column, "
1789                                           "add value None to map with key named after column")));
1790
1791                         Py_XDECREF(value);
1792                         value = NULL;
1793                 }
1794                 PG_CATCH();
1795                 {
1796                         Py_XDECREF(so);
1797                         Py_XDECREF(value);
1798                         PG_RE_THROW();
1799                 }
1800                 PG_END_TRY();
1801         }
1802
1803         tuple = heap_formtuple(desc, values, nulls);
1804         ReleaseTupleDesc(desc);
1805         pfree(values);
1806         pfree(nulls);
1807
1808         return tuple;
1809 }
1810
1811
1812 static HeapTuple
1813 PLySequence_ToTuple(PLyTypeInfo * info, PyObject * sequence)
1814 {
1815         TupleDesc       desc;
1816         HeapTuple       tuple;
1817         Datum      *values;
1818         char       *nulls;
1819         volatile int i;
1820
1821         Assert(PySequence_Check(sequence));
1822
1823         /*
1824          * Check that sequence length is exactly same as PG tuple's. We actually
1825          * can ignore exceeding items or assume missing ones as null but to avoid
1826          * plpython developer's errors we are strict here
1827          */
1828         desc = lookup_rowtype_tupdesc(info->out.d.typoid, -1);
1829         if (PySequence_Length(sequence) != desc->natts)
1830                 ereport(ERROR,
1831                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1832                 errmsg("returned sequence's length must be same as tuple's length")));
1833
1834         if (info->is_rowtype == 2)
1835                 PLy_output_tuple_funcs(info, desc);
1836         Assert(info->is_rowtype == 1);
1837
1838         /* Build tuple */
1839         values = palloc(sizeof(Datum) * desc->natts);
1840         nulls = palloc(sizeof(char) * desc->natts);
1841         for (i = 0; i < desc->natts; ++i)
1842         {
1843                 PyObject   *volatile value,
1844                                    *volatile so;
1845
1846                 value = so = NULL;
1847                 PG_TRY();
1848                 {
1849                         value = PySequence_GetItem(sequence, i);
1850                         Assert(value);
1851                         if (value == Py_None)
1852                         {
1853                                 values[i] = (Datum) NULL;
1854                                 nulls[i] = 'n';
1855                         }
1856                         else if (value)
1857                         {
1858                                 char       *valuestr;
1859
1860                                 so = PyObject_Str(value);
1861                                 if (so == NULL)
1862                                         PLy_elog(ERROR, "cannot convert sequence type");
1863                                 valuestr = PyString_AsString(so);
1864                                 values[i] = InputFunctionCall(&info->out.r.atts[i].typfunc
1865                                                                                           ,valuestr
1866                                                                                           ,info->out.r.atts[i].typioparam
1867                                                                                           ,-1);
1868                                 Py_DECREF(so);
1869                                 so = NULL;
1870                                 nulls[i] = ' ';
1871                         }
1872
1873                         Py_XDECREF(value);
1874                         value = NULL;
1875                 }
1876                 PG_CATCH();
1877                 {
1878                         Py_XDECREF(so);
1879                         Py_XDECREF(value);
1880                         PG_RE_THROW();
1881                 }
1882                 PG_END_TRY();
1883         }
1884
1885         tuple = heap_formtuple(desc, values, nulls);
1886         ReleaseTupleDesc(desc);
1887         pfree(values);
1888         pfree(nulls);
1889
1890         return tuple;
1891 }
1892
1893
1894 static HeapTuple
1895 PLyObject_ToTuple(PLyTypeInfo * info, PyObject * object)
1896 {
1897         TupleDesc       desc;
1898         HeapTuple       tuple;
1899         Datum      *values;
1900         char       *nulls;
1901         volatile int i;
1902
1903         desc = lookup_rowtype_tupdesc(info->out.d.typoid, -1);
1904         if (info->is_rowtype == 2)
1905                 PLy_output_tuple_funcs(info, desc);
1906         Assert(info->is_rowtype == 1);
1907
1908         /* Build tuple */
1909         values = palloc(sizeof(Datum) * desc->natts);
1910         nulls = palloc(sizeof(char) * desc->natts);
1911         for (i = 0; i < desc->natts; ++i)
1912         {
1913                 char       *key;
1914                 PyObject   *volatile value,
1915                                    *volatile so;
1916
1917                 key = NameStr(desc->attrs[i]->attname);
1918                 value = so = NULL;
1919                 PG_TRY();
1920                 {
1921                         value = PyObject_GetAttrString(object, key);
1922                         if (value == Py_None)
1923                         {
1924                                 values[i] = (Datum) NULL;
1925                                 nulls[i] = 'n';
1926                         }
1927                         else if (value)
1928                         {
1929                                 char       *valuestr;
1930
1931                                 so = PyObject_Str(value);
1932                                 if (so == NULL)
1933                                         PLy_elog(ERROR, "cannot convert object type");
1934                                 valuestr = PyString_AsString(so);
1935                                 values[i] = InputFunctionCall(&info->out.r.atts[i].typfunc
1936                                                                                           ,valuestr
1937                                                                                           ,info->out.r.atts[i].typioparam
1938                                                                                           ,-1);
1939                                 Py_DECREF(so);
1940                                 so = NULL;
1941                                 nulls[i] = ' ';
1942                         }
1943                         else
1944                                 ereport(ERROR,
1945                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
1946                                                  errmsg("no attribute named \"%s\"", key),
1947                                                  errhint("to return null in specific column, "
1948                                                            "let returned object to have attribute named "
1949                                                                  "after column with value None")));
1950
1951                         Py_XDECREF(value);
1952                         value = NULL;
1953                 }
1954                 PG_CATCH();
1955                 {
1956                         Py_XDECREF(so);
1957                         Py_XDECREF(value);
1958                         PG_RE_THROW();
1959                 }
1960                 PG_END_TRY();
1961         }
1962
1963         tuple = heap_formtuple(desc, values, nulls);
1964         ReleaseTupleDesc(desc);
1965         pfree(values);
1966         pfree(nulls);
1967
1968         return tuple;
1969 }
1970
1971
1972 /* initialization, some python variables function declared here */
1973
1974 /* interface to postgresql elog */
1975 static PyObject *PLy_debug(PyObject *, PyObject *);
1976 static PyObject *PLy_log(PyObject *, PyObject *);
1977 static PyObject *PLy_info(PyObject *, PyObject *);
1978 static PyObject *PLy_notice(PyObject *, PyObject *);
1979 static PyObject *PLy_warning(PyObject *, PyObject *);
1980 static PyObject *PLy_error(PyObject *, PyObject *);
1981 static PyObject *PLy_fatal(PyObject *, PyObject *);
1982
1983 /* PLyPlanObject, PLyResultObject and SPI interface */
1984 #define is_PLyPlanObject(x) ((x)->ob_type == &PLy_PlanType)
1985 static PyObject *PLy_plan_new(void);
1986 static void PLy_plan_dealloc(PyObject *);
1987 static PyObject *PLy_plan_getattr(PyObject *, char *);
1988 static PyObject *PLy_plan_status(PyObject *, PyObject *);
1989
1990 static PyObject *PLy_result_new(void);
1991 static void PLy_result_dealloc(PyObject *);
1992 static PyObject *PLy_result_getattr(PyObject *, char *);
1993 static PyObject *PLy_result_nrows(PyObject *, PyObject *);
1994 static PyObject *PLy_result_status(PyObject *, PyObject *);
1995 static Py_ssize_t PLy_result_length(PyObject *);
1996 static PyObject *PLy_result_item(PyObject *, Py_ssize_t);
1997 static PyObject *PLy_result_slice(PyObject *, Py_ssize_t, Py_ssize_t);
1998 static int      PLy_result_ass_item(PyObject *, Py_ssize_t, PyObject *);
1999 static int      PLy_result_ass_slice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
2000
2001
2002 static PyObject *PLy_spi_prepare(PyObject *, PyObject *);
2003 static PyObject *PLy_spi_execute(PyObject *, PyObject *);
2004 static PyObject *PLy_spi_execute_query(char *query, long limit);
2005 static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, long);
2006 static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
2007
2008
2009 static PyTypeObject PLy_PlanType = {
2010         PyObject_HEAD_INIT(NULL)
2011         0,                                                      /* ob_size */
2012         "PLyPlan",                                      /* tp_name */
2013         sizeof(PLyPlanObject),          /* tp_size */
2014         0,                                                      /* tp_itemsize */
2015
2016         /*
2017          * methods
2018          */
2019         PLy_plan_dealloc,                       /* tp_dealloc */
2020         0,                                                      /* tp_print */
2021         PLy_plan_getattr,                       /* tp_getattr */
2022         0,                                                      /* tp_setattr */
2023         0,                                                      /* tp_compare */
2024         0,                                                      /* tp_repr */
2025         0,                                                      /* tp_as_number */
2026         0,                                                      /* tp_as_sequence */
2027         0,                                                      /* tp_as_mapping */
2028         0,                                                      /* tp_hash */
2029         0,                                                      /* tp_call */
2030         0,                                                      /* tp_str */
2031         0,                                                      /* tp_getattro */
2032         0,                                                      /* tp_setattro */
2033         0,                                                      /* tp_as_buffer */
2034         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
2035         PLy_plan_doc,                           /* tp_doc */
2036 };
2037
2038 static PyMethodDef PLy_plan_methods[] = {
2039         {"status", PLy_plan_status, METH_VARARGS, NULL},
2040         {NULL, NULL, 0, NULL}
2041 };
2042
2043 static PySequenceMethods PLy_result_as_sequence = {
2044         PLy_result_length,                      /* sq_length */
2045         NULL,                                           /* sq_concat */
2046         NULL,                                           /* sq_repeat */
2047         PLy_result_item,                        /* sq_item */
2048         PLy_result_slice,                       /* sq_slice */
2049         PLy_result_ass_item,            /* sq_ass_item */
2050         PLy_result_ass_slice,           /* sq_ass_slice */
2051 };
2052
2053 static PyTypeObject PLy_ResultType = {
2054         PyObject_HEAD_INIT(NULL)
2055         0,                                                      /* ob_size */
2056         "PLyResult",                            /* tp_name */
2057         sizeof(PLyResultObject),        /* tp_size */
2058         0,                                                      /* tp_itemsize */
2059
2060         /*
2061          * methods
2062          */
2063         PLy_result_dealloc,                     /* tp_dealloc */
2064         0,                                                      /* tp_print */
2065         PLy_result_getattr,                     /* tp_getattr */
2066         0,                                                      /* tp_setattr */
2067         0,                                                      /* tp_compare */
2068         0,                                                      /* tp_repr */
2069         0,                                                      /* tp_as_number */
2070         &PLy_result_as_sequence,        /* tp_as_sequence */
2071         0,                                                      /* tp_as_mapping */
2072         0,                                                      /* tp_hash */
2073         0,                                                      /* tp_call */
2074         0,                                                      /* tp_str */
2075         0,                                                      /* tp_getattro */
2076         0,                                                      /* tp_setattro */
2077         0,                                                      /* tp_as_buffer */
2078         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
2079         PLy_result_doc,                         /* tp_doc */
2080 };
2081
2082 static PyMethodDef PLy_result_methods[] = {
2083         {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
2084         {"status", PLy_result_status, METH_VARARGS, NULL},
2085         {NULL, NULL, 0, NULL}
2086 };
2087
2088 static PyMethodDef PLy_methods[] = {
2089         /*
2090          * logging methods
2091          */
2092         {"debug", PLy_debug, METH_VARARGS, NULL},
2093         {"log", PLy_log, METH_VARARGS, NULL},
2094         {"info", PLy_info, METH_VARARGS, NULL},
2095         {"notice", PLy_notice, METH_VARARGS, NULL},
2096         {"warning", PLy_warning, METH_VARARGS, NULL},
2097         {"error", PLy_error, METH_VARARGS, NULL},
2098         {"fatal", PLy_fatal, METH_VARARGS, NULL},
2099
2100         /*
2101          * create a stored plan
2102          */
2103         {"prepare", PLy_spi_prepare, METH_VARARGS, NULL},
2104
2105         /*
2106          * execute a plan or query
2107          */
2108         {"execute", PLy_spi_execute, METH_VARARGS, NULL},
2109
2110         {NULL, NULL, 0, NULL}
2111 };
2112
2113
2114 /* plan object methods */
2115 static PyObject *
2116 PLy_plan_new(void)
2117 {
2118         PLyPlanObject *ob;
2119
2120         if ((ob = PyObject_NEW(PLyPlanObject, &PLy_PlanType)) == NULL)
2121                 return NULL;
2122
2123         ob->plan = NULL;
2124         ob->nargs = 0;
2125         ob->types = NULL;
2126         ob->args = NULL;
2127
2128         return (PyObject *) ob;
2129 }
2130
2131
2132 static void
2133 PLy_plan_dealloc(PyObject * arg)
2134 {
2135         PLyPlanObject *ob = (PLyPlanObject *) arg;
2136
2137         if (ob->plan)
2138                 SPI_freeplan(ob->plan);
2139         if (ob->types)
2140                 PLy_free(ob->types);
2141         if (ob->args)
2142         {
2143                 int                     i;
2144
2145                 for (i = 0; i < ob->nargs; i++)
2146                         PLy_typeinfo_dealloc(&ob->args[i]);
2147                 PLy_free(ob->args);
2148         }
2149
2150         arg->ob_type->tp_free(arg);
2151 }
2152
2153
2154 static PyObject *
2155 PLy_plan_getattr(PyObject * self, char *name)
2156 {
2157         return Py_FindMethod(PLy_plan_methods, self, name);
2158 }
2159
2160 static PyObject *
2161 PLy_plan_status(PyObject * self, PyObject * args)
2162 {
2163         if (PyArg_ParseTuple(args, ""))
2164         {
2165                 Py_INCREF(Py_True);
2166                 return Py_True;
2167                 /* return PyInt_FromLong(self->status); */
2168         }
2169         PyErr_SetString(PLy_exc_error, "plan.status() takes no arguments");
2170         return NULL;
2171 }
2172
2173
2174
2175 /* result object methods */
2176
2177 static PyObject *
2178 PLy_result_new(void)
2179 {
2180         PLyResultObject *ob;
2181
2182         if ((ob = PyObject_NEW(PLyResultObject, &PLy_ResultType)) == NULL)
2183                 return NULL;
2184
2185         /* ob->tuples = NULL; */
2186
2187         Py_INCREF(Py_None);
2188         ob->status = Py_None;
2189         ob->nrows = PyInt_FromLong(-1);
2190         ob->rows = PyList_New(0);
2191
2192         return (PyObject *) ob;
2193 }
2194
2195 static void
2196 PLy_result_dealloc(PyObject * arg)
2197 {
2198         PLyResultObject *ob = (PLyResultObject *) arg;
2199
2200         Py_XDECREF(ob->nrows);
2201         Py_XDECREF(ob->rows);
2202         Py_XDECREF(ob->status);
2203
2204         arg->ob_type->tp_free(arg);
2205 }
2206
2207 static PyObject *
2208 PLy_result_getattr(PyObject * self, char *name)
2209 {
2210         return Py_FindMethod(PLy_result_methods, self, name);
2211 }
2212
2213 static PyObject *
2214 PLy_result_nrows(PyObject * self, PyObject * args)
2215 {
2216         PLyResultObject *ob = (PLyResultObject *) self;
2217
2218         Py_INCREF(ob->nrows);
2219         return ob->nrows;
2220 }
2221
2222 static PyObject *
2223 PLy_result_status(PyObject * self, PyObject * args)
2224 {
2225         PLyResultObject *ob = (PLyResultObject *) self;
2226
2227         Py_INCREF(ob->status);
2228         return ob->status;
2229 }
2230
2231 static Py_ssize_t
2232 PLy_result_length(PyObject * arg)
2233 {
2234         PLyResultObject *ob = (PLyResultObject *) arg;
2235
2236         return PyList_Size(ob->rows);
2237 }
2238
2239 static PyObject *
2240 PLy_result_item(PyObject * arg, Py_ssize_t idx)
2241 {
2242         PyObject   *rv;
2243         PLyResultObject *ob = (PLyResultObject *) arg;
2244
2245         rv = PyList_GetItem(ob->rows, idx);
2246         if (rv != NULL)
2247                 Py_INCREF(rv);
2248         return rv;
2249 }
2250
2251 static int
2252 PLy_result_ass_item(PyObject * arg, Py_ssize_t idx, PyObject * item)
2253 {
2254         int                     rv;
2255         PLyResultObject *ob = (PLyResultObject *) arg;
2256
2257         Py_INCREF(item);
2258         rv = PyList_SetItem(ob->rows, idx, item);
2259         return rv;
2260 }
2261
2262 static PyObject *
2263 PLy_result_slice(PyObject * arg, Py_ssize_t lidx, Py_ssize_t hidx)
2264 {
2265         PyObject   *rv;
2266         PLyResultObject *ob = (PLyResultObject *) arg;
2267
2268         rv = PyList_GetSlice(ob->rows, lidx, hidx);
2269         if (rv == NULL)
2270                 return NULL;
2271         Py_INCREF(rv);
2272         return rv;
2273 }
2274
2275 static int
2276 PLy_result_ass_slice(PyObject * arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject * slice)
2277 {
2278         int                     rv;
2279         PLyResultObject *ob = (PLyResultObject *) arg;
2280
2281         rv = PyList_SetSlice(ob->rows, lidx, hidx, slice);
2282         return rv;
2283 }
2284
2285 /* SPI interface */
2286 static PyObject *
2287 PLy_spi_prepare(PyObject * self, PyObject * args)
2288 {
2289         PLyPlanObject *plan;
2290         PyObject   *list = NULL;
2291         PyObject   *volatile optr = NULL;
2292         char       *query;
2293         void       *tmpplan;
2294         MemoryContext oldcontext;
2295
2296         /* Can't execute more if we have an unhandled error */
2297         if (PLy_error_in_progress)
2298         {
2299                 PyErr_SetString(PLy_exc_error, "Transaction aborted.");
2300                 return NULL;
2301         }
2302
2303         if (!PyArg_ParseTuple(args, "s|O", &query, &list))
2304         {
2305                 PyErr_SetString(PLy_exc_spi_error,
2306                                                 "Invalid arguments for plpy.prepare()");
2307                 return NULL;
2308         }
2309
2310         if (list && (!PySequence_Check(list)))
2311         {
2312                 PyErr_SetString(PLy_exc_spi_error,
2313                                          "Second argument in plpy.prepare() must be a sequence");
2314                 return NULL;
2315         }
2316
2317         if ((plan = (PLyPlanObject *) PLy_plan_new()) == NULL)
2318                 return NULL;
2319
2320         oldcontext = CurrentMemoryContext;
2321         PG_TRY();
2322         {
2323                 if (list != NULL)
2324                 {
2325                         int                     nargs,
2326                                                 i;
2327
2328                         nargs = PySequence_Length(list);
2329                         if (nargs > 0)
2330                         {
2331                                 plan->nargs = nargs;
2332                                 plan->types = PLy_malloc(sizeof(Oid) * nargs);
2333                                 plan->values = PLy_malloc(sizeof(Datum) * nargs);
2334                                 plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs);
2335
2336                                 /*
2337                                  * the other loop might throw an exception, if PLyTypeInfo
2338                                  * member isn't properly initialized the Py_DECREF(plan) will
2339                                  * go boom
2340                                  */
2341                                 for (i = 0; i < nargs; i++)
2342                                 {
2343                                         PLy_typeinfo_init(&plan->args[i]);
2344                                         plan->values[i] = PointerGetDatum(NULL);
2345                                 }
2346
2347                                 for (i = 0; i < nargs; i++)
2348                                 {
2349                                         char       *sptr;
2350                                         HeapTuple       typeTup;
2351                                         Oid                     typeId;
2352                                         int32           typmod;
2353                                         Form_pg_type typeStruct;
2354
2355                                         optr = PySequence_GetItem(list, i);
2356                                         if (!PyString_Check(optr))
2357                                                 elog(ERROR, "Type names must be strings.");
2358                                         sptr = PyString_AsString(optr);
2359
2360                                         /********************************************************
2361                                          * Resolve argument type names and then look them up by
2362                                          * oid in the system cache, and remember the required
2363                                          *information for input conversion.
2364                                          ********************************************************/
2365
2366                                         parseTypeString(sptr, &typeId, &typmod);
2367
2368                                         typeTup = SearchSysCache(TYPEOID,
2369                                                                                          ObjectIdGetDatum(typeId),
2370                                                                                          0, 0, 0);
2371                                         if (!HeapTupleIsValid(typeTup))
2372                                                 elog(ERROR, "cache lookup failed for type %u", typeId);
2373
2374                                         Py_DECREF(optr);
2375                                         optr = NULL;    /* this is important */
2376
2377                                         plan->types[i] = typeId;
2378                                         typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2379                                         if (typeStruct->typtype != TYPTYPE_COMPOSITE)
2380                                                 PLy_output_datum_func(&plan->args[i], typeTup);
2381                                         else
2382                                                 elog(ERROR, "tuples not handled in plpy.prepare, yet.");
2383                                         ReleaseSysCache(typeTup);
2384                                 }
2385                         }
2386                 }
2387
2388                 plan->plan = SPI_prepare(query, plan->nargs, plan->types);
2389                 if (plan->plan == NULL)
2390                         elog(ERROR, "SPI_prepare failed: %s",
2391                                  SPI_result_code_string(SPI_result));
2392
2393                 /* transfer plan from procCxt to topCxt */
2394                 tmpplan = plan->plan;
2395                 plan->plan = SPI_saveplan(tmpplan);
2396                 SPI_freeplan(tmpplan);
2397                 if (plan->plan == NULL)
2398                         elog(ERROR, "SPI_saveplan failed: %s",
2399                                  SPI_result_code_string(SPI_result));
2400         }
2401         PG_CATCH();
2402         {
2403                 MemoryContextSwitchTo(oldcontext);
2404                 PLy_error_in_progress = CopyErrorData();
2405                 FlushErrorState();
2406                 Py_DECREF(plan);
2407                 Py_XDECREF(optr);
2408                 if (!PyErr_Occurred())
2409                         PyErr_SetString(PLy_exc_spi_error,
2410                                                         "Unknown error in PLy_spi_prepare");
2411                 /* XXX this oughta be replaced with errcontext mechanism */
2412                 PLy_elog(WARNING, "in function %s:",
2413                                  PLy_procedure_name(PLy_curr_procedure));
2414                 return NULL;
2415         }
2416         PG_END_TRY();
2417
2418         return (PyObject *) plan;
2419 }
2420
2421 /* execute(query="select * from foo", limit=5)
2422  * execute(plan=plan, values=(foo, bar), limit=5)
2423  */
2424 static PyObject *
2425 PLy_spi_execute(PyObject * self, PyObject * args)
2426 {
2427         char       *query;
2428         PyObject   *plan;
2429         PyObject   *list = NULL;
2430         long            limit = 0;
2431
2432         /* Can't execute more if we have an unhandled error */
2433         if (PLy_error_in_progress)
2434         {
2435                 PyErr_SetString(PLy_exc_error, "Transaction aborted.");
2436                 return NULL;
2437         }
2438
2439         if (PyArg_ParseTuple(args, "s|l", &query, &limit))
2440                 return PLy_spi_execute_query(query, limit);
2441
2442         PyErr_Clear();
2443
2444         if (PyArg_ParseTuple(args, "O|Ol", &plan, &list, &limit) &&
2445                 is_PLyPlanObject(plan))
2446                 return PLy_spi_execute_plan(plan, list, limit);
2447
2448         PyErr_SetString(PLy_exc_error, "Expected a query or plan.");
2449         return NULL;
2450 }
2451
2452 static PyObject *
2453 PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
2454 {
2455         volatile int nargs;
2456         int                     i,
2457                                 rv;
2458         PLyPlanObject *plan;
2459         MemoryContext oldcontext;
2460
2461         if (list != NULL)
2462         {
2463                 if (!PySequence_Check(list) || PyString_Check(list))
2464                 {
2465                         char       *msg = "plpy.execute() takes a sequence as its second argument";
2466
2467                         PyErr_SetString(PLy_exc_spi_error, msg);
2468                         return NULL;
2469                 }
2470                 nargs = PySequence_Length(list);
2471         }
2472         else
2473                 nargs = 0;
2474
2475         plan = (PLyPlanObject *) ob;
2476
2477         if (nargs != plan->nargs)
2478         {
2479                 char       *sv;
2480                 PyObject   *so = PyObject_Str(list);
2481
2482                 if (!so)
2483                         PLy_elog(ERROR, "function \"%s\" could not execute plan",
2484                                          PLy_procedure_name(PLy_curr_procedure));
2485                 sv = PyString_AsString(so);
2486                 PLy_exception_set(PLy_exc_spi_error,
2487                                                   "Expected sequence of %d arguments, got %d. %s",
2488                                                   plan->nargs, nargs, sv);
2489                 Py_DECREF(so);
2490
2491                 return NULL;
2492         }
2493
2494         oldcontext = CurrentMemoryContext;
2495         PG_TRY();
2496         {
2497                 char       *nulls = palloc(nargs * sizeof(char));
2498                 volatile int j;
2499
2500                 for (j = 0; j < nargs; j++)
2501                 {
2502                         PyObject   *elem,
2503                                            *so;
2504
2505                         elem = PySequence_GetItem(list, j);
2506                         if (elem != Py_None)
2507                         {
2508                                 so = PyObject_Str(elem);
2509                                 if (!so)
2510                                         PLy_elog(ERROR, "function \"%s\" could not execute plan",
2511                                                          PLy_procedure_name(PLy_curr_procedure));
2512                                 Py_DECREF(elem);
2513
2514                                 PG_TRY();
2515                                 {
2516                                         char       *sv = PyString_AsString(so);
2517
2518                                         plan->values[j] =
2519                                                 InputFunctionCall(&(plan->args[j].out.d.typfunc),
2520                                                                                   sv,
2521                                                                                   plan->args[j].out.d.typioparam,
2522                                                                                   -1);
2523                                 }
2524                                 PG_CATCH();
2525                                 {
2526                                         Py_DECREF(so);
2527                                         PG_RE_THROW();
2528                                 }
2529                                 PG_END_TRY();
2530
2531                                 Py_DECREF(so);
2532                                 nulls[j] = ' ';
2533                         }
2534                         else
2535                         {
2536                                 Py_DECREF(elem);
2537                                 plan->values[j] =
2538                                         InputFunctionCall(&(plan->args[j].out.d.typfunc),
2539                                                                           NULL,
2540                                                                           plan->args[j].out.d.typioparam,
2541                                                                           -1);
2542                                 nulls[j] = 'n';
2543                         }
2544                 }
2545
2546                 rv = SPI_execute_plan(plan->plan, plan->values, nulls,
2547                                                           PLy_curr_procedure->fn_readonly, limit);
2548
2549                 pfree(nulls);
2550         }
2551         PG_CATCH();
2552         {
2553                 int                     k;
2554
2555                 MemoryContextSwitchTo(oldcontext);
2556                 PLy_error_in_progress = CopyErrorData();
2557                 FlushErrorState();
2558
2559                 /*
2560                  * cleanup plan->values array
2561                  */
2562                 for (k = 0; k < nargs; k++)
2563                 {
2564                         if (!plan->args[k].out.d.typbyval &&
2565                                 (plan->values[k] != PointerGetDatum(NULL)))
2566                         {
2567                                 pfree(DatumGetPointer(plan->values[k]));
2568                                 plan->values[k] = PointerGetDatum(NULL);
2569                         }
2570                 }
2571
2572                 if (!PyErr_Occurred())
2573                         PyErr_SetString(PLy_exc_error,
2574                                                         "Unknown error in PLy_spi_execute_plan");
2575                 /* XXX this oughta be replaced with errcontext mechanism */
2576                 PLy_elog(WARNING, "in function %s:",
2577                                  PLy_procedure_name(PLy_curr_procedure));
2578                 return NULL;
2579         }
2580         PG_END_TRY();
2581
2582         for (i = 0; i < nargs; i++)
2583         {
2584                 if (!plan->args[i].out.d.typbyval &&
2585                         (plan->values[i] != PointerGetDatum(NULL)))
2586                 {
2587                         pfree(DatumGetPointer(plan->values[i]));
2588                         plan->values[i] = PointerGetDatum(NULL);
2589                 }
2590         }
2591
2592         if (rv < 0)
2593         {
2594                 PLy_exception_set(PLy_exc_spi_error,
2595                                                   "SPI_execute_plan failed: %s",
2596                                                   SPI_result_code_string(rv));
2597                 return NULL;
2598         }
2599
2600         return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);
2601 }
2602
2603 static PyObject *
2604 PLy_spi_execute_query(char *query, long limit)
2605 {
2606         int                     rv;
2607         MemoryContext oldcontext;
2608
2609         oldcontext = CurrentMemoryContext;
2610         PG_TRY();
2611         {
2612                 rv = SPI_execute(query, PLy_curr_procedure->fn_readonly, limit);
2613         }
2614         PG_CATCH();
2615         {
2616                 MemoryContextSwitchTo(oldcontext);
2617                 PLy_error_in_progress = CopyErrorData();
2618                 FlushErrorState();
2619                 if (!PyErr_Occurred())
2620                         PyErr_SetString(PLy_exc_spi_error,
2621                                                         "Unknown error in PLy_spi_execute_query");
2622                 /* XXX this oughta be replaced with errcontext mechanism */
2623                 PLy_elog(WARNING, "in function %s:",
2624                                  PLy_procedure_name(PLy_curr_procedure));
2625                 return NULL;
2626         }
2627         PG_END_TRY();
2628
2629         if (rv < 0)
2630         {
2631                 PLy_exception_set(PLy_exc_spi_error,
2632                                                   "SPI_execute failed: %s",
2633                                                   SPI_result_code_string(rv));
2634                 return NULL;
2635         }
2636
2637         return PLy_spi_execute_fetch_result(SPI_tuptable, SPI_processed, rv);
2638 }
2639
2640 static PyObject *
2641 PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
2642 {
2643         PLyResultObject *result;
2644         MemoryContext oldcontext;
2645
2646         result = (PLyResultObject *) PLy_result_new();
2647         Py_DECREF(result->status);
2648         result->status = PyInt_FromLong(status);
2649
2650         if (status > 0 && tuptable == NULL)
2651         {
2652                 Py_DECREF(result->nrows);
2653                 result->nrows = PyInt_FromLong(rows);
2654         }
2655         else if (status > 0 && tuptable != NULL)
2656         {
2657                 PLyTypeInfo args;
2658                 int                     i;
2659
2660                 Py_DECREF(result->nrows);
2661                 result->nrows = PyInt_FromLong(rows);
2662                 PLy_typeinfo_init(&args);
2663
2664                 oldcontext = CurrentMemoryContext;
2665                 PG_TRY();
2666                 {
2667                         if (rows)
2668                         {
2669                                 Py_DECREF(result->rows);
2670                                 result->rows = PyList_New(rows);
2671
2672                                 PLy_input_tuple_funcs(&args, tuptable->tupdesc);
2673                                 for (i = 0; i < rows; i++)
2674                                 {
2675                                         PyObject   *row = PLyDict_FromTuple(&args, tuptable->vals[i],
2676                                                                                                                 tuptable->tupdesc);
2677
2678                                         PyList_SetItem(result->rows, i, row);
2679                                 }
2680                                 PLy_typeinfo_dealloc(&args);
2681
2682                                 SPI_freetuptable(tuptable);
2683                         }
2684                 }
2685                 PG_CATCH();
2686                 {
2687                         MemoryContextSwitchTo(oldcontext);
2688                         PLy_error_in_progress = CopyErrorData();
2689                         FlushErrorState();
2690                         if (!PyErr_Occurred())
2691                                 PyErr_SetString(PLy_exc_error,
2692                                                         "Unknown error in PLy_spi_execute_fetch_result");
2693                         Py_DECREF(result);
2694                         PLy_typeinfo_dealloc(&args);
2695                         return NULL;
2696                 }
2697                 PG_END_TRY();
2698         }
2699
2700         return (PyObject *) result;
2701 }
2702
2703
2704 /*
2705  * language handler and interpreter initialization
2706  */
2707
2708 /*
2709  * _PG_init()                   - library load-time initialization
2710  *
2711  * DO NOT make this static nor change its name!
2712  */
2713 void
2714 _PG_init(void)
2715 {
2716         /* Be sure we do initialization only once (should be redundant now) */
2717         static bool inited = false;
2718
2719         if (inited)
2720                 return;
2721
2722         Py_Initialize();
2723         PLy_init_interp();
2724         PLy_init_plpy();
2725         if (PyErr_Occurred())
2726                 PLy_elog(FATAL, "untrapped error in initialization");
2727         PLy_procedure_cache = PyDict_New();
2728         if (PLy_procedure_cache == NULL)
2729                 PLy_elog(ERROR, "could not create procedure cache");
2730
2731         inited = true;
2732 }
2733
2734 static void
2735 PLy_init_interp(void)
2736 {
2737         PyObject   *mainmod;
2738
2739         mainmod = PyImport_AddModule("__main__");
2740         if (mainmod == NULL || PyErr_Occurred())
2741                 PLy_elog(ERROR, "could not import \"__main__\" module.");
2742         Py_INCREF(mainmod);
2743         PLy_interp_globals = PyModule_GetDict(mainmod);
2744         PLy_interp_safe_globals = PyDict_New();
2745         PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
2746         Py_DECREF(mainmod);
2747         if (PLy_interp_globals == NULL || PyErr_Occurred())
2748                 PLy_elog(ERROR, "could not initialize globals");
2749 }
2750
2751 static void
2752 PLy_init_plpy(void)
2753 {
2754         PyObject   *main_mod,
2755                            *main_dict,
2756                            *plpy_mod;
2757         PyObject   *plpy,
2758                            *plpy_dict;
2759
2760         /*
2761          * initialize plpy module
2762          */
2763         if (PyType_Ready(&PLy_PlanType) < 0)
2764                 elog(ERROR, "could not init PLy_PlanType");
2765         if (PyType_Ready(&PLy_ResultType) < 0)
2766                 elog(ERROR, "could not init PLy_ResultType");
2767
2768         plpy = Py_InitModule("plpy", PLy_methods);
2769         plpy_dict = PyModule_GetDict(plpy);
2770
2771         /* PyDict_SetItemString(plpy, "PlanType", (PyObject *) &PLy_PlanType); */
2772
2773         PLy_exc_error = PyErr_NewException("plpy.Error", NULL, NULL);
2774         PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);
2775         PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);
2776         PyDict_SetItemString(plpy_dict, "Error", PLy_exc_error);
2777         PyDict_SetItemString(plpy_dict, "Fatal", PLy_exc_fatal);
2778         PyDict_SetItemString(plpy_dict, "SPIError", PLy_exc_spi_error);
2779
2780         /*
2781          * initialize main module, and add plpy
2782          */
2783         main_mod = PyImport_AddModule("__main__");
2784         main_dict = PyModule_GetDict(main_mod);
2785         plpy_mod = PyImport_AddModule("plpy");
2786         PyDict_SetItemString(main_dict, "plpy", plpy_mod);
2787         if (PyErr_Occurred())
2788                 elog(ERROR, "could not init plpy");
2789 }
2790
2791 /* the python interface to the elog function
2792  * don't confuse these with PLy_elog
2793  */
2794 static PyObject *PLy_output(volatile int, PyObject *, PyObject *);
2795
2796 static PyObject *
2797 PLy_debug(PyObject * self, PyObject * args)
2798 {
2799         return PLy_output(DEBUG2, self, args);
2800 }
2801
2802 static PyObject *
2803 PLy_log(PyObject * self, PyObject * args)
2804 {
2805         return PLy_output(LOG, self, args);
2806 }
2807
2808 static PyObject *
2809 PLy_info(PyObject * self, PyObject * args)
2810 {
2811         return PLy_output(INFO, self, args);
2812 }
2813
2814 static PyObject *
2815 PLy_notice(PyObject * self, PyObject * args)
2816 {
2817         return PLy_output(NOTICE, self, args);
2818 }
2819
2820 static PyObject *
2821 PLy_warning(PyObject * self, PyObject * args)
2822 {
2823         return PLy_output(WARNING, self, args);
2824 }
2825
2826 static PyObject *
2827 PLy_error(PyObject * self, PyObject * args)
2828 {
2829         return PLy_output(ERROR, self, args);
2830 }
2831
2832 static PyObject *
2833 PLy_fatal(PyObject * self, PyObject * args)
2834 {
2835         return PLy_output(FATAL, self, args);
2836 }
2837
2838
2839 static PyObject *
2840 PLy_output(volatile int level, PyObject * self, PyObject * args)
2841 {
2842         PyObject   *so;
2843         char       *volatile sv;
2844         MemoryContext oldcontext;
2845
2846         so = PyObject_Str(args);
2847         if (so == NULL || ((sv = PyString_AsString(so)) == NULL))
2848         {
2849                 level = ERROR;
2850                 sv = "could not parse error message in `plpy.elog'";
2851         }
2852
2853         oldcontext = CurrentMemoryContext;
2854         PG_TRY();
2855         {
2856                 elog(level, "%s", sv);
2857         }
2858         PG_CATCH();
2859         {
2860                 MemoryContextSwitchTo(oldcontext);
2861                 PLy_error_in_progress = CopyErrorData();
2862                 FlushErrorState();
2863                 Py_XDECREF(so);
2864
2865                 /*
2866                  * returning NULL here causes the python interpreter to bail. when
2867                  * control passes back to PLy_procedure_call, we check for PG
2868                  * exceptions and re-throw the error.
2869                  */
2870                 PyErr_SetString(PLy_exc_error, sv);
2871                 return NULL;
2872         }
2873         PG_END_TRY();
2874
2875         Py_XDECREF(so);
2876
2877         /*
2878          * return a legal object so the interpreter will continue on its merry way
2879          */
2880         Py_INCREF(Py_None);
2881         return Py_None;
2882 }
2883
2884
2885 /*
2886  * Get the name of the last procedure called by the backend (the
2887  * innermost, if a plpython procedure call calls the backend and the
2888  * backend calls another plpython procedure).
2889  *
2890  * NB: this returns the SQL name, not the internal Python procedure name
2891  */
2892 static char *
2893 PLy_procedure_name(PLyProcedure * proc)
2894 {
2895         if (proc == NULL)
2896                 return "<unknown procedure>";
2897         return proc->proname;
2898 }
2899
2900 /* output a python traceback/exception via the postgresql elog
2901  * function.  not pretty.
2902  */
2903 static void
2904 PLy_exception_set(PyObject * exc, const char *fmt,...)
2905 {
2906         char            buf[1024];
2907         va_list         ap;
2908
2909         va_start(ap, fmt);
2910         vsnprintf(buf, sizeof(buf), fmt, ap);
2911         va_end(ap);
2912
2913         PyErr_SetString(exc, buf);
2914 }
2915
2916 /* Emit a PG error or notice, together with any available info about the
2917  * current Python error.  This should be used to propagate Python errors
2918  * into PG.
2919  */
2920 static void
2921 PLy_elog(int elevel, const char *fmt,...)
2922 {
2923         char       *xmsg;
2924         int                     xlevel;
2925         StringInfoData emsg;
2926
2927         xmsg = PLy_traceback(&xlevel);
2928
2929         initStringInfo(&emsg);
2930         for (;;)
2931         {
2932                 va_list         ap;
2933                 bool            success;
2934
2935                 va_start(ap, fmt);
2936                 success = appendStringInfoVA(&emsg, fmt, ap);
2937                 va_end(ap);
2938                 if (success)
2939                         break;
2940                 enlargeStringInfo(&emsg, emsg.maxlen);
2941         }
2942
2943         PG_TRY();
2944         {
2945                 ereport(elevel,
2946                                 (errmsg("plpython: %s", emsg.data),
2947                                  (xmsg) ? errdetail("%s", xmsg) : 0));
2948         }
2949         PG_CATCH();
2950         {
2951                 pfree(emsg.data);
2952                 if (xmsg)
2953                         pfree(xmsg);
2954                 PG_RE_THROW();
2955         }
2956         PG_END_TRY();
2957
2958         pfree(emsg.data);
2959         if (xmsg)
2960                 pfree(xmsg);
2961 }
2962
2963 static char *
2964 PLy_traceback(int *xlevel)
2965 {
2966         PyObject   *e,
2967                            *v,
2968                            *tb;
2969         PyObject   *eob,
2970                            *vob = NULL;
2971         char       *vstr,
2972                            *estr;
2973         StringInfoData xstr;
2974
2975         /*
2976          * get the current exception
2977          */
2978         PyErr_Fetch(&e, &v, &tb);
2979
2980         /*
2981          * oops, no exception, return
2982          */
2983         if (e == NULL)
2984         {
2985                 *xlevel = WARNING;
2986                 return NULL;
2987         }
2988
2989         PyErr_NormalizeException(&e, &v, &tb);
2990         Py_XDECREF(tb);
2991
2992         eob = PyObject_Str(e);
2993         if (v && ((vob = PyObject_Str(v)) != NULL))
2994                 vstr = PyString_AsString(vob);
2995         else
2996                 vstr = "Unknown";
2997
2998         /*
2999          * I'm not sure what to do if eob is NULL here -- we can't call PLy_elog
3000          * because that function calls us, so we could end up with infinite
3001          * recursion.  I'm not even sure if eob could be NULL here -- would an
3002          * Assert() be more appropriate?
3003          */
3004         estr = eob ? PyString_AsString(eob) : "Unknown Exception";
3005         initStringInfo(&xstr);
3006         appendStringInfo(&xstr, "%s: %s", estr, vstr);
3007
3008         Py_DECREF(eob);
3009         Py_XDECREF(vob);
3010         Py_XDECREF(v);
3011
3012         /*
3013          * intuit an appropriate error level based on the exception type
3014          */
3015         if (PLy_exc_error && PyErr_GivenExceptionMatches(e, PLy_exc_error))
3016                 *xlevel = ERROR;
3017         else if (PLy_exc_fatal && PyErr_GivenExceptionMatches(e, PLy_exc_fatal))
3018                 *xlevel = FATAL;
3019         else
3020                 *xlevel = ERROR;
3021
3022         Py_DECREF(e);
3023         return xstr.data;
3024 }
3025
3026 /* python module code */
3027
3028 /* some dumb utility functions */
3029 static void *
3030 PLy_malloc(size_t bytes)
3031 {
3032         void       *ptr = malloc(bytes);
3033
3034         if (ptr == NULL)
3035                 ereport(FATAL,
3036                                 (errcode(ERRCODE_OUT_OF_MEMORY),
3037                                  errmsg("out of memory")));
3038         return ptr;
3039 }
3040
3041 static void *
3042 PLy_malloc0(size_t bytes)
3043 {
3044         void       *ptr = PLy_malloc(bytes);
3045
3046         MemSet(ptr, 0, bytes);
3047         return ptr;
3048 }
3049
3050 static char *
3051 PLy_strdup(const char *str)
3052 {
3053         char       *result;
3054         size_t          len;
3055
3056         len = strlen(str) + 1;
3057         result = PLy_malloc(len);
3058         memcpy(result, str, len);
3059
3060         return result;
3061 }
3062
3063 /* define this away */
3064 static void
3065 PLy_free(void *ptr)
3066 {
3067         free(ptr);
3068 }