mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	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.
This commit is contained in:
		| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * 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 | ||||
|  *	  See acl.h. | ||||
| @@ -34,6 +34,7 @@ | ||||
| #include "catalog/pg_proc.h" | ||||
| #include "catalog/pg_tablespace.h" | ||||
| #include "catalog/pg_type.h" | ||||
| #include "commands/dbcommands.h" | ||||
| #include "miscadmin.h" | ||||
| #include "parser/parse_func.h" | ||||
| #include "utils/acl.h" | ||||
| @@ -412,8 +413,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) | ||||
| 		case ACL_OBJECT_SEQUENCE: | ||||
| 			foreach(cell, objnames) | ||||
| 			{ | ||||
| 				Oid			relOid; | ||||
| 				RangeVar   *relvar = (RangeVar *) lfirst(cell); | ||||
| 				Oid			relOid; | ||||
|  | ||||
| 				relOid = RangeVarGetRelid(relvar, false); | ||||
| 				objects = lappend_oid(objects, relOid); | ||||
| @@ -423,32 +424,15 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) | ||||
| 			foreach(cell, objnames) | ||||
| 			{ | ||||
| 				char	   *dbname = strVal(lfirst(cell)); | ||||
| 				ScanKeyData entry[1]; | ||||
| 				HeapScanDesc scan; | ||||
| 				HeapTuple	tuple; | ||||
| 				Relation	relation; | ||||
| 				Oid			dbid; | ||||
|  | ||||
| 				relation = heap_open(DatabaseRelationId, AccessShareLock); | ||||
|  | ||||
| 				/* | ||||
| 				 * There's no syscache for pg_database, so we must look the | ||||
| 				 * 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)) | ||||
| 				dbid = get_database_oid(dbname); | ||||
| 				if (!OidIsValid(dbid)) | ||||
| 					ereport(ERROR, | ||||
| 							(errcode(ERRCODE_UNDEFINED_DATABASE), | ||||
| 						  errmsg("database \"%s\" does not exist", dbname))); | ||||
| 				objects = lappend_oid(objects, HeapTupleGetOid(tuple)); | ||||
|  | ||||
| 				heap_close(relation, AccessShareLock); | ||||
|  | ||||
| 				heap_endscan(scan); | ||||
| 							 errmsg("database \"%s\" does not exist", | ||||
| 									dbname))); | ||||
| 				objects = lappend_oid(objects, dbid); | ||||
| 			} | ||||
| 			break; | ||||
| 		case ACL_OBJECT_FUNCTION: | ||||
| @@ -474,7 +458,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) | ||||
| 				if (!HeapTupleIsValid(tuple)) | ||||
| 					ereport(ERROR, | ||||
| 							(errcode(ERRCODE_UNDEFINED_OBJECT), | ||||
| 						errmsg("language \"%s\" does not exist", langname))); | ||||
| 							 errmsg("language \"%s\" does not exist", | ||||
| 									langname))); | ||||
|  | ||||
| 				objects = lappend_oid(objects, HeapTupleGetOid(tuple)); | ||||
|  | ||||
| @@ -493,7 +478,8 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) | ||||
| 				if (!HeapTupleIsValid(tuple)) | ||||
| 					ereport(ERROR, | ||||
| 							(errcode(ERRCODE_UNDEFINED_SCHEMA), | ||||
| 						   errmsg("schema \"%s\" does not exist", nspname))); | ||||
| 							 errmsg("schema \"%s\" does not exist", | ||||
| 									nspname))); | ||||
|  | ||||
| 				objects = lappend_oid(objects, HeapTupleGetOid(tuple)); | ||||
|  | ||||
| @@ -764,22 +750,13 @@ ExecGrant_Database(InternalGrant *istmt) | ||||
| 		int			nnewmembers; | ||||
| 		Oid		   *oldmembers; | ||||
| 		Oid		   *newmembers; | ||||
| 		ScanKeyData entry[1]; | ||||
| 		SysScanDesc scan; | ||||
| 		HeapTuple	tuple; | ||||
|  | ||||
| 		/* There's no syscache for pg_database, so must look the hard way */ | ||||
| 		ScanKeyInit(&entry[0], | ||||
| 					ObjectIdAttributeNumber, | ||||
| 					BTEqualStrategyNumber, F_OIDEQ, | ||||
| 					ObjectIdGetDatum(datId)); | ||||
| 		scan = systable_beginscan(relation, DatabaseOidIndexId, true, | ||||
| 								  SnapshotNow, 1, entry); | ||||
|  | ||||
| 		tuple = systable_getnext(scan); | ||||
|  | ||||
| 		tuple = SearchSysCache(DATABASEOID, | ||||
| 							   ObjectIdGetDatum(datId), | ||||
| 							   0, 0, 0); | ||||
| 		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); | ||||
|  | ||||
| @@ -847,7 +824,7 @@ ExecGrant_Database(InternalGrant *istmt) | ||||
| 							  noldmembers, oldmembers, | ||||
| 							  nnewmembers, newmembers); | ||||
|  | ||||
| 		systable_endscan(scan); | ||||
| 		ReleaseSysCache(tuple); | ||||
|  | ||||
| 		pfree(new_acl); | ||||
|  | ||||
| @@ -1657,10 +1634,11 @@ pg_database_aclmask(Oid db_oid, Oid roleid, | ||||
| 					AclMode mask, AclMaskHow how) | ||||
| { | ||||
| 	AclMode		result; | ||||
| 	Relation	pg_database; | ||||
| 	ScanKeyData entry[1]; | ||||
| 	SysScanDesc scan; | ||||
| 	HeapTuple	tuple; | ||||
| 	Datum		aclDatum; | ||||
| 	bool		isNull; | ||||
| 	Acl		   *acl; | ||||
| 	Oid			ownerId; | ||||
|  | ||||
| 	/* Superusers bypass all permission checking. */ | ||||
| 	if (superuser_arg(roleid)) | ||||
| @@ -1668,50 +1646,19 @@ pg_database_aclmask(Oid db_oid, Oid roleid, | ||||
|  | ||||
| 	/* | ||||
| 	 * 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); | ||||
| 	ScanKeyInit(&entry[0], | ||||
| 				ObjectIdAttributeNumber, | ||||
| 				BTEqualStrategyNumber, F_OIDEQ, | ||||
| 				ObjectIdGetDatum(db_oid)); | ||||
| 	scan = systable_beginscan(pg_database, DatabaseOidIndexId, true, | ||||
| 							  SnapshotNow, 1, entry); | ||||
| 	tuple = systable_getnext(scan); | ||||
| 	tuple = SearchSysCache(DATABASEOID, | ||||
| 						   ObjectIdGetDatum(db_oid), | ||||
| 						   0, 0, 0); | ||||
| 	if (!HeapTupleIsValid(tuple)) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_UNDEFINED_DATABASE), | ||||
| 				 errmsg("database with OID %u does not exist", db_oid))); | ||||
|  | ||||
| 	result = pg_database_tuple_aclmask(tuple, RelationGetDescr(pg_database), | ||||
| 									   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); | ||||
| 	ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba; | ||||
|  | ||||
| 	aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl, | ||||
| 							   &isNull); | ||||
| 	if (isNull) | ||||
| 	{ | ||||
| 		/* 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)) | ||||
| 		pfree(acl); | ||||
|  | ||||
| 	ReleaseSysCache(tuple); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -2298,36 +2247,24 @@ pg_opclass_ownercheck(Oid opc_oid, Oid roleid) | ||||
| bool | ||||
| pg_database_ownercheck(Oid db_oid, Oid roleid) | ||||
| { | ||||
| 	Relation	pg_database; | ||||
| 	ScanKeyData entry[1]; | ||||
| 	SysScanDesc scan; | ||||
| 	HeapTuple	dbtuple; | ||||
| 	HeapTuple	tuple; | ||||
| 	Oid			dba; | ||||
|  | ||||
| 	/* Superusers bypass all permission checking. */ | ||||
| 	if (superuser_arg(roleid)) | ||||
| 		return true; | ||||
|  | ||||
| 	/* There's no syscache for pg_database, so must look the hard way */ | ||||
| 	pg_database = heap_open(DatabaseRelationId, AccessShareLock); | ||||
| 	ScanKeyInit(&entry[0], | ||||
| 				ObjectIdAttributeNumber, | ||||
| 				BTEqualStrategyNumber, F_OIDEQ, | ||||
| 				ObjectIdGetDatum(db_oid)); | ||||
| 	scan = systable_beginscan(pg_database, DatabaseOidIndexId, true, | ||||
| 							  SnapshotNow, 1, entry); | ||||
|  | ||||
| 	dbtuple = systable_getnext(scan); | ||||
|  | ||||
| 	if (!HeapTupleIsValid(dbtuple)) | ||||
| 	tuple = SearchSysCache(DATABASEOID, | ||||
| 						   ObjectIdGetDatum(db_oid), | ||||
| 						   0, 0, 0); | ||||
| 	if (!HeapTupleIsValid(tuple)) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_UNDEFINED_DATABASE), | ||||
| 				 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); | ||||
| 	heap_close(pg_database, AccessShareLock); | ||||
| 	ReleaseSysCache(tuple); | ||||
|  | ||||
| 	return has_privs_of_role(roleid, dba); | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * 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; | ||||
| 	bool		db_istemplate; | ||||
| 	Relation	pgdbrel; | ||||
| 	SysScanDesc pgdbscan; | ||||
| 	ScanKeyData key; | ||||
| 	HeapTuple	tup; | ||||
|  | ||||
| 	PreventTransactionChain((void *) dbname, "DROP DATABASE"); | ||||
| @@ -629,31 +627,17 @@ dropdb(const char *dbname, bool missing_ok) | ||||
| 						dbname))); | ||||
|  | ||||
| 	/* | ||||
| 	 * Find the database's tuple by OID (should be unique). | ||||
| 	 * Remove the database's tuple from pg_database. | ||||
| 	 */ | ||||
| 	ScanKeyInit(&key, | ||||
| 				ObjectIdAttributeNumber, | ||||
| 				BTEqualStrategyNumber, F_OIDEQ, | ||||
| 				ObjectIdGetDatum(db_id)); | ||||
|  | ||||
| 	pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndexId, true, | ||||
| 								  SnapshotNow, 1, &key); | ||||
|  | ||||
| 	tup = systable_getnext(pgdbscan); | ||||
| 	tup = SearchSysCache(DATABASEOID, | ||||
| 						 ObjectIdGetDatum(db_id), | ||||
| 						 0, 0, 0); | ||||
| 	if (!HeapTupleIsValid(tup)) | ||||
| 	{ | ||||
| 		/* | ||||
| 		 * 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); | ||||
| 	} | ||||
| 		elog(ERROR, "cache lookup failed for database %u", db_id); | ||||
|  | ||||
| 	/* Remove the database's tuple from pg_database */ | ||||
| 	simple_heap_delete(pgdbrel, &tup->t_self); | ||||
|  | ||||
| 	systable_endscan(pgdbscan); | ||||
| 	ReleaseSysCache(tup); | ||||
|  | ||||
| 	/* | ||||
| 	 * Delete any comments associated with the database | ||||
| @@ -1262,7 +1246,10 @@ get_database_oid(const char *dbname) | ||||
| 	HeapTuple	dbtuple; | ||||
| 	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); | ||||
| 	ScanKeyInit(&entry[0], | ||||
| 				Anum_pg_database_datname, | ||||
| @@ -1296,32 +1283,20 @@ get_database_oid(const char *dbname) | ||||
| char * | ||||
| get_database_name(Oid dbid) | ||||
| { | ||||
| 	Relation	pg_database; | ||||
| 	ScanKeyData entry[1]; | ||||
| 	SysScanDesc scan; | ||||
| 	HeapTuple	dbtuple; | ||||
| 	char	   *result; | ||||
|  | ||||
| 	/* There's no syscache for pg_database, so must look the hard way */ | ||||
| 	pg_database = heap_open(DatabaseRelationId, AccessShareLock); | ||||
| 	ScanKeyInit(&entry[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 */ | ||||
| 	dbtuple = SearchSysCache(DATABASEOID, | ||||
| 							 ObjectIdGetDatum(dbid), | ||||
| 							 0, 0, 0); | ||||
| 	if (HeapTupleIsValid(dbtuple)) | ||||
| 	{ | ||||
| 		result = pstrdup(NameStr(((Form_pg_database) GETSTRUCT(dbtuple))->datname)); | ||||
| 		ReleaseSysCache(dbtuple); | ||||
| 	} | ||||
| 	else | ||||
| 		result = NULL; | ||||
|  | ||||
| 	systable_endscan(scan); | ||||
| 	heap_close(pg_database, AccessShareLock); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * 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/xlog.h" | ||||
| #include "catalog/catalog.h" | ||||
| #include "catalog/indexing.h" | ||||
| #include "catalog/namespace.h" | ||||
| #include "catalog/pg_database.h" | ||||
| #include "catalog/pg_index.h" | ||||
| @@ -767,27 +768,33 @@ vac_update_dbstats(Oid dbid, | ||||
| { | ||||
| 	Relation	relation; | ||||
| 	ScanKeyData entry[1]; | ||||
| 	HeapScanDesc scan; | ||||
| 	SysScanDesc	scan; | ||||
| 	HeapTuple	tuple; | ||||
| 	Buffer		buf; | ||||
| 	Form_pg_database dbform; | ||||
|  | ||||
| 	relation = heap_open(DatabaseRelationId, RowExclusiveLock); | ||||
|  | ||||
| 	/* Must use a heap scan, since there's no syscache for pg_database */ | ||||
| 	ScanKeyInit(&entry[0], | ||||
| 				ObjectIdAttributeNumber, | ||||
| 				BTEqualStrategyNumber, F_OIDEQ, | ||||
| 				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)) | ||||
| 		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 */ | ||||
| 	LockBuffer(scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE); | ||||
| 	LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); | ||||
|  | ||||
| 	dbform = (Form_pg_database) GETSTRUCT(tuple); | ||||
|  | ||||
| @@ -795,14 +802,14 @@ vac_update_dbstats(Oid dbid, | ||||
| 	dbform->datvacuumxid = vacuumXID; | ||||
| 	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 */ | ||||
| 	CacheInvalidateHeapTuple(relation, tuple); | ||||
|  | ||||
| 	heap_endscan(scan); | ||||
| 	systable_endscan(scan); | ||||
|  | ||||
| 	heap_close(relation, RowExclusiveLock); | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * 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/ps_status.h" | ||||
| #include "utils/relcache.h" | ||||
| #include "utils/syscache.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
| @@ -493,9 +494,6 @@ autovac_get_database_list(void) | ||||
| static void | ||||
| process_whole_db(void) | ||||
| { | ||||
| 	Relation	dbRel; | ||||
| 	ScanKeyData entry[1]; | ||||
| 	SysScanDesc scan; | ||||
| 	HeapTuple	tup; | ||||
| 	Form_pg_database dbForm; | ||||
| 	bool		freeze; | ||||
| @@ -511,21 +509,12 @@ process_whole_db(void) | ||||
| 	 */ | ||||
| 	pgstat_vacuum_tabstat(); | ||||
|  | ||||
| 	dbRel = heap_open(DatabaseRelationId, AccessShareLock); | ||||
|  | ||||
| 	/* Must use a table scan, since there's no syscache for pg_database */ | ||||
| 	ScanKeyInit(&entry[0], | ||||
| 				ObjectIdAttributeNumber, | ||||
| 				BTEqualStrategyNumber, F_OIDEQ, | ||||
| 				ObjectIdGetDatum(MyDatabaseId)); | ||||
|  | ||||
| 	scan = systable_beginscan(dbRel, DatabaseOidIndexId, true, | ||||
| 							  SnapshotNow, 1, entry); | ||||
|  | ||||
| 	tup = systable_getnext(scan); | ||||
|  | ||||
| 	/* Look up the pg_database entry and decide whether to FREEZE */ | ||||
| 	tup = SearchSysCache(DATABASEOID, | ||||
| 						 ObjectIdGetDatum(MyDatabaseId), | ||||
| 						 0, 0, 0); | ||||
| 	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); | ||||
|  | ||||
| @@ -534,9 +523,7 @@ process_whole_db(void) | ||||
| 	else | ||||
| 		freeze = false; | ||||
|  | ||||
| 	systable_endscan(scan); | ||||
|  | ||||
| 	heap_close(dbRel, AccessShareLock); | ||||
| 	ReleaseSysCache(tup); | ||||
|  | ||||
| 	elog(DEBUG2, "autovacuum: VACUUM%s whole database", | ||||
| 		 (freeze) ? " FREEZE" : ""); | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/backend/utils/cache/syscache.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								src/backend/utils/cache/syscache.c
									
									
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * 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 | ||||
|  *	  These routines allow the parser/planner/executor to perform | ||||
| @@ -31,6 +31,7 @@ | ||||
| #include "catalog/pg_auth_members.h" | ||||
| #include "catalog/pg_cast.h" | ||||
| #include "catalog/pg_conversion.h" | ||||
| #include "catalog/pg_database.h" | ||||
| #include "catalog/pg_index.h" | ||||
| #include "catalog/pg_inherits.h" | ||||
| #include "catalog/pg_language.h" | ||||
| @@ -273,6 +274,16 @@ static const struct cachedesc cacheinfo[] = { | ||||
| 			0, | ||||
| 			0 | ||||
| 	}}, | ||||
| 	{DatabaseRelationId,		/* DATABASEOID */ | ||||
| 		DatabaseOidIndexId, | ||||
| 		0, | ||||
| 		1, | ||||
| 		{ | ||||
| 			ObjectIdAttributeNumber, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0 | ||||
| 	}}, | ||||
| 	{IndexRelationId,			/* INDEXRELID */ | ||||
| 		IndexRelidIndexId, | ||||
| 		Anum_pg_index_indrelid, | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * 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))); | ||||
|  | ||||
| 		/* | ||||
| 		 * Check privilege to connect to the database.  To avoid making | ||||
| 		 * a whole extra search of pg_database here, we don't go through | ||||
| 		 * pg_database_aclcheck, but instead use a lower-level routine | ||||
| 		 * that we can pass the pg_database tuple to. | ||||
| 		 * Check privilege to connect to the database.  (The am_superuser | ||||
| 		 * test is redundant, but since we have the flag, might as well | ||||
| 		 * check it and save a few cycles.) | ||||
| 		 */ | ||||
| 		if (!am_superuser && | ||||
| 			pg_database_tuple_aclmask(tup, RelationGetDescr(pgdbrel), | ||||
| 									  GetUserId(), | ||||
| 									  ACL_CONNECT, ACLMASK_ANY) == 0) | ||||
| 			pg_database_aclcheck(MyDatabaseId, GetUserId(), | ||||
| 								 ACL_CONNECT) != ACLCHECK_OK) | ||||
| 			ereport(FATAL, | ||||
| 					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), | ||||
| 					 errmsg("permission denied for database %s", | ||||
| 							NameStr(dbform->datname)), | ||||
| 					 errmsg("permission denied for database \"%s\"", name), | ||||
| 					 errdetail("User does not have CONNECT privilege."))); | ||||
|  | ||||
| 		/* | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group | ||||
|  * 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 | ||||
|  *	  An ACL array is simply an array of AclItems, representing the union | ||||
| @@ -24,8 +24,6 @@ | ||||
| #ifndef ACL_H | ||||
| #define ACL_H | ||||
|  | ||||
| #include "access/htup.h" | ||||
| #include "access/tupdesc.h" | ||||
| #include "nodes/parsenodes.h" | ||||
| #include "utils/array.h" | ||||
|  | ||||
| @@ -252,8 +250,6 @@ extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, | ||||
| 				 AclMode mask, AclMaskHow how); | ||||
| extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid, | ||||
| 					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, | ||||
| 				AclMode mask, AclMaskHow how); | ||||
| 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) 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 CONNAMENSP		16 | ||||
| #define CONOID			17 | ||||
| #define INDEXRELID		18 | ||||
| #define INHRELID		19 | ||||
| #define LANGNAME		20 | ||||
| #define LANGOID			21 | ||||
| #define NAMESPACENAME	22 | ||||
| #define NAMESPACEOID	23 | ||||
| #define OPERNAMENSP		24 | ||||
| #define OPEROID			25 | ||||
| #define PROCNAMEARGSNSP 26 | ||||
| #define PROCOID			27 | ||||
| #define RELNAMENSP		28 | ||||
| #define RELOID			29 | ||||
| #define RULERELNAME		30 | ||||
| #define STATRELATT		31 | ||||
| #define TYPENAMENSP		32 | ||||
| #define TYPEOID			33 | ||||
| #define DATABASEOID		18 | ||||
| #define INDEXRELID		19 | ||||
| #define INHRELID		20 | ||||
| #define LANGNAME		21 | ||||
| #define LANGOID			22 | ||||
| #define NAMESPACENAME	23 | ||||
| #define NAMESPACEOID	24 | ||||
| #define OPERNAMENSP		25 | ||||
| #define OPEROID			26 | ||||
| #define PROCNAMEARGSNSP 27 | ||||
| #define PROCOID			28 | ||||
| #define RELNAMENSP		29 | ||||
| #define RELOID			30 | ||||
| #define RULERELNAME		31 | ||||
| #define STATRELATT		32 | ||||
| #define TYPENAMENSP		33 | ||||
| #define TYPEOID			34 | ||||
|  | ||||
| extern void InitCatalogCache(void); | ||||
| extern void InitCatalogCachePhase2(void); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user