summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-07-31 18:36:46 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-07-31 18:36:46 +0000
commit8b1ea2f58b5f6c65a06781250ef38418c20796a1 (patch)
tree7ecf8db773370daad151a5b977b2210755db3204 /src
parent8488f25425fa9edb4d1264224c43053680232d47 (diff)
Cause library-preload feature to report error if specified initialization
function is not found. Also, make all the PL libraries have initialization functions with standard names. Patch from Joe Conway.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/init/miscinit.c4
-rw-r--r--src/pl/plperl/plperl.c39
-rw-r--r--src/pl/plpgsql/src/pl_comp.c6
-rw-r--r--src/pl/plpgsql/src/pl_handler.c44
-rw-r--r--src/pl/plpgsql/src/plpgsql.h3
-rw-r--r--src/pl/plpython/plpython.c38
-rw-r--r--src/pl/tcl/pltcl.c63
7 files changed, 155 insertions, 42 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 8f20f25dc19..4c4a7f61dff 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.108 2003/07/28 00:09:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.109 2003/07/31 18:36:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1165,7 +1165,7 @@ process_preload_libraries(char *preload_libraries_string)
}
initfunc = (func_ptr) load_external_function(filename, funcname,
- false, NULL);
+ true, NULL);
if (initfunc)
(*initfunc)();
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index fcbe55c9c2e..7edcac6c68b 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.37 2003/07/25 23:37:28 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.38 2003/07/31 18:36:28 tgl Exp $
*
**********************************************************************/
@@ -101,6 +101,7 @@ static void plperl_init_all(void);
static void plperl_init_interp(void);
Datum plperl_call_handler(PG_FUNCTION_ARGS);
+void plperl_init(void);
static Datum plperl_func_handler(PG_FUNCTION_ARGS);
@@ -128,12 +129,15 @@ perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
}
/**********************************************************************
- * plperl_init_all() - Initialize all
+ * plperl_init() - Initialize everything that can be
+ * safely initialized during postmaster
+ * startup.
+ *
+ * DO NOT make this static --- it has to be callable by preload
**********************************************************************/
-static void
-plperl_init_all(void)
+void
+plperl_init(void)
{
-
/************************************************************
* Do initialization only once
************************************************************/
@@ -168,6 +172,26 @@ plperl_init_all(void)
plperl_firstcall = 0;
}
+/**********************************************************************
+ * plperl_init_all() - Initialize all
+ **********************************************************************/
+static void
+plperl_init_all(void)
+{
+
+ /************************************************************
+ * Execute postmaster-startup safe initialization
+ ************************************************************/
+ if (plperl_firstcall)
+ plperl_init();
+
+ /************************************************************
+ * Any other initialization that must be done each time a new
+ * backend starts -- currently none
+ ************************************************************/
+
+}
+
/**********************************************************************
* plperl_init_interp() - Create the Perl interpreter
@@ -222,10 +246,9 @@ plperl_call_handler(PG_FUNCTION_ARGS)
Datum retval;
/************************************************************
- * Initialize interpreter on first call
+ * Initialize interpreter
************************************************************/
- if (plperl_firstcall)
- plperl_init_all();
+ plperl_init_all();
/************************************************************
* Connect to SPI manager
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 8ede81d061e..e08d6c82d75 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.63 2003/07/27 21:49:54 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.64 2003/07/31 18:36:35 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -106,7 +106,6 @@ static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
static void compute_function_hashkey(FmgrInfo *flinfo,
Form_pg_proc procStruct,
PLpgSQL_func_hashkey *hashkey);
-static void plpgsql_HashTableInit(void);
static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
static void plpgsql_HashTableInsert(PLpgSQL_function *function,
PLpgSQL_func_hashkey *func_key);
@@ -1743,7 +1742,8 @@ compute_function_hashkey(FmgrInfo *flinfo,
}
}
-static void
+/* exported so we can call it from plpgsql_init() */
+void
plpgsql_HashTableInit(void)
{
HASHCTL ctl;
diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c
index e77a2f9e0aa..0e0072e4ff4 100644
--- a/src/pl/plpgsql/src/pl_handler.c
+++ b/src/pl/plpgsql/src/pl_handler.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.15 2003/07/27 17:10:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.16 2003/07/31 18:36:35 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -44,6 +44,45 @@
#include "utils/builtins.h"
#include "utils/syscache.h"
+static int plpgsql_firstcall = 1;
+
+void plpgsql_init(void);
+static void plpgsql_init_all(void);
+
+
+/*
+ * plpgsql_init() - postmaster-startup safe initialization
+ *
+ * DO NOT make this static --- it has to be callable by preload
+ */
+void
+plpgsql_init(void)
+{
+ /* Do initialization only once */
+ if (!plpgsql_firstcall)
+ return;
+
+ plpgsql_HashTableInit();
+
+ plpgsql_firstcall = 0;
+}
+
+/*
+ * plpgsql_init_all() - Initialize all
+ */
+static void
+plpgsql_init_all(void)
+{
+ /* Execute any postmaster-startup safe initialization */
+ if (plpgsql_firstcall)
+ plpgsql_init();
+
+ /*
+ * Any other initialization that must be done each time a new
+ * backend starts -- currently none
+ */
+
+}
/* ----------
* plpgsql_call_handler
@@ -61,6 +100,9 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
PLpgSQL_function *func;
Datum retval;
+ /* perform initialization */
+ plpgsql_init_all();
+
/*
* Connect to SPI manager
*/
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index ae4d8909167..e12586011f1 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.37 2003/07/01 21:47:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.38 2003/07/31 18:36:35 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -613,6 +613,7 @@ extern PLpgSQL_row *plpgsql_build_rowtype(Oid classOid);
extern void plpgsql_adddatum(PLpgSQL_datum * new);
extern int plpgsql_add_initdatums(int **varnos);
extern void plpgsql_yyerror(const char *s);
+extern void plpgsql_HashTableInit(void);
/* ----------
* Functions in pl_handler.c
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 2a4c45e6e56..6f49e75ae47 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.35 2003/07/25 23:37:30 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.36 2003/07/31 18:36:39 tgl Exp $
*
*********************************************************************
*/
@@ -170,10 +170,12 @@ typedef struct PLyResultObject
/* function declarations
*/
-/* the only exported function, with the magic telling Postgresql
- * what function call interface it implements.
+/* Two exported functions: first is the magic telling Postgresql
+ * what function call interface it implements. Second allows
+ * preinitialization of the interpreter during postmaster startup.
*/
Datum plpython_call_handler(PG_FUNCTION_ARGS);
+void plpython_init(void);
PG_FUNCTION_INFO_V1(plpython_call_handler);
@@ -329,8 +331,7 @@ plpython_call_handler(PG_FUNCTION_ARGS)
enter();
- if (PLy_first_call)
- PLy_init_all();
+ PLy_init_all();
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI manager");
@@ -2302,11 +2303,22 @@ PLy_spi_error_string(int code)
/* language handler and interpreter initialization
*/
+/*
+ * plpython_init() - Initialize everything that can be
+ * safely initialized during postmaster
+ * startup.
+ *
+ * DO NOT make this static --- it has to be callable by preload
+ */
void
-PLy_init_all(void)
+plpython_init(void)
{
static volatile int init_active = 0;
+ /* Do initialization only once */
+ if (!PLy_first_call)
+ return;
+
enter();
if (init_active)
@@ -2327,6 +2339,20 @@ PLy_init_all(void)
leave();
}
+static void
+PLy_init_all(void)
+{
+ /* Execute postmaster-startup safe initialization */
+ if (PLy_first_call)
+ plpython_init();
+
+ /*
+ * Any other initialization that must be done each time a new
+ * backend starts -- currently none
+ */
+
+}
+
void
PLy_init_interp(void)
{
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 2f14245ee17..1375c9720cd 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.72 2003/07/25 23:37:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.73 2003/07/31 18:36:46 tgl Exp $
*
**********************************************************************/
@@ -128,7 +128,8 @@ typedef struct pltcl_query_desc
/**********************************************************************
* Global data
**********************************************************************/
-static int pltcl_firstcall = 1;
+static bool pltcl_pm_init_done = false;
+static bool pltcl_be_init_done = false;
static int pltcl_call_level = 0;
static int pltcl_restart_in_progress = 0;
static Tcl_Interp *pltcl_hold_interp = NULL;
@@ -149,6 +150,7 @@ static void pltcl_init_load_unknown(Tcl_Interp *interp);
Datum pltcl_call_handler(PG_FUNCTION_ARGS);
Datum pltclu_call_handler(PG_FUNCTION_ARGS);
+void pltcl_init(void);
static Datum pltcl_func_handler(PG_FUNCTION_ARGS);
@@ -197,17 +199,18 @@ perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
-
/**********************************************************************
- * pltcl_init_all() - Initialize all
+ * pltcl_init() - Initialize all that's safe to do in the postmaster
+ *
+ * DO NOT make this static --- it has to be callable by preload
**********************************************************************/
-static void
-pltcl_init_all(void)
+void
+pltcl_init(void)
{
/************************************************************
* Do initialization only once
************************************************************/
- if (!pltcl_firstcall)
+ if (pltcl_pm_init_done)
return;
/************************************************************
@@ -240,8 +243,36 @@ pltcl_init_all(void)
Tcl_InitHashTable(pltcl_norm_query_hash, TCL_STRING_KEYS);
Tcl_InitHashTable(pltcl_safe_query_hash, TCL_STRING_KEYS);
- pltcl_firstcall = 0;
- return;
+ pltcl_pm_init_done = true;
+}
+
+/**********************************************************************
+ * pltcl_init_all() - Initialize all
+ **********************************************************************/
+static void
+pltcl_init_all(void)
+{
+ /************************************************************
+ * Execute postmaster-startup safe initialization
+ ************************************************************/
+ if (!pltcl_pm_init_done)
+ pltcl_init();
+
+ /************************************************************
+ * Any other initialization that must be done each time a new
+ * backend starts:
+ * - Try to load the unknown procedure from pltcl_modules
+ ************************************************************/
+ if (!pltcl_be_init_done)
+ {
+ if (SPI_connect() != SPI_OK_CONNECT)
+ elog(ERROR, "SPI_connect failed");
+ pltcl_init_load_unknown(pltcl_norm_interp);
+ pltcl_init_load_unknown(pltcl_safe_interp);
+ if (SPI_finish() != SPI_OK_FINISH)
+ elog(ERROR, "SPI_finish failed");
+ pltcl_be_init_done = true;
+ }
}
@@ -271,15 +302,6 @@ pltcl_init_interp(Tcl_Interp *interp)
pltcl_SPI_execp, NULL, NULL);
Tcl_CreateCommand(interp, "spi_lastoid",
pltcl_SPI_lastoid, NULL, NULL);
-
- /************************************************************
- * Try to load the unknown procedure from pltcl_modules
- ************************************************************/
- if (SPI_connect() != SPI_OK_CONNECT)
- elog(ERROR, "SPI_connect failed");
- pltcl_init_load_unknown(interp);
- if (SPI_finish() != SPI_OK_FINISH)
- elog(ERROR, "SPI_finish failed");
}
@@ -373,10 +395,9 @@ pltcl_call_handler(PG_FUNCTION_ARGS)
FunctionCallInfo save_fcinfo;
/************************************************************
- * Initialize interpreters on first call
+ * Initialize interpreters
************************************************************/
- if (pltcl_firstcall)
- pltcl_init_all();
+ pltcl_init_all();
/************************************************************
* Connect to SPI manager