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