![]() | |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Hi, I need to include a column in a table that *references* another table. I.e., the type of the column would be "name of table". |
|
Furthermore, I want to constrain the value in that column to ensure that it represents an *existing* table. And, ensure that the referenced table is not removed while it is thusly referenced. |
|
I *think* creating a column of type "name" and tying it to pg_tables.tablename satisfies the first criteria. But, how do I ensure the RDBMS prevents the deletion of the referenced table while any such reference exists? |
#3
| |||
| |||
|
|
On 2011-01-20, D Yuniskis<not.going.to.be (AT) seen (DOT) com> wrote: I need to include a column in a table that *references* another table. I.e., the type of the column would be "name of table". the postgres type 'name' seems suitable here Furthermore, I want to constrain the value in that column to ensure that it represents an *existing* table. And, ensure that the referenced table is not removed while it is thusly referenced. That's not going to happen, Tom Lane (who is spokesman if not leader of the development team) has repeatedly said there is no support for triggers on relations in the information or pg_catalog schemas, nor are there future plans to support that. |
|
I *think* creating a column of type "name" and tying it to pg_tables.tablename satisfies the first criteria. But, how do I ensure the RDBMS prevents the deletion of the referenced table while any such reference exists? a references constraint would normally block the changing of that column or removal of that row, and thus block deleting the table, but you're not allowd to create references constraints to or triggers on system catalogs. jasen=# create table loki(t name,ns oid,foreign key (t,ns) references pg_catalog.pg_class(relname,relnamespace)); ERROR: permission denied: "pg_class" is a system catalog this means you'll need to handle the deletions after the fact, or constrain the ordinary users into only deleting tables using a certain method you define. |
#4
| ||||
| ||||
|
|
Hi Jasen, this behavior on a PG deployment. E.g., it need not look like a generic PG deployment (it is for use in a set of embedded systems so *I* control all access to the PG running therein). For example, I could impose a front end that intercepts {CREATE,DROP,ALTER} TABLE requests and rewrites them prior to passing them on to PG. That front end could be free to use whatever resources it needs to impose this extra constraint (i.e., it's own idea of "system catalogs") as the performance hit would be justifiable. |
|
Since all I am doing is adding one capability/restriction (and not arbitrarily allowing "any" trigger or relation involving system tables), the problem's scope is considerably less than expecting/requiring PG to handle system catalogs *identically* to "regular" tables. |
|
To that end, I am trying to identify any subtleties that could *unintentionally* circumvent this sort of approach. (remember, *I* control access to the RDBMS so all I have to do is "protect me from myself") I *think* creating a column of type "name" and tying it to pg_tables.tablename satisfies the first criteria. But, how do I ensure the RDBMS prevents the deletion of the referenced table while any such reference exists? a references constraint would normally block the changing of that column or removal of that row, and thus block deleting the table, but you're not allowd to create references constraints to or triggers on system catalogs. jasen=# create table loki(t name,ns oid,foreign key (t,ns) references pg_catalog.pg_class(relname,relnamespace)); ERROR: permission denied: "pg_class" is a system catalog this means you'll need to handle the deletions after the fact, or constrain the ordinary users into only deleting tables using a certain method you define. "After the fact" isn't an option. If a table thusly referenced is deleted, the device crashes. Sort of like letting something erase the VTOC on a drive and trying to "clean up" later (i.e., "hoping" all the other applications referencing that drive will be able to, somehow, compensate.) |
|
Are there other RDBMS offerings that might have this ability? |
#5
| ||||
| ||||
|
|
On 2011-01-24, D Yuniskis<not.going.to.be (AT) seen (DOT) com> wrote: For example, I could impose a front end that intercepts {CREATE,DROP,ALTER} TABLE requests and rewrites them prior to passing them on to PG. That front end could be free to use whatever resources it needs to impose this extra constraint (i.e., it's own idea of "system catalogs") as the performance hit would be justifiable. rewriting of requests is what RULES do in PG CREATE [ OR REPLACE ] RULE name AS ON event TO table [ WHERE condition ] DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) } The event is one of SELECT, INSERT, UPDATE, or DELETE. I don't know how much work would need to be done on the source (which is freely available) to get DROP and ALTER added to that list. |
|
Since all I am doing is adding one capability/restriction (and not arbitrarily allowing "any" trigger or relation involving system tables), the problem's scope is considerably less than expecting/requiring PG to handle system catalogs *identically* to "regular" tables. trying to go that way is dependant on the system tables being sufficiently like ordinary tables. and the code being organised in such a way that supporting triggers on a system table doesn't immediately lead to infinite recursion. |
|
To that end, I am trying to identify any subtleties that could *unintentionally* circumvent this sort of approach. (remember, *I* control access to the RDBMS so all I have to do is "protect me from myself") I *think* creating a column of type "name" and tying it to pg_tables.tablename satisfies the first criteria. But, how do I ensure the RDBMS prevents the deletion of the referenced table while any such reference exists? a references constraint would normally block the changing of that column or removal of that row, and thus block deleting the table, but you're not allowd to create references constraints to or triggers on system catalogs. jasen=# create table loki(t name,ns oid,foreign key (t,ns) references pg_catalog.pg_class(relname,relnamespace)); ERROR: permission denied: "pg_class" is a system catalog this means you'll need to handle the deletions after the fact, or constrain the ordinary users into only deleting tables using a certain method you define. "After the fact" isn't an option. If a table thusly referenced is deleted, the device crashes. Sort of like letting something erase the VTOC on a drive and trying to "clean up" later (i.e., "hoping" all the other applications referencing that drive will be able to, somehow, compensate.) So instead constrain the ordinary users into only deleting tables using a certain method you define. that's easy. if the user of the normal database connection doesn't match the owner of the table (or schema or database) they can't drop the table, using the "DROP TABLE" command. but if you provide a function with "SECURITY DEFINER" owned by rhe owner of the table, and this fnction does the "DROP TABLE", then in this function you can do the extra checks needed before dropping the table. you also need to constrain them from creating tables that they own (easy: don't grant them create table permission) and if necessary provide a similar interface to create and alter tables |
|
Are there other RDBMS offerings that might have this ability? I only know postgres in sufficient detail to offer useful comment on it.. |
![]() |
| Thread Tools | |
| Display Modes | |
| |