Replies: 3 comments 2 replies
-
Hi Chapman, Thank you for this post! It's an interesting proposal, and I've run into cases where I wanted new "kinds" of database objects. I'll digest it more deeply over the next few days, but I ponder if this should necessarily be limited to extensions. What would be the reasons for not allowing the creation of new database object kinds through a normal course of operation? If we allowed this, we would have less complex restrictions to implement and explain. |
Beta Was this translation helpful? Give feedback.
-
Hi Chapman! I ran into a similar problem when we implemented the job handling in TimescaleDB. Each job has an owner and associated procedures, and if you drop the owner or the procedure, we want the dependency to be tracked so that you either get an error message that you have a dependency, or can use cascade to delete the job. When I tried to use the Strictly speaking, I do not think that it needs to be part of an extension but I do not think that is a serious limitation since in most cases these will be in an extension. Thanks for writing down this proposal. I will take a look at it over the coming days. |
Beta Was this translation helpful? Give feedback.
-
This reminds me of an idea I had, in thinking about the problem of making third-party packages available to trusted languages. Today, if you want to make Perl modules or Rust crates available to PL/Perl or PL/Rust — well, you can't. But what if there was core support for PL dependencies? The idea is something like this: There's a system catalog for PL dependencies. All the dependency stuff you mention would apply to their rows, such as ACLs. Each row defines some unique name, perhaps associated with a PL, and then there's a payload: JAR file, rust Crate, Perl module, etc. Where possible, the Postgres PL implementation hooks into the module-loading API of the PL (e.g., Perl's This allows the superuser to load supporting libraries for any PL into the database and set up appropriate permissions for PL functions to call them. Anyway, seems like there might be a more general problem to be solved here. |
Beta Was this translation helpful? Give feedback.
-
it's easy to write an extension that creates new database objects of existing kinds: functions, types, operators.... These all have first-class support in PostgreSQL, they can have owners and ACLs and they are recorded in
pg_depend
as being members of the extension that creates them.It is less nice when your extension makes possible some new kind of database object.
For one example, when the PL/Java extension is installed, a Java jar file is a new kind of database object. ISO 9075-13 defines it; you can load one, you can drop one, it has an owner , and you can grant
USAGE
on it. These are all familiar things you can do with the built-in kinds of object. (PL/Java currently implements the owner kind of poorly, and the ACL not at all. Why? read on.)And, ideally, there could then be other extensions, which supply their own instances of objects of this new kind, and those instances would be recorded as members of those extensions.
While this Java example may be the top one on my mind, it's surely not the only case where an extension supplies a new kind of database object. @mkindahl and I had a brief hallway conversation about it in Vancouver.
But these new kinds of object are decidedly second-class citizens. I can have PL/Java maintain a table of jar files, just as Postgres maintains, say,
pg_proc
. The oid of my table plus the id of a row form the "object address" of a jar file, just as the oid ofpg_proc
and the oid of a row form theObjectAddress
of a routine.But my "object address" isn't a real one 😢. It can't be entered in
pg_depend
as a member of an extension. It can't depend on or be depended on by anything else. If ISO SQL says my jar objects should have owners, I can add an owner column, but with little support from the system. Even if the column is typedregrole
, Postgres won't record that a newly-inserted row depends on its owner role. (And if it isn't typedregrole
, the choice is between two ways of being wrong: store the role oid and be broken by dump/restore or upgrade, or store the role name and be broken by renames).If I want my objects to have ACLs, as ISO says they should, I can add an
aclitem[]
column, but again, Postgres will not record dependencies on the roles named in my ACLs.The bulk of the problems here boil down to the restrictions on what can go into
pg_depend
andpg_shdepend
.When I first raised these issues on
-hackers
in 2015, it led to my making this proposal.A note from the passage-of-time department:
Two relevant things have changed in PostgreSQL since I made that proposal:
WITH OIDS
int4
primary key is perfectly workable.ALTER EXTENSION ... ADD LARGE OBJECT
? An oversight, perhaps?)So I still think the proposal from 2015, with minor updates, is worth thinking about.
The proposal started with key observations:
pg_depend
(orpg_shdepend
) from mentioning rows in a non-system table. A pair (oid of table, 32-bit key into table) can identify a row in an extension-supplied table just as easily as in a system table.pg_depend
/pg_shdepend
is explicit logic enforcing that the table oid must refer to a system table.So, I asked, how could the restriction be cautiously loosened to allow selective, well-controlled usage with particular tables managed by extensions?
How about, if a dependency is about to be added and the table oid (
classid
orrefclassid
inpg_depend
, orclassid
inpg_shdepend
) does not identify a system table, then the table it does identify must:int4
primary key, andDELETE FOR EACH ROW
trigger with a specific system-provided target function.CREATE TRIGGER
would forbid creating any trigger with that target function, except when:creating_extension
is true, andint4
primary key, andMaking
CREATE TRIGGER
responsible for checking the full list of conditions (when that special target function is named) allows the dependency machinery to get away with only checking that the trigger is present. If so, the table is allowed to be mentioned inpg_depend
/pg_shdepend
entries.That was a short recap of the more detailed proposal from 2015 here.
One remaining piece would be a hook allowing the extension to supply names for the new class of object and instances of it, for use by
getObjectTypeDescription
andgetObjectDescription
. So one more condition to be checked above would be thatgetObjectTypeDescription
returns a name for the table's oid, confirming that the hook has been hooked.Edit: my original proposal contemplated a hook. Peter Eisentraut recently submitted patches for virtual generated columns. When those make it into PostgreSQL, they'd be a perfect SQL-only replacement for the proposed hook. Simply require that the extension-managed table have two virtual columns,
ObjectTypeDescription
(returning a constant string like'jar file'
) andObjectDescription
(returning a constructed string for that row like'jar file foo'
).This seems like a proposal with a small handful of moving parts but nothing really difficult or complex. Possibly I should start implementing it as a PR to pgedc's fork.
I would welcome reactions and comments.
Beta Was this translation helpful? Give feedback.
All reactions