29
29
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
30
30
*
31
31
* 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 $
33
33
*
34
34
*********************************************************************
35
35
*/
61
61
#include "utils/syscache.h"
62
62
63
63
#include <Python.h>
64
+ #include <compile.h>
65
+ #include <eval.h>
64
66
#include "plpython.h"
65
67
66
68
/* convert Postgresql Datum or tuple into a PyObject.
@@ -135,8 +137,6 @@ typedef struct PLyProcedure
135
137
* tuple type */
136
138
PLyTypeInfo args [FUNC_MAX_ARGS ];
137
139
int nargs ;
138
- PyObject * interp ; /* restricted interpreter instance */
139
- PyObject * reval ; /* interpreter return */
140
140
PyObject * code ; /* compiled procedure code */
141
141
PyObject * statics ; /* data saved across calls, local scope */
142
142
PyObject * globals ; /* data saved across calls, global score */
@@ -186,13 +186,8 @@ PG_FUNCTION_INFO_V1(plpython_call_handler);
186
186
*/
187
187
static void PLy_init_all (void );
188
188
static void PLy_init_interp (void );
189
- static void PLy_init_safe_interp (void );
190
189
static void PLy_init_plpy (void );
191
190
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
-
196
191
/* error handler. collects the current Python exception, if any,
197
192
* and appends it to the error and sends it to elog
198
193
*/
@@ -249,10 +244,6 @@ static void PLy_input_datum_func2(PLyDatumToOb *, Oid, Form_pg_type);
249
244
static void PLy_output_tuple_funcs (PLyTypeInfo * , TupleDesc );
250
245
static void PLy_input_tuple_funcs (PLyTypeInfo * , TupleDesc );
251
246
252
- /* RExec methods
253
- */
254
- static PyObject * PLy_r_open (PyObject * self , PyObject * args );
255
-
256
247
/* conversion functions
257
248
*/
258
249
static PyObject * PLyDict_FromTuple (PLyTypeInfo * , HeapTuple , TupleDesc );
@@ -280,58 +271,9 @@ static PLyProcedure *PLy_last_procedure = NULL;
280
271
static volatile int PLy_restart_in_progress = 0 ;
281
272
282
273
static PyObject * PLy_interp_globals = NULL ;
283
- static PyObject * PLy_interp_safe = NULL ;
284
274
static 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 ;
288
275
static PyObject * PLy_procedure_cache = NULL ;
289
276
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
-
335
277
/* Python exceptions
336
278
*/
337
279
static PyObject * PLy_exc_error = NULL ;
@@ -904,7 +846,7 @@ PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs)
904
846
current = PLy_last_procedure ;
905
847
PLy_last_procedure = proc ;
906
848
PyDict_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 );
908
850
PLy_last_procedure = current ;
909
851
910
852
if ((rv == NULL ) || (PyErr_Occurred ()))
@@ -1084,7 +1026,7 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
1084
1026
for (i = 0 ; i < FUNC_MAX_ARGS ; i ++ )
1085
1027
PLy_typeinfo_init (& proc -> args [i ]);
1086
1028
proc -> nargs = 0 ;
1087
- proc -> code = proc -> interp = proc -> reval = proc -> statics = NULL ;
1029
+ proc -> code = proc -> statics = NULL ;
1088
1030
proc -> globals = proc -> me = NULL ;
1089
1031
1090
1032
SAVE_EXC ();
@@ -1189,59 +1131,25 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
1189
1131
void
1190
1132
PLy_procedure_compile (PLyProcedure * proc , const char * src )
1191
1133
{
1192
- PyObject * module ,
1193
- * crv = NULL ;
1134
+ PyObject * crv = NULL ;
1194
1135
char * msrc ;
1195
1136
1196
1137
enter ();
1197
1138
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 );
1231
1140
1232
1141
/*
1233
1142
* SD is private preserved data between calls GD is global data shared
1234
1143
* by all functions
1235
1144
*/
1236
1145
proc -> statics = PyDict_New ();
1237
1146
PyDict_SetItemString (proc -> globals , "SD" , proc -> statics );
1238
- PyDict_SetItemString (proc -> globals , "GD" , PLy_interp_safe_globals );
1239
1147
1240
1148
/*
1241
1149
* insert the function code into the interpreter
1242
1150
*/
1243
1151
msrc = 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 );
1245
1153
free (msrc );
1246
1154
1247
1155
if ((crv != NULL ) && (!PyErr_Occurred ()))
@@ -1319,8 +1227,6 @@ PLy_procedure_delete(PLyProcedure * proc)
1319
1227
enter ();
1320
1228
1321
1229
Py_XDECREF (proc -> code );
1322
- Py_XDECREF (proc -> interp );
1323
- Py_XDECREF (proc -> reval );
1324
1230
Py_XDECREF (proc -> statics );
1325
1231
Py_XDECREF (proc -> globals );
1326
1232
Py_XDECREF (proc -> me );
@@ -2418,7 +2324,6 @@ PLy_init_all(void)
2418
2324
Py_Initialize ();
2419
2325
PLy_init_interp ();
2420
2326
PLy_init_plpy ();
2421
- PLy_init_safe_interp ();
2422
2327
if (PyErr_Occurred ())
2423
2328
PLy_elog (FATAL , "Untrapped error in initialization." );
2424
2329
PLy_procedure_cache = PyDict_New ();
@@ -2442,6 +2347,8 @@ PLy_init_interp(void)
2442
2347
PLy_elog (ERROR , "Unable to import '__main__' module." );
2443
2348
Py_INCREF (mainmod );
2444
2349
PLy_interp_globals = PyModule_GetDict (mainmod );
2350
+ PLy_interp_safe_globals = PyDict_New ();
2351
+ PyDict_SetItemString (PLy_interp_globals , "GD" , PLy_interp_safe_globals );
2445
2352
Py_DECREF (mainmod );
2446
2353
if ((PLy_interp_globals == NULL ) || (PyErr_Occurred ()))
2447
2354
PLy_elog (ERROR , "Unable to initialize globals." );
@@ -2485,139 +2392,6 @@ PLy_init_plpy(void)
2485
2392
elog (ERROR , "Unable to init plpy." );
2486
2393
}
2487
2394
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
-
2621
2395
/* the python interface to the elog function
2622
2396
* don't confuse these with PLy_elog
2623
2397
*/
0 commit comments