v1-0004-plpython-Streamline-initialization.patch
text/plain
Filename: v1-0004-plpython-Streamline-initialization.patch
Type: text/plain
Part: 3
Message:
PL/Python initialization cleanup
From 247ea7aa96df56253754e88c17974488ea09e39b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Tue, 30 Dec 2025 22:17:57 +0100
Subject: [PATCH v1 4/4] 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().
---
src/pl/plpython/plpy_main.c | 77 ++++++++++++++++---------------
src/pl/plpython/plpy_plpymodule.c | 25 +---------
src/pl/plpython/plpy_plpymodule.h | 1 -
3 files changed, 40 insertions(+), 63 deletions(-)
diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index 7673b5eca7b..482ca7a1ada 100644
--- a/src/pl/plpython/plpy_main.c
+++ b/src/pl/plpython/plpy_main.c
@@ -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,52 @@ static PLyExecutionContext *PLy_execution_contexts = NULL;
void
_PG_init(void)
{
- pg_bindtextdomain(TEXTDOMAIN);
+ PyObject *main_mod;
+ PyObject *main_dict;
+ PyObject *GD;
+ PyObject *plpy_mod;
- PLy_initialize();
-}
+ pg_bindtextdomain(TEXTDOMAIN);
-/*
- * 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 get \"__main__\" module");
+ Py_INCREF(main_mod);
+
+ main_dict = PyModule_GetDict(main_mod);
+
+ /*
+ * 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 \"plpy\" module");
+ PyDict_SetItemString(main_dict, "plpy", plpy_mod);
+ if (PyErr_Occurred())
+ PLy_elog(ERROR, "could not import \"plpy\" module");
+
+ Py_DECREF(main_mod);
+
if (PyErr_Occurred())
PLy_elog(FATAL, "untrapped error in initialization");
+ Py_INCREF(main_dict);
+ PLy_interp_globals = main_dict;
+
init_procedure_caches();
explicit_subtransactions = NIL;
@@ -84,30 +109,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)
{
diff --git a/src/pl/plpython/plpy_plpymodule.c b/src/pl/plpython/plpy_plpymodule.c
index 2d76c6a5573..e24ad02e086 100644
--- a/src/pl/plpython/plpy_plpymodule.c
+++ b/src/pl/plpython/plpy_plpymodule.c
@@ -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
diff --git a/src/pl/plpython/plpy_plpymodule.h b/src/pl/plpython/plpy_plpymodule.h
index 1ca3823daf2..88f902346a6 100644
--- a/src/pl/plpython/plpy_plpymodule.h
+++ b/src/pl/plpython/plpy_plpymodule.h
@@ -13,6 +13,5 @@ extern HTAB *PLy_spi_exceptions;
PyMODINIT_FUNC PyInit_plpy(void);
-extern void PLy_init_plpy(void);
#endif /* PLPY_PLPYMODULE_H */
--
2.52.0