mirror of
https://github.com/postgres/postgres.git
synced 2025-10-19 15:49:24 +03:00
plpython: Remove support for major version conflict detection
This essentially reverts commit866566a690
, which installed safeguards against loading plpython2 and plpython3 into the same process. We don't support plpython2 anymore, so this is obsolete. The Python and PL/Python initialization now happens again in _PG_init() rather than the first time a PL/Python call handler is invoked. (Often, these will be very close together.) I kept the separate PLy_initialize() function introduced by866566a690
to keep _PG_init() a bit modular. Reviewed-by: Mario González Troncoso <gonzalemario@gmail.com> Reviewed-by: Nathan Bossart <nathandbossart@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/9eb9feb6-1df3-4f0c-a0dc-9bcf35273111%40eisentraut.org
This commit is contained in:
@@ -39,6 +39,7 @@ 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);
|
||||
@@ -47,10 +48,6 @@ static void PLy_init_interp(void);
|
||||
static PLyExecutionContext *PLy_push_execution_context(bool atomic_context);
|
||||
static void PLy_pop_execution_context(void);
|
||||
|
||||
/* static state for Python library conflict detection */
|
||||
static int *plpython_version_bitmask_ptr = NULL;
|
||||
static int plpython_version_bitmask = 0;
|
||||
|
||||
/* initialize global variables */
|
||||
PyObject *PLy_interp_globals = NULL;
|
||||
|
||||
@@ -61,62 +58,17 @@ static PLyExecutionContext *PLy_execution_contexts = NULL;
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
int **bitmask_ptr;
|
||||
|
||||
/*
|
||||
* Set up a shared bitmask variable telling which Python version(s) are
|
||||
* loaded into this process's address space. If there's more than one, we
|
||||
* cannot call into libpython for fear of causing crashes. But postpone
|
||||
* the actual failure for later, so that operations like pg_restore can
|
||||
* load more than one plpython library so long as they don't try to do
|
||||
* anything much with the language.
|
||||
*
|
||||
* While we only support Python 3 these days, somebody might create an
|
||||
* out-of-tree version adding back support for Python 2. Conflicts with
|
||||
* such an extension should be detected.
|
||||
*/
|
||||
bitmask_ptr = (int **) find_rendezvous_variable("plpython_version_bitmask");
|
||||
if (!(*bitmask_ptr)) /* am I the first? */
|
||||
*bitmask_ptr = &plpython_version_bitmask;
|
||||
/* Retain pointer to the agreed-on shared variable ... */
|
||||
plpython_version_bitmask_ptr = *bitmask_ptr;
|
||||
/* ... and announce my presence */
|
||||
*plpython_version_bitmask_ptr |= (1 << PY_MAJOR_VERSION);
|
||||
|
||||
/*
|
||||
* This should be safe even in the presence of conflicting plpythons, and
|
||||
* it's necessary to do it before possibly throwing a conflict error, or
|
||||
* the error message won't get localized.
|
||||
*/
|
||||
pg_bindtextdomain(TEXTDOMAIN);
|
||||
|
||||
PLy_initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform one-time setup of PL/Python, after checking for a conflict
|
||||
* with other versions of Python.
|
||||
* Perform one-time setup of PL/Python.
|
||||
*/
|
||||
static void
|
||||
PLy_initialize(void)
|
||||
{
|
||||
static bool inited = false;
|
||||
|
||||
/*
|
||||
* Check for multiple Python libraries before actively doing anything with
|
||||
* libpython. This must be repeated on each entry to PL/Python, in case a
|
||||
* conflicting library got loaded since we last looked.
|
||||
*
|
||||
* It is attractive to weaken this error from FATAL to ERROR, but there
|
||||
* would be corner cases, so it seems best to be conservative.
|
||||
*/
|
||||
if (*plpython_version_bitmask_ptr != (1 << PY_MAJOR_VERSION))
|
||||
ereport(FATAL,
|
||||
(errmsg("multiple Python libraries are present in session"),
|
||||
errdetail("Only one Python major version can be used in one session.")));
|
||||
|
||||
/* The rest should only be done once per session */
|
||||
if (inited)
|
||||
return;
|
||||
|
||||
PyImport_AppendInittab("plpy", PyInit_plpy);
|
||||
Py_Initialize();
|
||||
PyImport_ImportModule("plpy");
|
||||
@@ -130,8 +82,6 @@ PLy_initialize(void)
|
||||
explicit_subtransactions = NIL;
|
||||
|
||||
PLy_execution_contexts = NULL;
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -172,9 +122,6 @@ plpython3_validator(PG_FUNCTION_ARGS)
|
||||
if (!check_function_bodies)
|
||||
PG_RETURN_VOID();
|
||||
|
||||
/* Do this only after making sure we need to do something */
|
||||
PLy_initialize();
|
||||
|
||||
/* Get the new function's pg_proc entry */
|
||||
tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
@@ -199,8 +146,6 @@ plpython3_call_handler(PG_FUNCTION_ARGS)
|
||||
PLyExecutionContext *exec_ctx;
|
||||
ErrorContextCallback plerrcontext;
|
||||
|
||||
PLy_initialize();
|
||||
|
||||
nonatomic = fcinfo->context &&
|
||||
IsA(fcinfo->context, CallContext) &&
|
||||
!castNode(CallContext, fcinfo->context)->atomic;
|
||||
@@ -279,8 +224,6 @@ plpython3_inline_handler(PG_FUNCTION_ARGS)
|
||||
PLyExecutionContext *exec_ctx;
|
||||
ErrorContextCallback plerrcontext;
|
||||
|
||||
PLy_initialize();
|
||||
|
||||
/* Note: SPI_finish() happens in plpy_exec.c, which is dubious design */
|
||||
SPI_connect_ext(codeblock->atomic ? 0 : SPI_OPT_NONATOMIC);
|
||||
|
||||
|
Reference in New Issue
Block a user