Thread: Dealing with table names in functions
Is there a safe way to deal with tables being passed into a function, specifically in terms of what schema they're in? I can just blindly accept a text string and hope that it's always evaluated in the correct search_path context, but that doesn't seem so good. OTOH, if I accept an OID, there's no great way to pass that to most of the rest of the system... I can cast the OID to regclass, but that doesn't get me a fully-qualified name. It would be nice if there was a way to convert an OID into a fully- qualified name. I'm working on some partitioning stuff, and I'm currently writing a function that will return the name of a partition given the parent table and what period to partition on (ie: day, month, year, etc). Originally, I thought I'd just accept an OID for the table name, but I can't think of a safe way to look up that tables schema name (because I want to return a fully qualified name). Obviously, I can look in pg_class and pg_namespace, but someone could do a DROP TABLE between when I do that lookup and when I actually use the name. So I thought I'd just do a LOCK TABLE... except I need the table name to do that. Catch-22. -- Jim Nasby jim@nasby.net EnterpriseDB http://enterprisedb.com 512.569.9461 (cell)
On 3/22/07, Jim Nasby <decibel@decibel.org> wrote: > Is there a safe way to deal with tables being passed into a function, > specifically in terms of what schema they're in? I can just blindly > accept a text string and hope that it's always evaluated in the > correct search_path context, but that doesn't seem so good. OTOH, if > I accept an OID, there's no great way to pass that to most of the > rest of the system... I can cast the OID to regclass, but that > doesn't get me a fully-qualified name. > > It would be nice if there was a way to convert an OID into a fully- > qualified name. > > I'm working on some partitioning stuff, and I'm currently writing a > function that will return the name of a partition given the parent > table and what period to partition on (ie: day, month, year, etc). > > Originally, I thought I'd just accept an OID for the table name, but > I can't think of a safe way to look up that tables schema name > (because I want to return a fully qualified name). Obviously, I can > look in pg_class and pg_namespace, but someone could do a DROP TABLE > between when I do that lookup and when I actually use the name. So I > thought I'd just do a LOCK TABLE... except I need the table name to > do that. Catch-22. You can select pg_class name in transaction by oid 'for update'. This will block drop table, etc. from other sessions. This will only work if you are the superuser however. merlin
-----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 > Is there a safe way to deal with tables being passed into a function, > specifically in terms of what schema they're in? Pass in the schema and tablename together as a string: select foobar('public.baz'); or (better, IMO) make it two separate arguments: select foobar('baz', 'public'); I usually put the table first as it allows me to overload the function with a single arg and a default schema. - -- Greg Sabino Mullane greg@turnstep.com PGP Key: 0x14964AC8 200703220923 http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8 -----BEGIN PGP SIGNATURE----- iD8DBQFGAoOGvJuQZxSWSsgRAxYOAJ9kuyz8YY+LvMsVxHSuqFbintcSAQCfWX6y zk5PVMhN9Pqxxkwvy/erCbw= =ZTzZ -----END PGP SIGNATURE-----
Jim Nasby wrote: > Is there a safe way to deal with tables being passed into a function, > specifically in terms of what schema they're in? I can just blindly > accept a text string and hope that it's always evaluated in the > correct search_path context, but that doesn't seem so good. OTOH, if > I accept an OID, there's no great way to pass that to most of the > rest of the system... I can cast the OID to regclass, but that > doesn't get me a fully-qualified name. Pass the optionally qualified name and cast it to regclass. It will work correctly when the name is not qualified, applying search_path, and it will also work when the name is qualified. -- Alvaro Herrera http://www.CommandPrompt.com/ The PostgreSQL Company - Command Prompt, Inc.
Jim Nasby <decibel@decibel.org> writes: > ... I can cast the OID to regclass, but that > doesn't get me a fully-qualified name. It does if the name needs to be qualified given your current search_path. regards, tom lane
On Thu, 2007-03-22 at 09:40 -0400, Alvaro Herrera wrote: > Pass the optionally qualified name and cast it to regclass. It will > work correctly when the name is not qualified, applying search_path, > and it will also work when the name is qualified. Is there a way to get names that are always qualified, irrespective of the search_path? Once one has the oid, it's an easy function to write, but I suspect this machinery already exists. For example, I'd like the hypothetical cast: rkh@csb-dev=> set search_path = 'unison'; SET rkh@csb-dev=> select 'pseq'::regclass::oid::FQregclass; regclass ---------- unison.pseq (1 row) -Reece -- Reece Hart, http://harts.net/reece/, GPG:0x25EC91A0 ./universe -G 6.672e-11 -e 1.602e-19 -protonmass 1.673e-27 -uspres bush kernel warning: universe consuming too many resources. Killing. universe killed due to catastrophic leadership. Try -uspres carter.