From: Robert Haas on 23 May 2010 00:50 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
|
Pages: 1 Prev: "unexpected" query behaviour after i change parser code Next: mapping object names to role IDs |