Commit cb98e6fb authored by Tom Lane's avatar Tom Lane

Create a syscache for pg_database-indexed-by-oid, and make use of it

in various places that were previously doing ad hoc pg_database searches.
This may speed up database-related privilege checks a little bit, but
the main motivation is to eliminate the performance reason for having
ReverifyMyDatabase do such a lot of stuff (viz, avoiding repeat scans
of pg_database during backend startup).  The locking reason for having
that routine is about to go away, and it'd be good to have the option
to break it up.
parent 5320c6cf
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.127 2006/04/30 21:15:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.128 2006/05/03 22:45:26 tgl Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "utils/acl.h" #include "utils/acl.h"
...@@ -412,8 +413,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) ...@@ -412,8 +413,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
case ACL_OBJECT_SEQUENCE: case ACL_OBJECT_SEQUENCE:
foreach(cell, objnames) foreach(cell, objnames)
{ {
Oid relOid;
RangeVar *relvar = (RangeVar *) lfirst(cell); RangeVar *relvar = (RangeVar *) lfirst(cell);
Oid relOid;
relOid = RangeVarGetRelid(relvar, false); relOid = RangeVarGetRelid(relvar, false);
objects = lappend_oid(objects, relOid); objects = lappend_oid(objects, relOid);
...@@ -423,32 +424,15 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) ...@@ -423,32 +424,15 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames) foreach(cell, objnames)
{ {
char *dbname = strVal(lfirst(cell)); char *dbname = strVal(lfirst(cell));
ScanKeyData entry[1]; Oid dbid;
HeapScanDesc scan;
HeapTuple tuple;
Relation relation;
relation = heap_open(DatabaseRelationId, AccessShareLock);
/* dbid = get_database_oid(dbname);
* There's no syscache for pg_database, so we must look the if (!OidIsValid(dbid))
* hard way.
*/
ScanKeyInit(&entry[0],
Anum_pg_database_datname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(dbname));
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
tuple = heap_getnext(scan, ForwardScanDirection);
if (!HeapTupleIsValid(tuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", dbname))); errmsg("database \"%s\" does not exist",
objects = lappend_oid(objects, HeapTupleGetOid(tuple)); dbname)));
objects = lappend_oid(objects, dbid);
heap_close(relation, AccessShareLock);
heap_endscan(scan);
} }
break; break;
case ACL_OBJECT_FUNCTION: case ACL_OBJECT_FUNCTION:
...@@ -474,7 +458,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) ...@@ -474,7 +458,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language \"%s\" does not exist", langname))); errmsg("language \"%s\" does not exist",
langname)));
objects = lappend_oid(objects, HeapTupleGetOid(tuple)); objects = lappend_oid(objects, HeapTupleGetOid(tuple));
...@@ -493,7 +478,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) ...@@ -493,7 +478,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA), (errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema \"%s\" does not exist", nspname))); errmsg("schema \"%s\" does not exist",
nspname)));
objects = lappend_oid(objects, HeapTupleGetOid(tuple)); objects = lappend_oid(objects, HeapTupleGetOid(tuple));
...@@ -764,22 +750,13 @@ ExecGrant_Database(InternalGrant *istmt) ...@@ -764,22 +750,13 @@ ExecGrant_Database(InternalGrant *istmt)
int nnewmembers; int nnewmembers;
Oid *oldmembers; Oid *oldmembers;
Oid *newmembers; Oid *newmembers;
ScanKeyData entry[1];
SysScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
/* There's no syscache for pg_database, so must look the hard way */ tuple = SearchSysCache(DATABASEOID,
ScanKeyInit(&entry[0], ObjectIdGetDatum(datId),
ObjectIdAttributeNumber, 0, 0, 0);
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(datId));
scan = systable_beginscan(relation, DatabaseOidIndexId, true,
SnapshotNow, 1, entry);
tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "could not find tuple for database %u", datId); elog(ERROR, "cache lookup failed for database %u", datId);
pg_database_tuple = (Form_pg_database) GETSTRUCT(tuple); pg_database_tuple = (Form_pg_database) GETSTRUCT(tuple);
...@@ -847,7 +824,7 @@ ExecGrant_Database(InternalGrant *istmt) ...@@ -847,7 +824,7 @@ ExecGrant_Database(InternalGrant *istmt)
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
systable_endscan(scan); ReleaseSysCache(tuple);
pfree(new_acl); pfree(new_acl);
...@@ -1657,10 +1634,11 @@ pg_database_aclmask(Oid db_oid, Oid roleid, ...@@ -1657,10 +1634,11 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
Relation pg_database;
ScanKeyData entry[1];
SysScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
Datum aclDatum;
bool isNull;
Acl *acl;
Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(roleid)) if (superuser_arg(roleid))
...@@ -1668,50 +1646,19 @@ pg_database_aclmask(Oid db_oid, Oid roleid, ...@@ -1668,50 +1646,19 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
/* /*
* Get the database's ACL from pg_database * Get the database's ACL from pg_database
*
* There's no syscache for pg_database, so must look the hard way
*/ */
pg_database = heap_open(DatabaseRelationId, AccessShareLock); tuple = SearchSysCache(DATABASEOID,
ScanKeyInit(&entry[0], ObjectIdGetDatum(db_oid),
ObjectIdAttributeNumber, 0, 0, 0);
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(db_oid));
scan = systable_beginscan(pg_database, DatabaseOidIndexId, true,
SnapshotNow, 1, entry);
tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database with OID %u does not exist", db_oid))); errmsg("database with OID %u does not exist", db_oid)));
result = pg_database_tuple_aclmask(tuple, RelationGetDescr(pg_database), ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
roleid, mask, how);
systable_endscan(scan);
heap_close(pg_database, AccessShareLock);
return result;
}
/*
* This is split out so that ReverifyMyDatabase can perform an ACL check
* without a whole extra search of pg_database
*/
AclMode
pg_database_tuple_aclmask(HeapTuple db_tuple, TupleDesc tupdesc,
Oid roleid, AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
Oid ownerId;
ownerId = ((Form_pg_database) GETSTRUCT(db_tuple))->datdba;
aclDatum = heap_getattr(db_tuple, Anum_pg_database_datacl,
tupdesc, &isNull);
aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl,
&isNull);
if (isNull) if (isNull)
{ {
/* No ACL, so build default ACL */ /* No ACL, so build default ACL */
...@@ -1730,6 +1677,8 @@ pg_database_tuple_aclmask(HeapTuple db_tuple, TupleDesc tupdesc, ...@@ -1730,6 +1677,8 @@ pg_database_tuple_aclmask(HeapTuple db_tuple, TupleDesc tupdesc,
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
pfree(acl); pfree(acl);
ReleaseSysCache(tuple);
return result; return result;
} }
...@@ -2298,36 +2247,24 @@ pg_opclass_ownercheck(Oid opc_oid, Oid roleid) ...@@ -2298,36 +2247,24 @@ pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
bool bool
pg_database_ownercheck(Oid db_oid, Oid roleid) pg_database_ownercheck(Oid db_oid, Oid roleid)
{ {
Relation pg_database; HeapTuple tuple;
ScanKeyData entry[1];
SysScanDesc scan;
HeapTuple dbtuple;
Oid dba; Oid dba;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(roleid)) if (superuser_arg(roleid))
return true; return true;
/* There's no syscache for pg_database, so must look the hard way */ tuple = SearchSysCache(DATABASEOID,
pg_database = heap_open(DatabaseRelationId, AccessShareLock); ObjectIdGetDatum(db_oid),
ScanKeyInit(&entry[0], 0, 0, 0);
ObjectIdAttributeNumber, if (!HeapTupleIsValid(tuple))
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(db_oid));
scan = systable_beginscan(pg_database, DatabaseOidIndexId, true,
SnapshotNow, 1, entry);
dbtuple = systable_getnext(scan);
if (!HeapTupleIsValid(dbtuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database with OID %u does not exist", db_oid))); errmsg("database with OID %u does not exist", db_oid)));
dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba; dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
systable_endscan(scan); ReleaseSysCache(tuple);
heap_close(pg_database, AccessShareLock);
return has_privs_of_role(roleid, dba); return has_privs_of_role(roleid, dba);
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.179 2006/03/29 21:17:38 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.180 2006/05/03 22:45:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -556,8 +556,6 @@ dropdb(const char *dbname, bool missing_ok) ...@@ -556,8 +556,6 @@ dropdb(const char *dbname, bool missing_ok)
Oid db_id; Oid db_id;
bool db_istemplate; bool db_istemplate;
Relation pgdbrel; Relation pgdbrel;
SysScanDesc pgdbscan;
ScanKeyData key;
HeapTuple tup; HeapTuple tup;
PreventTransactionChain((void *) dbname, "DROP DATABASE"); PreventTransactionChain((void *) dbname, "DROP DATABASE");
...@@ -629,31 +627,17 @@ dropdb(const char *dbname, bool missing_ok) ...@@ -629,31 +627,17 @@ dropdb(const char *dbname, bool missing_ok)
dbname))); dbname)));
/* /*
* Find the database's tuple by OID (should be unique). * Remove the database's tuple from pg_database.
*/ */
ScanKeyInit(&key, tup = SearchSysCache(DATABASEOID,
ObjectIdAttributeNumber, ObjectIdGetDatum(db_id),
BTEqualStrategyNumber, F_OIDEQ, 0, 0, 0);
ObjectIdGetDatum(db_id));
pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndexId, true,
SnapshotNow, 1, &key);
tup = systable_getnext(pgdbscan);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{ elog(ERROR, "cache lookup failed for database %u", db_id);
/*
* This error should never come up since the existence of the database
* is checked earlier
*/
elog(ERROR, "database \"%s\" doesn't exist despite earlier reports to the contrary",
dbname);
}
/* Remove the database's tuple from pg_database */
simple_heap_delete(pgdbrel, &tup->t_self); simple_heap_delete(pgdbrel, &tup->t_self);
systable_endscan(pgdbscan); ReleaseSysCache(tup);
/* /*
* Delete any comments associated with the database * Delete any comments associated with the database
...@@ -1262,7 +1246,10 @@ get_database_oid(const char *dbname) ...@@ -1262,7 +1246,10 @@ get_database_oid(const char *dbname)
HeapTuple dbtuple; HeapTuple dbtuple;
Oid oid; Oid oid;
/* There's no syscache for pg_database, so must look the hard way */ /*
* There's no syscache for pg_database indexed by name,
* so we must look the hard way.
*/
pg_database = heap_open(DatabaseRelationId, AccessShareLock); pg_database = heap_open(DatabaseRelationId, AccessShareLock);
ScanKeyInit(&entry[0], ScanKeyInit(&entry[0],
Anum_pg_database_datname, Anum_pg_database_datname,
...@@ -1296,32 +1283,20 @@ get_database_oid(const char *dbname) ...@@ -1296,32 +1283,20 @@ get_database_oid(const char *dbname)
char * char *
get_database_name(Oid dbid) get_database_name(Oid dbid)
{ {
Relation pg_database;
ScanKeyData entry[1];
SysScanDesc scan;
HeapTuple dbtuple; HeapTuple dbtuple;
char *result; char *result;
/* There's no syscache for pg_database, so must look the hard way */ dbtuple = SearchSysCache(DATABASEOID,
pg_database = heap_open(DatabaseRelationId, AccessShareLock); ObjectIdGetDatum(dbid),
ScanKeyInit(&entry[0], 0, 0, 0);
ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(dbid));
scan = systable_beginscan(pg_database, DatabaseOidIndexId, true,
SnapshotNow, 1, entry);
dbtuple = systable_getnext(scan);
/* We assume that there can be at most one matching tuple */
if (HeapTupleIsValid(dbtuple)) if (HeapTupleIsValid(dbtuple))
{
result = pstrdup(NameStr(((Form_pg_database) GETSTRUCT(dbtuple))->datname)); result = pstrdup(NameStr(((Form_pg_database) GETSTRUCT(dbtuple))->datname));
ReleaseSysCache(dbtuple);
}
else else
result = NULL; result = NULL;
systable_endscan(scan);
heap_close(pg_database, AccessShareLock);
return result; return result;
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.328 2006/05/02 22:25:10 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.329 2006/05/03 22:45:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "access/subtrans.h" #include "access/subtrans.h"
#include "access/xlog.h" #include "access/xlog.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
...@@ -767,27 +768,33 @@ vac_update_dbstats(Oid dbid, ...@@ -767,27 +768,33 @@ vac_update_dbstats(Oid dbid,
{ {
Relation relation; Relation relation;
ScanKeyData entry[1]; ScanKeyData entry[1];
HeapScanDesc scan; SysScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
Buffer buf;
Form_pg_database dbform; Form_pg_database dbform;
relation = heap_open(DatabaseRelationId, RowExclusiveLock); relation = heap_open(DatabaseRelationId, RowExclusiveLock);
/* Must use a heap scan, since there's no syscache for pg_database */
ScanKeyInit(&entry[0], ScanKeyInit(&entry[0],
ObjectIdAttributeNumber, ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ, BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(dbid)); ObjectIdGetDatum(dbid));
scan = heap_beginscan(relation, SnapshotNow, 1, entry); scan = systable_beginscan(relation, DatabaseOidIndexId, true,
SnapshotNow, 1, entry);
tuple = heap_getnext(scan, ForwardScanDirection); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "could not find tuple for database %u", dbid); elog(ERROR, "could not find tuple for database %u", dbid);
if (scan->irel)
buf = scan->iscan->xs_cbuf;
else
buf = scan->scan->rs_cbuf;
/* ensure no one else does this at the same time */ /* ensure no one else does this at the same time */
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
dbform = (Form_pg_database) GETSTRUCT(tuple); dbform = (Form_pg_database) GETSTRUCT(tuple);
...@@ -795,14 +802,14 @@ vac_update_dbstats(Oid dbid, ...@@ -795,14 +802,14 @@ vac_update_dbstats(Oid dbid,
dbform->datvacuumxid = vacuumXID; dbform->datvacuumxid = vacuumXID;
dbform->datfrozenxid = frozenXID; dbform->datfrozenxid = frozenXID;
MarkBufferDirty(scan->rs_cbuf); MarkBufferDirty(buf);
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); LockBuffer(buf, BUFFER_LOCK_UNLOCK);
/* invalidate the tuple in the cache so we'll see the change in cache */ /* invalidate the tuple in the cache so we'll see the change in cache */
CacheInvalidateHeapTuple(relation, tuple); CacheInvalidateHeapTuple(relation, tuple);
heap_endscan(scan); systable_endscan(scan);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.17 2006/04/27 15:57:10 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.18 2006/05/03 22:45:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/ps_status.h" #include "utils/ps_status.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/syscache.h"
/* /*
...@@ -493,9 +494,6 @@ autovac_get_database_list(void) ...@@ -493,9 +494,6 @@ autovac_get_database_list(void)
static void static void
process_whole_db(void) process_whole_db(void)
{ {
Relation dbRel;
ScanKeyData entry[1];
SysScanDesc scan;
HeapTuple tup; HeapTuple tup;
Form_pg_database dbForm; Form_pg_database dbForm;
bool freeze; bool freeze;
...@@ -511,21 +509,12 @@ process_whole_db(void) ...@@ -511,21 +509,12 @@ process_whole_db(void)
*/ */
pgstat_vacuum_tabstat(); pgstat_vacuum_tabstat();
dbRel = heap_open(DatabaseRelationId, AccessShareLock); /* Look up the pg_database entry and decide whether to FREEZE */
tup = SearchSysCache(DATABASEOID,
/* Must use a table scan, since there's no syscache for pg_database */ ObjectIdGetDatum(MyDatabaseId),
ScanKeyInit(&entry[0], 0, 0, 0);
ObjectIdAttributeNumber,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(MyDatabaseId));
scan = systable_beginscan(dbRel, DatabaseOidIndexId, true,
SnapshotNow, 1, entry);
tup = systable_getnext(scan);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "could not find tuple for database %u", MyDatabaseId); elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
dbForm = (Form_pg_database) GETSTRUCT(tup); dbForm = (Form_pg_database) GETSTRUCT(tup);
...@@ -534,9 +523,7 @@ process_whole_db(void) ...@@ -534,9 +523,7 @@ process_whole_db(void)
else else
freeze = false; freeze = false;
systable_endscan(scan); ReleaseSysCache(tup);
heap_close(dbRel, AccessShareLock);
elog(DEBUG2, "autovacuum: VACUUM%s whole database", elog(DEBUG2, "autovacuum: VACUUM%s whole database",
(freeze) ? " FREEZE" : ""); (freeze) ? " FREEZE" : "");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.102 2006/03/05 15:58:45 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.103 2006/05/03 22:45:26 tgl Exp $
* *
* NOTES * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "catalog/pg_auth_members.h" #include "catalog/pg_auth_members.h"
#include "catalog/pg_cast.h" #include "catalog/pg_cast.h"
#include "catalog/pg_conversion.h" #include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
...@@ -273,6 +274,16 @@ static const struct cachedesc cacheinfo[] = { ...@@ -273,6 +274,16 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{DatabaseRelationId, /* DATABASEOID */
DatabaseOidIndexId,
0,
1,
{
ObjectIdAttributeNumber,
0,
0,
0
}},
{IndexRelationId, /* INDEXRELID */ {IndexRelationId, /* INDEXRELID */
IndexRelidIndexId, IndexRelidIndexId,
Anum_pg_index_indrelid, Anum_pg_index_indrelid,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.164 2006/04/30 21:15:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.165 2006/05/03 22:45:26 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
...@@ -195,19 +195,16 @@ ReverifyMyDatabase(const char *name, bool am_superuser) ...@@ -195,19 +195,16 @@ ReverifyMyDatabase(const char *name, bool am_superuser)
name))); name)));
/* /*
* Check privilege to connect to the database. To avoid making * Check privilege to connect to the database. (The am_superuser
* a whole extra search of pg_database here, we don't go through * test is redundant, but since we have the flag, might as well
* pg_database_aclcheck, but instead use a lower-level routine * check it and save a few cycles.)
* that we can pass the pg_database tuple to.
*/ */
if (!am_superuser && if (!am_superuser &&
pg_database_tuple_aclmask(tup, RelationGetDescr(pgdbrel), pg_database_aclcheck(MyDatabaseId, GetUserId(),
GetUserId(), ACL_CONNECT) != ACLCHECK_OK)
ACL_CONNECT, ACLMASK_ANY) == 0)
ereport(FATAL, ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied for database %s", errmsg("permission denied for database \"%s\"", name),
NameStr(dbform->datname)),
errdetail("User does not have CONNECT privilege."))); errdetail("User does not have CONNECT privilege.")));
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.95 2006/04/30 21:15:33 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.96 2006/05/03 22:45:26 tgl Exp $
* *
* NOTES * NOTES
* An ACL array is simply an array of AclItems, representing the union * An ACL array is simply an array of AclItems, representing the union
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#ifndef ACL_H #ifndef ACL_H
#define ACL_H #define ACL_H
#include "access/htup.h"
#include "access/tupdesc.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "utils/array.h" #include "utils/array.h"
...@@ -252,8 +250,6 @@ extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, ...@@ -252,8 +250,6 @@ extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid, extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
extern AclMode pg_database_tuple_aclmask(HeapTuple db_tuple, TupleDesc tupdesc,
Oid roleid, AclMode mask, AclMaskHow how);
extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid, extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.62 2006/03/05 15:59:08 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.63 2006/05/03 22:45:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -46,22 +46,23 @@ ...@@ -46,22 +46,23 @@
#define CONDEFAULT 15 #define CONDEFAULT 15
#define CONNAMENSP 16 #define CONNAMENSP 16
#define CONOID 17 #define CONOID 17
#define INDEXRELID 18 #define DATABASEOID 18
#define INHRELID 19 #define INDEXRELID 19
#define LANGNAME 20 #define INHRELID 20
#define LANGOID 21 #define LANGNAME 21
#define NAMESPACENAME 22 #define LANGOID 22
#define NAMESPACEOID 23 #define NAMESPACENAME 23
#define OPERNAMENSP 24 #define NAMESPACEOID 24
#define OPEROID 25 #define OPERNAMENSP 25
#define PROCNAMEARGSNSP 26 #define OPEROID 26
#define PROCOID 27 #define PROCNAMEARGSNSP 27
#define RELNAMENSP 28 #define PROCOID 28
#define RELOID 29 #define RELNAMENSP 29
#define RULERELNAME 30 #define RELOID 30
#define STATRELATT 31 #define RULERELNAME 31
#define TYPENAMENSP 32 #define STATRELATT 32
#define TYPEOID 33 #define TYPENAMENSP 33
#define TYPEOID 34
extern void InitCatalogCache(void); extern void InitCatalogCache(void);
extern void InitCatalogCachePhase2(void); extern void InitCatalogCachePhase2(void);
......
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