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.
REL8_2_STABLE
Tom Lane 20 years ago
parent 5320c6cf6b
commit cb98e6fb8f
  1. 137
      src/backend/catalog/aclchk.c
  2. 59
      src/backend/commands/dbcommands.c
  3. 25
      src/backend/commands/vacuum.c
  4. 29
      src/backend/postmaster/autovacuum.c
  5. 13
      src/backend/utils/cache/syscache.c
  6. 17
      src/backend/utils/init/postinit.c
  7. 6
      src/include/utils/acl.h
  8. 35
      src/include/utils/syscache.h

@ -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 @@
#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)
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)
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)
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)
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)
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)
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,
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,
/* /*
* 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,
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)
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 @@
* *
* *
* 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)
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)
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)
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)
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 @@
* *
* *
* 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 @@
#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,
{ {
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,
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 @@
* *
* *
* 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 @@
#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)
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)
*/ */
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)
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 @@
* *
* *
* 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 @@
#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[] = {
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 @@
* *
* *
* 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)
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 @@
* 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 @@
#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,
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 @@
* 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 @@
#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);

Loading…
Cancel
Save