2929 * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
3030 *
3131 * IDENTIFICATION
32- *$Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.33 2003/06/11 18:33:39 tgl Exp $
32+ *$Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.34 2003/06/25 01: 18:58 momjian Exp $
3333 *
3434 *********************************************************************
3535 */
6161#include "utils/syscache.h"
6262
6363#include <Python.h>
64+ #include <compile.h>
65+ #include <eval.h>
6466#include "plpython.h"
6567
6668/* convert Postgresql Datum or tuple into a PyObject.
@@ -135,8 +137,6 @@ typedef struct PLyProcedure
135137 * tuple type */
136138PLyTypeInfo args [FUNC_MAX_ARGS ];
137139int nargs ;
138- PyObject * interp ;/* restricted interpreter instance */
139- PyObject * reval ;/* interpreter return */
140140PyObject * code ;/* compiled procedure code */
141141PyObject * statics ;/* data saved across calls, local scope */
142142PyObject * globals ;/* data saved across calls, global score */
@@ -186,13 +186,8 @@ PG_FUNCTION_INFO_V1(plpython_call_handler);
186186 */
187187static void PLy_init_all (void );
188188static void PLy_init_interp (void );
189- static void PLy_init_safe_interp (void );
190189static void PLy_init_plpy (void );
191190
192- /* Helper functions used during initialization */
193- static int populate_methods (PyObject * klass ,PyMethodDef * methods );
194- static PyObject * build_tuple (char * string_list [],int len );
195-
196191/* error handler. collects the current Python exception, if any,
197192 * and appends it to the error and sends it to elog
198193 */
@@ -249,10 +244,6 @@ static void PLy_input_datum_func2(PLyDatumToOb *, Oid, Form_pg_type);
249244static void PLy_output_tuple_funcs (PLyTypeInfo * ,TupleDesc );
250245static void PLy_input_tuple_funcs (PLyTypeInfo * ,TupleDesc );
251246
252- /* RExec methods
253- */
254- static PyObject * PLy_r_open (PyObject * self ,PyObject * args );
255-
256247/* conversion functions
257248 */
258249static PyObject * PLyDict_FromTuple (PLyTypeInfo * ,HeapTuple ,TupleDesc );
@@ -280,58 +271,9 @@ static PLyProcedure *PLy_last_procedure = NULL;
280271static volatile int PLy_restart_in_progress = 0 ;
281272
282273static PyObject * PLy_interp_globals = NULL ;
283- static PyObject * PLy_interp_safe = NULL ;
284274static PyObject * PLy_interp_safe_globals = NULL ;
285- static PyObject * PLy_importable_modules = NULL ;
286- static PyObject * PLy_ok_posix_names = NULL ;
287- static PyObject * PLy_ok_sys_names = NULL ;
288275static PyObject * PLy_procedure_cache = NULL ;
289276
290- static char * PLy_importable_modules_list []= {
291- "array" ,
292- "bisect" ,
293- "binascii" ,
294- "calendar" ,
295- "cmath" ,
296- "codecs" ,
297- "errno" ,
298- "marshal" ,
299- "math" ,
300- "md5" ,
301- "mpz" ,
302- "operator" ,
303- "pcre" ,
304- "pickle" ,
305- "random" ,
306- "re" ,
307- "regex" ,
308- "sre" ,
309- "sha" ,
310- "string" ,
311- "StringIO" ,
312- "struct" ,
313- "time" ,
314- "whrandom" ,
315- "zlib"
316- };
317-
318- static char * PLy_ok_posix_names_list []= {
319- /* None for now */
320- };
321-
322- static char * PLy_ok_sys_names_list []= {
323- "byteeorder" ,
324- "copyright" ,
325- "getdefaultencoding" ,
326- "getrefcount" ,
327- "hexrevision" ,
328- "maxint" ,
329- "maxunicode" ,
330- "platform" ,
331- "version" ,
332- "version_info"
333- };
334-
335277/* Python exceptions
336278 */
337279static PyObject * PLy_exc_error = NULL ;
@@ -904,7 +846,7 @@ PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs)
904846current = PLy_last_procedure ;
905847PLy_last_procedure = proc ;
906848PyDict_SetItemString (proc -> globals ,kargs ,vargs );
907- rv = PyObject_CallFunction ( proc -> reval , "O" ,proc -> code );
849+ rv = PyEval_EvalCode ( ( PyCodeObject * ) proc -> code , proc -> globals ,proc -> globals );
908850PLy_last_procedure = current ;
909851
910852if ((rv == NULL )|| (PyErr_Occurred ()))
@@ -1084,7 +1026,7 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
10841026for (i = 0 ;i < FUNC_MAX_ARGS ;i ++ )
10851027PLy_typeinfo_init (& proc -> args [i ]);
10861028proc -> nargs = 0 ;
1087- proc -> code = proc -> interp = proc -> reval = proc -> statics = NULL ;
1029+ proc -> code = proc -> statics = NULL ;
10881030proc -> globals = proc -> me = NULL ;
10891031
10901032SAVE_EXC ();
@@ -1189,59 +1131,25 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
11891131void
11901132PLy_procedure_compile (PLyProcedure * proc ,const char * src )
11911133{
1192- PyObject * module ,
1193- * crv = NULL ;
1134+ PyObject * crv = NULL ;
11941135char * msrc ;
11951136
11961137enter ();
11971138
1198- /*
1199- * get an instance of rexec.RExec for the function
1200- */
1201- proc -> interp = PyObject_CallMethod (PLy_interp_safe ,"RExec" ,NULL );
1202- if ((proc -> interp == NULL )|| (PyErr_Occurred ()))
1203- PLy_elog (ERROR ,"Unable to create rexec.RExec instance" );
1204-
1205- proc -> reval = PyObject_GetAttrString (proc -> interp ,"r_eval" );
1206- if ((proc -> reval == NULL )|| (PyErr_Occurred ()))
1207- PLy_elog (ERROR ,"Unable to get method `r_eval' from rexec.RExec" );
1208-
1209- /*
1210- * add a __main__ module to the function's interpreter
1211- */
1212- module = PyObject_CallMethod (proc -> interp ,"add_module" ,"s" ,"__main__" );
1213- if ((module == NULL )|| (PyErr_Occurred ()))
1214- PLy_elog (ERROR ,"Unable to get module `__main__' from rexec.RExec" );
1215-
1216- /*
1217- * add plpy module to the interpreters main dictionary
1218- */
1219- proc -> globals = PyModule_GetDict (module );
1220- if ((proc -> globals == NULL )|| (PyErr_Occurred ()))
1221- PLy_elog (ERROR ,"Unable to get `__main__.__dict__' from rexec.RExec" );
1222-
1223- /*
1224- * why the hell won't r_import or r_exec('import plpy') work?
1225- */
1226- module = PyDict_GetItemString (PLy_interp_globals ,"plpy" );
1227- if ((module == NULL )|| (PyErr_Occurred ()))
1228- PLy_elog (ERROR ,"Unable to get `plpy'" );
1229- Py_INCREF (module );
1230- PyDict_SetItemString (proc -> globals ,"plpy" ,module );
1139+ proc -> globals = PyDict_Copy (PLy_interp_globals );
12311140
12321141/*
12331142 * SD is private preserved data between calls GD is global data shared
12341143 * by all functions
12351144 */
12361145proc -> statics = PyDict_New ();
12371146PyDict_SetItemString (proc -> globals ,"SD" ,proc -> statics );
1238- PyDict_SetItemString (proc -> globals ,"GD" ,PLy_interp_safe_globals );
12391147
12401148/*
12411149 * insert the function code into the interpreter
12421150 */
12431151msrc = PLy_procedure_munge_source (proc -> pyname ,src );
1244- crv = PyObject_CallMethod ( proc -> interp , "r_exec" , "s" , msrc );
1152+ crv = PyRun_String ( msrc , Py_file_input , proc -> globals , NULL );
12451153free (msrc );
12461154
12471155if ((crv != NULL )&& (!PyErr_Occurred ()))
@@ -1319,8 +1227,6 @@ PLy_procedure_delete(PLyProcedure * proc)
13191227enter ();
13201228
13211229Py_XDECREF (proc -> code );
1322- Py_XDECREF (proc -> interp );
1323- Py_XDECREF (proc -> reval );
13241230Py_XDECREF (proc -> statics );
13251231Py_XDECREF (proc -> globals );
13261232Py_XDECREF (proc -> me );
@@ -2418,7 +2324,6 @@ PLy_init_all(void)
24182324Py_Initialize ();
24192325PLy_init_interp ();
24202326PLy_init_plpy ();
2421- PLy_init_safe_interp ();
24222327if (PyErr_Occurred ())
24232328PLy_elog (FATAL ,"Untrapped error in initialization." );
24242329PLy_procedure_cache = PyDict_New ();
@@ -2442,6 +2347,8 @@ PLy_init_interp(void)
24422347PLy_elog (ERROR ,"Unable to import '__main__' module." );
24432348Py_INCREF (mainmod );
24442349PLy_interp_globals = PyModule_GetDict (mainmod );
2350+ PLy_interp_safe_globals = PyDict_New ();
2351+ PyDict_SetItemString (PLy_interp_globals ,"GD" ,PLy_interp_safe_globals );
24452352Py_DECREF (mainmod );
24462353if ((PLy_interp_globals == NULL )|| (PyErr_Occurred ()))
24472354PLy_elog (ERROR ,"Unable to initialize globals." );
@@ -2485,139 +2392,6 @@ PLy_init_plpy(void)
24852392elog (ERROR ,"Unable to init plpy." );
24862393}
24872394
2488- /*
2489- *New RExec methods
2490- */
2491-
2492- PyObject *
2493- PLy_r_open (PyObject * self ,PyObject * args )
2494- {
2495- PyErr_SetString (PyExc_IOError ,"can't open files in restricted mode" );
2496- return NULL ;
2497- }
2498-
2499-
2500- static PyMethodDef PLy_r_exec_methods []= {
2501- {"r_open" , (PyCFunction )PLy_r_open ,METH_VARARGS ,NULL },
2502- {NULL ,NULL ,0 ,NULL }
2503- };
2504-
2505- /*
2506- *Init new RExec
2507- */
2508-
2509- void
2510- PLy_init_safe_interp (void )
2511- {
2512- PyObject * rmod ,
2513- * rexec ,
2514- * rexec_dict ;
2515- char * rname = "rexec" ;
2516- int len ;
2517-
2518- enter ();
2519-
2520- rmod = PyImport_ImportModuleEx (rname ,PLy_interp_globals ,
2521- PLy_interp_globals ,Py_None );
2522- if ((rmod == NULL )|| (PyErr_Occurred ()))
2523- PLy_elog (ERROR ,"Unable to import %s." ,rname );
2524- PyDict_SetItemString (PLy_interp_globals ,rname ,rmod );
2525- PLy_interp_safe = rmod ;
2526-
2527- len = sizeof (PLy_importable_modules_list ) /sizeof (char * );
2528- PLy_importable_modules = build_tuple (PLy_importable_modules_list ,len );
2529-
2530- len = sizeof (PLy_ok_posix_names_list ) /sizeof (char * );
2531- PLy_ok_posix_names = build_tuple (PLy_ok_posix_names_list ,len );
2532-
2533- len = sizeof (PLy_ok_sys_names_list ) /sizeof (char * );
2534- PLy_ok_sys_names = build_tuple (PLy_ok_sys_names_list ,len );
2535-
2536- PLy_interp_safe_globals = PyDict_New ();
2537- if (PLy_interp_safe_globals == NULL )
2538- PLy_elog (ERROR ,"Unable to create shared global dictionary." );
2539-
2540- /*
2541- * get an rexec.RExec class
2542- */
2543- rexec = PyDict_GetItemString (PyModule_GetDict (rmod ),"RExec" );
2544-
2545- if (rexec == NULL || !PyClass_Check (rexec ))
2546- PLy_elog (ERROR ,"Unable to get RExec object." );
2547-
2548-
2549- rexec_dict = ((PyClassObject * )rexec )-> cl_dict ;
2550-
2551- /*
2552- * tweak the list of permitted modules, posix and sys functions
2553- */
2554- PyDict_SetItemString (rexec_dict ,"ok_builtin_modules" ,PLy_importable_modules );
2555- PyDict_SetItemString (rexec_dict ,"ok_posix_names" ,PLy_ok_posix_names );
2556- PyDict_SetItemString (rexec_dict ,"ok_sys_names" ,PLy_ok_sys_names );
2557-
2558- /*
2559- * change the r_open behavior
2560- */
2561- if (populate_methods (rexec ,PLy_r_exec_methods ))
2562- PLy_elog (ERROR ,"Failed to update RExec methods." );
2563- }
2564-
2565- /* Helper function to build tuples from string lists */
2566- static
2567- PyObject *
2568- build_tuple (char * string_list [],int len )
2569- {
2570- PyObject * tup = PyTuple_New (len );
2571- int i ;
2572-
2573- for (i = 0 ;i < len ;i ++ )
2574- {
2575- PyObject * m = PyString_FromString (string_list [i ]);
2576-
2577- PyTuple_SetItem (tup ,i ,m );
2578- }
2579- return tup ;
2580- }
2581-
2582- /* Helper function for populating a class with method wrappers. */
2583- static int
2584- populate_methods (PyObject * klass ,PyMethodDef * methods )
2585- {
2586- if (!klass || !methods )
2587- return 0 ;
2588-
2589- for (;methods -> ml_name ;++ methods )
2590- {
2591-
2592- /* get a wrapper for the built-in function */
2593- PyObject * func = PyCFunction_New (methods ,NULL );
2594- PyObject * meth ;
2595- int status ;
2596-
2597- if (!func )
2598- return -1 ;
2599-
2600- /* turn the function into an unbound method */
2601- if (!(meth = PyMethod_New (func ,NULL ,klass )))
2602- {
2603- Py_DECREF (func );
2604- return -1 ;
2605- }
2606-
2607- /* add method to dictionary */
2608- status = PyDict_SetItemString (((PyClassObject * )klass )-> cl_dict ,
2609- methods -> ml_name ,meth );
2610- Py_DECREF (meth );
2611- Py_DECREF (func );
2612-
2613- /* stop now if an error occurred, otherwise do the next method */
2614- if (status )
2615- return status ;
2616- }
2617- return 0 ;
2618- }
2619-
2620-
26212395/* the python interface to the elog function
26222396 * don't confuse these with PLy_elog
26232397 */