mirror of
https://github.com/postgres/postgres.git
synced 2026-01-26 09:41:40 +03:00
plpython: Streamline initialization
The initialization of PL/Python (the Python interpreter, the global state, the plpy module) was arranged confusingly across different functions with unclear and confusing boundaries. For example, PLy_init_interp() said "Initialize the Python interpreter ..." but it didn't actually do this, and PLy_init_plpy() said "initialize plpy module" but it didn't do that either. After this change, all the global initialization is called directly from _PG_init(), and the plpy module initialization is all called from its registered initialization function PyInit_plpy(). Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com> Reviewed-by: li carol <carol.li2025@outlook.com> Reviewed-by: Kirill Reshke <reshkekirill@gmail.com> Discussion: https://www.postgresql.org/message-id/f31333f1-fbb7-4098-b209-bf2d71fbd4f3%40eisentraut.org
This commit is contained in:
@@ -39,11 +39,9 @@ PG_FUNCTION_INFO_V1(plpython3_call_handler);
|
||||
PG_FUNCTION_INFO_V1(plpython3_inline_handler);
|
||||
|
||||
|
||||
static void PLy_initialize(void);
|
||||
static PLyTrigType PLy_procedure_is_trigger(Form_pg_proc procStruct);
|
||||
static void plpython_error_callback(void *arg);
|
||||
static void plpython_inline_error_callback(void *arg);
|
||||
static void PLy_init_interp(void);
|
||||
|
||||
static PLyExecutionContext *PLy_push_execution_context(bool atomic_context);
|
||||
static void PLy_pop_execution_context(void);
|
||||
@@ -58,25 +56,53 @@ static PLyExecutionContext *PLy_execution_contexts = NULL;
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
PyObject *main_mod;
|
||||
PyObject *main_dict;
|
||||
PyObject *GD;
|
||||
PyObject *plpy_mod;
|
||||
|
||||
pg_bindtextdomain(TEXTDOMAIN);
|
||||
|
||||
PLy_initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform one-time setup of PL/Python.
|
||||
*/
|
||||
static void
|
||||
PLy_initialize(void)
|
||||
{
|
||||
/* Add plpy to table of built-in modules. */
|
||||
PyImport_AppendInittab("plpy", PyInit_plpy);
|
||||
|
||||
/* Initialize Python interpreter. */
|
||||
Py_Initialize();
|
||||
PyImport_ImportModule("plpy");
|
||||
PLy_init_interp();
|
||||
PLy_init_plpy();
|
||||
|
||||
main_mod = PyImport_AddModule("__main__");
|
||||
if (main_mod == NULL || PyErr_Occurred())
|
||||
PLy_elog(ERROR, "could not import \"%s\" module", "__main__");
|
||||
Py_INCREF(main_mod);
|
||||
|
||||
main_dict = PyModule_GetDict(main_mod);
|
||||
if (main_dict == NULL)
|
||||
PLy_elog(ERROR, NULL);
|
||||
|
||||
/*
|
||||
* Set up GD.
|
||||
*/
|
||||
GD = PyDict_New();
|
||||
if (GD == NULL)
|
||||
PLy_elog(ERROR, NULL);
|
||||
PyDict_SetItemString(main_dict, "GD", GD);
|
||||
|
||||
/*
|
||||
* Import plpy.
|
||||
*/
|
||||
plpy_mod = PyImport_ImportModule("plpy");
|
||||
if (plpy_mod == NULL)
|
||||
PLy_elog(ERROR, "could not import \"%s\" module", "plpy");
|
||||
if (PyDict_SetItemString(main_dict, "plpy", plpy_mod) == -1)
|
||||
PLy_elog(ERROR, NULL);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PLy_elog(FATAL, "untrapped error in initialization");
|
||||
|
||||
Py_INCREF(main_dict);
|
||||
PLy_interp_globals = main_dict;
|
||||
|
||||
Py_DECREF(main_mod);
|
||||
|
||||
init_procedure_caches();
|
||||
|
||||
explicit_subtransactions = NIL;
|
||||
@@ -84,30 +110,6 @@ PLy_initialize(void)
|
||||
PLy_execution_contexts = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be called only once, from PLy_initialize. Initialize the Python
|
||||
* interpreter and global data.
|
||||
*/
|
||||
static void
|
||||
PLy_init_interp(void)
|
||||
{
|
||||
static PyObject *PLy_interp_safe_globals = NULL;
|
||||
PyObject *mainmod;
|
||||
|
||||
mainmod = PyImport_AddModule("__main__");
|
||||
if (mainmod == NULL || PyErr_Occurred())
|
||||
PLy_elog(ERROR, "could not import \"__main__\" module");
|
||||
Py_INCREF(mainmod);
|
||||
PLy_interp_globals = PyModule_GetDict(mainmod);
|
||||
PLy_interp_safe_globals = PyDict_New();
|
||||
if (PLy_interp_safe_globals == NULL)
|
||||
PLy_elog(ERROR, NULL);
|
||||
PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
|
||||
Py_DECREF(mainmod);
|
||||
if (PLy_interp_globals == NULL || PyErr_Occurred())
|
||||
PLy_elog(ERROR, "could not initialize globals");
|
||||
}
|
||||
|
||||
Datum
|
||||
plpython3_validator(PG_FUNCTION_ARGS)
|
||||
{
|
||||
|
||||
@@ -133,35 +133,12 @@ PyInit_plpy(void)
|
||||
|
||||
PLy_add_exceptions(m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
PLy_init_plpy(void)
|
||||
{
|
||||
PyObject *main_mod,
|
||||
*main_dict,
|
||||
*plpy_mod;
|
||||
|
||||
/*
|
||||
* initialize plpy module
|
||||
*/
|
||||
PLy_plan_init_type();
|
||||
PLy_result_init_type();
|
||||
PLy_subtransaction_init_type();
|
||||
PLy_cursor_init_type();
|
||||
|
||||
/*
|
||||
* initialize main module, and add plpy
|
||||
*/
|
||||
main_mod = PyImport_AddModule("__main__");
|
||||
main_dict = PyModule_GetDict(main_mod);
|
||||
plpy_mod = PyImport_AddModule("plpy");
|
||||
if (plpy_mod == NULL)
|
||||
PLy_elog(ERROR, "could not import \"plpy\" module");
|
||||
PyDict_SetItemString(main_dict, "plpy", plpy_mod);
|
||||
if (PyErr_Occurred())
|
||||
PLy_elog(ERROR, "could not import \"plpy\" module");
|
||||
return m;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -13,6 +13,5 @@ extern HTAB *PLy_spi_exceptions;
|
||||
|
||||
|
||||
PyMODINIT_FUNC PyInit_plpy(void);
|
||||
extern void PLy_init_plpy(void);
|
||||
|
||||
#endif /* PLPY_PLPYMODULE_H */
|
||||
|
||||
Reference in New Issue
Block a user