mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
User and database-specific session defaults for run-time configuration
variables. New commands ALTER DATABASE ... SET and ALTER USER ... SET.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.82 2002/01/09 19:13:41 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.83 2002/03/01 22:45:15 petere Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "libpq/libpq-be.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
@@ -437,6 +438,8 @@ void
|
||||
InitializeSessionUserId(const char *username)
|
||||
{
|
||||
HeapTuple userTup;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
|
||||
/*
|
||||
* Don't do scans if we're bootstrapping, none of the system catalogs
|
||||
@@ -457,6 +460,21 @@ InitializeSessionUserId(const char *username)
|
||||
|
||||
AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
|
||||
|
||||
/*
|
||||
* Set up user-specific configuration variables. This is a good
|
||||
* place to do it so we don't have to read pg_shadow twice during
|
||||
* session startup.
|
||||
*/
|
||||
datum = SysCacheGetAttr(SHADOWNAME, userTup,
|
||||
Anum_pg_shadow_useconfig, &isnull);
|
||||
if (!isnull)
|
||||
{
|
||||
ArrayType *a;
|
||||
|
||||
a = (ArrayType *) pg_detoast_datum((struct varlena *)datum);
|
||||
ProcessGUCArray(a, PGC_S_USER);
|
||||
}
|
||||
|
||||
ReleaseSysCache(userTup);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.98 2002/02/19 20:11:18 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.99 2002/03/01 22:45:15 petere Exp $
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "storage/sinval.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/portal.h"
|
||||
#include "utils/relcache.h"
|
||||
#include "utils/syscache.h"
|
||||
@@ -70,6 +71,10 @@ static bool ThereIsAtLeastOneUser(void);
|
||||
*
|
||||
* This is also a handy place to fetch the database encoding info out
|
||||
* of pg_database, if we are in MULTIBYTE mode.
|
||||
*
|
||||
* To avoid having to read pg_database more times than necessary
|
||||
* during session startup, this place is also fitting to set up any
|
||||
* database-specific configuration variables.
|
||||
* --------------------------------
|
||||
*/
|
||||
static void
|
||||
@@ -132,6 +137,25 @@ ReverifyMyDatabase(const char *name)
|
||||
dbform->encoding);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up datbase-specific configuration variables.
|
||||
*/
|
||||
if (IsUnderPostmaster)
|
||||
{
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
|
||||
datum = heap_getattr(tup, Anum_pg_database_datconfig,
|
||||
RelationGetDescr(pgdbrel), &isnull);
|
||||
if (!isnull)
|
||||
{
|
||||
ArrayType *a;
|
||||
|
||||
a = (ArrayType *) pg_detoast_datum((struct varlena *)datum);
|
||||
ProcessGUCArray(a, PGC_S_DATABASE);
|
||||
}
|
||||
}
|
||||
|
||||
heap_endscan(pgdbscan);
|
||||
heap_close(pgdbrel, AccessShareLock);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Support for grand unified configuration scheme, including SET
|
||||
* command, configuration file, and command line options.
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.59 2002/02/23 01:31:36 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.60 2002/03/01 22:45:16 petere Exp $
|
||||
*
|
||||
* Copyright 2000 by PostgreSQL Global Development Group
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "storage/lock.h"
|
||||
#include "storage/proc.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/datetime.h"
|
||||
#include "pgstat.h"
|
||||
|
||||
@@ -89,6 +91,7 @@ bool Password_encryption = false;
|
||||
#define PG_KRB_SRVTAB ""
|
||||
#endif
|
||||
|
||||
static bool guc_session_init = false; /* XXX mildly bogus */
|
||||
|
||||
/*
|
||||
* Declarations for GUC tables
|
||||
@@ -882,7 +885,12 @@ set_config_option(const char *name, const char *value,
|
||||
int elevel;
|
||||
bool makeDefault;
|
||||
|
||||
elevel = (context == PGC_SIGHUP) ? DEBUG : ERROR;
|
||||
if (context == PGC_SIGHUP)
|
||||
elevel = DEBUG;
|
||||
else if (guc_session_init)
|
||||
elevel = NOTICE;
|
||||
else
|
||||
elevel = ERROR;
|
||||
|
||||
type = find_option(name, &record);
|
||||
if (type == PGC_NONE)
|
||||
@@ -1362,3 +1370,147 @@ assign_defaultxactisolevel(const char *value)
|
||||
else
|
||||
elog(ERROR, "bogus transaction isolation level");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ProcessGUCArray(ArrayType *array, GucSource source)
|
||||
{
|
||||
int i;
|
||||
|
||||
Assert(array);
|
||||
|
||||
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
||||
{
|
||||
Datum d;
|
||||
bool isnull;
|
||||
char *s;
|
||||
char *name;
|
||||
char *value;
|
||||
|
||||
d = array_ref(array, 1, &i,
|
||||
false /*notbyvalue*/,
|
||||
-1 /*varlenelem*/,
|
||||
-1 /*varlenarray*/,
|
||||
&isnull);
|
||||
|
||||
if (isnull)
|
||||
continue;
|
||||
|
||||
s = DatumGetCString(DirectFunctionCall1(textout, d));
|
||||
ParseLongOption(s, &name, &value);
|
||||
if (!value)
|
||||
{
|
||||
elog(NOTICE, "cannot to parse setting \"%s\"", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* prevent errors from incorrect options */
|
||||
guc_session_init = true;
|
||||
|
||||
SetConfigOption(name, value, PGC_SUSET, source);
|
||||
|
||||
guc_session_init = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ArrayType *
|
||||
GUCArrayAdd(ArrayType *array, const char *name, const char *value)
|
||||
{
|
||||
Datum datum;
|
||||
char *newval;
|
||||
ArrayType *a;
|
||||
|
||||
Assert(name);
|
||||
Assert(value);
|
||||
|
||||
/* test if the option is valid */
|
||||
set_config_option(name, value,
|
||||
superuser() ? PGC_SUSET : PGC_USERSET,
|
||||
false, PGC_S_INFINITY);
|
||||
|
||||
newval = palloc(strlen(name) + 1 + strlen(value) + 1);
|
||||
sprintf(newval, "%s=%s", name, value);
|
||||
datum = DirectFunctionCall1(textin, CStringGetDatum(newval));
|
||||
|
||||
if (array)
|
||||
{
|
||||
int index;
|
||||
bool isnull;
|
||||
int i;
|
||||
|
||||
index = ARR_DIMS(array)[0] + 1; /* add after end */
|
||||
|
||||
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
||||
{
|
||||
Datum d;
|
||||
char *current;
|
||||
|
||||
d = array_ref(array, 1, &i,
|
||||
false /*notbyvalue*/,
|
||||
-1 /*varlenelem*/,
|
||||
-1 /*varlenarray*/,
|
||||
&isnull);
|
||||
current = DatumGetCString(DirectFunctionCall1(textout, d));
|
||||
if (strncmp(current, newval, strlen(name) + 1)==0)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isnull = false;
|
||||
a = array_set(array, 1, &index, datum, false/*notbyval*/, -1, -1, &isnull);
|
||||
}
|
||||
else
|
||||
a = construct_array(&datum, 1, false, -1, 'i');
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ArrayType *
|
||||
GUCArrayDelete(ArrayType *array, const char *name)
|
||||
{
|
||||
ArrayType *newarray;
|
||||
int i;
|
||||
int index;
|
||||
|
||||
Assert(name);
|
||||
Assert(array);
|
||||
|
||||
/* test if the option is valid */
|
||||
set_config_option(name, NULL,
|
||||
superuser() ? PGC_SUSET : PGC_USERSET,
|
||||
false, PGC_S_INFINITY);
|
||||
|
||||
newarray = construct_array(NULL, 0, false, -1, 'i');
|
||||
index = 1;
|
||||
|
||||
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
||||
{
|
||||
Datum d;
|
||||
char *val;
|
||||
bool isnull;
|
||||
|
||||
d = array_ref(array, 1, &i,
|
||||
false /*notbyvalue*/,
|
||||
-1 /*varlenelem*/,
|
||||
-1 /*varlenarray*/,
|
||||
&isnull);
|
||||
val = DatumGetCString(DirectFunctionCall1(textout, d));
|
||||
|
||||
if (strncmp(val, name, strlen(name))==0
|
||||
&& val[strlen(name)] == '=')
|
||||
continue;
|
||||
|
||||
isnull = false;
|
||||
newarray = array_set(newarray, 1, &index, d, false/*notbyval*/, -1, -1, &isnull);
|
||||
index++;
|
||||
}
|
||||
|
||||
return newarray;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user