get_whatever_oid, part 1: object types with unqualifed names
Link to previous discussion:
http://archives.postgresql.org/pgsql-hackers/2010-05/msg01195.php
Attached, please find a patch which standardizes the following
interface for object types that use unqualifed names.
Oid get_whatever_oid(char *name, bool missing_ok);
It also refactors the existing code to use these functions whenever
possible. I'm going to work up a similar path for the object types
that use qualified names, but I thought it would be a good idea to
send this first before I invest too much time in it.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Attachments:
get_whatever_oid_part1.patchapplication/octet-stream; name=get_whatever_oid_part1.patchDownload
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 2561d83..029ecda 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -43,6 +43,8 @@
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "commands/dbcommands.h"
+#include "commands/proclang.h"
+#include "commands/tablespace.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
@@ -418,7 +420,7 @@ ExecuteGrantStmt(GrantStmt *stmt)
else
istmt.grantees =
lappend_oid(istmt.grantees,
- get_roleid_checked(grantee->rolname));
+ get_role_oid(grantee->rolname, false));
}
/*
@@ -606,12 +608,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
char *dbname = strVal(lfirst(cell));
Oid dbid;
- dbid = get_database_oid(dbname);
- if (!OidIsValid(dbid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist",
- dbname)));
+ dbid = get_database_oid(dbname, false);
objects = lappend_oid(objects, dbid);
}
break;
@@ -630,18 +627,10 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *langname = strVal(lfirst(cell));
- HeapTuple tuple;
-
- tuple = SearchSysCache1(LANGNAME, PointerGetDatum(langname));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist",
- langname)));
+ Oid oid;
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
-
- ReleaseSysCache(tuple);
+ oid = get_language_oid(langname, false);
+ objects = lappend_oid(objects, oid);
}
break;
case ACL_OBJECT_LARGEOBJECT:
@@ -662,49 +651,20 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *nspname = strVal(lfirst(cell));
- HeapTuple tuple;
-
- tuple = SearchSysCache1(NAMESPACENAME,
- CStringGetDatum(nspname));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- nspname)));
-
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
+ Oid oid;
- ReleaseSysCache(tuple);
+ oid = get_namespace_oid(nspname, false);
+ objects = lappend_oid(objects, oid);
}
break;
case ACL_OBJECT_TABLESPACE:
foreach(cell, objnames)
{
char *spcname = strVal(lfirst(cell));
- ScanKeyData entry[1];
- HeapScanDesc scan;
- HeapTuple tuple;
- Relation relation;
+ Oid spcoid;
- relation = heap_open(TableSpaceRelationId, AccessShareLock);
-
- ScanKeyInit(&entry[0],
- Anum_pg_tablespace_spcname,
- BTEqualStrategyNumber, F_NAMEEQ,
- CStringGetDatum(spcname));
-
- scan = heap_beginscan(relation, SnapshotNow, 1, entry);
- tuple = heap_getnext(scan, ForwardScanDirection);
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", spcname)));
-
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
-
- heap_endscan(scan);
-
- heap_close(relation, AccessShareLock);
+ spcoid = get_tablespace_oid(spcname, false);
+ objects = lappend_oid(objects, spcoid);
}
break;
case ACL_OBJECT_FDW:
@@ -912,7 +872,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
else
iacls.grantees =
lappend_oid(iacls.grantees,
- get_roleid_checked(grantee->rolname));
+ get_role_oid(grantee->rolname, false));
}
/*
@@ -995,7 +955,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
{
char *rolename = strVal(lfirst(rolecell));
- iacls.roleid = get_roleid_checked(rolename);
+ iacls.roleid = get_role_oid(rolename, false);
/*
* We insist that calling user be a member of each target role. If
@@ -1036,18 +996,12 @@ SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
AclResult aclresult;
/*
- * Normally we'd use LookupCreationNamespace here, but it's
- * important to do the permissions check against the target role
- * not the calling user, so write it out in full. We require
- * CREATE privileges, since without CREATE you won't be able to do
- * anything using the default privs anyway.
+ * Note that we must do the permissions check against the target
+ * role not the calling user. We require CREATE privileges,
+ * since without CREATE you won't be able to do anything using the
+ * default privs anyway.
*/
- iacls->nspid = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(nspname));
- if (!OidIsValid(iacls->nspid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ iacls->nspid = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(iacls->nspid, iacls->roleid,
ACL_CREATE);
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 5581346..52acc23 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -332,13 +332,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
return myTempNamespace;
}
/* use exact schema given */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(newRelation->schemaname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- newRelation->schemaname)));
+ namespaceId = get_namespace_oid(newRelation->schemaname, false);
/* we do not check for USAGE rights here! */
}
else
@@ -2270,7 +2264,7 @@ LookupNamespaceNoError(const char *nspname)
return InvalidOid;
}
- return GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
+ return get_namespace_oid(nspname, true);
}
/*
@@ -2300,11 +2294,7 @@ LookupExplicitNamespace(const char *nspname)
*/
}
- namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ namespaceId = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
@@ -2339,11 +2329,7 @@ LookupCreationNamespace(const char *nspname)
return myTempNamespace;
}
- namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ namespaceId = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -2385,12 +2371,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
return myTempNamespace;
}
/* use exact schema given */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(schemaname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", schemaname)));
+ namespaceId = get_namespace_oid(schemaname, false);
/* we do not check for USAGE rights here! */
}
else
@@ -2414,6 +2395,26 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
}
/*
+ * get_namespace_oid - given a namespace name, look up the OID
+ *
+ * If missing_ok is false, throw an error if namespace name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_namespace_oid(const char *nspname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_SCHEMA),
+ errmsg("schema \"%s\" does not exist", nspname)));
+
+ return oid;
+}
+
+/*
* makeRangeVarFromNameList
* Utility routine to convert a qualified-name list into RangeVar form.
*/
@@ -2897,8 +2898,7 @@ recomputeNamespacePath(void)
char *rname;
rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(rname));
+ namespaceId = get_namespace_oid(rname, true);
ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
@@ -2925,8 +2925,7 @@ recomputeNamespacePath(void)
else
{
/* normal namespace reference */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(curname));
+ namespaceId = get_namespace_oid(curname, true);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
pg_namespace_aclcheck(namespaceId, roleid,
@@ -3033,8 +3032,7 @@ InitTempTableNamespace(void)
snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ namespaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(namespaceId))
{
/*
@@ -3066,8 +3064,7 @@ InitTempTableNamespace(void)
snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
MyBackendId);
- toastspaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ toastspaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(toastspaceId))
{
toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 17e1e77..ba90b60 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -210,7 +210,7 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- Oid newowner = get_roleid_checked(stmt->newowner);
+ Oid newowner = get_role_oid(stmt->newowner, true);
switch (stmt->objectType)
{
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 64792f2..2ec5019 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -42,6 +42,8 @@
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
+#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "libpq/be-fsstubs.h"
#include "miscadmin.h"
@@ -686,11 +688,10 @@ CommentDatabase(List *qualname, char *comment)
* of the database. Erroring out would prevent pg_restore from completing
* (which is really pg_restore's fault, but for now we will work around
* the problem here). Consensus is that the best fix is to treat wrong
- * database name as a WARNING not an ERROR.
+ * database name as a WARNING not an ERROR (thus, we tell get_database_oid
+ * to ignore the error so that we can handle it differently here).
*/
-
- /* First get the database OID */
- oid = get_database_oid(database);
+ oid = get_database_oid(database, true);
if (!OidIsValid(oid))
{
ereport(WARNING,
@@ -729,14 +730,7 @@ CommentTablespace(List *qualname, char *comment)
errmsg("tablespace name cannot be qualified")));
tablespace = strVal(linitial(qualname));
- oid = get_tablespace_oid(tablespace);
- if (!OidIsValid(oid))
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", tablespace)));
- return;
- }
+ oid = get_tablespace_oid(tablespace, false);
/* Check object security */
if (!pg_tablespace_ownercheck(oid, GetUserId()))
@@ -766,7 +760,7 @@ CommentRole(List *qualname, char *comment)
errmsg("role name cannot be qualified")));
role = strVal(linitial(qualname));
- oid = get_roleid_checked(role);
+ oid = get_role_oid(role, false);
/* Check object security */
if (!has_privs_of_role(GetUserId(), oid))
@@ -799,11 +793,7 @@ CommentNamespace(List *qualname, char *comment)
errmsg("schema name cannot be qualified")));
namespace = strVal(linitial(qualname));
- oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(namespace));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", namespace)));
+ oid = get_namespace_oid(namespace, false);
/* Check object security */
if (!pg_namespace_ownercheck(oid, GetUserId()))
@@ -1213,11 +1203,7 @@ CommentLanguage(List *qualname, char *comment)
errmsg("language name cannot be qualified")));
language = strVal(linitial(qualname));
- oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(language));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("language \"%s\" does not exist", language)));
+ oid = get_language_oid(language, false);
/* Check object security */
if (!superuser())
@@ -1254,12 +1240,7 @@ CommentOpClass(List *qualname, List *arguments, char *comment)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- amname)));
+ amID = get_am_oid(amname, false);
/*
* Look up the opclass.
@@ -1335,12 +1316,7 @@ CommentOpFamily(List *qualname, List *arguments, char *comment)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- amname)));
+ amID = get_am_oid(amname, false);
/*
* Look up the opfamily.
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e7dac22..9937083 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -255,7 +255,7 @@ createdb(const CreatedbStmt *stmt)
/* obtain OID of proposed owner */
if (dbowner)
- datdba = get_roleid_checked(dbowner);
+ datdba = get_role_oid(dbowner, false);
else
datdba = GetUserId();
@@ -429,12 +429,7 @@ createdb(const CreatedbStmt *stmt)
AclResult aclresult;
tablespacename = strVal(dtablespacename->arg);
- dst_deftablespace = get_tablespace_oid(tablespacename);
- if (!OidIsValid(dst_deftablespace))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- tablespacename)));
+ dst_deftablespace = get_tablespace_oid(tablespacename, false);
/* check permissions */
aclresult = pg_tablespace_aclcheck(dst_deftablespace, GetUserId(),
ACL_CREATE);
@@ -491,7 +486,7 @@ createdb(const CreatedbStmt *stmt)
* message than "unique index violation". There's a race condition but
* we're willing to accept the less friendly message in that case.
*/
- if (OidIsValid(get_database_oid(dbname)))
+ if (OidIsValid(get_database_oid(dbname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", dbname)));
@@ -919,7 +914,7 @@ RenameDatabase(const char *oldname, const char *newname)
* Make sure the new name doesn't exist. See notes for same error in
* CREATE DATABASE.
*/
- if (OidIsValid(get_database_oid(newname)))
+ if (OidIsValid(get_database_oid(newname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", newname)));
@@ -1030,11 +1025,7 @@ movedb(const char *dbname, const char *tblspcname)
/*
* Get tablespace's oid
*/
- dst_tblspcoid = get_tablespace_oid(tblspcname);
- if (dst_tblspcoid == InvalidOid)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("tablespace \"%s\" does not exist", tblspcname)));
+ dst_tblspcoid = get_tablespace_oid(tblspcname, false);
/*
* Permission checks
@@ -1402,12 +1393,7 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
void
AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
{
- Oid datid = get_database_oid(stmt->dbname);
-
- if (!OidIsValid(datid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", stmt->dbname)));
+ Oid datid = get_database_oid(stmt->dbname, false);
/*
* Obtain a lock on the database and make sure it didn't go away in the
@@ -1818,10 +1804,11 @@ errdetail_busy_db(int notherbackends, int npreparedxacts)
/*
* get_database_oid - given a database name, look up the OID
*
- * Returns InvalidOid if database name not found.
+ * If missing_ok is false, throw an error if database name not found. If
+ * true, just return InvalidOid.
*/
Oid
-get_database_oid(const char *dbname)
+get_database_oid(const char *dbname, bool missing_ok)
{
Relation pg_database;
ScanKeyData entry[1];
@@ -1852,6 +1839,12 @@ get_database_oid(const char *dbname)
systable_endscan(scan);
heap_close(pg_database, AccessShareLock);
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("database \"%s\" does not exist",
+ dbname)));
+
return oid;
}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 14356a2..6b22570 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -184,7 +184,7 @@ GetUserOidFromMapping(const char *username, bool missing_ok)
return GetUserId();
/* map to provided user */
- return missing_ok ? get_roleid(username) : get_roleid_checked(username);
+ return get_role_oid(username, missing_ok);
}
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 94657b8..69adf63 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -217,12 +217,7 @@ DefineIndex(RangeVar *heapRelation,
*/
if (tableSpaceName)
{
- tablespaceId = get_tablespace_oid(tableSpaceName);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- tableSpaceName)));
+ tablespaceId = get_tablespace_oid(tableSpaceName, false);
}
else
{
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index ac0270f..234d133 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1488,12 +1488,7 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
+ amID = get_am_oid(stmt->amname, false);
/*
* Look up the opclass.
@@ -1549,12 +1544,7 @@ RemoveOpFamily(RemoveOpFamilyStmt *stmt)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
+ amID = get_am_oid(stmt->amname, false);
/*
* Look up the opfamily.
@@ -1711,12 +1701,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
Relation rel;
AclResult aclresult;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
@@ -1805,12 +1790,7 @@ RenameOpFamily(List *name, const char *access_method, const char *newname)
Relation rel;
AclResult aclresult;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
@@ -1896,12 +1876,7 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
char *opcname;
char *schemaname;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
@@ -2018,12 +1993,7 @@ AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId)
char *opfname;
char *schemaname;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
@@ -2127,3 +2097,22 @@ AlterOpFamilyOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
newOwnerId);
}
}
+
+/*
+ * get_am_oid - given an access method name, look up the OID
+ *
+ * If missing_ok is false, throw an error if access method not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_am_oid(const char *amname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("access method \"%s\" does not exist", amname)));
+ return oid;
+}
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 633a093..a4e3afe 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -514,7 +514,7 @@ void
DropProceduralLanguage(DropPLangStmt *stmt)
{
char *languageName;
- HeapTuple langTup;
+ Oid oid;
ObjectAddress object;
/*
@@ -522,34 +522,26 @@ DropProceduralLanguage(DropPLangStmt *stmt)
*/
languageName = case_translate_language_name(stmt->plname);
- langTup = SearchSysCache1(LANGNAME, CStringGetDatum(languageName));
- if (!HeapTupleIsValid(langTup))
+ oid = get_language_oid(languageName, stmt->missing_ok);
+ if (!OidIsValid(oid))
{
- if (!stmt->missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", languageName)));
- else
- ereport(NOTICE,
- (errmsg("language \"%s\" does not exist, skipping",
- languageName)));
-
+ ereport(NOTICE,
+ (errmsg("language \"%s\" does not exist, skipping",
+ languageName)));
return;
}
/*
* Check permission
*/
- if (!pg_language_ownercheck(HeapTupleGetOid(langTup), GetUserId()))
+ if (!pg_language_ownercheck(oid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
languageName);
object.classId = LanguageRelationId;
- object.objectId = HeapTupleGetOid(langTup);
+ object.objectId = oid;
object.objectSubId = 0;
- ReleaseSysCache(langTup);
-
/*
* Do the deletion
*/
@@ -735,3 +727,22 @@ AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
newOwnerId);
}
}
+
+/*
+ * get_language_oid - given a language name, look up the OID
+ *
+ * If missing_ok is false, throw an error if language name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_language_oid(const char *langname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("language \"%s\" does not exist", langname)));
+ return oid;
+}
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index b0a9a22..6b48b52 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -57,7 +57,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
* Who is supposed to own the new schema?
*/
if (authId)
- owner_uid = get_roleid_checked(authId);
+ owner_uid = get_role_oid(authId, false);
else
owner_uid = saved_uid;
@@ -178,24 +178,13 @@ RemoveSchemas(DropStmt *drop)
errmsg("schema name cannot be qualified")));
namespaceName = strVal(linitial(names));
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ namespaceId = get_namespace_oid(namespaceName, drop->missing_ok);
if (!OidIsValid(namespaceId))
{
- if (!drop->missing_ok)
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- namespaceName)));
- }
- else
- {
- ereport(NOTICE,
- (errmsg("schema \"%s\" does not exist, skipping",
- namespaceName)));
- }
+ ereport(NOTICE,
+ (errmsg("schema \"%s\" does not exist, skipping",
+ namespaceName)));
continue;
}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 9b5ce65..9a9d9ae 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -411,12 +411,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
*/
if (stmt->tablespacename)
{
- tablespaceId = get_tablespace_oid(stmt->tablespacename);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- stmt->tablespacename)));
+ tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
}
else
{
@@ -2750,7 +2745,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
- get_roleid_checked(cmd->name),
+ get_role_oid(cmd->name, false),
false);
break;
case AT_ClusterOn: /* CLUSTER ON */
@@ -6739,11 +6734,7 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
AclResult aclresult;
/* Check that the tablespace exists */
- tablespaceId = get_tablespace_oid(tablespacename);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", tablespacename)));
+ tablespaceId = get_tablespace_oid(tablespacename, false);
/* Check its permissions */
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 862cd2d..db17841 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -246,7 +246,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */
if (stmt->owner)
- ownerId = get_roleid_checked(stmt->owner);
+ ownerId = get_role_oid(stmt->owner, false);
else
ownerId = GetUserId();
@@ -298,7 +298,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
* index would catch this anyway, but might as well give a friendlier
* message.)
*/
- if (OidIsValid(get_tablespace_oid(stmt->tablespacename)))
+ if (OidIsValid(get_tablespace_oid(stmt->tablespacename, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("tablespace \"%s\" already exists",
@@ -999,7 +999,7 @@ assign_default_tablespace(const char *newval, bool doit, GucSource source)
if (IsTransactionState())
{
if (newval[0] != '\0' &&
- !OidIsValid(get_tablespace_oid(newval)))
+ !OidIsValid(get_tablespace_oid(newval, true)))
{
ereport(GUC_complaint_elevel(source),
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -1049,7 +1049,7 @@ GetDefaultTablespace(bool forTemp)
* to refer to an existing tablespace; we just silently return InvalidOid,
* causing the new object to be created in the database's tablespace.
*/
- result = get_tablespace_oid(default_tablespace);
+ result = get_tablespace_oid(default_tablespace, true);
/*
* Allow explicit specification of database's default tablespace in
@@ -1116,21 +1116,13 @@ assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
continue;
}
- /* Else verify that name is a valid tablespace name */
- curoid = get_tablespace_oid(curname);
+ /*
+ * In an interactive SET command, we ereport for bad info.
+ * Otherwise, silently ignore any bad list elements.
+ */
+ curoid = get_tablespace_oid(curname, source < PGC_S_INTERACTIVE);
if (curoid == InvalidOid)
- {
- /*
- * In an interactive SET command, we ereport for bad info.
- * Otherwise, silently ignore any bad list elements.
- */
- if (source >= PGC_S_INTERACTIVE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- curname)));
continue;
- }
/*
* Allow explicit specification of database's default tablespace
@@ -1229,10 +1221,10 @@ PrepareTempTablespaces(void)
}
/* Else verify that name is a valid tablespace name */
- curoid = get_tablespace_oid(curname);
+ curoid = get_tablespace_oid(curname, true);
if (curoid == InvalidOid)
{
- /* Silently ignore any bad list elements */
+ /* Skip any bad list elements */
continue;
}
@@ -1265,10 +1257,11 @@ PrepareTempTablespaces(void)
/*
* get_tablespace_oid - given a tablespace name, look up the OID
*
- * Returns InvalidOid if tablespace name not found.
+ * If missing_ok is false, throw an error if tablespace name not found. If
+ * true, just return InvalidOid.
*/
Oid
-get_tablespace_oid(const char *tablespacename)
+get_tablespace_oid(const char *tablespacename, bool missing_ok)
{
Oid result;
Relation rel;
@@ -1299,6 +1292,12 @@ get_tablespace_oid(const char *tablespacename)
heap_endscan(scandesc);
heap_close(rel, AccessShareLock);
+ if (!OidIsValid(result) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("tablespace \"%s\" does not exist",
+ tablespacename)));
+
return result;
}
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 2f0788e..0007a6d 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -384,7 +384,7 @@ CreateRole(CreateRoleStmt *stmt)
foreach(item, addroleto)
{
char *oldrolename = strVal(lfirst(item));
- Oid oldroleid = get_roleid_checked(oldrolename);
+ Oid oldroleid = get_role_oid(oldrolename, false);
AddRoleMems(oldrolename, oldroleid,
list_make1(makeString(stmt->role)),
@@ -795,11 +795,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
/* look up and lock the database, if specified */
if (stmt->database != NULL)
{
- databaseid = get_database_oid(stmt->database);
- if (!OidIsValid(databaseid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("database \"%s\" not found", stmt->database)));
+ databaseid = get_database_oid(stmt->database, false);
shdepLockAndCheckObject(DatabaseRelationId, databaseid);
}
@@ -1099,7 +1095,7 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
- grantor = get_roleid_checked(stmt->grantor);
+ grantor = get_role_oid(stmt->grantor, false);
else
grantor = GetUserId();
@@ -1127,7 +1123,7 @@ GrantRole(GrantRoleStmt *stmt)
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
- roleid = get_roleid_checked(rolename);
+ roleid = get_role_oid(rolename, false);
if (stmt->is_grant)
AddRoleMems(rolename, roleid,
stmt->grantee_roles, grantee_ids,
@@ -1194,7 +1190,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/* Must have privileges on the receiving side too */
- newrole = get_roleid_checked(stmt->newrole);
+ newrole = get_role_oid(stmt->newrole, false);
if (!has_privs_of_role(GetUserId(), newrole))
ereport(ERROR,
@@ -1220,7 +1216,7 @@ roleNamesToIds(List *memberNames)
foreach(l, memberNames)
{
char *rolename = strVal(lfirst(l));
- Oid roleid = get_roleid_checked(rolename);
+ Oid roleid = get_role_oid(rolename, false);
result = lappend_oid(result, roleid);
}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index d299310..857483a 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2118,12 +2118,7 @@ OpenIntoRel(QueryDesc *queryDesc)
*/
if (into->tableSpaceName)
{
- tablespaceId = get_tablespace_oid(into->tableSpaceName);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- into->tableSpaceName)));
+ tablespaceId = get_tablespace_oid(into->tableSpaceName, false);
}
else
{
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 8d07f43..05d0fc6 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -459,7 +459,7 @@ is_member(Oid userid, const char *role)
if (!OidIsValid(userid))
return false; /* if user not exist, say "no" */
- roleid = get_roleid(role);
+ roleid = get_role_oid(role, true);
if (!OidIsValid(roleid))
return false; /* if target role not exist, say "no" */
@@ -1327,7 +1327,7 @@ check_hba(hbaPort *port)
HbaLine *hba;
/* Get the target role's OID. Note we do not error out for bad role. */
- roleid = get_roleid(port->user_name);
+ roleid = get_role_oid(port->user_name, true);
foreach(line, parsed_hba_lines)
{
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index faad11e..b320569 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -22,6 +22,7 @@
#include "catalog/pg_type.h"
#include "catalog/pg_class.h"
#include "commands/dbcommands.h"
+#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "foreign/foreign.h"
#include "funcapi.h"
@@ -324,7 +325,7 @@ aclparse(const char *s, AclItem *aip)
if (name[0] == '\0')
aip->ai_grantee = ACL_ID_PUBLIC;
else
- aip->ai_grantee = get_roleid_checked(name);
+ aip->ai_grantee = get_role_oid(name, false);
/*
* XXX Allow a degree of backward compatibility by defaulting the grantor
@@ -337,7 +338,7 @@ aclparse(const char *s, AclItem *aip)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("a name must follow the \"/\" sign")));
- aip->ai_grantor = get_roleid_checked(name2);
+ aip->ai_grantor = get_role_oid(name2, false);
}
else
{
@@ -1790,7 +1791,7 @@ has_table_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
@@ -1839,7 +1840,7 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_table_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
@@ -1997,7 +1998,7 @@ has_sequence_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
mode = convert_sequence_priv_string(priv_type_text);
sequenceoid = convert_table_name(sequencename);
if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE)
@@ -2057,7 +2058,7 @@ has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
AclResult aclresult;
char relkind;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_sequence_priv_string(priv_type_text);
relkind = get_rel_relkind(sequenceoid);
if (relkind == '\0')
@@ -2208,7 +2209,7 @@ has_any_column_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_column_priv_string(priv_type_text);
@@ -2265,7 +2266,7 @@ has_any_column_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_column_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
@@ -2450,7 +2451,7 @@ has_column_privilege_name_name_name(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
colattnum = convert_column_name(tableoid, column);
mode = convert_column_priv_string(priv_type_text);
@@ -2478,7 +2479,7 @@ has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_column_priv_string(priv_type_text);
@@ -2505,7 +2506,7 @@ has_column_privilege_name_id_name(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
colattnum = convert_column_name(tableoid, column);
mode = convert_column_priv_string(priv_type_text);
@@ -2531,7 +2532,7 @@ has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_column_priv_string(priv_type_text);
privresult = column_privilege_check(tableoid, colattnum, roleid, mode);
@@ -2822,7 +2823,7 @@ has_database_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
@@ -2871,7 +2872,7 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_database_priv_string(priv_type_text);
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
@@ -2966,15 +2967,8 @@ static Oid
convert_database_name(text *databasename)
{
char *dbname = text_to_cstring(databasename);
- Oid oid;
- oid = get_database_oid(dbname);
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", dbname)));
-
- return oid;
+ return get_database_oid(dbname, false);
}
/*
@@ -3027,7 +3021,7 @@ has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
@@ -3076,7 +3070,7 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
@@ -3209,7 +3203,7 @@ has_function_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
@@ -3258,7 +3252,7 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_function_priv_string(priv_type_text);
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
@@ -3409,7 +3403,7 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
@@ -3458,7 +3452,7 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_language_priv_string(priv_type_text);
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
@@ -3553,15 +3547,8 @@ static Oid
convert_language_name(text *languagename)
{
char *langname = text_to_cstring(languagename);
- Oid oid;
- oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", langname)));
-
- return oid;
+ return get_language_oid(langname, false);
}
/*
@@ -3607,7 +3594,7 @@ has_schema_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
@@ -3656,7 +3643,7 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_schema_priv_string(priv_type_text);
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
@@ -3751,15 +3738,8 @@ static Oid
convert_schema_name(text *schemaname)
{
char *nspname = text_to_cstring(schemaname);
- Oid oid;
-
- oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
- return oid;
+ return get_namespace_oid(nspname, false);
}
/*
@@ -3807,7 +3787,7 @@ has_server_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
@@ -3856,7 +3836,7 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_server_priv_string(priv_type_text);
aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
@@ -3989,7 +3969,7 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
@@ -4038,7 +4018,7 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_tablespace_priv_string(priv_type_text);
aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
@@ -4124,16 +4104,8 @@ static Oid
convert_tablespace_name(text *tablespacename)
{
char *spcname = text_to_cstring(tablespacename);
- Oid oid;
- oid = get_tablespace_oid(spcname);
-
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", spcname)));
-
- return oid;
+ return get_tablespace_oid(spcname, false);
}
/*
@@ -4178,8 +4150,8 @@ pg_has_role_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*username), false);
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4204,7 +4176,7 @@ pg_has_role_name(PG_FUNCTION_ARGS)
AclResult aclresult;
roleid = GetUserId();
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4227,7 +4199,7 @@ pg_has_role_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4273,7 +4245,7 @@ pg_has_role_id_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4830,3 +4802,22 @@ select_best_grantor(Oid roleId, AclMode privileges,
}
}
}
+
+/*
+ * get_role_oid - Given a role name, look up the role's OID.
+ *
+ * If missing_ok is false, throw an error if tablespace name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_role_oid(const char *rolname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(rolname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", rolname)));
+ return oid;
+}
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index a4e0252..8ec6b71 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -141,13 +141,7 @@ Datum
pg_database_size_name(PG_FUNCTION_ARGS)
{
Name dbName = PG_GETARG_NAME(0);
- Oid dbOid = get_database_oid(NameStr(*dbName));
-
- if (!OidIsValid(dbOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist",
- NameStr(*dbName))));
+ Oid dbOid = get_database_oid(NameStr(*dbName), false);
PG_RETURN_INT64(calculate_database_size(dbOid));
}
@@ -240,13 +234,7 @@ Datum
pg_tablespace_size_name(PG_FUNCTION_ARGS)
{
Name tblspcName = PG_GETARG_NAME(0);
- Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName));
-
- if (!OidIsValid(tblspcOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- NameStr(*tblspcName))));
+ Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName), false);
PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index aad6c35..9932415 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2626,34 +2626,3 @@ get_namespace_name(Oid nspid)
else
return NULL;
}
-
-/* ---------- PG_AUTHID CACHE ---------- */
-
-/*
- * get_roleid
- * Given a role name, look up the role's OID.
- * Returns InvalidOid if no such role.
- */
-Oid
-get_roleid(const char *rolname)
-{
- return GetSysCacheOid1(AUTHNAME, PointerGetDatum(rolname));
-}
-
-/*
- * get_roleid_checked
- * Given a role name, look up the role's OID.
- * ereports if no such role.
- */
-Oid
-get_roleid_checked(const char *rolname)
-{
- Oid roleid;
-
- roleid = get_roleid(rolname);
- if (!OidIsValid(roleid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", rolname)));
- return roleid;
-}
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index fe3b783..0fd61a9 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -91,6 +91,7 @@ extern void DeconstructQualifiedName(List *names,
char **objname_p);
extern Oid LookupNamespaceNoError(const char *nspname);
extern Oid LookupExplicitNamespace(const char *nspname);
+extern Oid get_namespace_oid(const char *nspname, bool missing_ok);
extern Oid LookupCreationNamespace(const char *nspname);
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h
index 542fc27..8c5ba1b 100644
--- a/src/include/commands/dbcommands.h
+++ b/src/include/commands/dbcommands.h
@@ -59,7 +59,7 @@ extern void AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel);
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId);
-extern Oid get_database_oid(const char *dbname);
+extern Oid get_database_oid(const char *dbname, bool missingok);
extern char *get_database_name(Oid dbid);
extern void dbase_redo(XLogRecPtr lsn, XLogRecord *rptr);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index e8dbe81..54011a0 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -97,6 +97,7 @@ extern void RenameOpClass(List *name, const char *access_method, const char *new
extern void RenameOpFamily(List *name, const char *access_method, const char *newname);
extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
+extern Oid get_am_oid(const char *amname, bool missing_ok);
/* commands/tsearchcmds.c */
extern void DefineTSParser(List *names, List *parameters);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index 5feff87..16c1d14 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -21,5 +21,6 @@ extern void RenameLanguage(const char *oldname, const char *newname);
extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
extern void AlterLanguageOwner_oid(Oid oid, Oid newOwnerId);
extern bool PLTemplateExists(const char *languageName);
+extern Oid get_language_oid(const char *langname, bool missing_ok);
#endif /* PROCLANG_H */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index cf005ee..98a9b86 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -51,7 +51,7 @@ extern Oid GetDefaultTablespace(bool forTemp);
extern void PrepareTempTablespaces(void);
-extern Oid get_tablespace_oid(const char *tablespacename);
+extern Oid get_tablespace_oid(const char *tablespacename, bool missing_ok);
extern char *get_tablespace_name(Oid spc_oid);
extern bool directory_is_empty(const char *path);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 9c38bd1..d9921e8 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -223,6 +223,7 @@ extern bool is_member_of_role(Oid member, Oid role);
extern bool is_member_of_role_nosuper(Oid member, Oid role);
extern bool is_admin_of_role(Oid member, Oid role);
extern void check_is_member_of_role(Oid member, Oid role);
+extern Oid get_role_oid(const char *rolname, bool missing_ok);
extern void select_best_grantor(Oid roleId, AclMode privileges,
const Acl *acl, Oid ownerId,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 131acb7..066ad76 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -136,8 +136,6 @@ extern void free_attstatsslot(Oid atttype,
Datum *values, int nvalues,
float4 *numbers, int nnumbers);
extern char *get_namespace_name(Oid nspid);
-extern Oid get_roleid(const char *rolname);
-extern Oid get_roleid_checked(const char *rolname);
#define type_is_array(typid) (get_element_type(typid) != InvalidOid)
(2010/05/27 11:51), Robert Haas wrote:
Link to previous discussion:
http://archives.postgresql.org/pgsql-hackers/2010-05/msg01195.php
Attached, please find a patch which standardizes the following
interface for object types that use unqualifed names.Oid get_whatever_oid(char *name, bool missing_ok);
It also refactors the existing code to use these functions whenever
possible. I'm going to work up a similar path for the object types
that use qualified names, but I thought it would be a good idea to
send this first before I invest too much time in it.
This patch is not obviously small, but most part of the changeset are
mechanical. So, I could not find any other matters in this patch except
for the following three items.
* Patch format.
This patch uses the unified format, instead of the context format. :D
* ExecAlterOwnerStmt()
The original code uses get_roleid_checked() which does not allow invalid
username, but the new code gives missing_ok = true on the get_role_oid().
It should be fixed.
| --- a/src/backend/commands/alter.c
| +++ b/src/backend/commands/alter.c
| @@ -210,7 +210,7 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
| void
| ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
| {
| - Oid newowner = get_roleid_checked(stmt->newowner);
| + Oid newowner = get_role_oid(stmt->newowner, true);
|
| switch (stmt->objectType)
| {
* assign_temp_tablespaces()?
| @@ -1116,21 +1116,13 @@ assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
| continue;
| }
|
| - /* Else verify that name is a valid tablespace name */
| - curoid = get_tablespace_oid(curname);
| + /*
| + * In an interactive SET command, we ereport for bad info.
| + * Otherwise, silently ignore any bad list elements.
| + */
| + curoid = get_tablespace_oid(curname, source < PGC_S_INTERACTIVE);
| if (curoid == InvalidOid)
It seems to me "if (!OidIsValid(curoid))" should be here, instead of comparison
with InvalidOid here. However, it may be cleaned up in any other patch instead
of get_whatever_oid() efforts.
| - {
| - /*
| - * In an interactive SET command, we ereport for bad info.
| - * Otherwise, silently ignore any bad list elements.
| - */
| - if (source >= PGC_S_INTERACTIVE)
| - ereport(ERROR,
| - (errcode(ERRCODE_UNDEFINED_OBJECT),
| - errmsg("tablespace \"%s\" does not exist",
| - curname)));
| continue;
| - }
|
| /*
| * Allow explicit specification of database's default tablespace
In addition, I could find out the following candidates to be replaced with
the new get_xxx_oid() APIs. Apart from whether these items should be cleaned
up in this patch at once, or not, it seems to me this patch can refactor the
following redundant codes.
* at the CreateRole(CreateRoleStmt *stmt)
| tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
| if (HeapTupleIsValid(tuple))
| ereport(ERROR,
| (errcode(ERRCODE_DUPLICATE_OBJECT),
| errmsg("role \"%s\" already exists",
| stmt->role)));
I saw similar code which was replaced with the new APIs in this patch.
It seems to me "if (OidIsValid(get_role_oid(stmt->role, true)))" can be used,
and it enables to write the code more clean.
* at the DefineOpFamily()
| /* Get necessary info about access method */
| tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
| if (!HeapTupleIsValid(tup))
| ereport(ERROR,
| (errcode(ERRCODE_UNDEFINED_OBJECT),
| errmsg("access method \"%s\" does not exist",
| stmt->amname)));
|
| amoid = HeapTupleGetOid(tup);
|
| /* XXX Should we make any privilege check against the AM? */
|
| ReleaseSysCache(tup);
It can be replaced by get_am_oid(stmt->amname, false).
* at the RenameSchema()
| /* make sure the new name doesn't exist */
| if (HeapTupleIsValid(
| SearchSysCache1(NAMESPACENAME,
| CStringGetDatum(newname))))
| ereport(ERROR,
| (errcode(ERRCODE_DUPLICATE_SCHEMA),
| errmsg("schema \"%s\" already exists", newname)));
It is similar to the case of CreateRole(). Does get_namespace_oid()
enables to write the code more clean?
Thanks,
--
KaiGai Kohei <kaigai@ak.jp.nec.com>
2010/6/28 KaiGai Kohei <kaigai@ak.jp.nec.com>:
* ExecAlterOwnerStmt()
The original code uses get_roleid_checked() which does not allow invalid
username, but the new code gives missing_ok = true on the get_role_oid().
It should be fixed.
Woops, good catch. Fixed.
* assign_temp_tablespaces()?
It seems to me "if (!OidIsValid(curoid))" should be here, instead of comparison
with InvalidOid here. However, it may be cleaned up in any other patch instead
of get_whatever_oid() efforts.
Yeah, we have a lot of places that check foo == InvalidOid or foo !=
InvalidOid rather than using OidIsValid(). That might or might not be
worth changing, but I don't see a strong need for this patch to change
this particular instance.
* at the CreateRole(CreateRoleStmt *stmt)
I saw similar code which was replaced with the new APIs in this patch.
It seems to me "if (OidIsValid(get_role_oid(stmt->role, true)))" can be used,
and it enables to write the code more clean.
I agree. Changed.
* at the DefineOpFamily()
| /* Get necessary info about access method */
| tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
| if (!HeapTupleIsValid(tup))
| ereport(ERROR,
| (errcode(ERRCODE_UNDEFINED_OBJECT),
| errmsg("access method \"%s\" does not exist",
| stmt->amname)));
|
| amoid = HeapTupleGetOid(tup);
|
| /* XXX Should we make any privilege check against the AM? */
|
| ReleaseSysCache(tup);It can be replaced by get_am_oid(stmt->amname, false).
I agree, done. In fact, aren't we leaking a syscache reference here?
And if so, should we fix it in HEAD and the backbranches also? I'm
tempted not to bother because, after all, how often do you invoke
DefineOpFamily(), but maybe someone else has a different opinion?
* at the RenameSchema()
| /* make sure the new name doesn't exist */
| if (HeapTupleIsValid(
| SearchSysCache1(NAMESPACENAME,
| CStringGetDatum(newname))))
| ereport(ERROR,
| (errcode(ERRCODE_DUPLICATE_SCHEMA),
| errmsg("schema \"%s\" already exists", newname)));It is similar to the case of CreateRole(). Does get_namespace_oid()
enables to write the code more clean?
This looks like another syscache reference leak. I have changed it to
use get_namespace_oid() in the patch, but we need to decide whether to
fix this in pre-9.1 releases.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Attachments:
get_whatever_oid_part1-v2.patchapplication/octet-stream; name=get_whatever_oid_part1-v2.patchDownload
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 23d604e..2b2c326 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -43,6 +43,8 @@
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "commands/dbcommands.h"
+#include "commands/proclang.h"
+#include "commands/tablespace.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
@@ -419,7 +421,7 @@ ExecuteGrantStmt(GrantStmt *stmt)
else
istmt.grantees =
lappend_oid(istmt.grantees,
- get_roleid_checked(grantee->rolname));
+ get_role_oid(grantee->rolname, false));
}
/*
@@ -607,12 +609,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
char *dbname = strVal(lfirst(cell));
Oid dbid;
- dbid = get_database_oid(dbname);
- if (!OidIsValid(dbid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist",
- dbname)));
+ dbid = get_database_oid(dbname, false);
objects = lappend_oid(objects, dbid);
}
break;
@@ -631,18 +628,10 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *langname = strVal(lfirst(cell));
- HeapTuple tuple;
-
- tuple = SearchSysCache1(LANGNAME, PointerGetDatum(langname));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist",
- langname)));
+ Oid oid;
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
-
- ReleaseSysCache(tuple);
+ oid = get_language_oid(langname, false);
+ objects = lappend_oid(objects, oid);
}
break;
case ACL_OBJECT_LARGEOBJECT:
@@ -663,49 +652,20 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *nspname = strVal(lfirst(cell));
- HeapTuple tuple;
-
- tuple = SearchSysCache1(NAMESPACENAME,
- CStringGetDatum(nspname));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- nspname)));
-
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
+ Oid oid;
- ReleaseSysCache(tuple);
+ oid = get_namespace_oid(nspname, false);
+ objects = lappend_oid(objects, oid);
}
break;
case ACL_OBJECT_TABLESPACE:
foreach(cell, objnames)
{
char *spcname = strVal(lfirst(cell));
- ScanKeyData entry[1];
- HeapScanDesc scan;
- HeapTuple tuple;
- Relation relation;
+ Oid spcoid;
- relation = heap_open(TableSpaceRelationId, AccessShareLock);
-
- ScanKeyInit(&entry[0],
- Anum_pg_tablespace_spcname,
- BTEqualStrategyNumber, F_NAMEEQ,
- CStringGetDatum(spcname));
-
- scan = heap_beginscan(relation, SnapshotNow, 1, entry);
- tuple = heap_getnext(scan, ForwardScanDirection);
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", spcname)));
-
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
-
- heap_endscan(scan);
-
- heap_close(relation, AccessShareLock);
+ spcoid = get_tablespace_oid(spcname, false);
+ objects = lappend_oid(objects, spcoid);
}
break;
case ACL_OBJECT_FDW:
@@ -913,7 +873,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
else
iacls.grantees =
lappend_oid(iacls.grantees,
- get_roleid_checked(grantee->rolname));
+ get_role_oid(grantee->rolname, false));
}
/*
@@ -996,7 +956,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
{
char *rolename = strVal(lfirst(rolecell));
- iacls.roleid = get_roleid_checked(rolename);
+ iacls.roleid = get_role_oid(rolename, false);
/*
* We insist that calling user be a member of each target role. If
@@ -1037,18 +997,12 @@ SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
AclResult aclresult;
/*
- * Normally we'd use LookupCreationNamespace here, but it's
- * important to do the permissions check against the target role
- * not the calling user, so write it out in full. We require
- * CREATE privileges, since without CREATE you won't be able to do
- * anything using the default privs anyway.
+ * Note that we must do the permissions check against the target
+ * role not the calling user. We require CREATE privileges,
+ * since without CREATE you won't be able to do anything using the
+ * default privs anyway.
*/
- iacls->nspid = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(nspname));
- if (!OidIsValid(iacls->nspid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ iacls->nspid = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(iacls->nspid, iacls->roleid,
ACL_CREATE);
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 5581346..52acc23 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -332,13 +332,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
return myTempNamespace;
}
/* use exact schema given */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(newRelation->schemaname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- newRelation->schemaname)));
+ namespaceId = get_namespace_oid(newRelation->schemaname, false);
/* we do not check for USAGE rights here! */
}
else
@@ -2270,7 +2264,7 @@ LookupNamespaceNoError(const char *nspname)
return InvalidOid;
}
- return GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
+ return get_namespace_oid(nspname, true);
}
/*
@@ -2300,11 +2294,7 @@ LookupExplicitNamespace(const char *nspname)
*/
}
- namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ namespaceId = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
@@ -2339,11 +2329,7 @@ LookupCreationNamespace(const char *nspname)
return myTempNamespace;
}
- namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ namespaceId = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -2385,12 +2371,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
return myTempNamespace;
}
/* use exact schema given */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(schemaname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", schemaname)));
+ namespaceId = get_namespace_oid(schemaname, false);
/* we do not check for USAGE rights here! */
}
else
@@ -2414,6 +2395,26 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
}
/*
+ * get_namespace_oid - given a namespace name, look up the OID
+ *
+ * If missing_ok is false, throw an error if namespace name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_namespace_oid(const char *nspname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_SCHEMA),
+ errmsg("schema \"%s\" does not exist", nspname)));
+
+ return oid;
+}
+
+/*
* makeRangeVarFromNameList
* Utility routine to convert a qualified-name list into RangeVar form.
*/
@@ -2897,8 +2898,7 @@ recomputeNamespacePath(void)
char *rname;
rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(rname));
+ namespaceId = get_namespace_oid(rname, true);
ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
@@ -2925,8 +2925,7 @@ recomputeNamespacePath(void)
else
{
/* normal namespace reference */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(curname));
+ namespaceId = get_namespace_oid(curname, true);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
pg_namespace_aclcheck(namespaceId, roleid,
@@ -3033,8 +3032,7 @@ InitTempTableNamespace(void)
snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ namespaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(namespaceId))
{
/*
@@ -3066,8 +3064,7 @@ InitTempTableNamespace(void)
snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
MyBackendId);
- toastspaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ toastspaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(toastspaceId))
{
toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index a6c4755..f09d595 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -211,7 +211,7 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- Oid newowner = get_roleid_checked(stmt->newowner);
+ Oid newowner = get_role_oid(stmt->newowner, false);
switch (stmt->objectType)
{
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index b613cbf..2ba2368 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -42,6 +42,8 @@
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
+#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "libpq/be-fsstubs.h"
#include "miscadmin.h"
@@ -686,11 +688,10 @@ CommentDatabase(List *qualname, char *comment)
* of the database. Erroring out would prevent pg_restore from completing
* (which is really pg_restore's fault, but for now we will work around
* the problem here). Consensus is that the best fix is to treat wrong
- * database name as a WARNING not an ERROR.
+ * database name as a WARNING not an ERROR (thus, we tell get_database_oid
+ * to ignore the error so that we can handle it differently here).
*/
-
- /* First get the database OID */
- oid = get_database_oid(database);
+ oid = get_database_oid(database, true);
if (!OidIsValid(oid))
{
ereport(WARNING,
@@ -729,14 +730,7 @@ CommentTablespace(List *qualname, char *comment)
errmsg("tablespace name cannot be qualified")));
tablespace = strVal(linitial(qualname));
- oid = get_tablespace_oid(tablespace);
- if (!OidIsValid(oid))
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", tablespace)));
- return;
- }
+ oid = get_tablespace_oid(tablespace, false);
/* Check object security */
if (!pg_tablespace_ownercheck(oid, GetUserId()))
@@ -766,7 +760,7 @@ CommentRole(List *qualname, char *comment)
errmsg("role name cannot be qualified")));
role = strVal(linitial(qualname));
- oid = get_roleid_checked(role);
+ oid = get_role_oid(role, false);
/* Check object security */
if (!has_privs_of_role(GetUserId(), oid))
@@ -799,11 +793,7 @@ CommentNamespace(List *qualname, char *comment)
errmsg("schema name cannot be qualified")));
namespace = strVal(linitial(qualname));
- oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(namespace));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", namespace)));
+ oid = get_namespace_oid(namespace, false);
/* Check object security */
if (!pg_namespace_ownercheck(oid, GetUserId()))
@@ -1213,11 +1203,7 @@ CommentLanguage(List *qualname, char *comment)
errmsg("language name cannot be qualified")));
language = strVal(linitial(qualname));
- oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(language));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("language \"%s\" does not exist", language)));
+ oid = get_language_oid(language, false);
/* Check object security */
if (!superuser())
@@ -1254,12 +1240,7 @@ CommentOpClass(List *qualname, List *arguments, char *comment)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- amname)));
+ amID = get_am_oid(amname, false);
/*
* Look up the opclass.
@@ -1335,12 +1316,7 @@ CommentOpFamily(List *qualname, List *arguments, char *comment)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- amname)));
+ amID = get_am_oid(amname, false);
/*
* Look up the opfamily.
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e7dac22..9937083 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -255,7 +255,7 @@ createdb(const CreatedbStmt *stmt)
/* obtain OID of proposed owner */
if (dbowner)
- datdba = get_roleid_checked(dbowner);
+ datdba = get_role_oid(dbowner, false);
else
datdba = GetUserId();
@@ -429,12 +429,7 @@ createdb(const CreatedbStmt *stmt)
AclResult aclresult;
tablespacename = strVal(dtablespacename->arg);
- dst_deftablespace = get_tablespace_oid(tablespacename);
- if (!OidIsValid(dst_deftablespace))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- tablespacename)));
+ dst_deftablespace = get_tablespace_oid(tablespacename, false);
/* check permissions */
aclresult = pg_tablespace_aclcheck(dst_deftablespace, GetUserId(),
ACL_CREATE);
@@ -491,7 +486,7 @@ createdb(const CreatedbStmt *stmt)
* message than "unique index violation". There's a race condition but
* we're willing to accept the less friendly message in that case.
*/
- if (OidIsValid(get_database_oid(dbname)))
+ if (OidIsValid(get_database_oid(dbname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", dbname)));
@@ -919,7 +914,7 @@ RenameDatabase(const char *oldname, const char *newname)
* Make sure the new name doesn't exist. See notes for same error in
* CREATE DATABASE.
*/
- if (OidIsValid(get_database_oid(newname)))
+ if (OidIsValid(get_database_oid(newname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", newname)));
@@ -1030,11 +1025,7 @@ movedb(const char *dbname, const char *tblspcname)
/*
* Get tablespace's oid
*/
- dst_tblspcoid = get_tablespace_oid(tblspcname);
- if (dst_tblspcoid == InvalidOid)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("tablespace \"%s\" does not exist", tblspcname)));
+ dst_tblspcoid = get_tablespace_oid(tblspcname, false);
/*
* Permission checks
@@ -1402,12 +1393,7 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
void
AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
{
- Oid datid = get_database_oid(stmt->dbname);
-
- if (!OidIsValid(datid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", stmt->dbname)));
+ Oid datid = get_database_oid(stmt->dbname, false);
/*
* Obtain a lock on the database and make sure it didn't go away in the
@@ -1818,10 +1804,11 @@ errdetail_busy_db(int notherbackends, int npreparedxacts)
/*
* get_database_oid - given a database name, look up the OID
*
- * Returns InvalidOid if database name not found.
+ * If missing_ok is false, throw an error if database name not found. If
+ * true, just return InvalidOid.
*/
Oid
-get_database_oid(const char *dbname)
+get_database_oid(const char *dbname, bool missing_ok)
{
Relation pg_database;
ScanKeyData entry[1];
@@ -1852,6 +1839,12 @@ get_database_oid(const char *dbname)
systable_endscan(scan);
heap_close(pg_database, AccessShareLock);
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("database \"%s\" does not exist",
+ dbname)));
+
return oid;
}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 14356a2..6b22570 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -184,7 +184,7 @@ GetUserOidFromMapping(const char *username, bool missing_ok)
return GetUserId();
/* map to provided user */
- return missing_ok ? get_roleid(username) : get_roleid_checked(username);
+ return get_role_oid(username, missing_ok);
}
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 503148f..60f4c44 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -218,12 +218,7 @@ DefineIndex(RangeVar *heapRelation,
*/
if (tableSpaceName)
{
- tablespaceId = get_tablespace_oid(tableSpaceName);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- tableSpaceName)));
+ tablespaceId = get_tablespace_oid(tableSpaceName, false);
}
else
{
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index ac0270f..fef2113 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -661,20 +661,11 @@ DefineOpFamily(CreateOpFamilyStmt *stmt)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceoid));
- /* Get necessary info about access method */
- tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
-
- amoid = HeapTupleGetOid(tup);
+ /* Get access method OID, throwing an error if it doesn't exist. */
+ amoid = get_am_oid(stmt->amname, false);
/* XXX Should we make any privilege check against the AM? */
- ReleaseSysCache(tup);
-
/*
* Currently, we require superuser privileges to create an opfamily. See
* comments in DefineOpClass.
@@ -1488,12 +1479,7 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
+ amID = get_am_oid(stmt->amname, false);
/*
* Look up the opclass.
@@ -1549,12 +1535,7 @@ RemoveOpFamily(RemoveOpFamilyStmt *stmt)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
+ amID = get_am_oid(stmt->amname, false);
/*
* Look up the opfamily.
@@ -1711,12 +1692,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
Relation rel;
AclResult aclresult;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
@@ -1805,12 +1781,7 @@ RenameOpFamily(List *name, const char *access_method, const char *newname)
Relation rel;
AclResult aclresult;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
@@ -1896,12 +1867,7 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
char *opcname;
char *schemaname;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
@@ -2018,12 +1984,7 @@ AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId)
char *opfname;
char *schemaname;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
@@ -2127,3 +2088,22 @@ AlterOpFamilyOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
newOwnerId);
}
}
+
+/*
+ * get_am_oid - given an access method name, look up the OID
+ *
+ * If missing_ok is false, throw an error if access method not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_am_oid(const char *amname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("access method \"%s\" does not exist", amname)));
+ return oid;
+}
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 633a093..a4e3afe 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -514,7 +514,7 @@ void
DropProceduralLanguage(DropPLangStmt *stmt)
{
char *languageName;
- HeapTuple langTup;
+ Oid oid;
ObjectAddress object;
/*
@@ -522,34 +522,26 @@ DropProceduralLanguage(DropPLangStmt *stmt)
*/
languageName = case_translate_language_name(stmt->plname);
- langTup = SearchSysCache1(LANGNAME, CStringGetDatum(languageName));
- if (!HeapTupleIsValid(langTup))
+ oid = get_language_oid(languageName, stmt->missing_ok);
+ if (!OidIsValid(oid))
{
- if (!stmt->missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", languageName)));
- else
- ereport(NOTICE,
- (errmsg("language \"%s\" does not exist, skipping",
- languageName)));
-
+ ereport(NOTICE,
+ (errmsg("language \"%s\" does not exist, skipping",
+ languageName)));
return;
}
/*
* Check permission
*/
- if (!pg_language_ownercheck(HeapTupleGetOid(langTup), GetUserId()))
+ if (!pg_language_ownercheck(oid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
languageName);
object.classId = LanguageRelationId;
- object.objectId = HeapTupleGetOid(langTup);
+ object.objectId = oid;
object.objectSubId = 0;
- ReleaseSysCache(langTup);
-
/*
* Do the deletion
*/
@@ -735,3 +727,22 @@ AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
newOwnerId);
}
}
+
+/*
+ * get_language_oid - given a language name, look up the OID
+ *
+ * If missing_ok is false, throw an error if language name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_language_oid(const char *langname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("language \"%s\" does not exist", langname)));
+ return oid;
+}
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index b0a9a22..9edd59d 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -57,7 +57,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
* Who is supposed to own the new schema?
*/
if (authId)
- owner_uid = get_roleid_checked(authId);
+ owner_uid = get_role_oid(authId, false);
else
owner_uid = saved_uid;
@@ -178,24 +178,13 @@ RemoveSchemas(DropStmt *drop)
errmsg("schema name cannot be qualified")));
namespaceName = strVal(linitial(names));
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ namespaceId = get_namespace_oid(namespaceName, drop->missing_ok);
if (!OidIsValid(namespaceId))
{
- if (!drop->missing_ok)
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- namespaceName)));
- }
- else
- {
- ereport(NOTICE,
- (errmsg("schema \"%s\" does not exist, skipping",
- namespaceName)));
- }
+ ereport(NOTICE,
+ (errmsg("schema \"%s\" does not exist, skipping",
+ namespaceName)));
continue;
}
@@ -264,9 +253,7 @@ RenameSchema(const char *oldname, const char *newname)
errmsg("schema \"%s\" does not exist", oldname)));
/* make sure the new name doesn't exist */
- if (HeapTupleIsValid(
- SearchSysCache1(NAMESPACENAME,
- CStringGetDatum(newname))))
+ if (OidIsValid(get_namespace_oid(newname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_SCHEMA),
errmsg("schema \"%s\" already exists", newname)));
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 9b5ce65..9a9d9ae 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -411,12 +411,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
*/
if (stmt->tablespacename)
{
- tablespaceId = get_tablespace_oid(stmt->tablespacename);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- stmt->tablespacename)));
+ tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
}
else
{
@@ -2750,7 +2745,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
- get_roleid_checked(cmd->name),
+ get_role_oid(cmd->name, false),
false);
break;
case AT_ClusterOn: /* CLUSTER ON */
@@ -6739,11 +6734,7 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
AclResult aclresult;
/* Check that the tablespace exists */
- tablespaceId = get_tablespace_oid(tablespacename);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", tablespacename)));
+ tablespaceId = get_tablespace_oid(tablespacename, false);
/* Check its permissions */
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 862cd2d..db17841 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -246,7 +246,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */
if (stmt->owner)
- ownerId = get_roleid_checked(stmt->owner);
+ ownerId = get_role_oid(stmt->owner, false);
else
ownerId = GetUserId();
@@ -298,7 +298,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
* index would catch this anyway, but might as well give a friendlier
* message.)
*/
- if (OidIsValid(get_tablespace_oid(stmt->tablespacename)))
+ if (OidIsValid(get_tablespace_oid(stmt->tablespacename, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("tablespace \"%s\" already exists",
@@ -999,7 +999,7 @@ assign_default_tablespace(const char *newval, bool doit, GucSource source)
if (IsTransactionState())
{
if (newval[0] != '\0' &&
- !OidIsValid(get_tablespace_oid(newval)))
+ !OidIsValid(get_tablespace_oid(newval, true)))
{
ereport(GUC_complaint_elevel(source),
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -1049,7 +1049,7 @@ GetDefaultTablespace(bool forTemp)
* to refer to an existing tablespace; we just silently return InvalidOid,
* causing the new object to be created in the database's tablespace.
*/
- result = get_tablespace_oid(default_tablespace);
+ result = get_tablespace_oid(default_tablespace, true);
/*
* Allow explicit specification of database's default tablespace in
@@ -1116,21 +1116,13 @@ assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
continue;
}
- /* Else verify that name is a valid tablespace name */
- curoid = get_tablespace_oid(curname);
+ /*
+ * In an interactive SET command, we ereport for bad info.
+ * Otherwise, silently ignore any bad list elements.
+ */
+ curoid = get_tablespace_oid(curname, source < PGC_S_INTERACTIVE);
if (curoid == InvalidOid)
- {
- /*
- * In an interactive SET command, we ereport for bad info.
- * Otherwise, silently ignore any bad list elements.
- */
- if (source >= PGC_S_INTERACTIVE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- curname)));
continue;
- }
/*
* Allow explicit specification of database's default tablespace
@@ -1229,10 +1221,10 @@ PrepareTempTablespaces(void)
}
/* Else verify that name is a valid tablespace name */
- curoid = get_tablespace_oid(curname);
+ curoid = get_tablespace_oid(curname, true);
if (curoid == InvalidOid)
{
- /* Silently ignore any bad list elements */
+ /* Skip any bad list elements */
continue;
}
@@ -1265,10 +1257,11 @@ PrepareTempTablespaces(void)
/*
* get_tablespace_oid - given a tablespace name, look up the OID
*
- * Returns InvalidOid if tablespace name not found.
+ * If missing_ok is false, throw an error if tablespace name not found. If
+ * true, just return InvalidOid.
*/
Oid
-get_tablespace_oid(const char *tablespacename)
+get_tablespace_oid(const char *tablespacename, bool missing_ok)
{
Oid result;
Relation rel;
@@ -1299,6 +1292,12 @@ get_tablespace_oid(const char *tablespacename)
heap_endscan(scandesc);
heap_close(rel, AccessShareLock);
+ if (!OidIsValid(result) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("tablespace \"%s\" does not exist",
+ tablespacename)));
+
return result;
}
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 2f0788e..1c73d9b 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -293,8 +293,7 @@ CreateRole(CreateRoleStmt *stmt)
pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
pg_authid_dsc = RelationGetDescr(pg_authid_rel);
- tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
- if (HeapTupleIsValid(tuple))
+ if (OidIsValid(get_role_oid(stmt->role, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("role \"%s\" already exists",
@@ -384,7 +383,7 @@ CreateRole(CreateRoleStmt *stmt)
foreach(item, addroleto)
{
char *oldrolename = strVal(lfirst(item));
- Oid oldroleid = get_roleid_checked(oldrolename);
+ Oid oldroleid = get_role_oid(oldrolename, false);
AddRoleMems(oldrolename, oldroleid,
list_make1(makeString(stmt->role)),
@@ -795,11 +794,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
/* look up and lock the database, if specified */
if (stmt->database != NULL)
{
- databaseid = get_database_oid(stmt->database);
- if (!OidIsValid(databaseid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("database \"%s\" not found", stmt->database)));
+ databaseid = get_database_oid(stmt->database, false);
shdepLockAndCheckObject(DatabaseRelationId, databaseid);
}
@@ -1099,7 +1094,7 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
- grantor = get_roleid_checked(stmt->grantor);
+ grantor = get_role_oid(stmt->grantor, false);
else
grantor = GetUserId();
@@ -1127,7 +1122,7 @@ GrantRole(GrantRoleStmt *stmt)
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
- roleid = get_roleid_checked(rolename);
+ roleid = get_role_oid(rolename, false);
if (stmt->is_grant)
AddRoleMems(rolename, roleid,
stmt->grantee_roles, grantee_ids,
@@ -1194,7 +1189,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/* Must have privileges on the receiving side too */
- newrole = get_roleid_checked(stmt->newrole);
+ newrole = get_role_oid(stmt->newrole, false);
if (!has_privs_of_role(GetUserId(), newrole))
ereport(ERROR,
@@ -1220,7 +1215,7 @@ roleNamesToIds(List *memberNames)
foreach(l, memberNames)
{
char *rolename = strVal(lfirst(l));
- Oid roleid = get_roleid_checked(rolename);
+ Oid roleid = get_role_oid(rolename, false);
result = lappend_oid(result, roleid);
}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index d299310..857483a 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2118,12 +2118,7 @@ OpenIntoRel(QueryDesc *queryDesc)
*/
if (into->tableSpaceName)
{
- tablespaceId = get_tablespace_oid(into->tableSpaceName);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- into->tableSpaceName)));
+ tablespaceId = get_tablespace_oid(into->tableSpaceName, false);
}
else
{
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index c967364..7ee7842 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -459,7 +459,7 @@ is_member(Oid userid, const char *role)
if (!OidIsValid(userid))
return false; /* if user not exist, say "no" */
- roleid = get_roleid(role);
+ roleid = get_role_oid(role, true);
if (!OidIsValid(roleid))
return false; /* if target role not exist, say "no" */
@@ -1327,7 +1327,7 @@ check_hba(hbaPort *port)
HbaLine *hba;
/* Get the target role's OID. Note we do not error out for bad role. */
- roleid = get_roleid(port->user_name);
+ roleid = get_role_oid(port->user_name, true);
foreach(line, parsed_hba_lines)
{
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index faad11e..b320569 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -22,6 +22,7 @@
#include "catalog/pg_type.h"
#include "catalog/pg_class.h"
#include "commands/dbcommands.h"
+#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "foreign/foreign.h"
#include "funcapi.h"
@@ -324,7 +325,7 @@ aclparse(const char *s, AclItem *aip)
if (name[0] == '\0')
aip->ai_grantee = ACL_ID_PUBLIC;
else
- aip->ai_grantee = get_roleid_checked(name);
+ aip->ai_grantee = get_role_oid(name, false);
/*
* XXX Allow a degree of backward compatibility by defaulting the grantor
@@ -337,7 +338,7 @@ aclparse(const char *s, AclItem *aip)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("a name must follow the \"/\" sign")));
- aip->ai_grantor = get_roleid_checked(name2);
+ aip->ai_grantor = get_role_oid(name2, false);
}
else
{
@@ -1790,7 +1791,7 @@ has_table_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
@@ -1839,7 +1840,7 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_table_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
@@ -1997,7 +1998,7 @@ has_sequence_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
mode = convert_sequence_priv_string(priv_type_text);
sequenceoid = convert_table_name(sequencename);
if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE)
@@ -2057,7 +2058,7 @@ has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
AclResult aclresult;
char relkind;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_sequence_priv_string(priv_type_text);
relkind = get_rel_relkind(sequenceoid);
if (relkind == '\0')
@@ -2208,7 +2209,7 @@ has_any_column_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_column_priv_string(priv_type_text);
@@ -2265,7 +2266,7 @@ has_any_column_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_column_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
@@ -2450,7 +2451,7 @@ has_column_privilege_name_name_name(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
colattnum = convert_column_name(tableoid, column);
mode = convert_column_priv_string(priv_type_text);
@@ -2478,7 +2479,7 @@ has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_column_priv_string(priv_type_text);
@@ -2505,7 +2506,7 @@ has_column_privilege_name_id_name(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
colattnum = convert_column_name(tableoid, column);
mode = convert_column_priv_string(priv_type_text);
@@ -2531,7 +2532,7 @@ has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_column_priv_string(priv_type_text);
privresult = column_privilege_check(tableoid, colattnum, roleid, mode);
@@ -2822,7 +2823,7 @@ has_database_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
@@ -2871,7 +2872,7 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_database_priv_string(priv_type_text);
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
@@ -2966,15 +2967,8 @@ static Oid
convert_database_name(text *databasename)
{
char *dbname = text_to_cstring(databasename);
- Oid oid;
- oid = get_database_oid(dbname);
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", dbname)));
-
- return oid;
+ return get_database_oid(dbname, false);
}
/*
@@ -3027,7 +3021,7 @@ has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
@@ -3076,7 +3070,7 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
@@ -3209,7 +3203,7 @@ has_function_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
@@ -3258,7 +3252,7 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_function_priv_string(priv_type_text);
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
@@ -3409,7 +3403,7 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
@@ -3458,7 +3452,7 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_language_priv_string(priv_type_text);
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
@@ -3553,15 +3547,8 @@ static Oid
convert_language_name(text *languagename)
{
char *langname = text_to_cstring(languagename);
- Oid oid;
- oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", langname)));
-
- return oid;
+ return get_language_oid(langname, false);
}
/*
@@ -3607,7 +3594,7 @@ has_schema_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
@@ -3656,7 +3643,7 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_schema_priv_string(priv_type_text);
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
@@ -3751,15 +3738,8 @@ static Oid
convert_schema_name(text *schemaname)
{
char *nspname = text_to_cstring(schemaname);
- Oid oid;
-
- oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
- return oid;
+ return get_namespace_oid(nspname, false);
}
/*
@@ -3807,7 +3787,7 @@ has_server_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
@@ -3856,7 +3836,7 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_server_priv_string(priv_type_text);
aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
@@ -3989,7 +3969,7 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
@@ -4038,7 +4018,7 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_tablespace_priv_string(priv_type_text);
aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
@@ -4124,16 +4104,8 @@ static Oid
convert_tablespace_name(text *tablespacename)
{
char *spcname = text_to_cstring(tablespacename);
- Oid oid;
- oid = get_tablespace_oid(spcname);
-
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", spcname)));
-
- return oid;
+ return get_tablespace_oid(spcname, false);
}
/*
@@ -4178,8 +4150,8 @@ pg_has_role_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*username), false);
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4204,7 +4176,7 @@ pg_has_role_name(PG_FUNCTION_ARGS)
AclResult aclresult;
roleid = GetUserId();
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4227,7 +4199,7 @@ pg_has_role_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4273,7 +4245,7 @@ pg_has_role_id_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4830,3 +4802,22 @@ select_best_grantor(Oid roleId, AclMode privileges,
}
}
}
+
+/*
+ * get_role_oid - Given a role name, look up the role's OID.
+ *
+ * If missing_ok is false, throw an error if tablespace name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_role_oid(const char *rolname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(rolname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", rolname)));
+ return oid;
+}
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index a4e0252..8ec6b71 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -141,13 +141,7 @@ Datum
pg_database_size_name(PG_FUNCTION_ARGS)
{
Name dbName = PG_GETARG_NAME(0);
- Oid dbOid = get_database_oid(NameStr(*dbName));
-
- if (!OidIsValid(dbOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist",
- NameStr(*dbName))));
+ Oid dbOid = get_database_oid(NameStr(*dbName), false);
PG_RETURN_INT64(calculate_database_size(dbOid));
}
@@ -240,13 +234,7 @@ Datum
pg_tablespace_size_name(PG_FUNCTION_ARGS)
{
Name tblspcName = PG_GETARG_NAME(0);
- Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName));
-
- if (!OidIsValid(tblspcOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- NameStr(*tblspcName))));
+ Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName), false);
PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index aad6c35..9932415 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2626,34 +2626,3 @@ get_namespace_name(Oid nspid)
else
return NULL;
}
-
-/* ---------- PG_AUTHID CACHE ---------- */
-
-/*
- * get_roleid
- * Given a role name, look up the role's OID.
- * Returns InvalidOid if no such role.
- */
-Oid
-get_roleid(const char *rolname)
-{
- return GetSysCacheOid1(AUTHNAME, PointerGetDatum(rolname));
-}
-
-/*
- * get_roleid_checked
- * Given a role name, look up the role's OID.
- * ereports if no such role.
- */
-Oid
-get_roleid_checked(const char *rolname)
-{
- Oid roleid;
-
- roleid = get_roleid(rolname);
- if (!OidIsValid(roleid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", rolname)));
- return roleid;
-}
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index fe3b783..0fd61a9 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -91,6 +91,7 @@ extern void DeconstructQualifiedName(List *names,
char **objname_p);
extern Oid LookupNamespaceNoError(const char *nspname);
extern Oid LookupExplicitNamespace(const char *nspname);
+extern Oid get_namespace_oid(const char *nspname, bool missing_ok);
extern Oid LookupCreationNamespace(const char *nspname);
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h
index 542fc27..8c5ba1b 100644
--- a/src/include/commands/dbcommands.h
+++ b/src/include/commands/dbcommands.h
@@ -59,7 +59,7 @@ extern void AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel);
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId);
-extern Oid get_database_oid(const char *dbname);
+extern Oid get_database_oid(const char *dbname, bool missingok);
extern char *get_database_name(Oid dbid);
extern void dbase_redo(XLogRecPtr lsn, XLogRecord *rptr);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index e8dbe81..54011a0 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -97,6 +97,7 @@ extern void RenameOpClass(List *name, const char *access_method, const char *new
extern void RenameOpFamily(List *name, const char *access_method, const char *newname);
extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
+extern Oid get_am_oid(const char *amname, bool missing_ok);
/* commands/tsearchcmds.c */
extern void DefineTSParser(List *names, List *parameters);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index 5feff87..16c1d14 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -21,5 +21,6 @@ extern void RenameLanguage(const char *oldname, const char *newname);
extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
extern void AlterLanguageOwner_oid(Oid oid, Oid newOwnerId);
extern bool PLTemplateExists(const char *languageName);
+extern Oid get_language_oid(const char *langname, bool missing_ok);
#endif /* PROCLANG_H */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index cf005ee..98a9b86 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -51,7 +51,7 @@ extern Oid GetDefaultTablespace(bool forTemp);
extern void PrepareTempTablespaces(void);
-extern Oid get_tablespace_oid(const char *tablespacename);
+extern Oid get_tablespace_oid(const char *tablespacename, bool missing_ok);
extern char *get_tablespace_name(Oid spc_oid);
extern bool directory_is_empty(const char *path);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 9c38bd1..d9921e8 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -223,6 +223,7 @@ extern bool is_member_of_role(Oid member, Oid role);
extern bool is_member_of_role_nosuper(Oid member, Oid role);
extern bool is_admin_of_role(Oid member, Oid role);
extern void check_is_member_of_role(Oid member, Oid role);
+extern Oid get_role_oid(const char *rolname, bool missing_ok);
extern void select_best_grantor(Oid roleId, AclMode privileges,
const Acl *acl, Oid ownerId,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 131acb7..066ad76 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -136,8 +136,6 @@ extern void free_attstatsslot(Oid atttype,
Datum *values, int nvalues,
float4 *numbers, int nnumbers);
extern char *get_namespace_name(Oid nspid);
-extern Oid get_roleid(const char *rolname);
-extern Oid get_roleid_checked(const char *rolname);
#define type_is_array(typid) (get_element_type(typid) != InvalidOid)
Robert Haas <robertmhaas@gmail.com> writes:
I agree, done. In fact, aren't we leaking a syscache reference here?
How so? There's a ReleaseSysCache call.
regards, tom lane
Robert Haas <robertmhaas@gmail.com> writes:
2010/6/28 KaiGai Kohei <kaigai@ak.jp.nec.com>:
* at the RenameSchema()
This looks like another syscache reference leak.
Actually that one *is* a leak, although it doesn't matter much because
the leak occurs only in an error path, so transaction abort will clean
up the leaked reference. Still, it's sucky coding style:
SearchSysCacheExists should have been used.
I'm not sure I agree that replacing SearchSysCacheExists calls (or
things that should have been SearchSysCacheExists calls) with
OidIsValid(get_whatever_oid()) is an improvement. The Exists call
tells what you're actually trying to accomplish. The other way is
an overspecification of the required result.
regards, tom lane
On Mon, Jun 28, 2010 at 10:48 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
I agree, done. In fact, aren't we leaking a syscache reference here?
How so? There's a ReleaseSysCache call.
Oops, you're right.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
On Mon, Jun 28, 2010 at 10:53 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
2010/6/28 KaiGai Kohei <kaigai@ak.jp.nec.com>:
* at the RenameSchema()
This looks like another syscache reference leak.
Actually that one *is* a leak, although it doesn't matter much because
the leak occurs only in an error path, so transaction abort will clean
up the leaked reference. Still, it's sucky coding style:
SearchSysCacheExists should have been used.I'm not sure I agree that replacing SearchSysCacheExists calls (or
things that should have been SearchSysCacheExists calls) with
OidIsValid(get_whatever_oid()) is an improvement. The Exists call
tells what you're actually trying to accomplish. The other way is
an overspecification of the required result.
It is, but on the other hand it's only good fortune that testing
whether a schema exists is a one-liner even without using
get_namespace_oid(). Take a look at get_tablespace_oid() in CVS HEAD
[which BTW is already used in this style], or at get_trigger_oid() in
the "get_whatever_oid, part 2" patch, for example. I think the
assumption that system objects (with the exception of attributes) are
identified by OIDs is embedded pretty deeply in the code, so I don't
think it costs us much to rely on it. We're more likely to want to do
things like add or remove a syscache, in which case a style that
minimizes direct syscache references is apt to make life easier.
It's also slightly less wordy, which I like, too.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Robert Haas <robertmhaas@gmail.com> writes:
On Mon, Jun 28, 2010 at 10:53 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I'm not sure I agree that replacing SearchSysCacheExists calls (or
things that should have been SearchSysCacheExists calls) with
OidIsValid(get_whatever_oid()) is an improvement. �The Exists call
tells what you're actually trying to accomplish. �The other way is
an overspecification of the required result.
It is, but on the other hand it's only good fortune that testing
whether a schema exists is a one-liner even without using
get_namespace_oid().
True. Is it worth providing whatever_exists() macros that wrap
get_whatever_oid() like this, just so that callers are a bit clearer as
to what they're doing? I'm not certain though how many places it could
be used, since many callers probably actually do need the OID, and would
have to write separate lines anyway:
objoid = get_whatever_oid(...);
if (!OidIsValid(objoid))
ereport(...);
... code using objoid here ...
But it's been useful to have the SearchSysCacheExists functions, even
though they're just wrappers, so maybe whatever_exists() would be worth
its keep.
regards, tom lane
On Mon, Jun 28, 2010 at 12:17 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
On Mon, Jun 28, 2010 at 10:53 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I'm not sure I agree that replacing SearchSysCacheExists calls (or
things that should have been SearchSysCacheExists calls) with
OidIsValid(get_whatever_oid()) is an improvement. The Exists call
tells what you're actually trying to accomplish. The other way is
an overspecification of the required result.It is, but on the other hand it's only good fortune that testing
whether a schema exists is a one-liner even without using
get_namespace_oid().True. Is it worth providing whatever_exists() macros that wrap
get_whatever_oid() like this, just so that callers are a bit clearer as
to what they're doing? I'm not certain though how many places it could
be used, since many callers probably actually do need the OID, and would
have to write separate lines anyway:objoid = get_whatever_oid(...);
if (!OidIsValid(objoid))
ereport(...);
... code using objoid here ...But it's been useful to have the SearchSysCacheExists functions, even
though they're just wrappers, so maybe whatever_exists() would be worth
its keep.
I haven't made a detailed study of this issue, so I'm not 100% sure.
My gut feeling however is that nearly all of the callers need the OID,
and that some of the whatever_exists() functions wouldn't have any
callers at all. Which makes me pretty hesitant to add them,
especially given our decision not to centralize all the
get_whatever_oid() functions in one place.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Robert Haas <robertmhaas@gmail.com> writes:
On Mon, Jun 28, 2010 at 12:17 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
True. �Is it worth providing whatever_exists() macros that wrap
get_whatever_oid() like this, just so that callers are a bit clearer as
to what they're doing?
I haven't made a detailed study of this issue, so I'm not 100% sure.
My gut feeling however is that nearly all of the callers need the OID,
and that some of the whatever_exists() functions wouldn't have any
callers at all. Which makes me pretty hesitant to add them,
especially given our decision not to centralize all the
get_whatever_oid() functions in one place.
Well, the whatever_exists() things would just be one-liner macros
declared in the same headers that declare the underlying
get_whatever_oid() functions. So the cost of carrying ones that happen
to not be used would be nil.
regards, tom lane
On Mon, Jun 28, 2010 at 12:31 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
On Mon, Jun 28, 2010 at 12:17 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
True. Is it worth providing whatever_exists() macros that wrap
get_whatever_oid() like this, just so that callers are a bit clearer as
to what they're doing?I haven't made a detailed study of this issue, so I'm not 100% sure.
My gut feeling however is that nearly all of the callers need the OID,
and that some of the whatever_exists() functions wouldn't have any
callers at all. Which makes me pretty hesitant to add them,
especially given our decision not to centralize all the
get_whatever_oid() functions in one place.Well, the whatever_exists() things would just be one-liner macros
declared in the same headers that declare the underlying
get_whatever_oid() functions. So the cost of carrying ones that happen
to not be used would be nil.
True, but I think there's a pretty high chance that they woudn't get
used even in places where they ought to, for lack of existing
examples, or that new code would fail to add matching macros for new
object types. Even so, it's not a terrible idea; I just don't think
it should be a requirement for this particular patch. And to be
honest, I'd sort of like to see how this shakes out before going too
much further with it.
Another, and related idea that I had while looking at this is that a
lot of object types could benefit from a get_whatever_heaptuple()
function with the same calling syntax. get_whatever_oid() could be
restructured to use it, and most object types would have other
callers, also. But that too seems like opening a larger can of worms
than I really want to get into at this point.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Robert Haas <robertmhaas@gmail.com> writes:
On Mon, Jun 28, 2010 at 12:31 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Well, the whatever_exists() things would just be one-liner macros
declared in the same headers that declare the underlying
get_whatever_oid() functions. �So the cost of carrying ones that happen
to not be used would be nil.
True, but I think there's a pretty high chance that they woudn't get
used even in places where they ought to, for lack of existing
examples, or that new code would fail to add matching macros for new
object types. Even so, it's not a terrible idea; I just don't think
it should be a requirement for this particular patch. And to be
honest, I'd sort of like to see how this shakes out before going too
much further with it.
Well, once you've finished the get_whatever_oid() patch it won't be
hard to count how many instances of OidIsValid(get_whatever_oid()) there
are. If there's more than a few then I think the macros would be
appropriate to provide.
Another, and related idea that I had while looking at this is that a
lot of object types could benefit from a get_whatever_heaptuple()
function with the same calling syntax. get_whatever_oid() could be
restructured to use it, and most object types would have other
callers, also. But that too seems like opening a larger can of worms
than I really want to get into at this point.
This is the sort of thing that I think we should get right the first
time, rather than have multiple waves of large-scale changes.
I'm actually inclined to think we should try to land this stuff in 9.0
if we're going to do it at all. As a new committer, I suspect you do
not realize exactly how much pain this sort of thing inflicts on
back-patchers. The SearchSysCache call convention changes have already
ensured that the 8.4 to 9.0 crossover is going to be a major, major PITA
for back-patching, probably nearly as bad as the 8.1 changes in
pgindent's comment wrapping rules. (If I had it to do over I'd have
vetoed those changes --- I don't even want to think about how many
man-days I've lost to that completely useless cosmetic change.) This
proposed change will touch many of the same places that were already
modified for that. It'd be nice to have only one version boundary
where we're manually adjusting back-patched fixes, and not two.
regards, tom lane
On Mon, Jun 28, 2010 at 1:00 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Another, and related idea that I had while looking at this is that a
lot of object types could benefit from a get_whatever_heaptuple()
function with the same calling syntax. get_whatever_oid() could be
restructured to use it, and most object types would have other
callers, also. But that too seems like opening a larger can of worms
than I really want to get into at this point.This is the sort of thing that I think we should get right the first
time, rather than have multiple waves of large-scale changes.
After taking a walk around the block, I have two further thoughts about this:
1. I wouldn't have submitted these patches (this one and the part two
patch) unless it reflected my best judgment about how far it makes
sense to proceed with refactoring in a certain direction. I'm willing
to be second-guessed, if you or someone else wants to move the
goal-posts. But I don't personally feel that there's enough bang for
the buck in going further in this direction, or I would have done it
already. I'm not planning to commit these patches and then start
immediately working on a second set of patches that touches all of
these same spots in the code over again. In the particular area that
this patch touches (mapping names as gathered by the parser to OIDs),
there are many different permutations: the input can be a cstring, or
a text datum, or a list of cstrings, etc.; and the output can be a
boolean (is it there?), an OID, a heap tuple, etc. If you try to
cover every combination, especially for the more obscure object types,
you'll drive yourself nuts; on the other hand, trying to regularize
the more common cases is, I think, helpful and worthwhile. So it's a
trade-off; I took my best crack at it.
2. It might be too optimistic to think that we're going to avoid
having large-scale code changes in 9.1 by committing these to 9.0. I
think refactoring is a fact of life as we try to move the project
forward, and while we want to be careful about how we do it for the
reasons you mention, it's also important if we want to have a clean
base to build on for future features (which, in fact, is why I
proposed these patches in the first place - I discovered that this
code wasn't too clean right now while thinking about SE-PostgreSQL
security labels at PGCon). I have at least one other patch that's
basically just refactoring in the queue for 9.1 already, which is
fairly wide-ranging but in an area completely unrelated to these
patches, and a couple other less ambitious ones that I plan to work on
as time permits; so I think that the need for these kinds of changes
is not going to go away.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
(2010/06/29 3:52), Robert Haas wrote:
On Mon, Jun 28, 2010 at 1:00 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:
Another, and related idea that I had while looking at this is that a
lot of object types could benefit from a get_whatever_heaptuple()
function with the same calling syntax. get_whatever_oid() could be
restructured to use it, and most object types would have other
callers, also. But that too seems like opening a larger can of worms
than I really want to get into at this point.This is the sort of thing that I think we should get right the first
time, rather than have multiple waves of large-scale changes.After taking a walk around the block, I have two further thoughts about this:
1. I wouldn't have submitted these patches (this one and the part two
patch) unless it reflected my best judgment about how far it makes
sense to proceed with refactoring in a certain direction. I'm willing
to be second-guessed, if you or someone else wants to move the
goal-posts. But I don't personally feel that there's enough bang for
the buck in going further in this direction, or I would have done it
already. I'm not planning to commit these patches and then start
immediately working on a second set of patches that touches all of
these same spots in the code over again. In the particular area that
this patch touches (mapping names as gathered by the parser to OIDs),
there are many different permutations: the input can be a cstring, or
a text datum, or a list of cstrings, etc.; and the output can be a
boolean (is it there?), an OID, a heap tuple, etc. If you try to
cover every combination, especially for the more obscure object types,
you'll drive yourself nuts; on the other hand, trying to regularize
the more common cases is, I think, helpful and worthwhile. So it's a
trade-off; I took my best crack at it.
Sorry, I couldn't understand some of idiomatic expressions, but you are
saying that we have many variations of syscaches, so it is nonsense to
wrap up all the usecases of them, but being worthful to focus on major
usecases, such as name to oid translation, aren't you?
If so, it also seems to me fair enough. It seems to me translations from
name into oid, tuple or verifying object existence are major use cases,
but we have no reason why replace all the SysCacheSearch().
2. It might be too optimistic to think that we're going to avoid
having large-scale code changes in 9.1 by committing these to 9.0. I
think refactoring is a fact of life as we try to move the project
forward, and while we want to be careful about how we do it for the
reasons you mention, it's also important if we want to have a clean
base to build on for future features (which, in fact, is why I
proposed these patches in the first place - I discovered that this
code wasn't too clean right now while thinking about SE-PostgreSQL
security labels at PGCon). I have at least one other patch that's
basically just refactoring in the queue for 9.1 already, which is
fairly wide-ranging but in an area completely unrelated to these
patches, and a couple other less ambitious ones that I plan to work on
as time permits; so I think that the need for these kinds of changes
is not going to go away.
--
KaiGai Kohei <kaigai@ak.jp.nec.com>
2010/6/28 KaiGai Kohei <kaigai@ak.jp.nec.com>:
Sorry, I couldn't understand some of idiomatic expressions, but you are
saying that we have many variations of syscaches, so it is nonsense to
wrap up all the usecases of them, but being worthful to focus on major
usecases, such as name to oid translation, aren't you?
Yes.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Robert,
I checked the v2 patch, but I could not find anything to comment
except for its patch format.
The -v2 patch still uses unified format, instead of context format.
I believe it is just a careless miss. Please fix it later, if necessary.
When I submit a patch, I makes it as follows :D
git diff master my_branch | filterdiff --format=context > my_feature.patch
The transitions from object name to its oid are widely used in
the routines of the backend, so I also think this reworks will
enough worthwhile to keep the code clean.
So, I marked it as "ready for committer".
Thanks,
(2010/06/28 22:55), Robert Haas wrote:
2010/6/28 KaiGai Kohei<kaigai@ak.jp.nec.com>:
* ExecAlterOwnerStmt()
The original code uses get_roleid_checked() which does not allow invalid
username, but the new code gives missing_ok = true on the get_role_oid().
It should be fixed.Woops, good catch. Fixed.
* assign_temp_tablespaces()?
It seems to me "if (!OidIsValid(curoid))" should be here, instead of comparison
with InvalidOid here. However, it may be cleaned up in any other patch instead
of get_whatever_oid() efforts.Yeah, we have a lot of places that check foo == InvalidOid or foo !=
InvalidOid rather than using OidIsValid(). That might or might not be
worth changing, but I don't see a strong need for this patch to change
this particular instance.* at the CreateRole(CreateRoleStmt *stmt)
I saw similar code which was replaced with the new APIs in this patch.
It seems to me "if (OidIsValid(get_role_oid(stmt->role, true)))" can be used,
and it enables to write the code more clean.I agree. Changed.
* at the DefineOpFamily()
| /* Get necessary info about access method */
| tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
| if (!HeapTupleIsValid(tup))
| ereport(ERROR,
| (errcode(ERRCODE_UNDEFINED_OBJECT),
| errmsg("access method \"%s\" does not exist",
| stmt->amname)));
|
| amoid = HeapTupleGetOid(tup);
|
| /* XXX Should we make any privilege check against the AM? */
|
| ReleaseSysCache(tup);It can be replaced by get_am_oid(stmt->amname, false).
I agree, done. In fact, aren't we leaking a syscache reference here?
And if so, should we fix it in HEAD and the backbranches also? I'm
tempted not to bother because, after all, how often do you invoke
DefineOpFamily(), but maybe someone else has a different opinion?* at the RenameSchema()
| /* make sure the new name doesn't exist */
| if (HeapTupleIsValid(
| SearchSysCache1(NAMESPACENAME,
| CStringGetDatum(newname))))
| ereport(ERROR,
| (errcode(ERRCODE_DUPLICATE_SCHEMA),
| errmsg("schema \"%s\" already exists", newname)));It is similar to the case of CreateRole(). Does get_namespace_oid()
enables to write the code more clean?This looks like another syscache reference leak. I have changed it to
use get_namespace_oid() in the patch, but we need to decide whether to
fix this in pre-9.1 releases.
--
KaiGai Kohei <kaigai@ak.jp.nec.com>
2010/7/2 KaiGai Kohei <kaigai@ak.jp.nec.com>:
The transitions from object name to its oid are widely used in
the routines of the backend, so I also think this reworks will
enough worthwhile to keep the code clean.So, I marked it as "ready for committer".
Thanks. Are you planning to review the part 2 patch also?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
2010/7/2 KaiGai Kohei <kaigai@ak.jp.nec.com>:
So, I marked it as "ready for committer".
There is a minor merge conflict with this patch as a result of a patch
I committed last week. New version attached.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company
Attachments:
get_whatever_oid_part1-v3.patchapplication/octet-stream; name=get_whatever_oid_part1-v3.patchDownload
commit 56bbe72673a6f853e0d868a3c743ab1a926bf2b0
Author: Robert Haas <robertmhaas@gmail.com>
Date: Sun May 23 00:02:54 2010 -0400
Standardize get_whatever_oid functions for object types with
unqualified names.
- Add a missing_ok parameter to get_tablespace_oid.
- Avoid duplicating get_tablespace_od guts in objectNamesToOids.
- Add a missing_ok parameter to get_database_oid.
- Replace get_roleid and get_role_checked with get_role_oid.
- Add get_namespace_oid, get_language_oid, get_am_oid.
- Refactor existing code to use new interfaces.
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 23d604e..2b2c326 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -43,6 +43,8 @@
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "commands/dbcommands.h"
+#include "commands/proclang.h"
+#include "commands/tablespace.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
@@ -419,7 +421,7 @@ ExecuteGrantStmt(GrantStmt *stmt)
else
istmt.grantees =
lappend_oid(istmt.grantees,
- get_roleid_checked(grantee->rolname));
+ get_role_oid(grantee->rolname, false));
}
/*
@@ -607,12 +609,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
char *dbname = strVal(lfirst(cell));
Oid dbid;
- dbid = get_database_oid(dbname);
- if (!OidIsValid(dbid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist",
- dbname)));
+ dbid = get_database_oid(dbname, false);
objects = lappend_oid(objects, dbid);
}
break;
@@ -631,18 +628,10 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *langname = strVal(lfirst(cell));
- HeapTuple tuple;
-
- tuple = SearchSysCache1(LANGNAME, PointerGetDatum(langname));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist",
- langname)));
+ Oid oid;
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
-
- ReleaseSysCache(tuple);
+ oid = get_language_oid(langname, false);
+ objects = lappend_oid(objects, oid);
}
break;
case ACL_OBJECT_LARGEOBJECT:
@@ -663,49 +652,20 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
foreach(cell, objnames)
{
char *nspname = strVal(lfirst(cell));
- HeapTuple tuple;
-
- tuple = SearchSysCache1(NAMESPACENAME,
- CStringGetDatum(nspname));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- nspname)));
-
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
+ Oid oid;
- ReleaseSysCache(tuple);
+ oid = get_namespace_oid(nspname, false);
+ objects = lappend_oid(objects, oid);
}
break;
case ACL_OBJECT_TABLESPACE:
foreach(cell, objnames)
{
char *spcname = strVal(lfirst(cell));
- ScanKeyData entry[1];
- HeapScanDesc scan;
- HeapTuple tuple;
- Relation relation;
+ Oid spcoid;
- relation = heap_open(TableSpaceRelationId, AccessShareLock);
-
- ScanKeyInit(&entry[0],
- Anum_pg_tablespace_spcname,
- BTEqualStrategyNumber, F_NAMEEQ,
- CStringGetDatum(spcname));
-
- scan = heap_beginscan(relation, SnapshotNow, 1, entry);
- tuple = heap_getnext(scan, ForwardScanDirection);
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", spcname)));
-
- objects = lappend_oid(objects, HeapTupleGetOid(tuple));
-
- heap_endscan(scan);
-
- heap_close(relation, AccessShareLock);
+ spcoid = get_tablespace_oid(spcname, false);
+ objects = lappend_oid(objects, spcoid);
}
break;
case ACL_OBJECT_FDW:
@@ -913,7 +873,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
else
iacls.grantees =
lappend_oid(iacls.grantees,
- get_roleid_checked(grantee->rolname));
+ get_role_oid(grantee->rolname, false));
}
/*
@@ -996,7 +956,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
{
char *rolename = strVal(lfirst(rolecell));
- iacls.roleid = get_roleid_checked(rolename);
+ iacls.roleid = get_role_oid(rolename, false);
/*
* We insist that calling user be a member of each target role. If
@@ -1037,18 +997,12 @@ SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
AclResult aclresult;
/*
- * Normally we'd use LookupCreationNamespace here, but it's
- * important to do the permissions check against the target role
- * not the calling user, so write it out in full. We require
- * CREATE privileges, since without CREATE you won't be able to do
- * anything using the default privs anyway.
+ * Note that we must do the permissions check against the target
+ * role not the calling user. We require CREATE privileges,
+ * since without CREATE you won't be able to do anything using the
+ * default privs anyway.
*/
- iacls->nspid = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(nspname));
- if (!OidIsValid(iacls->nspid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ iacls->nspid = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(iacls->nspid, iacls->roleid,
ACL_CREATE);
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 5581346..52acc23 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -332,13 +332,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
return myTempNamespace;
}
/* use exact schema given */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(newRelation->schemaname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- newRelation->schemaname)));
+ namespaceId = get_namespace_oid(newRelation->schemaname, false);
/* we do not check for USAGE rights here! */
}
else
@@ -2270,7 +2264,7 @@ LookupNamespaceNoError(const char *nspname)
return InvalidOid;
}
- return GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
+ return get_namespace_oid(nspname, true);
}
/*
@@ -2300,11 +2294,7 @@ LookupExplicitNamespace(const char *nspname)
*/
}
- namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ namespaceId = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
@@ -2339,11 +2329,7 @@ LookupCreationNamespace(const char *nspname)
return myTempNamespace;
}
- namespaceId = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
+ namespaceId = get_namespace_oid(nspname, false);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -2385,12 +2371,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
return myTempNamespace;
}
/* use exact schema given */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(schemaname));
- if (!OidIsValid(namespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", schemaname)));
+ namespaceId = get_namespace_oid(schemaname, false);
/* we do not check for USAGE rights here! */
}
else
@@ -2414,6 +2395,26 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
}
/*
+ * get_namespace_oid - given a namespace name, look up the OID
+ *
+ * If missing_ok is false, throw an error if namespace name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_namespace_oid(const char *nspname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_SCHEMA),
+ errmsg("schema \"%s\" does not exist", nspname)));
+
+ return oid;
+}
+
+/*
* makeRangeVarFromNameList
* Utility routine to convert a qualified-name list into RangeVar form.
*/
@@ -2897,8 +2898,7 @@ recomputeNamespacePath(void)
char *rname;
rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(rname));
+ namespaceId = get_namespace_oid(rname, true);
ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
@@ -2925,8 +2925,7 @@ recomputeNamespacePath(void)
else
{
/* normal namespace reference */
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(curname));
+ namespaceId = get_namespace_oid(curname, true);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
pg_namespace_aclcheck(namespaceId, roleid,
@@ -3033,8 +3032,7 @@ InitTempTableNamespace(void)
snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ namespaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(namespaceId))
{
/*
@@ -3066,8 +3064,7 @@ InitTempTableNamespace(void)
snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
MyBackendId);
- toastspaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ toastspaceId = get_namespace_oid(namespaceName, true);
if (!OidIsValid(toastspaceId))
{
toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index a6c4755..f09d595 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -211,7 +211,7 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- Oid newowner = get_roleid_checked(stmt->newowner);
+ Oid newowner = get_role_oid(stmt->newowner, false);
switch (stmt->objectType)
{
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index b613cbf..2ba2368 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -42,6 +42,8 @@
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
+#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "libpq/be-fsstubs.h"
#include "miscadmin.h"
@@ -686,11 +688,10 @@ CommentDatabase(List *qualname, char *comment)
* of the database. Erroring out would prevent pg_restore from completing
* (which is really pg_restore's fault, but for now we will work around
* the problem here). Consensus is that the best fix is to treat wrong
- * database name as a WARNING not an ERROR.
+ * database name as a WARNING not an ERROR (thus, we tell get_database_oid
+ * to ignore the error so that we can handle it differently here).
*/
-
- /* First get the database OID */
- oid = get_database_oid(database);
+ oid = get_database_oid(database, true);
if (!OidIsValid(oid))
{
ereport(WARNING,
@@ -729,14 +730,7 @@ CommentTablespace(List *qualname, char *comment)
errmsg("tablespace name cannot be qualified")));
tablespace = strVal(linitial(qualname));
- oid = get_tablespace_oid(tablespace);
- if (!OidIsValid(oid))
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", tablespace)));
- return;
- }
+ oid = get_tablespace_oid(tablespace, false);
/* Check object security */
if (!pg_tablespace_ownercheck(oid, GetUserId()))
@@ -766,7 +760,7 @@ CommentRole(List *qualname, char *comment)
errmsg("role name cannot be qualified")));
role = strVal(linitial(qualname));
- oid = get_roleid_checked(role);
+ oid = get_role_oid(role, false);
/* Check object security */
if (!has_privs_of_role(GetUserId(), oid))
@@ -799,11 +793,7 @@ CommentNamespace(List *qualname, char *comment)
errmsg("schema name cannot be qualified")));
namespace = strVal(linitial(qualname));
- oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(namespace));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", namespace)));
+ oid = get_namespace_oid(namespace, false);
/* Check object security */
if (!pg_namespace_ownercheck(oid, GetUserId()))
@@ -1213,11 +1203,7 @@ CommentLanguage(List *qualname, char *comment)
errmsg("language name cannot be qualified")));
language = strVal(linitial(qualname));
- oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(language));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("language \"%s\" does not exist", language)));
+ oid = get_language_oid(language, false);
/* Check object security */
if (!superuser())
@@ -1254,12 +1240,7 @@ CommentOpClass(List *qualname, List *arguments, char *comment)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- amname)));
+ amID = get_am_oid(amname, false);
/*
* Look up the opclass.
@@ -1335,12 +1316,7 @@ CommentOpFamily(List *qualname, List *arguments, char *comment)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- amname)));
+ amID = get_am_oid(amname, false);
/*
* Look up the opfamily.
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e7dac22..9937083 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -255,7 +255,7 @@ createdb(const CreatedbStmt *stmt)
/* obtain OID of proposed owner */
if (dbowner)
- datdba = get_roleid_checked(dbowner);
+ datdba = get_role_oid(dbowner, false);
else
datdba = GetUserId();
@@ -429,12 +429,7 @@ createdb(const CreatedbStmt *stmt)
AclResult aclresult;
tablespacename = strVal(dtablespacename->arg);
- dst_deftablespace = get_tablespace_oid(tablespacename);
- if (!OidIsValid(dst_deftablespace))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- tablespacename)));
+ dst_deftablespace = get_tablespace_oid(tablespacename, false);
/* check permissions */
aclresult = pg_tablespace_aclcheck(dst_deftablespace, GetUserId(),
ACL_CREATE);
@@ -491,7 +486,7 @@ createdb(const CreatedbStmt *stmt)
* message than "unique index violation". There's a race condition but
* we're willing to accept the less friendly message in that case.
*/
- if (OidIsValid(get_database_oid(dbname)))
+ if (OidIsValid(get_database_oid(dbname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", dbname)));
@@ -919,7 +914,7 @@ RenameDatabase(const char *oldname, const char *newname)
* Make sure the new name doesn't exist. See notes for same error in
* CREATE DATABASE.
*/
- if (OidIsValid(get_database_oid(newname)))
+ if (OidIsValid(get_database_oid(newname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", newname)));
@@ -1030,11 +1025,7 @@ movedb(const char *dbname, const char *tblspcname)
/*
* Get tablespace's oid
*/
- dst_tblspcoid = get_tablespace_oid(tblspcname);
- if (dst_tblspcoid == InvalidOid)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("tablespace \"%s\" does not exist", tblspcname)));
+ dst_tblspcoid = get_tablespace_oid(tblspcname, false);
/*
* Permission checks
@@ -1402,12 +1393,7 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
void
AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
{
- Oid datid = get_database_oid(stmt->dbname);
-
- if (!OidIsValid(datid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", stmt->dbname)));
+ Oid datid = get_database_oid(stmt->dbname, false);
/*
* Obtain a lock on the database and make sure it didn't go away in the
@@ -1818,10 +1804,11 @@ errdetail_busy_db(int notherbackends, int npreparedxacts)
/*
* get_database_oid - given a database name, look up the OID
*
- * Returns InvalidOid if database name not found.
+ * If missing_ok is false, throw an error if database name not found. If
+ * true, just return InvalidOid.
*/
Oid
-get_database_oid(const char *dbname)
+get_database_oid(const char *dbname, bool missing_ok)
{
Relation pg_database;
ScanKeyData entry[1];
@@ -1852,6 +1839,12 @@ get_database_oid(const char *dbname)
systable_endscan(scan);
heap_close(pg_database, AccessShareLock);
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_DATABASE),
+ errmsg("database \"%s\" does not exist",
+ dbname)));
+
return oid;
}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 14356a2..6b22570 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -184,7 +184,7 @@ GetUserOidFromMapping(const char *username, bool missing_ok)
return GetUserId();
/* map to provided user */
- return missing_ok ? get_roleid(username) : get_roleid_checked(username);
+ return get_role_oid(username, missing_ok);
}
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 503148f..60f4c44 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -218,12 +218,7 @@ DefineIndex(RangeVar *heapRelation,
*/
if (tableSpaceName)
{
- tablespaceId = get_tablespace_oid(tableSpaceName);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- tableSpaceName)));
+ tablespaceId = get_tablespace_oid(tableSpaceName, false);
}
else
{
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 0d6aad1..d2d9f3a 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -661,20 +661,11 @@ DefineOpFamily(CreateOpFamilyStmt *stmt)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceoid));
- /* Get necessary info about access method */
- tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
-
- amoid = HeapTupleGetOid(tup);
+ /* Get access method OID, throwing an error if it doesn't exist. */
+ amoid = get_am_oid(stmt->amname, false);
/* XXX Should we make any privilege check against the AM? */
- ReleaseSysCache(tup);
-
/*
* Currently, we require superuser privileges to create an opfamily. See
* comments in DefineOpClass.
@@ -1488,12 +1479,7 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
+ amID = get_am_oid(stmt->amname, false);
/*
* Look up the opclass.
@@ -1549,12 +1535,7 @@ RemoveOpFamily(RemoveOpFamilyStmt *stmt)
/*
* Get the access method's OID.
*/
- amID = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname));
- if (!OidIsValid(amID))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- stmt->amname)));
+ amID = get_am_oid(stmt->amname, false);
/*
* Look up the opfamily.
@@ -1711,12 +1692,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
Relation rel;
AclResult aclresult;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
@@ -1805,12 +1781,7 @@ RenameOpFamily(List *name, const char *access_method, const char *newname)
Relation rel;
AclResult aclresult;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
@@ -1896,12 +1867,7 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
char *opcname;
char *schemaname;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
@@ -2039,12 +2005,7 @@ AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId)
char *opfname;
char *schemaname;
- amOid = GetSysCacheOid1(AMNAME, CStringGetDatum(access_method));
- if (!OidIsValid(amOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("access method \"%s\" does not exist",
- access_method)));
+ amOid = get_am_oid(access_method, false);
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
@@ -2169,3 +2130,22 @@ AlterOpFamilyOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
newOwnerId);
}
}
+
+/*
+ * get_am_oid - given an access method name, look up the OID
+ *
+ * If missing_ok is false, throw an error if access method not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_am_oid(const char *amname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(AMNAME, CStringGetDatum(amname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("access method \"%s\" does not exist", amname)));
+ return oid;
+}
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 633a093..a4e3afe 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -514,7 +514,7 @@ void
DropProceduralLanguage(DropPLangStmt *stmt)
{
char *languageName;
- HeapTuple langTup;
+ Oid oid;
ObjectAddress object;
/*
@@ -522,34 +522,26 @@ DropProceduralLanguage(DropPLangStmt *stmt)
*/
languageName = case_translate_language_name(stmt->plname);
- langTup = SearchSysCache1(LANGNAME, CStringGetDatum(languageName));
- if (!HeapTupleIsValid(langTup))
+ oid = get_language_oid(languageName, stmt->missing_ok);
+ if (!OidIsValid(oid))
{
- if (!stmt->missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", languageName)));
- else
- ereport(NOTICE,
- (errmsg("language \"%s\" does not exist, skipping",
- languageName)));
-
+ ereport(NOTICE,
+ (errmsg("language \"%s\" does not exist, skipping",
+ languageName)));
return;
}
/*
* Check permission
*/
- if (!pg_language_ownercheck(HeapTupleGetOid(langTup), GetUserId()))
+ if (!pg_language_ownercheck(oid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
languageName);
object.classId = LanguageRelationId;
- object.objectId = HeapTupleGetOid(langTup);
+ object.objectId = oid;
object.objectSubId = 0;
- ReleaseSysCache(langTup);
-
/*
* Do the deletion
*/
@@ -735,3 +727,22 @@ AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
newOwnerId);
}
}
+
+/*
+ * get_language_oid - given a language name, look up the OID
+ *
+ * If missing_ok is false, throw an error if language name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_language_oid(const char *langname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("language \"%s\" does not exist", langname)));
+ return oid;
+}
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index b0a9a22..9edd59d 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -57,7 +57,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
* Who is supposed to own the new schema?
*/
if (authId)
- owner_uid = get_roleid_checked(authId);
+ owner_uid = get_role_oid(authId, false);
else
owner_uid = saved_uid;
@@ -178,24 +178,13 @@ RemoveSchemas(DropStmt *drop)
errmsg("schema name cannot be qualified")));
namespaceName = strVal(linitial(names));
- namespaceId = GetSysCacheOid1(NAMESPACENAME,
- CStringGetDatum(namespaceName));
+ namespaceId = get_namespace_oid(namespaceName, drop->missing_ok);
if (!OidIsValid(namespaceId))
{
- if (!drop->missing_ok)
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist",
- namespaceName)));
- }
- else
- {
- ereport(NOTICE,
- (errmsg("schema \"%s\" does not exist, skipping",
- namespaceName)));
- }
+ ereport(NOTICE,
+ (errmsg("schema \"%s\" does not exist, skipping",
+ namespaceName)));
continue;
}
@@ -264,9 +253,7 @@ RenameSchema(const char *oldname, const char *newname)
errmsg("schema \"%s\" does not exist", oldname)));
/* make sure the new name doesn't exist */
- if (HeapTupleIsValid(
- SearchSysCache1(NAMESPACENAME,
- CStringGetDatum(newname))))
+ if (OidIsValid(get_namespace_oid(newname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_SCHEMA),
errmsg("schema \"%s\" already exists", newname)));
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b32cd4f..fb50827 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -411,12 +411,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
*/
if (stmt->tablespacename)
{
- tablespaceId = get_tablespace_oid(stmt->tablespacename);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- stmt->tablespacename)));
+ tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
}
else
{
@@ -2750,7 +2745,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
- get_roleid_checked(cmd->name),
+ get_role_oid(cmd->name, false),
false);
break;
case AT_ClusterOn: /* CLUSTER ON */
@@ -6739,11 +6734,7 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
AclResult aclresult;
/* Check that the tablespace exists */
- tablespaceId = get_tablespace_oid(tablespacename);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", tablespacename)));
+ tablespaceId = get_tablespace_oid(tablespacename, false);
/* Check its permissions */
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 58a7b75..08a8c48 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -246,7 +246,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */
if (stmt->owner)
- ownerId = get_roleid_checked(stmt->owner);
+ ownerId = get_role_oid(stmt->owner, false);
else
ownerId = GetUserId();
@@ -298,7 +298,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
* index would catch this anyway, but might as well give a friendlier
* message.)
*/
- if (OidIsValid(get_tablespace_oid(stmt->tablespacename)))
+ if (OidIsValid(get_tablespace_oid(stmt->tablespacename, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("tablespace \"%s\" already exists",
@@ -1000,7 +1000,7 @@ assign_default_tablespace(const char *newval, bool doit, GucSource source)
if (IsTransactionState())
{
if (newval[0] != '\0' &&
- !OidIsValid(get_tablespace_oid(newval)))
+ !OidIsValid(get_tablespace_oid(newval, true)))
{
ereport(GUC_complaint_elevel(source),
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -1050,7 +1050,7 @@ GetDefaultTablespace(bool forTemp)
* to refer to an existing tablespace; we just silently return InvalidOid,
* causing the new object to be created in the database's tablespace.
*/
- result = get_tablespace_oid(default_tablespace);
+ result = get_tablespace_oid(default_tablespace, true);
/*
* Allow explicit specification of database's default tablespace in
@@ -1117,21 +1117,13 @@ assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
continue;
}
- /* Else verify that name is a valid tablespace name */
- curoid = get_tablespace_oid(curname);
+ /*
+ * In an interactive SET command, we ereport for bad info.
+ * Otherwise, silently ignore any bad list elements.
+ */
+ curoid = get_tablespace_oid(curname, source < PGC_S_INTERACTIVE);
if (curoid == InvalidOid)
- {
- /*
- * In an interactive SET command, we ereport for bad info.
- * Otherwise, silently ignore any bad list elements.
- */
- if (source >= PGC_S_INTERACTIVE)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- curname)));
continue;
- }
/*
* Allow explicit specification of database's default tablespace
@@ -1230,10 +1222,10 @@ PrepareTempTablespaces(void)
}
/* Else verify that name is a valid tablespace name */
- curoid = get_tablespace_oid(curname);
+ curoid = get_tablespace_oid(curname, true);
if (curoid == InvalidOid)
{
- /* Silently ignore any bad list elements */
+ /* Skip any bad list elements */
continue;
}
@@ -1266,10 +1258,11 @@ PrepareTempTablespaces(void)
/*
* get_tablespace_oid - given a tablespace name, look up the OID
*
- * Returns InvalidOid if tablespace name not found.
+ * If missing_ok is false, throw an error if tablespace name not found. If
+ * true, just return InvalidOid.
*/
Oid
-get_tablespace_oid(const char *tablespacename)
+get_tablespace_oid(const char *tablespacename, bool missing_ok)
{
Oid result;
Relation rel;
@@ -1300,6 +1293,12 @@ get_tablespace_oid(const char *tablespacename)
heap_endscan(scandesc);
heap_close(rel, AccessShareLock);
+ if (!OidIsValid(result) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("tablespace \"%s\" does not exist",
+ tablespacename)));
+
return result;
}
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 2f0788e..1c73d9b 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -293,8 +293,7 @@ CreateRole(CreateRoleStmt *stmt)
pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
pg_authid_dsc = RelationGetDescr(pg_authid_rel);
- tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
- if (HeapTupleIsValid(tuple))
+ if (OidIsValid(get_role_oid(stmt->role, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("role \"%s\" already exists",
@@ -384,7 +383,7 @@ CreateRole(CreateRoleStmt *stmt)
foreach(item, addroleto)
{
char *oldrolename = strVal(lfirst(item));
- Oid oldroleid = get_roleid_checked(oldrolename);
+ Oid oldroleid = get_role_oid(oldrolename, false);
AddRoleMems(oldrolename, oldroleid,
list_make1(makeString(stmt->role)),
@@ -795,11 +794,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
/* look up and lock the database, if specified */
if (stmt->database != NULL)
{
- databaseid = get_database_oid(stmt->database);
- if (!OidIsValid(databaseid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("database \"%s\" not found", stmt->database)));
+ databaseid = get_database_oid(stmt->database, false);
shdepLockAndCheckObject(DatabaseRelationId, databaseid);
}
@@ -1099,7 +1094,7 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
- grantor = get_roleid_checked(stmt->grantor);
+ grantor = get_role_oid(stmt->grantor, false);
else
grantor = GetUserId();
@@ -1127,7 +1122,7 @@ GrantRole(GrantRoleStmt *stmt)
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
- roleid = get_roleid_checked(rolename);
+ roleid = get_role_oid(rolename, false);
if (stmt->is_grant)
AddRoleMems(rolename, roleid,
stmt->grantee_roles, grantee_ids,
@@ -1194,7 +1189,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/* Must have privileges on the receiving side too */
- newrole = get_roleid_checked(stmt->newrole);
+ newrole = get_role_oid(stmt->newrole, false);
if (!has_privs_of_role(GetUserId(), newrole))
ereport(ERROR,
@@ -1220,7 +1215,7 @@ roleNamesToIds(List *memberNames)
foreach(l, memberNames)
{
char *rolename = strVal(lfirst(l));
- Oid roleid = get_roleid_checked(rolename);
+ Oid roleid = get_role_oid(rolename, false);
result = lappend_oid(result, roleid);
}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index d299310..857483a 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2118,12 +2118,7 @@ OpenIntoRel(QueryDesc *queryDesc)
*/
if (into->tableSpaceName)
{
- tablespaceId = get_tablespace_oid(into->tableSpaceName);
- if (!OidIsValid(tablespaceId))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- into->tableSpaceName)));
+ tablespaceId = get_tablespace_oid(into->tableSpaceName, false);
}
else
{
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index c967364..7ee7842 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -459,7 +459,7 @@ is_member(Oid userid, const char *role)
if (!OidIsValid(userid))
return false; /* if user not exist, say "no" */
- roleid = get_roleid(role);
+ roleid = get_role_oid(role, true);
if (!OidIsValid(roleid))
return false; /* if target role not exist, say "no" */
@@ -1327,7 +1327,7 @@ check_hba(hbaPort *port)
HbaLine *hba;
/* Get the target role's OID. Note we do not error out for bad role. */
- roleid = get_roleid(port->user_name);
+ roleid = get_role_oid(port->user_name, true);
foreach(line, parsed_hba_lines)
{
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index faad11e..b320569 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -22,6 +22,7 @@
#include "catalog/pg_type.h"
#include "catalog/pg_class.h"
#include "commands/dbcommands.h"
+#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "foreign/foreign.h"
#include "funcapi.h"
@@ -324,7 +325,7 @@ aclparse(const char *s, AclItem *aip)
if (name[0] == '\0')
aip->ai_grantee = ACL_ID_PUBLIC;
else
- aip->ai_grantee = get_roleid_checked(name);
+ aip->ai_grantee = get_role_oid(name, false);
/*
* XXX Allow a degree of backward compatibility by defaulting the grantor
@@ -337,7 +338,7 @@ aclparse(const char *s, AclItem *aip)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("a name must follow the \"/\" sign")));
- aip->ai_grantor = get_roleid_checked(name2);
+ aip->ai_grantor = get_role_oid(name2, false);
}
else
{
@@ -1790,7 +1791,7 @@ has_table_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
@@ -1839,7 +1840,7 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_table_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
@@ -1997,7 +1998,7 @@ has_sequence_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
mode = convert_sequence_priv_string(priv_type_text);
sequenceoid = convert_table_name(sequencename);
if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE)
@@ -2057,7 +2058,7 @@ has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
AclResult aclresult;
char relkind;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_sequence_priv_string(priv_type_text);
relkind = get_rel_relkind(sequenceoid);
if (relkind == '\0')
@@ -2208,7 +2209,7 @@ has_any_column_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_column_priv_string(priv_type_text);
@@ -2265,7 +2266,7 @@ has_any_column_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_column_priv_string(priv_type_text);
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid)))
@@ -2450,7 +2451,7 @@ has_column_privilege_name_name_name(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
colattnum = convert_column_name(tableoid, column);
mode = convert_column_priv_string(priv_type_text);
@@ -2478,7 +2479,7 @@ has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*rolename), false);
tableoid = convert_table_name(tablename);
mode = convert_column_priv_string(priv_type_text);
@@ -2505,7 +2506,7 @@ has_column_privilege_name_id_name(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
colattnum = convert_column_name(tableoid, column);
mode = convert_column_priv_string(priv_type_text);
@@ -2531,7 +2532,7 @@ has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS)
AclMode mode;
int privresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_column_priv_string(priv_type_text);
privresult = column_privilege_check(tableoid, colattnum, roleid, mode);
@@ -2822,7 +2823,7 @@ has_database_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
@@ -2871,7 +2872,7 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_database_priv_string(priv_type_text);
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(databaseoid)))
@@ -2966,15 +2967,8 @@ static Oid
convert_database_name(text *databasename)
{
char *dbname = text_to_cstring(databasename);
- Oid oid;
- oid = get_database_oid(dbname);
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", dbname)));
-
- return oid;
+ return get_database_oid(dbname, false);
}
/*
@@ -3027,7 +3021,7 @@ has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
fdwid = convert_foreign_data_wrapper_name(fdwname);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
@@ -3076,7 +3070,7 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_foreign_data_wrapper_priv_string(priv_type_text);
aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode);
@@ -3209,7 +3203,7 @@ has_function_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
@@ -3258,7 +3252,7 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_function_priv_string(priv_type_text);
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(functionoid)))
@@ -3409,7 +3403,7 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
@@ -3458,7 +3452,7 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_language_priv_string(priv_type_text);
if (!SearchSysCacheExists1(LANGOID, ObjectIdGetDatum(languageoid)))
@@ -3553,15 +3547,8 @@ static Oid
convert_language_name(text *languagename)
{
char *langname = text_to_cstring(languagename);
- Oid oid;
- oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", langname)));
-
- return oid;
+ return get_language_oid(langname, false);
}
/*
@@ -3607,7 +3594,7 @@ has_schema_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
@@ -3656,7 +3643,7 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_schema_priv_string(priv_type_text);
if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(schemaoid)))
@@ -3751,15 +3738,8 @@ static Oid
convert_schema_name(text *schemaname)
{
char *nspname = text_to_cstring(schemaname);
- Oid oid;
-
- oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname));
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", nspname)));
- return oid;
+ return get_namespace_oid(nspname, false);
}
/*
@@ -3807,7 +3787,7 @@ has_server_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
serverid = convert_server_name(servername);
mode = convert_server_priv_string(priv_type_text);
@@ -3856,7 +3836,7 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_server_priv_string(priv_type_text);
aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode);
@@ -3989,7 +3969,7 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
@@ -4038,7 +4018,7 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_tablespace_priv_string(priv_type_text);
aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
@@ -4124,16 +4104,8 @@ static Oid
convert_tablespace_name(text *tablespacename)
{
char *spcname = text_to_cstring(tablespacename);
- Oid oid;
- oid = get_tablespace_oid(spcname);
-
- if (!OidIsValid(oid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", spcname)));
-
- return oid;
+ return get_tablespace_oid(spcname, false);
}
/*
@@ -4178,8 +4150,8 @@ pg_has_role_name_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleid = get_role_oid(NameStr(*username), false);
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4204,7 +4176,7 @@ pg_has_role_name(PG_FUNCTION_ARGS)
AclResult aclresult;
roleid = GetUserId();
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4227,7 +4199,7 @@ pg_has_role_name_id(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleid = get_roleid_checked(NameStr(*username));
+ roleid = get_role_oid(NameStr(*username), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4273,7 +4245,7 @@ pg_has_role_id_name(PG_FUNCTION_ARGS)
AclMode mode;
AclResult aclresult;
- roleoid = get_roleid_checked(NameStr(*rolename));
+ roleoid = get_role_oid(NameStr(*rolename), false);
mode = convert_role_priv_string(priv_type_text);
aclresult = pg_role_aclcheck(roleoid, roleid, mode);
@@ -4830,3 +4802,22 @@ select_best_grantor(Oid roleId, AclMode privileges,
}
}
}
+
+/*
+ * get_role_oid - Given a role name, look up the role's OID.
+ *
+ * If missing_ok is false, throw an error if tablespace name not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_role_oid(const char *rolname, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(rolname));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", rolname)));
+ return oid;
+}
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index a4e0252..8ec6b71 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -141,13 +141,7 @@ Datum
pg_database_size_name(PG_FUNCTION_ARGS)
{
Name dbName = PG_GETARG_NAME(0);
- Oid dbOid = get_database_oid(NameStr(*dbName));
-
- if (!OidIsValid(dbOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist",
- NameStr(*dbName))));
+ Oid dbOid = get_database_oid(NameStr(*dbName), false);
PG_RETURN_INT64(calculate_database_size(dbOid));
}
@@ -240,13 +234,7 @@ Datum
pg_tablespace_size_name(PG_FUNCTION_ARGS)
{
Name tblspcName = PG_GETARG_NAME(0);
- Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName));
-
- if (!OidIsValid(tblspcOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- NameStr(*tblspcName))));
+ Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName), false);
PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index aad6c35..9932415 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2626,34 +2626,3 @@ get_namespace_name(Oid nspid)
else
return NULL;
}
-
-/* ---------- PG_AUTHID CACHE ---------- */
-
-/*
- * get_roleid
- * Given a role name, look up the role's OID.
- * Returns InvalidOid if no such role.
- */
-Oid
-get_roleid(const char *rolname)
-{
- return GetSysCacheOid1(AUTHNAME, PointerGetDatum(rolname));
-}
-
-/*
- * get_roleid_checked
- * Given a role name, look up the role's OID.
- * ereports if no such role.
- */
-Oid
-get_roleid_checked(const char *rolname)
-{
- Oid roleid;
-
- roleid = get_roleid(rolname);
- if (!OidIsValid(roleid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", rolname)));
- return roleid;
-}
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index fe3b783..0fd61a9 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -91,6 +91,7 @@ extern void DeconstructQualifiedName(List *names,
char **objname_p);
extern Oid LookupNamespaceNoError(const char *nspname);
extern Oid LookupExplicitNamespace(const char *nspname);
+extern Oid get_namespace_oid(const char *nspname, bool missing_ok);
extern Oid LookupCreationNamespace(const char *nspname);
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h
index 542fc27..8c5ba1b 100644
--- a/src/include/commands/dbcommands.h
+++ b/src/include/commands/dbcommands.h
@@ -59,7 +59,7 @@ extern void AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel);
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId);
-extern Oid get_database_oid(const char *dbname);
+extern Oid get_database_oid(const char *dbname, bool missingok);
extern char *get_database_name(Oid dbid);
extern void dbase_redo(XLogRecPtr lsn, XLogRecord *rptr);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 7edda97..76aff43 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -99,6 +99,7 @@ extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwne
extern void AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId);
extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
extern void AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId);
+extern Oid get_am_oid(const char *amname, bool missing_ok);
/* commands/tsearchcmds.c */
extern void DefineTSParser(List *names, List *parameters);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index 5feff87..16c1d14 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -21,5 +21,6 @@ extern void RenameLanguage(const char *oldname, const char *newname);
extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
extern void AlterLanguageOwner_oid(Oid oid, Oid newOwnerId);
extern bool PLTemplateExists(const char *languageName);
+extern Oid get_language_oid(const char *langname, bool missing_ok);
#endif /* PROCLANG_H */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index cf005ee..98a9b86 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -51,7 +51,7 @@ extern Oid GetDefaultTablespace(bool forTemp);
extern void PrepareTempTablespaces(void);
-extern Oid get_tablespace_oid(const char *tablespacename);
+extern Oid get_tablespace_oid(const char *tablespacename, bool missing_ok);
extern char *get_tablespace_name(Oid spc_oid);
extern bool directory_is_empty(const char *path);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 9c38bd1..d9921e8 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -223,6 +223,7 @@ extern bool is_member_of_role(Oid member, Oid role);
extern bool is_member_of_role_nosuper(Oid member, Oid role);
extern bool is_admin_of_role(Oid member, Oid role);
extern void check_is_member_of_role(Oid member, Oid role);
+extern Oid get_role_oid(const char *rolname, bool missing_ok);
extern void select_best_grantor(Oid roleId, AclMode privileges,
const Acl *acl, Oid ownerId,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 131acb7..066ad76 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -136,8 +136,6 @@ extern void free_attstatsslot(Oid atttype,
Datum *values, int nvalues,
float4 *numbers, int nnumbers);
extern char *get_namespace_name(Oid nspid);
-extern Oid get_roleid(const char *rolname);
-extern Oid get_roleid_checked(const char *rolname);
#define type_is_array(typid) (get_element_type(typid) != InvalidOid)