From: Robert Haas on
Suppose you have an object name as a CString and you want to convert
it to an OID. The method of doing this varies widely depending on the
object type:

oid = get_database_oid(name);
oid = get_tablespace_oid(name);
oid = GetForeignDataWrapperOidByName(name, true);
oid = GetForeignServerOidByName(name, true);
oid = LookupFuncNameTypeNames(name, args, true);
oid = LookupAggNameTypeNames(name, args, true);
oid = LookupFuncNameTypeNames(name, args, true);
oid = LookupOperNameTypeNames(name, args, true);
oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(name));
oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(name));
oid = GetSysCacheOid1(AMNAME, CStringGetDatum(name));
oid = get_roleid(name);
oid = GetConstraintByName(reloid, name);
oid = FindConversionByName(list_make1(name));
oid = TSDictionaryGetDictid(list_make1(name), true);
oid = TSTemplateGetTmplid(list_make1(name), true);
oid = TSConfigGetCfgid(list_make1(name), true);

If you'd like to throw an error if the object doesn't exist, then you
can change the "true" parameter in the above examples to false, where
it exists, or you can use get_roleid_checked for roles. For the types
where a direct syscache lookup is used, you get to write the check
yourself. For constraints, GetConstraintByName throws an error
anyway; there's no equivalent that doesn't. Some other object types -
like rules and casts - have even more complex logic that is sometimes
duplicated in multiple places; and others (like tablespaces) that have
convenience functions still manage to duplicate the logic anyway.
Long story short, this is kind of a mess.

Looking at the different cases, there seem to be three main cases:

1. Objects that just have one name, like databases and procedural languages.
2. Objects that have possibly-qualified names, like conversions and
text search dictionaries.
3. Objects that have both names and argument, like functions and operators.

There's enough complexity about the stuff in category #3 that I'm
inclined to leave it alone, but try to make the other stuff more
standardized. What I would propose is that we create a new source
file somewhere (maybe utils/cache), move all of the other functions of
this type there, give them standardized names, and provide them all
with an argument that specifies whether an error is to be thrown if
the object doesn't exist. Begin bikeshedding here. I suggest that
the names be get_<object-type>_oid and that they take two parameters,
either a List * for possibly-qualified names (a little wonky, but it's
what we do now) or a char * for unqualified names, and a boolean
indicating whether to throw an error if the object isn't found. Thus:

Oid get_<object-type>_oid(List *qualname, bool missingok);
-or-
Oid get_<object-type>_oid(char *name, bool missingok);

Thus get_database_oid and get_tablespace_oid would remain unchanged
except for taking a second argument, get_roleid and get_roleid_checked
would merge, and all of the others would change to match that style.

Thoughts?

P.S. Purple.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers