1-- 2-- Verify system catalog foreign key relationships 3-- 4DO $doblock$ 5declare 6 fk record; 7 nkeys integer; 8 cmd text; 9 err record; 10begin 11 for fk in select * from pg_get_catalog_foreign_keys() 12 loop 13 raise notice 'checking % % => % %', 14 fk.fktable, fk.fkcols, fk.pktable, fk.pkcols; 15 nkeys := array_length(fk.fkcols, 1); 16 cmd := 'SELECT ctid'; 17 for i in 1 .. nkeys loop 18 cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); 19 end loop; 20 if fk.is_array then 21 cmd := cmd || ' FROM (SELECT ctid'; 22 for i in 1 .. nkeys-1 loop 23 cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); 24 end loop; 25 cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]); 26 cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]); 27 cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE '; 28 else 29 cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE '; 30 end if; 31 if fk.is_opt then 32 for i in 1 .. nkeys loop 33 cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND '; 34 end loop; 35 end if; 36 cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE '; 37 for i in 1 .. nkeys loop 38 if i > 1 then cmd := cmd || ' AND '; end if; 39 cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]); 40 cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]); 41 end loop; 42 cmd := cmd || ')'; 43 -- raise notice 'cmd = %', cmd; 44 for err in execute cmd loop 45 raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err; 46 end loop; 47 end loop; 48end 49$doblock$; 50NOTICE: checking pg_proc {pronamespace} => pg_namespace {oid} 51NOTICE: checking pg_proc {proowner} => pg_authid {oid} 52NOTICE: checking pg_proc {prolang} => pg_language {oid} 53NOTICE: checking pg_proc {provariadic} => pg_type {oid} 54NOTICE: checking pg_proc {prosupport} => pg_proc {oid} 55NOTICE: checking pg_proc {prorettype} => pg_type {oid} 56NOTICE: checking pg_proc {proargtypes} => pg_type {oid} 57NOTICE: checking pg_proc {proallargtypes} => pg_type {oid} 58NOTICE: checking pg_proc {protrftypes} => pg_type {oid} 59NOTICE: checking pg_type {typnamespace} => pg_namespace {oid} 60NOTICE: checking pg_type {typowner} => pg_authid {oid} 61NOTICE: checking pg_type {typrelid} => pg_class {oid} 62NOTICE: checking pg_type {typsubscript} => pg_proc {oid} 63NOTICE: checking pg_type {typelem} => pg_type {oid} 64NOTICE: checking pg_type {typarray} => pg_type {oid} 65NOTICE: checking pg_type {typinput} => pg_proc {oid} 66NOTICE: checking pg_type {typoutput} => pg_proc {oid} 67NOTICE: checking pg_type {typreceive} => pg_proc {oid} 68NOTICE: checking pg_type {typsend} => pg_proc {oid} 69NOTICE: checking pg_type {typmodin} => pg_proc {oid} 70NOTICE: checking pg_type {typmodout} => pg_proc {oid} 71NOTICE: checking pg_type {typanalyze} => pg_proc {oid} 72NOTICE: checking pg_type {typbasetype} => pg_type {oid} 73NOTICE: checking pg_type {typcollation} => pg_collation {oid} 74NOTICE: checking pg_attribute {attrelid} => pg_class {oid} 75NOTICE: checking pg_attribute {atttypid} => pg_type {oid} 76NOTICE: checking pg_attribute {attcollation} => pg_collation {oid} 77NOTICE: checking pg_class {relnamespace} => pg_namespace {oid} 78NOTICE: checking pg_class {reltype} => pg_type {oid} 79NOTICE: checking pg_class {reloftype} => pg_type {oid} 80NOTICE: checking pg_class {relowner} => pg_authid {oid} 81NOTICE: checking pg_class {relam} => pg_am {oid} 82NOTICE: checking pg_class {reltablespace} => pg_tablespace {oid} 83NOTICE: checking pg_class {reltoastrelid} => pg_class {oid} 84NOTICE: checking pg_class {relrewrite} => pg_class {oid} 85NOTICE: checking pg_attrdef {adrelid} => pg_class {oid} 86NOTICE: checking pg_attrdef {adrelid,adnum} => pg_attribute {attrelid,attnum} 87NOTICE: checking pg_constraint {connamespace} => pg_namespace {oid} 88NOTICE: checking pg_constraint {conrelid} => pg_class {oid} 89NOTICE: checking pg_constraint {contypid} => pg_type {oid} 90NOTICE: checking pg_constraint {conindid} => pg_class {oid} 91NOTICE: checking pg_constraint {conparentid} => pg_constraint {oid} 92NOTICE: checking pg_constraint {confrelid} => pg_class {oid} 93NOTICE: checking pg_constraint {conpfeqop} => pg_operator {oid} 94NOTICE: checking pg_constraint {conppeqop} => pg_operator {oid} 95NOTICE: checking pg_constraint {conffeqop} => pg_operator {oid} 96NOTICE: checking pg_constraint {conexclop} => pg_operator {oid} 97NOTICE: checking pg_constraint {conrelid,conkey} => pg_attribute {attrelid,attnum} 98NOTICE: checking pg_constraint {confrelid,confkey} => pg_attribute {attrelid,attnum} 99NOTICE: checking pg_inherits {inhrelid} => pg_class {oid} 100NOTICE: checking pg_inherits {inhparent} => pg_class {oid} 101NOTICE: checking pg_index {indexrelid} => pg_class {oid} 102NOTICE: checking pg_index {indrelid} => pg_class {oid} 103NOTICE: checking pg_index {indcollation} => pg_collation {oid} 104NOTICE: checking pg_index {indclass} => pg_opclass {oid} 105NOTICE: checking pg_index {indrelid,indkey} => pg_attribute {attrelid,attnum} 106NOTICE: checking pg_operator {oprnamespace} => pg_namespace {oid} 107NOTICE: checking pg_operator {oprowner} => pg_authid {oid} 108NOTICE: checking pg_operator {oprleft} => pg_type {oid} 109NOTICE: checking pg_operator {oprright} => pg_type {oid} 110NOTICE: checking pg_operator {oprresult} => pg_type {oid} 111NOTICE: checking pg_operator {oprcom} => pg_operator {oid} 112NOTICE: checking pg_operator {oprnegate} => pg_operator {oid} 113NOTICE: checking pg_operator {oprcode} => pg_proc {oid} 114NOTICE: checking pg_operator {oprrest} => pg_proc {oid} 115NOTICE: checking pg_operator {oprjoin} => pg_proc {oid} 116NOTICE: checking pg_opfamily {opfmethod} => pg_am {oid} 117NOTICE: checking pg_opfamily {opfnamespace} => pg_namespace {oid} 118NOTICE: checking pg_opfamily {opfowner} => pg_authid {oid} 119NOTICE: checking pg_opclass {opcmethod} => pg_am {oid} 120NOTICE: checking pg_opclass {opcnamespace} => pg_namespace {oid} 121NOTICE: checking pg_opclass {opcowner} => pg_authid {oid} 122NOTICE: checking pg_opclass {opcfamily} => pg_opfamily {oid} 123NOTICE: checking pg_opclass {opcintype} => pg_type {oid} 124NOTICE: checking pg_opclass {opckeytype} => pg_type {oid} 125NOTICE: checking pg_am {amhandler} => pg_proc {oid} 126NOTICE: checking pg_amop {amopfamily} => pg_opfamily {oid} 127NOTICE: checking pg_amop {amoplefttype} => pg_type {oid} 128NOTICE: checking pg_amop {amoprighttype} => pg_type {oid} 129NOTICE: checking pg_amop {amopopr} => pg_operator {oid} 130NOTICE: checking pg_amop {amopmethod} => pg_am {oid} 131NOTICE: checking pg_amop {amopsortfamily} => pg_opfamily {oid} 132NOTICE: checking pg_amproc {amprocfamily} => pg_opfamily {oid} 133NOTICE: checking pg_amproc {amproclefttype} => pg_type {oid} 134NOTICE: checking pg_amproc {amprocrighttype} => pg_type {oid} 135NOTICE: checking pg_amproc {amproc} => pg_proc {oid} 136NOTICE: checking pg_language {lanowner} => pg_authid {oid} 137NOTICE: checking pg_language {lanplcallfoid} => pg_proc {oid} 138NOTICE: checking pg_language {laninline} => pg_proc {oid} 139NOTICE: checking pg_language {lanvalidator} => pg_proc {oid} 140NOTICE: checking pg_largeobject_metadata {lomowner} => pg_authid {oid} 141NOTICE: checking pg_largeobject {loid} => pg_largeobject_metadata {oid} 142NOTICE: checking pg_aggregate {aggfnoid} => pg_proc {oid} 143NOTICE: checking pg_aggregate {aggtransfn} => pg_proc {oid} 144NOTICE: checking pg_aggregate {aggfinalfn} => pg_proc {oid} 145NOTICE: checking pg_aggregate {aggcombinefn} => pg_proc {oid} 146NOTICE: checking pg_aggregate {aggserialfn} => pg_proc {oid} 147NOTICE: checking pg_aggregate {aggdeserialfn} => pg_proc {oid} 148NOTICE: checking pg_aggregate {aggmtransfn} => pg_proc {oid} 149NOTICE: checking pg_aggregate {aggminvtransfn} => pg_proc {oid} 150NOTICE: checking pg_aggregate {aggmfinalfn} => pg_proc {oid} 151NOTICE: checking pg_aggregate {aggsortop} => pg_operator {oid} 152NOTICE: checking pg_aggregate {aggtranstype} => pg_type {oid} 153NOTICE: checking pg_aggregate {aggmtranstype} => pg_type {oid} 154NOTICE: checking pg_statistic {starelid} => pg_class {oid} 155NOTICE: checking pg_statistic {staop1} => pg_operator {oid} 156NOTICE: checking pg_statistic {staop2} => pg_operator {oid} 157NOTICE: checking pg_statistic {staop3} => pg_operator {oid} 158NOTICE: checking pg_statistic {staop4} => pg_operator {oid} 159NOTICE: checking pg_statistic {staop5} => pg_operator {oid} 160NOTICE: checking pg_statistic {stacoll1} => pg_collation {oid} 161NOTICE: checking pg_statistic {stacoll2} => pg_collation {oid} 162NOTICE: checking pg_statistic {stacoll3} => pg_collation {oid} 163NOTICE: checking pg_statistic {stacoll4} => pg_collation {oid} 164NOTICE: checking pg_statistic {stacoll5} => pg_collation {oid} 165NOTICE: checking pg_statistic {starelid,staattnum} => pg_attribute {attrelid,attnum} 166NOTICE: checking pg_statistic_ext {stxrelid} => pg_class {oid} 167NOTICE: checking pg_statistic_ext {stxnamespace} => pg_namespace {oid} 168NOTICE: checking pg_statistic_ext {stxowner} => pg_authid {oid} 169NOTICE: checking pg_statistic_ext {stxrelid,stxkeys} => pg_attribute {attrelid,attnum} 170NOTICE: checking pg_statistic_ext_data {stxoid} => pg_statistic_ext {oid} 171NOTICE: checking pg_rewrite {ev_class} => pg_class {oid} 172NOTICE: checking pg_trigger {tgrelid} => pg_class {oid} 173NOTICE: checking pg_trigger {tgparentid} => pg_trigger {oid} 174NOTICE: checking pg_trigger {tgfoid} => pg_proc {oid} 175NOTICE: checking pg_trigger {tgconstrrelid} => pg_class {oid} 176NOTICE: checking pg_trigger {tgconstrindid} => pg_class {oid} 177NOTICE: checking pg_trigger {tgconstraint} => pg_constraint {oid} 178NOTICE: checking pg_trigger {tgrelid,tgattr} => pg_attribute {attrelid,attnum} 179NOTICE: checking pg_event_trigger {evtowner} => pg_authid {oid} 180NOTICE: checking pg_event_trigger {evtfoid} => pg_proc {oid} 181NOTICE: checking pg_description {classoid} => pg_class {oid} 182NOTICE: checking pg_cast {castsource} => pg_type {oid} 183NOTICE: checking pg_cast {casttarget} => pg_type {oid} 184NOTICE: checking pg_cast {castfunc} => pg_proc {oid} 185NOTICE: checking pg_enum {enumtypid} => pg_type {oid} 186NOTICE: checking pg_namespace {nspowner} => pg_authid {oid} 187NOTICE: checking pg_conversion {connamespace} => pg_namespace {oid} 188NOTICE: checking pg_conversion {conowner} => pg_authid {oid} 189NOTICE: checking pg_conversion {conproc} => pg_proc {oid} 190NOTICE: checking pg_depend {classid} => pg_class {oid} 191NOTICE: checking pg_depend {refclassid} => pg_class {oid} 192NOTICE: checking pg_database {datdba} => pg_authid {oid} 193NOTICE: checking pg_database {dattablespace} => pg_tablespace {oid} 194NOTICE: checking pg_db_role_setting {setdatabase} => pg_database {oid} 195NOTICE: checking pg_db_role_setting {setrole} => pg_authid {oid} 196NOTICE: checking pg_tablespace {spcowner} => pg_authid {oid} 197NOTICE: checking pg_auth_members {roleid} => pg_authid {oid} 198NOTICE: checking pg_auth_members {member} => pg_authid {oid} 199NOTICE: checking pg_auth_members {grantor} => pg_authid {oid} 200NOTICE: checking pg_shdepend {dbid} => pg_database {oid} 201NOTICE: checking pg_shdepend {classid} => pg_class {oid} 202NOTICE: checking pg_shdepend {refclassid} => pg_class {oid} 203NOTICE: checking pg_shdescription {classoid} => pg_class {oid} 204NOTICE: checking pg_ts_config {cfgnamespace} => pg_namespace {oid} 205NOTICE: checking pg_ts_config {cfgowner} => pg_authid {oid} 206NOTICE: checking pg_ts_config {cfgparser} => pg_ts_parser {oid} 207NOTICE: checking pg_ts_config_map {mapcfg} => pg_ts_config {oid} 208NOTICE: checking pg_ts_config_map {mapdict} => pg_ts_dict {oid} 209NOTICE: checking pg_ts_dict {dictnamespace} => pg_namespace {oid} 210NOTICE: checking pg_ts_dict {dictowner} => pg_authid {oid} 211NOTICE: checking pg_ts_dict {dicttemplate} => pg_ts_template {oid} 212NOTICE: checking pg_ts_parser {prsnamespace} => pg_namespace {oid} 213NOTICE: checking pg_ts_parser {prsstart} => pg_proc {oid} 214NOTICE: checking pg_ts_parser {prstoken} => pg_proc {oid} 215NOTICE: checking pg_ts_parser {prsend} => pg_proc {oid} 216NOTICE: checking pg_ts_parser {prsheadline} => pg_proc {oid} 217NOTICE: checking pg_ts_parser {prslextype} => pg_proc {oid} 218NOTICE: checking pg_ts_template {tmplnamespace} => pg_namespace {oid} 219NOTICE: checking pg_ts_template {tmplinit} => pg_proc {oid} 220NOTICE: checking pg_ts_template {tmpllexize} => pg_proc {oid} 221NOTICE: checking pg_extension {extowner} => pg_authid {oid} 222NOTICE: checking pg_extension {extnamespace} => pg_namespace {oid} 223NOTICE: checking pg_extension {extconfig} => pg_class {oid} 224NOTICE: checking pg_foreign_data_wrapper {fdwowner} => pg_authid {oid} 225NOTICE: checking pg_foreign_data_wrapper {fdwhandler} => pg_proc {oid} 226NOTICE: checking pg_foreign_data_wrapper {fdwvalidator} => pg_proc {oid} 227NOTICE: checking pg_foreign_server {srvowner} => pg_authid {oid} 228NOTICE: checking pg_foreign_server {srvfdw} => pg_foreign_data_wrapper {oid} 229NOTICE: checking pg_user_mapping {umuser} => pg_authid {oid} 230NOTICE: checking pg_user_mapping {umserver} => pg_foreign_server {oid} 231NOTICE: checking pg_foreign_table {ftrelid} => pg_class {oid} 232NOTICE: checking pg_foreign_table {ftserver} => pg_foreign_server {oid} 233NOTICE: checking pg_policy {polrelid} => pg_class {oid} 234NOTICE: checking pg_policy {polroles} => pg_authid {oid} 235NOTICE: checking pg_default_acl {defaclrole} => pg_authid {oid} 236NOTICE: checking pg_default_acl {defaclnamespace} => pg_namespace {oid} 237NOTICE: checking pg_init_privs {classoid} => pg_class {oid} 238NOTICE: checking pg_seclabel {classoid} => pg_class {oid} 239NOTICE: checking pg_shseclabel {classoid} => pg_class {oid} 240NOTICE: checking pg_collation {collnamespace} => pg_namespace {oid} 241NOTICE: checking pg_collation {collowner} => pg_authid {oid} 242NOTICE: checking pg_partitioned_table {partrelid} => pg_class {oid} 243NOTICE: checking pg_partitioned_table {partdefid} => pg_class {oid} 244NOTICE: checking pg_partitioned_table {partclass} => pg_opclass {oid} 245NOTICE: checking pg_partitioned_table {partcollation} => pg_collation {oid} 246NOTICE: checking pg_partitioned_table {partrelid,partattrs} => pg_attribute {attrelid,attnum} 247NOTICE: checking pg_range {rngtypid} => pg_type {oid} 248NOTICE: checking pg_range {rngsubtype} => pg_type {oid} 249NOTICE: checking pg_range {rngmultitypid} => pg_type {oid} 250NOTICE: checking pg_range {rngcollation} => pg_collation {oid} 251NOTICE: checking pg_range {rngsubopc} => pg_opclass {oid} 252NOTICE: checking pg_range {rngcanonical} => pg_proc {oid} 253NOTICE: checking pg_range {rngsubdiff} => pg_proc {oid} 254NOTICE: checking pg_transform {trftype} => pg_type {oid} 255NOTICE: checking pg_transform {trflang} => pg_language {oid} 256NOTICE: checking pg_transform {trffromsql} => pg_proc {oid} 257NOTICE: checking pg_transform {trftosql} => pg_proc {oid} 258NOTICE: checking pg_sequence {seqrelid} => pg_class {oid} 259NOTICE: checking pg_sequence {seqtypid} => pg_type {oid} 260NOTICE: checking pg_publication {pubowner} => pg_authid {oid} 261NOTICE: checking pg_publication_rel {prpubid} => pg_publication {oid} 262NOTICE: checking pg_publication_rel {prrelid} => pg_class {oid} 263NOTICE: checking pg_subscription {subdbid} => pg_database {oid} 264NOTICE: checking pg_subscription {subowner} => pg_authid {oid} 265NOTICE: checking pg_subscription_rel {srsubid} => pg_subscription {oid} 266NOTICE: checking pg_subscription_rel {srrelid} => pg_class {oid} 267