Make superuser.c maintain a simple one-entry cache holding the superuser
status of the most recently queried userid. Since the common pattern is many successive queries about the same user (ie, the current user) this can save a lot of syscache probes.
This commit is contained in:
parent
db86f29617
commit
299c442077
@ -2,7 +2,11 @@
|
||||
*
|
||||
* superuser.c
|
||||
* The superuser() function. Determines if user has superuser privilege.
|
||||
* Also, a function to check for the owner (datdba) of a database.
|
||||
*
|
||||
* All code should use either of these two functions to find out
|
||||
* whether a given user is a superuser, rather than examining
|
||||
* pg_shadow.usesuper directly, so that the escape hatch built in for
|
||||
* the single-user case works.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
@ -10,26 +14,33 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.30 2004/12/31 22:02:45 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.31 2005/05/29 20:38:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "utils/inval.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "miscadmin.h"
|
||||
|
||||
|
||||
/*
|
||||
* In common cases the same userid (ie, the session or current ID) will
|
||||
* be queried repeatedly. So we maintain a simple one-entry cache for
|
||||
* the status of the last requested userid. The cache can be flushed
|
||||
* at need by watching for cache update events on pg_shadow.
|
||||
*/
|
||||
static AclId last_userid = 0; /* 0 == cache not valid */
|
||||
static bool last_userid_is_super = false;
|
||||
static bool userid_callback_registered = false;
|
||||
|
||||
static void UseridCallback(Datum arg, Oid relid);
|
||||
|
||||
|
||||
/*
|
||||
* The Postgres user running this command has Postgres superuser privileges
|
||||
*
|
||||
* All code should use either of these two functions to find out
|
||||
* whether a given user is a superuser, rather than evaluating
|
||||
* pg_shadow.usesuper directly, so that the escape hatch built in for
|
||||
* the single-user case works.
|
||||
*/
|
||||
bool
|
||||
superuser(void)
|
||||
@ -38,16 +49,24 @@ superuser(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The specified userid has Postgres superuser privileges
|
||||
*/
|
||||
bool
|
||||
superuser_arg(AclId userid)
|
||||
{
|
||||
bool result = false;
|
||||
bool result;
|
||||
HeapTuple utup;
|
||||
|
||||
/* Quick out for cache hit */
|
||||
if (AclIdIsValid(last_userid) && last_userid == userid)
|
||||
return last_userid_is_super;
|
||||
|
||||
/* Special escape path in case you deleted all your users. */
|
||||
if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYSID)
|
||||
return true;
|
||||
|
||||
/* OK, look up the information in pg_shadow */
|
||||
utup = SearchSysCache(SHADOWSYSID,
|
||||
Int32GetDatum(userid),
|
||||
0, 0, 0);
|
||||
@ -56,5 +75,35 @@ superuser_arg(AclId userid)
|
||||
result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
|
||||
ReleaseSysCache(utup);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Report "not superuser" for invalid userids */
|
||||
result = false;
|
||||
}
|
||||
|
||||
/* If first time through, set up callback for cache flushes */
|
||||
if (!userid_callback_registered)
|
||||
{
|
||||
CacheRegisterSyscacheCallback(SHADOWSYSID,
|
||||
UseridCallback,
|
||||
(Datum) 0);
|
||||
userid_callback_registered = true;
|
||||
}
|
||||
|
||||
/* Cache the result for next time */
|
||||
last_userid = userid;
|
||||
last_userid_is_super = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* UseridCallback
|
||||
* Syscache inval callback function
|
||||
*/
|
||||
static void
|
||||
UseridCallback(Datum arg, Oid relid)
|
||||
{
|
||||
/* Invalidate our local cache in case user's superuserness changed */
|
||||
last_userid = 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user