Commit 8b1ea2f5 authored by Tom Lane's avatar Tom Lane

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.
parent 8488f254
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.197 2003/07/29 00:03:17 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.198 2003/07/31 18:36:17 tgl Exp $
-->
<Chapter Id="runtime">
......@@ -1004,21 +1004,27 @@ SET ENABLE_SEQSCAN TO OFF;
<listitem>
<para>
This variable specifies one or more shared libraries that are
to be preloaded at server start. An initialization function
can also be optionally specified by adding a colon followed by
the name of the initialization function after the library
name. For example
<literal>'$libdir/mylib:init_mylib'</literal> would cause
<literal>mylib</> to be preloaded and <literal>init_mylib</>
to be executed. If more than one library is to be loaded, they
must be delimited with a comma.
to be preloaded at server start. A parameterless initialization
function can optionally be called for each library. To specify
that, add a colon and the name of the initialization function after
the library name. For example
<literal>'$libdir/mylib:mylib_init'</literal> would cause
<literal>mylib</> to be preloaded and <literal>mylib_init</>
to be executed. If more than one library is to be loaded, separate
their names with commas.
</para>
<para>
If <literal>mylib</> is not found, the server will fail to
start. However, if <literal>init_mylib</> is not found,
<literal>mylib</> will still be preloaded without executing
the initialization function.
If <literal>mylib</> or <literal>mylib_init</> are not found, the
server will fail to start.
</para>
<para>
PostgreSQL procedural language libraries may be preloaded in this way,
typically by using the syntax
<literal>'$libdir/plXXX:plXXX_init'</literal>
where <literal>XXX</literal> is <literal>pgsql</>,
<literal>perl</>, <literal>tcl</>, or <literal>python</>.
</para>
<para>
......
......@@ -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)();
......
......@@ -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,9 +246,8 @@ plperl_call_handler(PG_FUNCTION_ARGS)
Datum retval;
/************************************************************
* Initialize interpreter on first call
* Initialize interpreter
************************************************************/
if (plperl_firstcall)
plperl_init_all();
/************************************************************
......
......@@ -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;
......
......@@ -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
*/
......
......@@ -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
......
......@@ -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,7 +331,6 @@ plpython_call_handler(PG_FUNCTION_ARGS)
enter();
if (PLy_first_call)
PLy_init_all();
if (SPI_connect() != SPI_OK_CONNECT)
......@@ -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)
{
......
......@@ -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,9 +395,8 @@ pltcl_call_handler(PG_FUNCTION_ARGS)
FunctionCallInfo save_fcinfo;
/************************************************************
* Initialize interpreters on first call
* Initialize interpreters
************************************************************/
if (pltcl_firstcall)
pltcl_init_all();
/************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment