mirror of https://github.com/postgres/postgres
Add a feature for automatic initialization and finalization of dynamically
loaded libraries: call functions _PG_init() and _PG_fini() if the library defines such symbols. Hence we no longer need to specify an initialization function in preload_libraries: we can assume that the library used the _PG_init() convention, instead. This removes one source of pilot error in use of preloaded libraries. Original patch by Ralf Engelschall, preload_libraries changes by me.
This commit is contained in:
parent
e00664da48
commit
b09bfcaa57
|
@ -1,4 +1,4 @@
|
|||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.72 2006/08/08 01:23:15 momjian Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.73 2006/08/08 19:15:07 tgl Exp $ -->
|
||||
|
||||
<chapter Id="runtime-config">
|
||||
<title>Server Configuration</title>
|
||||
|
@ -957,38 +957,35 @@ SET ENABLE_SEQSCAN TO OFF;
|
|||
<listitem>
|
||||
<para>
|
||||
This variable specifies one or more shared libraries that are
|
||||
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 a specified library or initialization function is not found,
|
||||
the server will fail to start.
|
||||
to be preloaded at server start. If more than one library is to be
|
||||
loaded, separate their names with commas. For example,
|
||||
<literal>'$libdir/mylib'</literal> would cause
|
||||
<literal>mylib.so</> (or on some platforms,
|
||||
<literal>mylib.sl</>) to be preloaded from the installation's
|
||||
standard library directory.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<productname>PostgreSQL</productname> procedural language
|
||||
libraries can be preloaded in this way, typically by using the
|
||||
syntax <literal>'$libdir/plXXX:plXXX_init'</literal> where
|
||||
syntax <literal>'$libdir/plXXX'</literal> where
|
||||
<literal>XXX</literal> is <literal>pgsql</>, <literal>perl</>,
|
||||
<literal>tcl</>, or <literal>python</>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By preloading a shared library (and initializing it if
|
||||
applicable), the library startup time is avoided when the
|
||||
library is first used. However, the time to start each new
|
||||
By preloading a shared library, the library startup time is avoided
|
||||
when the library is first used. However, the time to start each new
|
||||
server process may increase slightly, even if that process never
|
||||
uses the library. So this parameter is recommended only for
|
||||
libraries that will be used in most sessions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If a specified library is not found,
|
||||
the server will fail to start.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Every PostgreSQL-supported library has a <quote>magic
|
||||
block</> that is checked to guarantee compatibility.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.115 2006/05/31 20:58:09 tgl Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.116 2006/08/08 19:15:07 tgl Exp $ -->
|
||||
|
||||
<sect1 id="xfunc">
|
||||
<title>User-Defined Functions</title>
|
||||
|
@ -1148,6 +1148,15 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
|||
that fails as well, the load will fail.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is recommended to locate shared libraries either relative to
|
||||
<literal>$libdir</literal> or through the dynamic library path.
|
||||
This simplifies version upgrades if the new installation is at a
|
||||
different location. The actual directory that
|
||||
<literal>$libdir</literal> stands for can be found out with the
|
||||
command <literal>pg_config --pkglibdir</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The user ID the <productname>PostgreSQL</productname> server runs
|
||||
as must be able to traverse the path to the file you intend to
|
||||
|
@ -1173,6 +1182,32 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
|||
</para>
|
||||
</note>
|
||||
|
||||
<indexterm zone="xfunc-c-dynload">
|
||||
<primary>magic block</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
To ensure that a dynamically loaded object file is not loaded into an
|
||||
incompatible server, <productname>PostgreSQL</productname> checks that the
|
||||
file contains a <quote>magic block</> with the appropriate contents.
|
||||
This allows the server to detect obvious incompatibilities, such as code
|
||||
compiled for a different major version of
|
||||
<productname>PostgreSQL</productname>. A magic block is required as of
|
||||
<productname>PostgreSQL</productname> 8.2. To include a magic block,
|
||||
write this in one (and only one) of the module source files, after having
|
||||
included the header <filename>fmgr.h</>:
|
||||
|
||||
<programlisting>
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
</programlisting>
|
||||
|
||||
The <literal>#ifdef</> test can be omitted if the code doesn't
|
||||
need to compile against pre-8.2 <productname>PostgreSQL</productname>
|
||||
releases.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After it is used for the first time, a dynamically loaded object
|
||||
file is retained in memory. Future calls in the same session to
|
||||
|
@ -1183,13 +1218,31 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
|||
fresh session.
|
||||
</para>
|
||||
|
||||
<indexterm zone="xfunc-c-dynload">
|
||||
<primary>_PG_init</primary>
|
||||
</indexterm>
|
||||
<indexterm zone="xfunc-c-dynload">
|
||||
<primary>_PG_fini</primary>
|
||||
</indexterm>
|
||||
<indexterm zone="xfunc-c-dynload">
|
||||
<primary>library initialization function</primary>
|
||||
</indexterm>
|
||||
<indexterm zone="xfunc-c-dynload">
|
||||
<primary>library finalization function</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
It is recommended to locate shared libraries either relative to
|
||||
<literal>$libdir</literal> or through the dynamic library path.
|
||||
This simplifies version upgrades if the new installation is at a
|
||||
different location. The actual directory that
|
||||
<literal>$libdir</literal> stands for can be found out with the
|
||||
command <literal>pg_config --pkglibdir</literal>.
|
||||
Optionally, a dynamically loaded file can contain initialization and
|
||||
finalization functions. If the file includes a function named
|
||||
<literal>_PG_init</>, that function will be called immediately after
|
||||
loading the file. The function receives no parameters and should
|
||||
return void. If the file includes a function named
|
||||
<literal>_PG_fini</>, that function will be called immediately before
|
||||
unloading the file. Likewise, the function receives no parameters and
|
||||
should return void. Note that <literal>_PG_fini</> will only be called
|
||||
during an unload of the file, not during process termination.
|
||||
(Presently, an unload only happens in the context of re-loading
|
||||
the file due to an explicit <command>LOAD</> command.)
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
@ -1910,31 +1963,6 @@ concat_text(PG_FUNCTION_ARGS)
|
|||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
To ensure your module is not loaded into an incompatible server,
|
||||
it must include a <quote>magic block</>. This allows
|
||||
the server to detect obvious incompatibilities, such as a module
|
||||
compiled for a different major version of
|
||||
<productname>PostgreSQL</productname>. A magic block is required
|
||||
as of <productname>PostgreSQL</productname> 8.2. To include a magic
|
||||
block, write this in one (and only one) of your module source files,
|
||||
after having included the header <filename>fmgr.h</>:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The <literal>#ifdef</> test can be omitted if your code doesn't
|
||||
need to compile against pre-8.2 <productname>PostgreSQL</productname>
|
||||
releases.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Compiling and linking your code so that it can be dynamically
|
||||
|
@ -1945,6 +1973,13 @@ PG_MODULE_MAGIC;
|
|||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Remember to define a <quote>magic block</> for your shared library,
|
||||
as described in <xref linkend="xfunc-c-dynload">.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
When allocating memory, use the
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.497 2006/07/29 03:02:55 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.498 2006/08/08 19:15:07 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
|
@ -197,9 +197,6 @@ bool Db_user_namespace = false;
|
|||
|
||||
char *bonjour_name;
|
||||
|
||||
/* list of library:init-function to be preloaded */
|
||||
char *preload_libraries_string = NULL;
|
||||
|
||||
/* PIDs of special child processes; 0 when not running */
|
||||
static pid_t StartupPID = 0,
|
||||
BgWriterPID = 0,
|
||||
|
@ -710,11 +707,9 @@ PostmasterMain(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
/*
|
||||
* process any libraries that should be preloaded and optionally
|
||||
* pre-initialized
|
||||
* process any libraries that should be preloaded at postmaster start
|
||||
*/
|
||||
if (preload_libraries_string)
|
||||
process_preload_libraries(preload_libraries_string);
|
||||
process_preload_libraries();
|
||||
|
||||
/*
|
||||
* Remove old temporary files. At this point there can be no other
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.86 2006/06/07 22:24:44 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.87 2006/08/08 19:15:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -25,6 +25,10 @@
|
|||
#include "utils/dynamic_loader.h"
|
||||
|
||||
|
||||
/* signatures for PostgreSQL-specific library init/fini functions */
|
||||
typedef void (*PG_init_t)(void);
|
||||
typedef void (*PG_fini_t)(void);
|
||||
|
||||
/*
|
||||
* List of dynamically loaded files (kept in malloc'd memory).
|
||||
*/
|
||||
|
@ -79,7 +83,7 @@ static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA;
|
|||
* identifying the library file. The filehandle can be used with
|
||||
* lookup_external_function to lookup additional functions in the same file
|
||||
* at less cost than repeating load_external_function.
|
||||
*/
|
||||
*/
|
||||
PGFunction
|
||||
load_external_function(char *filename, char *funcname,
|
||||
bool signalNotFound, void **filehandle)
|
||||
|
@ -90,6 +94,7 @@ load_external_function(char *filename, char *funcname,
|
|||
char *load_error;
|
||||
struct stat stat_buf;
|
||||
char *fullname;
|
||||
PG_init_t PG_init;
|
||||
|
||||
fullname = expand_dynamic_library_name(filename);
|
||||
if (!fullname)
|
||||
|
@ -201,7 +206,14 @@ load_external_function(char *filename, char *funcname,
|
|||
fullname),
|
||||
errhint("Extension libraries are now required to use the PG_MODULE_MAGIC macro.")));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If the library has a _PG_init() function, call it.
|
||||
*/
|
||||
PG_init = (PG_init_t) pg_dlsym(file_scanner->handle, "_PG_init");
|
||||
if (PG_init)
|
||||
(*PG_init)();
|
||||
|
||||
/* OK to link it into list */
|
||||
if (file_list == NULL)
|
||||
file_list = file_scanner;
|
||||
|
@ -248,6 +260,7 @@ load_file(char *filename)
|
|||
*nxt;
|
||||
struct stat stat_buf;
|
||||
char *fullname;
|
||||
PG_fini_t PG_fini;
|
||||
|
||||
fullname = expand_dynamic_library_name(filename);
|
||||
if (!fullname)
|
||||
|
@ -280,6 +293,14 @@ load_file(char *filename)
|
|||
else
|
||||
file_list = nxt;
|
||||
clear_external_function_hash(file_scanner->handle);
|
||||
|
||||
/*
|
||||
* If the library has a _PG_fini() function, call it.
|
||||
*/
|
||||
PG_fini = (PG_fini_t) pg_dlsym(file_scanner->handle, "_PG_fini");
|
||||
if (PG_fini)
|
||||
(*PG_fini)();
|
||||
|
||||
pg_dlclose(file_scanner->handle);
|
||||
free((char *) file_scanner);
|
||||
/* prv does not change */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.155 2006/07/14 14:52:25 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.156 2006/08/08 19:15:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -1097,14 +1097,14 @@ ValidatePgVersion(const char *path)
|
|||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef void (*func_ptr) ();
|
||||
/* GUC variable: list of library names to be preloaded */
|
||||
char *preload_libraries_string = NULL;
|
||||
|
||||
/*
|
||||
* process any libraries that should be preloaded and
|
||||
* optionally pre-initialized
|
||||
* process any libraries that should be preloaded at postmaster start
|
||||
*/
|
||||
void
|
||||
process_preload_libraries(char *preload_libraries_string)
|
||||
process_preload_libraries(void)
|
||||
{
|
||||
char *rawstring;
|
||||
List *elemlist;
|
||||
|
@ -1131,54 +1131,14 @@ process_preload_libraries(char *preload_libraries_string)
|
|||
foreach(l, elemlist)
|
||||
{
|
||||
char *tok = (char *) lfirst(l);
|
||||
char *sep = strstr(tok, ":");
|
||||
char *filename = NULL;
|
||||
char *funcname = NULL;
|
||||
func_ptr initfunc;
|
||||
|
||||
if (sep)
|
||||
{
|
||||
/*
|
||||
* a colon separator implies there is an initialization function
|
||||
* that we need to run in addition to loading the library
|
||||
*/
|
||||
size_t filename_len = sep - tok;
|
||||
size_t funcname_len = strlen(tok) - filename_len - 1;
|
||||
|
||||
filename = (char *) palloc(filename_len + 1);
|
||||
memcpy(filename, tok, filename_len);
|
||||
filename[filename_len] = '\0';
|
||||
|
||||
funcname = (char *) palloc(funcname_len + 1);
|
||||
strcpy(funcname, sep + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* no separator -- just load the library
|
||||
*/
|
||||
filename = pstrdup(tok);
|
||||
funcname = NULL;
|
||||
}
|
||||
char *filename;
|
||||
|
||||
filename = pstrdup(tok);
|
||||
canonicalize_path(filename);
|
||||
initfunc = (func_ptr) load_external_function(filename, funcname,
|
||||
true, NULL);
|
||||
if (initfunc)
|
||||
(*initfunc) ();
|
||||
|
||||
if (funcname)
|
||||
ereport(LOG,
|
||||
(errmsg("preloaded library \"%s\" with initialization function \"%s\"",
|
||||
filename, funcname)));
|
||||
else
|
||||
ereport(LOG,
|
||||
(errmsg("preloaded library \"%s\"",
|
||||
filename)));
|
||||
|
||||
(void) load_external_function(filename, NULL, true, NULL);
|
||||
ereport(LOG,
|
||||
(errmsg("preloaded library \"%s\"", filename)));
|
||||
pfree(filename);
|
||||
if (funcname)
|
||||
pfree(funcname);
|
||||
}
|
||||
|
||||
pfree(rawstring);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.186 2006/03/05 15:58:53 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.187 2006/08/08 19:15:08 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* some of the information in this file should be moved to other files.
|
||||
|
@ -307,6 +307,8 @@ extern void BaseInit(void);
|
|||
|
||||
/* in utils/init/miscinit.c */
|
||||
extern bool IgnoreSystemIndexes;
|
||||
extern char *preload_libraries_string;
|
||||
|
||||
extern void SetReindexProcessing(Oid heapOid, Oid indexOid);
|
||||
extern void ResetReindexProcessing(void);
|
||||
extern bool ReindexIsProcessingHeap(Oid heapOid);
|
||||
|
@ -317,6 +319,6 @@ extern void TouchSocketLockFile(void);
|
|||
extern void RecordSharedMemoryInLockFile(unsigned long id1,
|
||||
unsigned long id2);
|
||||
extern void ValidatePgVersion(const char *path);
|
||||
extern void process_preload_libraries(char *preload_libraries_string);
|
||||
extern void process_preload_libraries(void);
|
||||
|
||||
#endif /* MISCADMIN_H */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/postmaster/postmaster.h,v 1.13 2006/03/05 15:58:58 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/postmaster/postmaster.h,v 1.14 2006/08/08 19:15:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -25,7 +25,6 @@ extern char *ListenAddresses;
|
|||
extern bool ClientAuthInProgress;
|
||||
extern int PreAuthDelay;
|
||||
extern int AuthenticationTimeout;
|
||||
extern char *preload_libraries_string;
|
||||
extern bool Log_connections;
|
||||
extern bool log_hostname;
|
||||
extern char *bonjour_name;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**********************************************************************
|
||||
* plperl.c - perl as a procedural language for PostgreSQL
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.112 2006/06/16 18:42:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.113 2006/08/08 19:15:09 tgl Exp $
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
|
@ -87,7 +87,6 @@ typedef struct plperl_query_desc
|
|||
/**********************************************************************
|
||||
* Global data
|
||||
**********************************************************************/
|
||||
static bool plperl_firstcall = true;
|
||||
static bool plperl_safe_init_done = false;
|
||||
static PerlInterpreter *plperl_interp = NULL;
|
||||
static HV *plperl_proc_hash = NULL;
|
||||
|
@ -101,12 +100,11 @@ static plperl_call_data *current_call_data = NULL;
|
|||
/**********************************************************************
|
||||
* Forward declarations
|
||||
**********************************************************************/
|
||||
static void plperl_init_all(void);
|
||||
static void plperl_init_interp(void);
|
||||
|
||||
Datum plperl_call_handler(PG_FUNCTION_ARGS);
|
||||
Datum plperl_validator(PG_FUNCTION_ARGS);
|
||||
void plperl_init(void);
|
||||
void _PG_init(void);
|
||||
|
||||
static void plperl_init_interp(void);
|
||||
|
||||
static Datum plperl_func_handler(PG_FUNCTION_ARGS);
|
||||
|
||||
|
@ -135,16 +133,21 @@ perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
|
|||
}
|
||||
|
||||
|
||||
/* Perform initialization during postmaster startup. */
|
||||
|
||||
/*
|
||||
* _PG_init() - library load-time initialization
|
||||
*
|
||||
* DO NOT make this static nor change its name!
|
||||
*/
|
||||
void
|
||||
plperl_init(void)
|
||||
_PG_init(void)
|
||||
{
|
||||
if (!plperl_firstcall)
|
||||
/* Be sure we do initialization only once (should be redundant now) */
|
||||
static bool inited = false;
|
||||
|
||||
if (inited)
|
||||
return;
|
||||
|
||||
DefineCustomBoolVariable(
|
||||
"plperl.use_strict",
|
||||
DefineCustomBoolVariable("plperl.use_strict",
|
||||
"If true, will compile trusted and untrusted perl code in strict mode",
|
||||
NULL,
|
||||
&plperl_use_strict,
|
||||
|
@ -154,19 +157,8 @@ plperl_init(void)
|
|||
EmitWarningsOnPlaceholders("plperl");
|
||||
|
||||
plperl_init_interp();
|
||||
plperl_firstcall = false;
|
||||
}
|
||||
|
||||
|
||||
/* Perform initialization during backend startup. */
|
||||
|
||||
static void
|
||||
plperl_init_all(void)
|
||||
{
|
||||
if (plperl_firstcall)
|
||||
plperl_init();
|
||||
|
||||
/* We don't need to do anything yet when a new backend starts. */
|
||||
inited = true;
|
||||
}
|
||||
|
||||
/* Each of these macros must represent a single string literal */
|
||||
|
@ -657,8 +649,6 @@ plperl_call_handler(PG_FUNCTION_ARGS)
|
|||
Datum retval;
|
||||
plperl_call_data *save_call_data;
|
||||
|
||||
plperl_init_all();
|
||||
|
||||
save_call_data = current_call_data;
|
||||
PG_TRY();
|
||||
{
|
||||
|
@ -741,11 +731,7 @@ plperl_validator(PG_FUNCTION_ARGS)
|
|||
/* Postpone body checks if !check_function_bodies */
|
||||
if (check_function_bodies)
|
||||
{
|
||||
plperl_proc_desc *prodesc;
|
||||
|
||||
plperl_init_all();
|
||||
|
||||
prodesc = compile_plperl_function(funcoid, istrigger);
|
||||
(void) compile_plperl_function(funcoid, istrigger);
|
||||
}
|
||||
|
||||
/* the result of a validator is ignored */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.29 2006/05/30 22:12:16 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.30 2006/08/08 19:15:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -28,41 +28,25 @@ extern DLLIMPORT bool check_function_bodies;
|
|||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
static bool plpgsql_firstcall = true;
|
||||
|
||||
static void plpgsql_init_all(void);
|
||||
|
||||
|
||||
/*
|
||||
* plpgsql_init() - postmaster-startup safe initialization
|
||||
* _PG_init() - library load-time initialization
|
||||
*
|
||||
* DO NOT make this static --- it has to be callable by preload
|
||||
* DO NOT make this static nor change its name!
|
||||
*/
|
||||
void
|
||||
plpgsql_init(void)
|
||||
_PG_init(void)
|
||||
{
|
||||
/* Do initialization only once */
|
||||
if (!plpgsql_firstcall)
|
||||
/* Be sure we do initialization only once (should be redundant now) */
|
||||
static bool inited = false;
|
||||
|
||||
if (inited)
|
||||
return;
|
||||
|
||||
plpgsql_HashTableInit();
|
||||
RegisterXactCallback(plpgsql_xact_cb, NULL);
|
||||
plpgsql_firstcall = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* plpgsql_init_all() - Initialize all
|
||||
*/
|
||||
static void
|
||||
plpgsql_init_all(void)
|
||||
{
|
||||
/* Execute any postmaster-startup safe initialization */
|
||||
plpgsql_init();
|
||||
|
||||
/*
|
||||
* Any other initialization that must be done each time a new backend
|
||||
* starts -- currently none
|
||||
*/
|
||||
inited = true;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
|
@ -81,9 +65,6 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||
Datum retval;
|
||||
int rc;
|
||||
|
||||
/* perform initialization */
|
||||
plpgsql_init_all();
|
||||
|
||||
/*
|
||||
* Connect to SPI manager
|
||||
*/
|
||||
|
@ -135,9 +116,6 @@ plpgsql_validator(PG_FUNCTION_ARGS)
|
|||
bool istrigger = false;
|
||||
int i;
|
||||
|
||||
/* perform initialization */
|
||||
plpgsql_init_all();
|
||||
|
||||
/* Get the new function's pg_proc entry */
|
||||
tuple = SearchSysCache(PROCOID,
|
||||
ObjectIdGetDatum(funcoid),
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.77 2006/07/11 17:26:59 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.78 2006/08/08 19:15:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -678,7 +678,7 @@ extern void plpgsql_compile_error_callback(void *arg);
|
|||
* Functions in pl_handler.c
|
||||
* ----------
|
||||
*/
|
||||
extern void plpgsql_init(void);
|
||||
extern void _PG_init(void);
|
||||
extern Datum plpgsql_call_handler(PG_FUNCTION_ARGS);
|
||||
extern Datum plpgsql_validator(PG_FUNCTION_ARGS);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**********************************************************************
|
||||
* plpython.c - python as a procedural language for PostgreSQL
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.84 2006/07/06 01:55:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.85 2006/08/08 19:15:09 tgl Exp $
|
||||
*
|
||||
*********************************************************************
|
||||
*/
|
||||
|
@ -155,11 +155,11 @@ typedef struct PLyResultObject
|
|||
/* function declarations */
|
||||
|
||||
/* Two exported functions: first is the magic telling Postgresql
|
||||
* what function call interface it implements. Second allows
|
||||
* preinitialization of the interpreter during postmaster startup.
|
||||
* what function call interface it implements. Second is for
|
||||
* initialization of the interpreter during library load.
|
||||
*/
|
||||
Datum plpython_call_handler(PG_FUNCTION_ARGS);
|
||||
void plpython_init(void);
|
||||
void _PG_init(void);
|
||||
|
||||
PG_FUNCTION_INFO_V1(plpython_call_handler);
|
||||
|
||||
|
@ -169,7 +169,6 @@ PG_FUNCTION_INFO_V1(plpython_call_handler);
|
|||
* of plpython_call_handler. initialize the python interpreter
|
||||
* and global data.
|
||||
*/
|
||||
static void PLy_init_all(void);
|
||||
static void PLy_init_interp(void);
|
||||
static void PLy_init_plpy(void);
|
||||
|
||||
|
@ -233,9 +232,6 @@ static PyObject *PLyLong_FromString(const char *);
|
|||
static PyObject *PLyString_FromString(const char *);
|
||||
|
||||
|
||||
/* global data */
|
||||
static bool PLy_first_call = true;
|
||||
|
||||
/*
|
||||
* Currently active plpython function
|
||||
*/
|
||||
|
@ -301,8 +297,6 @@ plpython_call_handler(PG_FUNCTION_ARGS)
|
|||
PLyProcedure *save_curr_proc;
|
||||
PLyProcedure *volatile proc = NULL;
|
||||
|
||||
PLy_init_all();
|
||||
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "could not connect to SPI manager");
|
||||
|
||||
|
@ -2263,25 +2257,19 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
|
|||
*/
|
||||
|
||||
/*
|
||||
* plpython_init() - Initialize everything that can be
|
||||
* safely initialized during postmaster
|
||||
* startup.
|
||||
* _PG_init() - library load-time initialization
|
||||
*
|
||||
* DO NOT make this static --- it has to be callable by preload
|
||||
* DO NOT make this static nor change its name!
|
||||
*/
|
||||
void
|
||||
plpython_init(void)
|
||||
_PG_init(void)
|
||||
{
|
||||
static volatile bool init_active = false;
|
||||
/* Be sure we do initialization only once (should be redundant now) */
|
||||
static bool inited = false;
|
||||
|
||||
/* Do initialization only once */
|
||||
if (!PLy_first_call)
|
||||
if (inited)
|
||||
return;
|
||||
|
||||
if (init_active)
|
||||
elog(FATAL, "initialization of language module failed");
|
||||
init_active = true;
|
||||
|
||||
Py_Initialize();
|
||||
PLy_init_interp();
|
||||
PLy_init_plpy();
|
||||
|
@ -2291,20 +2279,7 @@ plpython_init(void)
|
|||
if (PLy_procedure_cache == NULL)
|
||||
PLy_elog(ERROR, "could not create procedure cache");
|
||||
|
||||
PLy_first_call = false;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
inited = true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* pltcl.c - PostgreSQL support for Tcl as
|
||||
* procedural language (PL)
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.105 2006/06/16 18:42:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.106 2006/08/08 19:15:09 tgl Exp $
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
|
@ -120,14 +120,13 @@ static pltcl_proc_desc *pltcl_current_prodesc = NULL;
|
|||
/**********************************************************************
|
||||
* Forward declarations
|
||||
**********************************************************************/
|
||||
static void pltcl_init_all(void);
|
||||
static void pltcl_init_interp(Tcl_Interp *interp);
|
||||
|
||||
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);
|
||||
void _PG_init(void);
|
||||
|
||||
static void pltcl_init_all(void);
|
||||
static void pltcl_init_interp(Tcl_Interp *interp);
|
||||
static void pltcl_init_load_unknown(Tcl_Interp *interp);
|
||||
|
||||
static Datum pltcl_func_handler(PG_FUNCTION_ARGS);
|
||||
|
||||
|
@ -182,17 +181,15 @@ perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
|
|||
fmgr_info_cxt(functionId, finfo, TopMemoryContext);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* pltcl_init() - Initialize all that's safe to do in the postmaster
|
||||
/*
|
||||
* _PG_init() - library load-time initialization
|
||||
*
|
||||
* DO NOT make this static --- it has to be callable by preload
|
||||
**********************************************************************/
|
||||
* DO NOT make this static nor change its name!
|
||||
*/
|
||||
void
|
||||
pltcl_init(void)
|
||||
_PG_init(void)
|
||||
{
|
||||
/************************************************************
|
||||
* Do initialization only once
|
||||
************************************************************/
|
||||
/* Be sure we do initialization only once (should be redundant now) */
|
||||
if (pltcl_pm_init_done)
|
||||
return;
|
||||
|
||||
|
@ -236,20 +233,15 @@ pltcl_init(void)
|
|||
|
||||
/**********************************************************************
|
||||
* pltcl_init_all() - Initialize all
|
||||
*
|
||||
* This does initialization that can't be done in the postmaster, and
|
||||
* hence is not safe to do at library load time.
|
||||
**********************************************************************/
|
||||
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
|
||||
* Try to load the unknown procedure from pltcl_modules
|
||||
************************************************************/
|
||||
if (!pltcl_be_init_done)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue