pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Subject: Add primary keys to system catalogs
Date: Sat, 3 Oct 2020 08:40:31 +0200
Message-ID: <dc5f44d9-5ec1-a596-0251-dadadcdede98@2ndquadrant.com> (raw)

I saw someone ask once for a schema diagram of the system catalogs. 
Things like that have occasionally been produced manually, but they are 
not regularly updated.  That made me wonder, why can't we add primary 
and foreign keys to system catalogs and then have existing tools produce 
such a schema diagram automatically?

Since we have ADD PRIMARY KEY USING INDEX, we can declare a primary key 
for an existing index.  So this doesn't have to affect the low-level 
early bootstrapping.  The attached patch adds those commands manually. 
Another option might be to have the catalog generation Perl tooling 
create those declarations automatically from some marker in the catalog 
files.  That would also allow declaring unique constraints for the 
unique indexes that don't end up being the primary key.

I'm not dealing here with how we might do foreign keys between system 
catalogs, but I think the idea would be to have some way to declare a 
foreign key "on paper" without any actual triggers.

Any thoughts on this direction?

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

0001-Add-primary-keys-to-system-catalogs.patch (text/plain, 9.8K) download From c9b1ff561dc7db045511a4da3cc87ecaac9c520b Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter@eisentraut.org> Date: Sat, 3 Oct 2020 08:27:36 +0200 Subject: [PATCH] Add primary keys to system catalogs For those system catalogs that have a unique index, make a primary key constraint, using ALTER TABLE ... PRIMARY KEY USING INDEX. This can be helpful for GUI tools that look for a primary key, and it might in the future allow declaring foreign keys, for making schema diagrams. System catalogs without a primary key so far: pg_depend, pg_shdepend don't have a unique key; pg_seclabel, pg_shseclabel use a nondefault operator class. --- src/backend/catalog/system_views.sql | 60 +++++++++++++++++++ .../expected/alter_system_table.out | 5 +- .../unsafe_tests/sql/alter_system_table.sql | 5 +- src/test/regress/expected/misc_sanity.out | 14 +++++ src/test/regress/sql/misc_sanity.sql | 9 +++ 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index ed4f3f142d..a1cdaed571 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -14,6 +14,66 @@ * string literal (including a function body!) or a multiline comment. */ +ALTER TABLE pg_aggregate ADD PRIMARY KEY USING INDEX pg_aggregate_fnoid_index; +ALTER TABLE pg_am ADD PRIMARY KEY USING INDEX pg_am_oid_index; +ALTER TABLE pg_amop ADD PRIMARY KEY USING INDEX pg_amop_oid_index; +ALTER TABLE pg_amproc ADD PRIMARY KEY USING INDEX pg_amproc_oid_index; +ALTER TABLE pg_attrdef ADD PRIMARY KEY USING INDEX pg_attrdef_oid_index; +ALTER TABLE pg_attribute ADD PRIMARY KEY USING INDEX pg_attribute_relid_attnum_index; +ALTER TABLE pg_authid ADD PRIMARY KEY USING INDEX pg_authid_oid_index; +ALTER TABLE pg_auth_members ADD PRIMARY KEY USING INDEX pg_auth_members_role_member_index; +ALTER TABLE pg_cast ADD PRIMARY KEY USING INDEX pg_cast_oid_index; +ALTER TABLE pg_class ADD PRIMARY KEY USING INDEX pg_class_oid_index; +ALTER TABLE pg_collation ADD PRIMARY KEY USING INDEX pg_collation_oid_index; +ALTER TABLE pg_constraint ADD PRIMARY KEY USING INDEX pg_constraint_oid_index; +ALTER TABLE pg_conversion ADD PRIMARY KEY USING INDEX pg_conversion_oid_index; +ALTER TABLE pg_database ADD PRIMARY KEY USING INDEX pg_database_oid_index; +ALTER TABLE pg_db_role_setting ADD PRIMARY KEY USING INDEX pg_db_role_setting_databaseid_rol_index; +ALTER TABLE pg_default_acl ADD PRIMARY KEY USING INDEX pg_default_acl_oid_index; +ALTER TABLE pg_description ADD PRIMARY KEY USING INDEX pg_description_o_c_o_index; +ALTER TABLE pg_enum ADD PRIMARY KEY USING INDEX pg_enum_oid_index; +ALTER TABLE pg_event_trigger ADD PRIMARY KEY USING INDEX pg_event_trigger_oid_index; +ALTER TABLE pg_extension ADD PRIMARY KEY USING INDEX pg_extension_oid_index; +ALTER TABLE pg_foreign_data_wrapper ADD PRIMARY KEY USING INDEX pg_foreign_data_wrapper_oid_index; +ALTER TABLE pg_foreign_server ADD PRIMARY KEY USING INDEX pg_foreign_server_oid_index; +ALTER TABLE pg_foreign_table ADD PRIMARY KEY USING INDEX pg_foreign_table_relid_index; +ALTER TABLE pg_index ADD PRIMARY KEY USING INDEX pg_index_indexrelid_index; +ALTER TABLE pg_inherits ADD PRIMARY KEY USING INDEX pg_inherits_relid_seqno_index; +ALTER TABLE pg_init_privs ADD PRIMARY KEY USING INDEX pg_init_privs_o_c_o_index; +ALTER TABLE pg_language ADD PRIMARY KEY USING INDEX pg_language_oid_index; +ALTER TABLE pg_largeobject ADD PRIMARY KEY USING INDEX pg_largeobject_loid_pn_index; +ALTER TABLE pg_largeobject_metadata ADD PRIMARY KEY USING INDEX pg_largeobject_metadata_oid_index; +ALTER TABLE pg_namespace ADD PRIMARY KEY USING INDEX pg_namespace_oid_index; +ALTER TABLE pg_opclass ADD PRIMARY KEY USING INDEX pg_opclass_oid_index; +ALTER TABLE pg_operator ADD PRIMARY KEY USING INDEX pg_operator_oid_index; +ALTER TABLE pg_opfamily ADD PRIMARY KEY USING INDEX pg_opfamily_oid_index; +ALTER TABLE pg_partitioned_table ADD PRIMARY KEY USING INDEX pg_partitioned_table_partrelid_index; +ALTER TABLE pg_policy ADD PRIMARY KEY USING INDEX pg_policy_oid_index; +ALTER TABLE pg_proc ADD PRIMARY KEY USING INDEX pg_proc_oid_index; +ALTER TABLE pg_publication ADD PRIMARY KEY USING INDEX pg_publication_oid_index; +ALTER TABLE pg_publication_rel ADD PRIMARY KEY USING INDEX pg_publication_rel_oid_index; +ALTER TABLE pg_range ADD PRIMARY KEY USING INDEX pg_range_rngtypid_index; +ALTER TABLE pg_replication_origin ADD PRIMARY KEY USING INDEX pg_replication_origin_roiident_index; +ALTER TABLE pg_rewrite ADD PRIMARY KEY USING INDEX pg_rewrite_oid_index; +ALTER TABLE pg_sequence ADD PRIMARY KEY USING INDEX pg_sequence_seqrelid_index; +ALTER TABLE pg_shdescription ADD PRIMARY KEY USING INDEX pg_shdescription_o_c_index; +ALTER TABLE pg_statistic ADD PRIMARY KEY USING INDEX pg_statistic_relid_att_inh_index; +ALTER TABLE pg_statistic_ext ADD PRIMARY KEY USING INDEX pg_statistic_ext_oid_index; +ALTER TABLE pg_statistic_ext_data ADD PRIMARY KEY USING INDEX pg_statistic_ext_data_stxoid_index; +ALTER TABLE pg_subscription ADD PRIMARY KEY USING INDEX pg_subscription_oid_index; +ALTER TABLE pg_subscription_rel ADD PRIMARY KEY USING INDEX pg_subscription_rel_srrelid_srsubid_index; +ALTER TABLE pg_tablespace ADD PRIMARY KEY USING INDEX pg_tablespace_oid_index; +ALTER TABLE pg_transform ADD PRIMARY KEY USING INDEX pg_transform_oid_index; +ALTER TABLE pg_trigger ADD PRIMARY KEY USING INDEX pg_trigger_oid_index; +ALTER TABLE pg_ts_config ADD PRIMARY KEY USING INDEX pg_ts_config_oid_index; +ALTER TABLE pg_ts_config_map ADD PRIMARY KEY USING INDEX pg_ts_config_map_index; +ALTER TABLE pg_ts_dict ADD PRIMARY KEY USING INDEX pg_ts_dict_oid_index; +ALTER TABLE pg_ts_parser ADD PRIMARY KEY USING INDEX pg_ts_parser_oid_index; +ALTER TABLE pg_ts_template ADD PRIMARY KEY USING INDEX pg_ts_template_oid_index; +ALTER TABLE pg_type ADD PRIMARY KEY USING INDEX pg_type_oid_index; +ALTER TABLE pg_user_mapping ADD PRIMARY KEY USING INDEX pg_user_mapping_oid_index; + + CREATE VIEW pg_roles AS SELECT rolname, diff --git a/src/test/modules/unsafe_tests/expected/alter_system_table.out b/src/test/modules/unsafe_tests/expected/alter_system_table.out index ecd1505cdc..941e4095d5 100644 --- a/src/test/modules/unsafe_tests/expected/alter_system_table.out +++ b/src/test/modules/unsafe_tests/expected/alter_system_table.out @@ -16,7 +16,7 @@ DETAIL: System catalog modifications are currently disallowed. CREATE TABLE t1x (a int, b anyarray); ERROR: column "b" has pseudo-type anyarray -- index on system catalog -ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_oid_index; +ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_nspname_index; ERROR: permission denied: "pg_namespace" is a system catalog -- write to system catalog table as superuser -- (allowed even without allow_system_table_mods) @@ -102,7 +102,7 @@ CREATE TABLE t1 (a int, b anyarray); ROLLBACK; -- index on system catalog BEGIN; -ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_oid_index; +ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_nspname_index; ROLLBACK; -- write to system catalog table as superuser BEGIN; @@ -146,7 +146,6 @@ ALTER TABLE pg_description ALTER COLUMN description SET STATISTICS -1; ROLLBACK; -- foreign key referencing catalog BEGIN; -ALTER TABLE pg_description ADD PRIMARY KEY USING INDEX pg_description_o_c_o_index; CREATE TABLE foo (a oid, b oid, c int, FOREIGN KEY (a, b, c) REFERENCES pg_description); ROLLBACK; -- RangeVarCallbackOwnsRelation() diff --git a/src/test/modules/unsafe_tests/sql/alter_system_table.sql b/src/test/modules/unsafe_tests/sql/alter_system_table.sql index 5663570d31..d65659afa6 100644 --- a/src/test/modules/unsafe_tests/sql/alter_system_table.sql +++ b/src/test/modules/unsafe_tests/sql/alter_system_table.sql @@ -18,7 +18,7 @@ CREATE TABLE pg_catalog.test (a int); CREATE TABLE t1x (a int, b anyarray); -- index on system catalog -ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_oid_index; +ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_nspname_index; -- write to system catalog table as superuser -- (allowed even without allow_system_table_mods) @@ -104,7 +104,7 @@ CREATE TABLE t1 (a int, b anyarray); -- index on system catalog BEGIN; -ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_oid_index; +ALTER TABLE pg_namespace ADD UNIQUE USING INDEX pg_namespace_nspname_index; ROLLBACK; -- write to system catalog table as superuser @@ -156,7 +156,6 @@ CREATE SCHEMA pg_foo; -- foreign key referencing catalog BEGIN; -ALTER TABLE pg_description ADD PRIMARY KEY USING INDEX pg_description_o_c_o_index; CREATE TABLE foo (a oid, b oid, c int, FOREIGN KEY (a, b, c) REFERENCES pg_description); ROLLBACK; diff --git a/src/test/regress/expected/misc_sanity.out b/src/test/regress/expected/misc_sanity.out index 8538173ff8..7de58a69d2 100644 --- a/src/test/regress/expected/misc_sanity.out +++ b/src/test/regress/expected/misc_sanity.out @@ -109,3 +109,17 @@ ORDER BY 1, 2; pg_largeobject_metadata | lomacl | aclitem[] (11 rows) +-- system catalogs without primary keys +SELECT relname +FROM pg_class +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'r' + AND pg_class.oid NOT IN (SELECT indrelid FROM pg_index WHERE indisprimary) +ORDER BY 1; + relname +--------------- + pg_depend + pg_seclabel + pg_shdepend + pg_shseclabel +(4 rows) + diff --git a/src/test/regress/sql/misc_sanity.sql b/src/test/regress/sql/misc_sanity.sql index 3ce32e4725..e4451fd11f 100644 --- a/src/test/regress/sql/misc_sanity.sql +++ b/src/test/regress/sql/misc_sanity.sql @@ -94,3 +94,12 @@ relkind = 'r' AND attstorage != 'p' ORDER BY 1, 2; + + +-- system catalogs without primary keys + +SELECT relname +FROM pg_class +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'r' + AND pg_class.oid NOT IN (SELECT indrelid FROM pg_index WHERE indisprimary) +ORDER BY 1; -- 2.28.0

view thread (39+ messages)  latest in thread

Message-ID: <dc5f44d9-5ec1-a596-0251-dadadcdede98@2ndquadrant.com>
Permalink:  ../dc5f44d9-5ec1-a596-0251-dadadcdede98@2ndquadrant.com/
Also on:    postgresql.org/message-id/dc5f44d9-5ec1-a596-0251-dadadcdede98@2ndquadrant.com

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: peter.eisentraut@2ndquadrant.com
  Subject: Re: Add primary keys to system catalogs
  In-Reply-To: <dc5f44d9-5ec1-a596-0251-dadadcdede98@2ndquadrant.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox