Build in some knowledge about foreign-key relationships in the catalogs.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Feb 2021 22:11:55 +0000 (17:11 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Feb 2021 22:11:55 +0000 (17:11 -0500)
This follows in the spirit of commit dfb75e478, which created primary
key and uniqueness constraints to improve the visibility of constraints
imposed on the system catalogs.  While our catalogs contain many
foreign-key-like relationships, they don't quite follow SQL semantics,
in that the convention for an omitted reference is to write zero not
NULL.  Plus, we have some cases in which there are arrays each of whose
elements is supposed to be an FK reference; SQL has no way to model that.
So we can't create actual foreign key constraints to describe the
situation.  Nonetheless, we can collect and use knowledge about these
relationships.

This patch therefore adds annotations to the catalog header files to
declare foreign-key relationships.  (The BKI_LOOKUP annotations cover
simple cases, but we weren't previously distinguishing which such
columns are allowed to contain zeroes; we also need new markings for
multi-column FK references.)  Then, Catalog.pm and genbki.pl are
taught to collect this information into a table in a new generated
header "system_fk_info.h".  The only user of that at the moment is
a new SQL function pg_get_catalog_foreign_keys(), which exposes the
table to SQL.  The oidjoins regression test is rewritten to use
pg_get_catalog_foreign_keys() to find out which columns to check.
Aside from removing the need for manual maintenance of that test
script, this allows it to cover numerous relationships that were not
checked by the old implementation based on findoidjoins.  (As of this
commit, 217 relationships are checked by the test, versus 181 before.)

Discussion: https://postgr.es/m/3240355.1612129197@sss.pgh.pa.us

78 files changed:
doc/src/sgml/bki.sgml
doc/src/sgml/func.sgml
src/backend/catalog/.gitignore
src/backend/catalog/Catalog.pm
src/backend/catalog/Makefile
src/backend/catalog/genbki.pl
src/backend/utils/adt/misc.c
src/include/Makefile
src/include/catalog/.gitignore
src/include/catalog/catversion.h
src/include/catalog/genbki.h
src/include/catalog/pg_aggregate.h
src/include/catalog/pg_amop.h
src/include/catalog/pg_attrdef.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_auth_members.h
src/include/catalog/pg_cast.h
src/include/catalog/pg_class.h
src/include/catalog/pg_collation.dat
src/include/catalog/pg_collation.h
src/include/catalog/pg_constraint.h
src/include/catalog/pg_conversion.h
src/include/catalog/pg_database.h
src/include/catalog/pg_db_role_setting.h
src/include/catalog/pg_default_acl.h
src/include/catalog/pg_depend.h
src/include/catalog/pg_description.h
src/include/catalog/pg_enum.h
src/include/catalog/pg_event_trigger.h
src/include/catalog/pg_extension.h
src/include/catalog/pg_foreign_data_wrapper.h
src/include/catalog/pg_foreign_server.h
src/include/catalog/pg_foreign_table.h
src/include/catalog/pg_index.h
src/include/catalog/pg_inherits.h
src/include/catalog/pg_init_privs.h
src/include/catalog/pg_language.h
src/include/catalog/pg_largeobject.h
src/include/catalog/pg_largeobject_metadata.h
src/include/catalog/pg_namespace.dat
src/include/catalog/pg_namespace.h
src/include/catalog/pg_opclass.h
src/include/catalog/pg_operator.h
src/include/catalog/pg_opfamily.h
src/include/catalog/pg_partitioned_table.h
src/include/catalog/pg_policy.h
src/include/catalog/pg_proc.dat
src/include/catalog/pg_proc.h
src/include/catalog/pg_publication.h
src/include/catalog/pg_publication_rel.h
src/include/catalog/pg_range.h
src/include/catalog/pg_rewrite.h
src/include/catalog/pg_seclabel.h
src/include/catalog/pg_sequence.h
src/include/catalog/pg_shdepend.h
src/include/catalog/pg_shdescription.h
src/include/catalog/pg_shseclabel.h
src/include/catalog/pg_statistic.h
src/include/catalog/pg_statistic_ext.h
src/include/catalog/pg_statistic_ext_data.h
src/include/catalog/pg_subscription.h
src/include/catalog/pg_subscription_rel.h
src/include/catalog/pg_tablespace.dat
src/include/catalog/pg_tablespace.h
src/include/catalog/pg_transform.h
src/include/catalog/pg_trigger.h
src/include/catalog/pg_ts_config.h
src/include/catalog/pg_ts_dict.h
src/include/catalog/pg_ts_parser.h
src/include/catalog/pg_ts_template.h
src/include/catalog/pg_type.h
src/include/catalog/pg_user_mapping.h
src/test/regress/expected/oidjoins.out
src/test/regress/parallel_schedule
src/test/regress/serial_schedule
src/test/regress/sql/oidjoins.sql
src/tools/msvc/Solution.pm
src/tools/msvc/clean.bat

index 036a72c81e9c8a67efdac1480f665fd0714e593e..6d3c5be67f8d1742ffd288736cdbb451caaa86a9 100644 (file)
 
     <listitem>
      <para>
-      In such a column, all entries must use the symbolic format except
-      when writing <literal>0</literal> for InvalidOid.  (If the column is
+      In some catalog columns, it's allowed for entries to be zero instead
+      of a valid reference.  If this is allowed, write
+      <literal>BKI_LOOKUP_OPT</literal> instead
+      of <literal>BKI_LOOKUP</literal>.  Then you can
+      write <literal>0</literal> for an entry.  (If the column is
       declared <type>regproc</type>, you can optionally
       write <literal>-</literal> instead of <literal>0</literal>.)
+      Except for this special case, all entries in
+      a <literal>BKI_LOOKUP</literal> column must be symbolic references.
       <filename>genbki.pl</filename> will warn about unrecognized names.
      </para>
     </listitem>
     therefore no need for the bootstrap backend to deal with symbolic
     references.
    </para>
+
+   <para>
+    It's desirable to mark OID reference columns
+    with <literal>BKI_LOOKUP</literal> or <literal>BKI_LOOKUP_OPT</literal>
+    even if the catalog has no initial data that requires lookup.  This
+    allows <filename>genbki.pl</filename> to record the foreign key
+    relationships that exist in the system catalogs.  That information is
+    used in the regression tests to check for incorrect entries.  See also
+    the macros <literal>DECLARE_FOREIGN_KEY</literal>,
+    <literal>DECLARE_FOREIGN_KEY_OPT</literal>,
+    <literal>DECLARE_ARRAY_FOREIGN_KEY</literal>,
+    and <literal>DECLARE_ARRAY_FOREIGN_KEY_OPT</literal>, which are
+    used to declare foreign key relationships that are too complex
+    for <literal>BKI_LOOKUP</literal> (typically, multi-column foreign
+    keys).
+   </para>
   </sect2>
 
   <sect2 id="system-catalog-auto-array-types">
index 081f04ce1a9fb200dd5458d94f38a68019e98f4c..b7150510aba464645e900c9c5fa06c66f4917d73 100644 (file)
@@ -22789,6 +22789,38 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
        </para></entry>
       </row>
 
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>pg_get_catalog_foreign_keys</primary>
+        </indexterm>
+        <function>pg_get_catalog_foreign_keys</function> ()
+        <returnvalue>setof record</returnvalue>
+        ( <parameter>fktable</parameter> <type>regclass</type>,
+          <parameter>fkcols</parameter> <type>text[]</type>,
+          <parameter>pktable</parameter> <type>regclass</type>,
+          <parameter>pkcols</parameter> <type>text[]</type>,
+          <parameter>is_array</parameter> <type>boolean</type>,
+          <parameter>is_opt</parameter> <type>boolean</type> )
+       </para>
+       <para>
+        Returns a set of records describing the foreign key relationships
+        that exist within the <productname>PostgreSQL</productname> system
+        catalogs.
+        The <parameter>fktable</parameter> column contains the name of the
+        referencing catalog, and the <parameter>fkcols</parameter> column
+        contains the name(s) of the referencing column(s).  Similarly,
+        the <parameter>pktable</parameter> column contains the name of the
+        referenced catalog, and the <parameter>pkcols</parameter> column
+        contains the name(s) of the referenced column(s).
+        If <parameter>is_array</parameter> is true, the last referencing
+        column is an array, each of whose elements should match some entry
+        in the referenced catalog.
+        If <parameter>is_opt</parameter> is true, the referencing column(s)
+        are allowed to contain zeroes instead of a valid reference.
+       </para></entry>
+      </row>
+
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
index 4bd3ee9d7f39171a0256a9daeea621e0e08a829c..237ff541659b15a680c160be93f9cbdb72fd61ac 100644 (file)
@@ -1,5 +1,6 @@
 /postgres.bki
 /schemapg.h
+/system_fk_info.h
 /system_constraints.sql
 /pg_*_d.h
 /bki-stamp
index 061f3d8c21ebd6a0a2200caf13cb63381eb24865..b44d568b5444067f684e60828650128b20738226 100644 (file)
@@ -105,6 +105,17 @@ sub ParseHeader
                                index_decl => $5
                          };
                }
+               elsif (/^DECLARE_(ARRAY_)?FOREIGN_KEY(_OPT)?\(\s*\(([^)]+)\),\s*(\w+),\s*\(([^)]+)\)\)/)
+               {
+                       push @{ $catalog{foreign_keys} },
+                         {
+                               is_array => $1 ? 1 : 0,
+                               is_opt   => $2 ? 1 : 0,
+                               fk_cols  => $3,
+                               pk_table => $4,
+                               pk_cols  => $5
+                         };
+               }
                elsif (/^CATALOG\((\w+),(\d+),(\w+)\)/)
                {
                        $catalog{catname}            = $1;
@@ -197,9 +208,22 @@ sub ParseHeader
                                        {
                                                $column{array_default} = $1;
                                        }
-                                       elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/)
+                                       elsif ($attopt =~ /BKI_LOOKUP(_OPT)?\((\w+)\)/)
                                        {
-                                               $column{lookup} = $1;
+                                               $column{lookup} = $2;
+                                               $column{lookup_opt} = $1 ? 1 : 0;
+                                               # BKI_LOOKUP implicitly makes an FK reference
+                                               push @{ $catalog{foreign_keys} },
+                                                 {
+                                                       is_array =>
+                                                         ($atttype eq 'oidvector' || $atttype eq '_oid')
+                                                       ? 1
+                                                       : 0,
+                                                       is_opt   => $column{lookup_opt},
+                                                       fk_cols  => $attname,
+                                                       pk_table => $column{lookup},
+                                                       pk_cols  => 'oid'
+                                                 };
                                        }
                                        else
                                        {
index 995ddf128523f30a57de62b27ffdf0112352ff93..70bc2123df7bf23111cf0ca289acdb8812910a9f 100644 (file)
@@ -70,7 +70,7 @@ CATALOG_HEADERS := \
        pg_sequence.h pg_publication.h pg_publication_rel.h pg_subscription.h \
        pg_subscription_rel.h
 
-GENERATED_HEADERS := $(CATALOG_HEADERS:%.h=%_d.h) schemapg.h
+GENERATED_HEADERS := $(CATALOG_HEADERS:%.h=%_d.h) schemapg.h system_fk_info.h
 
 POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/, $(CATALOG_HEADERS))
 
index b68c1752c0098cae09e5a767a95cdc65b13a5041..5bdc7adc44022087f2f10b499dcd509cf4aaf62a 100644 (file)
@@ -213,6 +213,12 @@ foreach my $row (@{ $catalog_data{pg_am} })
        $amoids{ $row->{amname} } = $row->{oid};
 }
 
+# There is only one authid at bootstrap time, and we handle it specially:
+# the usually-defaulted symbol PGUID becomes the bootstrap superuser's OID.
+# (We could drop this in favor of writing out BKI_DEFAULT(POSTGRES) ...)
+my %authidoids;
+$authidoids{'PGUID'} = $BOOTSTRAP_SUPERUSERID;
+
 # class (relation) OID lookup (note this only covers bootstrap catalogs!)
 my %classoids;
 foreach my $row (@{ $catalog_data{pg_class} })
@@ -234,6 +240,12 @@ foreach my $row (@{ $catalog_data{pg_language} })
        $langoids{ $row->{lanname} } = $row->{oid};
 }
 
+# There is only one namespace at bootstrap time, and we handle it specially:
+# the usually-defaulted symbol PGNSP becomes the pg_catalog namespace's OID.
+# (We could drop this in favor of writing out BKI_DEFAULT(pg_catalog) ...)
+my %namespaceoids;
+$namespaceoids{'PGNSP'} = $PG_CATALOG_NAMESPACE;
+
 # opclass OID lookup
 my %opcoids;
 foreach my $row (@{ $catalog_data{pg_opclass} })
@@ -376,9 +388,11 @@ close $ef;
 # Map lookup name to the corresponding hash table.
 my %lookup_kind = (
        pg_am          => \%amoids,
+       pg_authid      => \%authidoids,
        pg_class       => \%classoids,
        pg_collation   => \%collationoids,
        pg_language    => \%langoids,
+       pg_namespace   => \%namespaceoids,
        pg_opclass     => \%opcoids,
        pg_operator    => \%operoids,
        pg_opfamily    => \%opfoids,
@@ -400,6 +414,9 @@ open my $bki, '>', $bkifile . $tmpext
 my $schemafile = $output_path . 'schemapg.h';
 open my $schemapg, '>', $schemafile . $tmpext
   or die "can't open $schemafile$tmpext: $!";
+my $fk_info_file = $output_path . 'system_fk_info.h';
+open my $fk_info, '>', $fk_info_file . $tmpext
+  or die "can't open $fk_info_file$tmpext: $!";
 my $constraints_file = $output_path . 'system_constraints.sql';
 open my $constraints, '>', $constraints_file . $tmpext
   or die "can't open $constraints_file$tmpext: $!";
@@ -554,18 +571,14 @@ EOM
                                $GenbkiNextOid++;
                        }
 
-                       # Substitute constant values we acquired above.
-                       # (It's intentional that this can apply to parts of a field).
-                       $bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
-                       $bki_values{$attname} =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g;
-
                        # Replace OID synonyms with OIDs per the appropriate lookup rule.
                        #
                        # If the column type is oidvector or _oid, we have to replace
                        # each element of the array as per the lookup rule.
                        if ($column->{lookup})
                        {
-                               my $lookup = $lookup_kind{ $column->{lookup} };
+                               my $lookup     = $lookup_kind{ $column->{lookup} };
+                               my $lookup_opt = $column->{lookup_opt};
                                my @lookupnames;
                                my @lookupoids;
 
@@ -575,8 +588,9 @@ EOM
                                if ($atttype eq 'oidvector')
                                {
                                        @lookupnames = split /\s+/, $bki_values{$attname};
-                                       @lookupoids = lookup_oids($lookup, $catname, \%bki_values,
-                                               @lookupnames);
+                                       @lookupoids =
+                                         lookup_oids($lookup, $catname, $attname, $lookup_opt,
+                                               \%bki_values, @lookupnames);
                                        $bki_values{$attname} = join(' ', @lookupoids);
                                }
                                elsif ($atttype eq '_oid')
@@ -586,8 +600,8 @@ EOM
                                                $bki_values{$attname} =~ s/[{}]//g;
                                                @lookupnames = split /,/, $bki_values{$attname};
                                                @lookupoids =
-                                                 lookup_oids($lookup, $catname, \%bki_values,
-                                                       @lookupnames);
+                                                 lookup_oids($lookup, $catname, $attname,
+                                                       $lookup_opt, \%bki_values, @lookupnames);
                                                $bki_values{$attname} = sprintf "{%s}",
                                                  join(',', @lookupoids);
                                        }
@@ -595,8 +609,9 @@ EOM
                                else
                                {
                                        $lookupnames[0] = $bki_values{$attname};
-                                       @lookupoids = lookup_oids($lookup, $catname, \%bki_values,
-                                               @lookupnames);
+                                       @lookupoids =
+                                         lookup_oids($lookup, $catname, $attname, $lookup_opt,
+                                               \%bki_values, @lookupnames);
                                        $bki_values{$attname} = $lookupoids[0];
                                }
                        }
@@ -706,14 +721,78 @@ foreach my $table_name (@tables_needing_macros)
 # Closing boilerplate for schemapg.h
 print $schemapg "\n#endif\t\t\t\t\t\t\t/* SCHEMAPG_H */\n";
 
+# Now generate system_fk_info.h
+
+# Opening boilerplate for system_fk_info.h
+print $fk_info <<EOM;
+/*-------------------------------------------------------------------------
+ *
+ * system_fk_info.h
+ *    Data about the foreign-key relationships in the system catalogs
+ *
+ * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * NOTES
+ *  ******************************
+ *  *** DO NOT EDIT THIS FILE! ***
+ *  ******************************
+ *
+ *  It has been GENERATED by src/backend/catalog/genbki.pl
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SYSTEM_FK_INFO_H
+#define SYSTEM_FK_INFO_H
+
+typedef struct SysFKRelationship
+{
+       Oid                     fk_table;               /* referencing catalog */
+       Oid                     pk_table;               /* referenced catalog */
+       const char *fk_columns;         /* referencing column name(s) */
+       const char *pk_columns;         /* referenced column name(s) */
+       bool            is_array;               /* if true, last fk_column is an array */
+       bool            is_opt;                 /* if true, fk_column can be zero */
+} SysFKRelationship;
+
+static const SysFKRelationship sys_fk_relationships[] = {
+EOM
+
+# Emit system_fk_info data
+foreach my $catname (@catnames)
+{
+       my $catalog = $catalogs{$catname};
+       foreach my $fkinfo (@{ $catalog->{foreign_keys} })
+       {
+               my $pktabname = $fkinfo->{pk_table};
+
+               # We use BKI_LOOKUP for encodings, but there's no real catalog there
+               next if $pktabname eq 'encoding';
+
+               printf $fk_info
+                 "\t{ /* %s */ %s, /* %s */ %s, \"{%s}\", \"{%s}\", %s, %s},\n",
+                 $catname,   $catalog->{relation_oid},
+                 $pktabname, $catalogs{$pktabname}->{relation_oid},
+                 $fkinfo->{fk_cols},
+                 $fkinfo->{pk_cols},
+                 ($fkinfo->{is_array} ? "true" : "false"),
+                 ($fkinfo->{is_opt}   ? "true" : "false");
+       }
+}
+
+# Closing boilerplate for system_fk_info.h
+print $fk_info "};\n\n#endif\t\t\t\t\t\t\t/* SYSTEM_FK_INFO_H */\n";
+
 # We're done emitting data
 close $bki;
 close $schemapg;
+close $fk_info;
 close $constraints;
 
 # Finally, rename the completed files into place.
 Catalog::RenameTempFile($bkifile,    $tmpext);
 Catalog::RenameTempFile($schemafile, $tmpext);
+Catalog::RenameTempFile($fk_info_file, $tmpext);
 Catalog::RenameTempFile($constraints_file, $tmpext);
 
 exit 0;
@@ -948,7 +1027,8 @@ sub morph_row_for_schemapg
 # within this genbki.pl run.)
 sub lookup_oids
 {
-       my ($lookup, $catname, $bki_values, @lookupnames) = @_;
+       my ($lookup, $catname, $attname, $lookup_opt, $bki_values, @lookupnames)
+         = @_;
 
        my @lookupoids;
        foreach my $lookupname (@lookupnames)
@@ -961,10 +1041,19 @@ sub lookup_oids
                else
                {
                        push @lookupoids, $lookupname;
-                       warn sprintf
-                         "unresolved OID reference \"%s\" in %s.dat line %s\n",
-                         $lookupname, $catname, $bki_values->{line_number}
-                         if $lookupname ne '-' and $lookupname ne '0';
+                       if ($lookupname eq '-' or $lookupname eq '0')
+                       {
+                               warn sprintf
+                                 "invalid zero OID reference in %s.dat field %s line %s\n",
+                                 $catname, $attname, $bki_values->{line_number}
+                                 if !$lookup_opt;
+                       }
+                       else
+                       {
+                               warn sprintf
+                                 "unresolved OID reference \"%s\" in %s.dat field %s line %s\n",
+                                 $lookupname, $catname, $attname, $bki_values->{line_number};
+                       }
                }
        }
        return @lookupoids;
index 4096faff9a1965c4113b1a8376a4996aaaa75acd..634f574d7eb891e52e01ba60529030eb28de2ad8 100644 (file)
@@ -25,6 +25,7 @@
 #include "catalog/catalog.h"
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_type.h"
+#include "catalog/system_fk_info.h"
 #include "commands/dbcommands.h"
 #include "commands/tablespace.h"
 #include "common/keywords.h"
@@ -37,6 +38,7 @@
 #include "storage/fd.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
+#include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/ruleutils.h"
 #include "utils/timestamp.h"
@@ -489,6 +491,84 @@ pg_get_keywords(PG_FUNCTION_ARGS)
 }
 
 
+/* Function to return the list of catalog foreign key relationships */
+Datum
+pg_get_catalog_foreign_keys(PG_FUNCTION_ARGS)
+{
+       FuncCallContext *funcctx;
+       FmgrInfo   *arrayinp;
+
+       if (SRF_IS_FIRSTCALL())
+       {
+               MemoryContext oldcontext;
+               TupleDesc       tupdesc;
+
+               funcctx = SRF_FIRSTCALL_INIT();
+               oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+               tupdesc = CreateTemplateTupleDesc(6);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 1, "fktable",
+                                                  REGCLASSOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 2, "fkcols",
+                                                  TEXTARRAYOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 3, "pktable",
+                                                  REGCLASSOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pkcols",
+                                                  TEXTARRAYOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 5, "is_array",
+                                                  BOOLOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 6, "is_opt",
+                                                  BOOLOID, -1, 0);
+
+               funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+
+               /*
+                * We use array_in to convert the C strings in sys_fk_relationships[]
+                * to text arrays.  But we cannot use DirectFunctionCallN to call
+                * array_in, and it wouldn't be very efficient if we could.  Fill an
+                * FmgrInfo to use for the call.
+                */
+               arrayinp = (FmgrInfo *) palloc(sizeof(FmgrInfo));
+               fmgr_info(F_ARRAY_IN, arrayinp);
+               funcctx->user_fctx = arrayinp;
+
+               MemoryContextSwitchTo(oldcontext);
+       }
+
+       funcctx = SRF_PERCALL_SETUP();
+       arrayinp = (FmgrInfo *) funcctx->user_fctx;
+
+       if (funcctx->call_cntr < lengthof(sys_fk_relationships))
+       {
+               const SysFKRelationship *fkrel = &sys_fk_relationships[funcctx->call_cntr];
+               Datum           values[6];
+               bool            nulls[6];
+               HeapTuple       tuple;
+
+               memset(nulls, false, sizeof(nulls));
+
+               values[0] = ObjectIdGetDatum(fkrel->fk_table);
+               values[1] = FunctionCall3(arrayinp,
+                                                                 CStringGetDatum(fkrel->fk_columns),
+                                                                 ObjectIdGetDatum(TEXTOID),
+                                                                 Int32GetDatum(-1));
+               values[2] = ObjectIdGetDatum(fkrel->pk_table);
+               values[3] = FunctionCall3(arrayinp,
+                                                                 CStringGetDatum(fkrel->pk_columns),
+                                                                 ObjectIdGetDatum(TEXTOID),
+                                                                 Int32GetDatum(-1));
+               values[4] = BoolGetDatum(fkrel->is_array);
+               values[5] = BoolGetDatum(fkrel->is_opt);
+
+               tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
+
+               SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
+       }
+
+       SRF_RETURN_DONE(funcctx);
+}
+
+
 /*
  * Return the type of the argument.
  */
index c557375ae310f3dbfa3b8d6aa488890399a071c4..5f257a958c800ebac4e88dc720dcd98f8f6f42e4 100644 (file)
@@ -54,7 +54,7 @@ install: all installdirs
          cp $(srcdir)/$$dir/*.h '$(DESTDIR)$(includedir_server)'/$$dir/ || exit; \
        done
 ifeq ($(vpath_build),yes)
-       for file in catalog/schemapg.h catalog/pg_*_d.h parser/gram.h storage/lwlocknames.h utils/probes.h; do \
+       for file in catalog/schemapg.h catalog/system_fk_info.h catalog/pg_*_d.h parser/gram.h storage/lwlocknames.h utils/probes.h; do \
          cp $$file '$(DESTDIR)$(includedir_server)'/$$file || exit; \
        done
 endif
@@ -79,7 +79,8 @@ uninstall:
 clean:
        rm -f utils/fmgroids.h utils/fmgrprotos.h utils/errcodes.h utils/header-stamp
        rm -f parser/gram.h storage/lwlocknames.h utils/probes.h
-       rm -f catalog/schemapg.h catalog/pg_*_d.h catalog/header-stamp
+       rm -f catalog/schemapg.h catalog/system_fk_info.h
+       rm -f catalog/pg_*_d.h catalog/header-stamp
 
 distclean maintainer-clean: clean
        rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h
index 6c8da5401ddf4af5473bbdaa6b88093f931c1c75..6b83d4c7e6e5c52baa21eca1e1854bae83cf2ca0 100644 (file)
@@ -1,3 +1,4 @@
 /schemapg.h
+/system_fk_info.h
 /pg_*_d.h
 /header-stamp
index 133f4ee3094cabab46d7f47ca4ac678aca6f3364..638830aaac1aae58180157db3801551f6e0000ad 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     202101311
+#define CATALOG_VERSION_NO     202102021
 
 #endif
index 5d05fafb5dae9a4a4ec6be5fd605964283306ff1..b1fee54d3c29090dfa51803bf94d4351c3ea461e 100644 (file)
 /* Specifies a default value for auto-generated array types */
 #define BKI_ARRAY_DEFAULT(value)
 /*
- * Indicates how to perform name lookups, typically for an OID or
- * OID-array field
+ * Indicates that the attribute contains OIDs referencing the named catalog;
+ * can be applied to columns of oid, regproc, oid[], or oidvector type.
+ * genbki.pl uses this to know how to perform name lookups in the initial
+ * data (if any), and it also feeds into regression-test validity checks.
+ * The _OPT suffix indicates that values can be zero instead of
+ * a valid OID reference.
  */
 #define BKI_LOOKUP(catalog)
+#define BKI_LOOKUP_OPT(catalog)
 
 /*
  * These lines are processed by genbki.pl to create the statements
 #define DECLARE_UNIQUE_INDEX(name,oid,decl) extern int no_such_variable
 #define DECLARE_UNIQUE_INDEX_PKEY(name,oid,decl) extern int no_such_variable
 
+/*
+ * These lines are processed by genbki.pl to create a table for use
+ * by the pg_get_catalog_foreign_keys() function.  We do not have any
+ * mechanism that actually enforces foreign-key relationships in the
+ * system catalogs, but it is still useful to record the intended
+ * relationships in a machine-readable form.
+ *
+ * The keyword is DECLARE_FOREIGN_KEY[_OPT] or DECLARE_ARRAY_FOREIGN_KEY[_OPT].
+ * The first argument is a parenthesized list of the referencing columns;
+ * the second, the name of the referenced table; the third, a parenthesized
+ * list of the referenced columns.  Use of the ARRAY macros means that the
+ * last referencing column is an array, each of whose elements is supposed
+ * to match some entry in the last referenced column.  Use of the OPT suffix
+ * indicates that the referencing column(s) can be zero instead of a valid
+ * reference.
+ *
+ * Columns that are marked with a BKI_LOOKUP rule do not need an explicit
+ * DECLARE_FOREIGN_KEY macro, as genbki.pl can infer the FK relationship
+ * from that.  Thus, these macros are only needed in special cases.
+ *
+ * The macro definitions are just to keep the C compiler from spitting up.
+ */
+#define DECLARE_FOREIGN_KEY(cols,reftbl,refcols) extern int no_such_variable
+#define DECLARE_FOREIGN_KEY_OPT(cols,reftbl,refcols) extern int no_such_variable
+#define DECLARE_ARRAY_FOREIGN_KEY(cols,reftbl,refcols) extern int no_such_variable
+#define DECLARE_ARRAY_FOREIGN_KEY_OPT(cols,reftbl,refcols) extern int no_such_variable
+
 /* The following are never defined; they are here only for documentation. */
 
 /*
index 8b03cdeea2429d10421041b28e1be626b8194967..25feb41678ff04a1d00cc62bb4f6a653c7d15038 100644 (file)
@@ -44,25 +44,25 @@ CATALOG(pg_aggregate,2600,AggregateRelationId)
        regproc         aggtransfn BKI_LOOKUP(pg_proc);
 
        /* final function (0 if none) */
-       regproc         aggfinalfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggfinalfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* combine function (0 if none) */
-       regproc         aggcombinefn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggcombinefn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* function to convert transtype to bytea (0 if none) */
-       regproc         aggserialfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggserialfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* function to convert bytea to transtype (0 if none) */
-       regproc         aggdeserialfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggdeserialfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* forward function for moving-aggregate mode (0 if none) */
-       regproc         aggmtransfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggmtransfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* inverse function for moving-aggregate mode (0 if none) */
-       regproc         aggminvtransfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggminvtransfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* final function for moving-aggregate mode (0 if none) */
-       regproc         aggmfinalfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         aggmfinalfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* true to pass extra dummy arguments to aggfinalfn */
        bool            aggfinalextra BKI_DEFAULT(f);
@@ -77,7 +77,7 @@ CATALOG(pg_aggregate,2600,AggregateRelationId)
        char            aggmfinalmodify BKI_DEFAULT(r);
 
        /* associated sort operator (0 if none) */
-       Oid                     aggsortop BKI_DEFAULT(0) BKI_LOOKUP(pg_operator);
+       Oid                     aggsortop BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator);
 
        /* type of aggregate's transition (state) data */
        Oid                     aggtranstype BKI_LOOKUP(pg_type);
@@ -86,7 +86,7 @@ CATALOG(pg_aggregate,2600,AggregateRelationId)
        int32           aggtransspace BKI_DEFAULT(0);
 
        /* type of moving-aggregate state data (0 if none) */
-       Oid                     aggmtranstype BKI_DEFAULT(0) BKI_LOOKUP(pg_type);
+       Oid                     aggmtranstype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 
        /* estimated size of moving-agg state (0 for default est) */
        int32           aggmtransspace BKI_DEFAULT(0);
index 554fc41497d62fcfd0ba76f54fe34ca85a53e503..e1cca35e312a31c0f683fd94e7580cf1afbc2107 100644 (file)
@@ -77,7 +77,7 @@ CATALOG(pg_amop,2602,AccessMethodOperatorRelationId)
        Oid                     amopmethod BKI_LOOKUP(pg_am);
 
        /* ordering opfamily OID, or 0 if search op */
-       Oid                     amopsortfamily BKI_DEFAULT(0) BKI_LOOKUP(pg_opfamily);
+       Oid                     amopsortfamily BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_opfamily);
 } FormData_pg_amop;
 
 /* ----------------
index 03efaaded9cc1ce945c43bab4dbd355faec7cc67..d689ca20c8590ddd3b50e17ccdacd4e1334909ae 100644 (file)
@@ -30,7 +30,8 @@ CATALOG(pg_attrdef,2604,AttrDefaultRelationId)
 {
        Oid                     oid;                    /* oid */
 
-       Oid                     adrelid;                /* OID of table containing attribute */
+       Oid                     adrelid BKI_LOOKUP(pg_class);   /* OID of table containing
+                                                                                                * attribute */
        int16           adnum;                  /* attnum of attribute */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
@@ -53,4 +54,6 @@ DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index, 2656, on pg_attrdef using b
 DECLARE_UNIQUE_INDEX_PKEY(pg_attrdef_oid_index, 2657, on pg_attrdef using btree(oid oid_ops));
 #define AttrDefaultOidIndexId  2657
 
+DECLARE_FOREIGN_KEY((adrelid, adnum), pg_attribute, (attrelid, attnum));
+
 #endif                                                 /* PG_ATTRDEF_H */
index ba0efff08c02b26ce7ca71adadf4988ebed735dd..3db42abf087453bcd71e0d0e8851dac87aad6dde 100644 (file)
@@ -36,7 +36,8 @@
  */
 CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
-       Oid                     attrelid;               /* OID of relation containing this attribute */
+       Oid                     attrelid BKI_LOOKUP(pg_class);  /* OID of relation containing
+                                                                                                * this attribute */
        NameData        attname;                /* name of attribute */
 
        /*
@@ -44,9 +45,12 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
         * defines the data type of this attribute (e.g. int4).  Information in
         * that instance is redundant with the attlen, attbyval, and attalign
         * attributes of this instance, so they had better match or Postgres will
-        * fail.
+        * fail.  In an entry for a dropped column, this field is set to zero
+        * since the pg_type entry may no longer exist; but we rely on attlen,
+        * attbyval, and attalign to still tell us how large the values in the
+        * table are.
         */
-       Oid                     atttypid;
+       Oid                     atttypid BKI_LOOKUP_OPT(pg_type);
 
        /*
         * attstattarget is the target number of statistics datapoints to collect
@@ -153,8 +157,8 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
        /* Number of times inherited from direct parent relation(s) */
        int32           attinhcount BKI_DEFAULT(0);
 
-       /* attribute's collation */
-       Oid                     attcollation;
+       /* attribute's collation, if any */
+       Oid                     attcollation BKI_LOOKUP_OPT(pg_collation);
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        /* NOTE: The following fields are not present in tuple descriptors. */
index e90c39564088ff5fdb25aca6bb3616c4553b9c65..76ab90c9395b379d904ab345fc37ea7acd974ade 100644 (file)
@@ -29,9 +29,9 @@
  */
 CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
-       Oid                     roleid;                 /* ID of a role */
-       Oid                     member;                 /* ID of a member of that role */
-       Oid                     grantor;                /* who granted the membership */
+       Oid                     roleid BKI_LOOKUP(pg_authid);   /* ID of a role */
+       Oid                     member BKI_LOOKUP(pg_authid);   /* ID of a member of that role */
+       Oid                     grantor BKI_LOOKUP(pg_authid);  /* who granted the membership */
        bool            admin_option;   /* granted with admin option? */
 } FormData_pg_auth_members;
 
index 2d36628c2011dc811bc9645bfedf624bf7d30a07..f64a9df54ce3a4d469376fe3275bc0e25bc6e778 100644 (file)
@@ -40,7 +40,7 @@ CATALOG(pg_cast,2605,CastRelationId)
        Oid                     casttarget BKI_LOOKUP(pg_type);
 
        /* cast function; 0 = binary coercible */
-       Oid                     castfunc BKI_LOOKUP(pg_proc);
+       Oid                     castfunc BKI_LOOKUP_OPT(pg_proc);
 
        /* contexts in which cast can be used */
        char            castcontext;
index eca306ca98f5d1b6c3467a1d3df1ac68b3d0a3a3..bb6938caa23fdd7196c583f9900aaaa4e1d4301f 100644 (file)
@@ -38,26 +38,26 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
        NameData        relname;
 
        /* OID of namespace containing this class */
-       Oid                     relnamespace BKI_DEFAULT(PGNSP);
+       Oid                     relnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
-       /* OID of entry in pg_type for table's implicit row type */
-       Oid                     reltype BKI_LOOKUP(pg_type);
+       /* OID of entry in pg_type for relation's implicit row type, if any */
+       Oid                     reltype BKI_LOOKUP_OPT(pg_type);
 
-       /* OID of entry in pg_type for underlying composite type */
-       Oid                     reloftype BKI_DEFAULT(0) BKI_LOOKUP(pg_type);
+       /* OID of entry in pg_type for underlying composite type, if any */
+       Oid                     reloftype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 
        /* class owner */
-       Oid                     relowner BKI_DEFAULT(PGUID);
+       Oid                     relowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* access method; 0 if not a table / index */
-       Oid                     relam BKI_DEFAULT(heap) BKI_LOOKUP(pg_am);
+       Oid                     relam BKI_DEFAULT(heap) BKI_LOOKUP_OPT(pg_am);
 
        /* identifier of physical storage file */
        /* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */
        Oid                     relfilenode BKI_DEFAULT(0);
 
        /* identifier of table space for relation (0 means default for database) */
-       Oid                     reltablespace BKI_DEFAULT(0) BKI_LOOKUP(pg_tablespace);
+       Oid                     reltablespace BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_tablespace);
 
        /* # of blocks (not always up-to-date) */
        int32           relpages BKI_DEFAULT(0);
@@ -69,7 +69,7 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
        int32           relallvisible BKI_DEFAULT(0);
 
        /* OID of toast table; 0 if none */
-       Oid                     reltoastrelid BKI_DEFAULT(0);
+       Oid                     reltoastrelid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
        /* T if has (or has had) any indexes */
        bool            relhasindex BKI_DEFAULT(f);
@@ -119,8 +119,8 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
        /* is relation a partition? */
        bool            relispartition BKI_DEFAULT(f);
 
-       /* heap for rewrite during DDL, link to original rel */
-       Oid                     relrewrite BKI_DEFAULT(0);
+       /* link to original rel during table rewrite; otherwise 0 */
+       Oid                     relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
        /* all Xids < this are frozen in this rel */
        TransactionId relfrozenxid BKI_DEFAULT(3);      /* FirstNormalTransactionId */
index ad57b0fa6d141344bd06176fed2beaf9240cc6b1..6e0ab1ab4b83a4a02875aaaa9b486c5a020a8273 100644 (file)
 
 { oid => '100', oid_symbol => 'DEFAULT_COLLATION_OID',
   descr => 'database\'s default collation',
-  collname => 'default', collnamespace => 'PGNSP', collowner => 'PGUID',
-  collprovider => 'd', collencoding => '-1', collcollate => '',
-  collctype => '' },
+  collname => 'default', collprovider => 'd', collencoding => '-1',
+  collcollate => '', collctype => '' },
 { oid => '950', oid_symbol => 'C_COLLATION_OID',
   descr => 'standard C collation',
-  collname => 'C', collnamespace => 'PGNSP', collowner => 'PGUID',
-  collprovider => 'c', collencoding => '-1', collcollate => 'C',
-  collctype => 'C' },
+  collname => 'C', collprovider => 'c', collencoding => '-1',
+  collcollate => 'C', collctype => 'C' },
 { oid => '951', oid_symbol => 'POSIX_COLLATION_OID',
   descr => 'standard POSIX collation',
-  collname => 'POSIX', collnamespace => 'PGNSP', collowner => 'PGUID',
-  collprovider => 'c', collencoding => '-1', collcollate => 'POSIX',
-  collctype => 'POSIX' },
+  collname => 'POSIX', collprovider => 'c', collencoding => '-1',
+  collcollate => 'POSIX', collctype => 'POSIX' },
 
 ]
index 3c496ea914184c5345e8570ced3204ebea50b456..3bd7873c6885fe5e60eb07fe962f0610d63b3b60 100644 (file)
@@ -30,8 +30,9 @@ CATALOG(pg_collation,3456,CollationRelationId)
 {
        Oid                     oid;                    /* oid */
        NameData        collname;               /* collation name */
-       Oid                     collnamespace;  /* OID of namespace containing collation */
-       Oid                     collowner;              /* owner of collation */
+       Oid                     collnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);      /* OID of namespace
+                                                                                                                                                        * containing collation */
+       Oid                     collowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid); /* owner of collation */
        char            collprovider;   /* see constants below */
        bool            collisdeterministic BKI_DEFAULT(t);
        int32           collencoding;   /* encoding for this collation; -1 = "all" */
index 6449937b352db4ff0c60d5f35bb00d1ca0169e07..63f0f8bf41852cf269805f934cdfbdc5050df046 100644 (file)
@@ -46,7 +46,8 @@ CATALOG(pg_constraint,2606,ConstraintRelationId)
         * conrelid + contypid + conname.
         */
        NameData        conname;                /* name of this constraint */
-       Oid                     connamespace;   /* OID of namespace containing constraint */
+       Oid                     connamespace BKI_LOOKUP(pg_namespace);  /* OID of namespace
+                                                                                                                * containing constraint */
        char            contype;                /* constraint type; see codes below */
        bool            condeferrable;  /* deferrable constraint? */
        bool            condeferred;    /* deferred by default? */
@@ -57,7 +58,8 @@ CATALOG(pg_constraint,2606,ConstraintRelationId)
         * specific relation (this excludes domain constraints and assertions).
         * Otherwise conrelid is 0 and conkey is NULL.
         */
-       Oid                     conrelid;               /* relation this constraint constrains */
+       Oid                     conrelid BKI_LOOKUP_OPT(pg_class);      /* relation this
+                                                                                                        * constraint constrains */
 
        /*
         * contypid links to the pg_type row for a domain if this is a domain
@@ -66,7 +68,8 @@ CATALOG(pg_constraint,2606,ConstraintRelationId)
         * For SQL-style global ASSERTIONs, both conrelid and contypid would be
         * zero. This is not presently supported, however.
         */
-       Oid                     contypid;               /* domain this constraint constrains */
+       Oid                     contypid BKI_LOOKUP_OPT(pg_type);       /* domain this constraint
+                                                                                                        * constrains */
 
        /*
         * conindid links to the index supporting the constraint, if any;
@@ -76,19 +79,21 @@ CATALOG(pg_constraint,2606,ConstraintRelationId)
         * columns).  Notice that the index is on conrelid in the first case but
         * confrelid in the second.
         */
-       Oid                     conindid;               /* index supporting this constraint */
+       Oid                     conindid BKI_LOOKUP_OPT(pg_class);      /* index supporting this
+                                                                                                        * constraint */
 
        /*
         * If this constraint is on a partition inherited from a partitioned
         * table, this is the OID of the corresponding constraint in the parent.
         */
-       Oid                     conparentid;
+       Oid                     conparentid BKI_LOOKUP_OPT(pg_constraint);
 
        /*
         * These fields, plus confkey, are only meaningful for a foreign-key
         * constraint.  Otherwise confrelid is 0 and the char fields are spaces.
         */
-       Oid                     confrelid;              /* relation referenced by foreign key */
+       Oid                     confrelid BKI_LOOKUP_OPT(pg_class); /* relation referenced by
+                                                                                                        * foreign key */
        char            confupdtype;    /* foreign key's ON UPDATE action */
        char            confdeltype;    /* foreign key's ON DELETE action */
        char            confmatchtype;  /* foreign key's match type */
@@ -119,25 +124,25 @@ CATALOG(pg_constraint,2606,ConstraintRelationId)
         * If a foreign key, the OIDs of the PK = FK equality operators for each
         * column of the constraint
         */
-       Oid                     conpfeqop[1];
+       Oid                     conpfeqop[1] BKI_LOOKUP(pg_operator);
 
        /*
         * If a foreign key, the OIDs of the PK = PK equality operators for each
         * column of the constraint (i.e., equality for the referenced columns)
         */
-       Oid                     conppeqop[1];
+       Oid                     conppeqop[1] BKI_LOOKUP(pg_operator);
 
        /*
         * If a foreign key, the OIDs of the FK = FK equality operators for each
         * column of the constraint (i.e., equality for the referencing columns)
         */
-       Oid                     conffeqop[1];
+       Oid                     conffeqop[1] BKI_LOOKUP(pg_operator);
 
        /*
         * If an exclusion constraint, the OIDs of the exclusion operators for
         * each column of the constraint
         */
-       Oid                     conexclop[1];
+       Oid                     conexclop[1] BKI_LOOKUP(pg_operator);
 
        /*
         * If a check constraint, nodeToString representation of expression
@@ -166,6 +171,10 @@ DECLARE_UNIQUE_INDEX_PKEY(pg_constraint_oid_index, 2667, on pg_constraint using
 DECLARE_INDEX(pg_constraint_conparentid_index, 2579, on pg_constraint using btree(conparentid oid_ops));
 #define ConstraintParentIndexId        2579
 
+/* conkey can contain zero (InvalidAttrNumber) if a whole-row Var is used */
+DECLARE_ARRAY_FOREIGN_KEY_OPT((conrelid, conkey), pg_attribute, (attrelid, attnum));
+DECLARE_ARRAY_FOREIGN_KEY((confrelid, confkey), pg_attribute, (attrelid, attnum));
+
 #ifdef EXPOSE_TO_CLIENT_CODE
 
 /* Valid values for contype */
index b02dfe0c3f776d426b7a7845e3bcbf81b614afc7..96bb92f251b1e013bedfa03c07027160eed8f554 100644 (file)
@@ -35,10 +35,10 @@ CATALOG(pg_conversion,2607,ConversionRelationId)
        NameData        conname;
 
        /* namespace that the conversion belongs to */
-       Oid                     connamespace BKI_DEFAULT(PGNSP);
+       Oid                     connamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* owner of the conversion */
-       Oid                     conowner BKI_DEFAULT(PGUID);
+       Oid                     conowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* FOR encoding id */
        int32           conforencoding BKI_LOOKUP(encoding);
index b7a0b6a381b4c08304b52d8177b3f62820531aac..f0240c58cf1a339bfb4f95e782084c0b40ddca8f 100644 (file)
@@ -35,7 +35,7 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID
        NameData        datname;
 
        /* owner of database */
-       Oid                     datdba BKI_DEFAULT(PGUID);
+       Oid                     datdba BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* character encoding */
        int32           encoding;
index f18819d670c459e9b30f45ae129ceed8b8190bbc..705f698ae79fb7744735fe04c4f02905c9605bcc 100644 (file)
  */
 CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION
 {
-       Oid                     setdatabase;    /* database */
-       Oid                     setrole;                /* role */
+       /* database, or 0 for a role-specific setting */
+       Oid                     setdatabase BKI_LOOKUP_OPT(pg_database);
+
+       /* role, or 0 for a database-specific setting */
+       Oid                     setrole BKI_LOOKUP_OPT(pg_authid);
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        text            setconfig[1];   /* GUC settings to apply at login */
index bb7db32cd6c395f92518f4037dcf53fd88d2a0d7..156fc0712da745e44020ee581a5fe5c79b8958c1 100644 (file)
 CATALOG(pg_default_acl,826,DefaultAclRelationId)
 {
        Oid                     oid;                    /* oid */
-       Oid                     defaclrole;             /* OID of role owning this ACL */
-       Oid                     defaclnamespace;        /* OID of namespace, or 0 for all */
+       Oid                     defaclrole BKI_LOOKUP(pg_authid);       /* OID of role owning this
+                                                                                                        * ACL */
+       Oid                     defaclnamespace BKI_LOOKUP_OPT(pg_namespace);   /* OID of namespace, or
+                                                                                                                                * 0 for all */
        char            defaclobjtype;  /* see DEFACLOBJ_xxx constants below */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
index b0837901806f33efc52d49b44406ec655e873811..606a2a8e192ece3ab1a3e92c96b24aa63b645629 100644 (file)
@@ -45,14 +45,16 @@ CATALOG(pg_depend,2608,DependRelationId)
         *
         * These fields are all zeroes for a DEPENDENCY_PIN entry.
         */
-       Oid                     classid;                /* OID of table containing object */
+       Oid                     classid BKI_LOOKUP_OPT(pg_class);       /* OID of table containing
+                                                                                                        * object */
        Oid                     objid;                  /* OID of object itself */
        int32           objsubid;               /* column number, or 0 if not used */
 
        /*
         * Identification of the independent (referenced) object.
         */
-       Oid                     refclassid;             /* OID of table containing object */
+       Oid                     refclassid BKI_LOOKUP(pg_class);        /* OID of table containing
+                                                                                                        * object */
        Oid                     refobjid;               /* OID of object itself */
        int32           refobjsubid;    /* column number, or 0 if not used */
 
index ad9de5e0a06239ba2d96c9a3463eb852649928c3..adc06a854d9a565ee91e60b92140a6f3a44865c3 100644 (file)
@@ -68,4 +68,7 @@ DECLARE_TOAST(pg_description, 2834, 2835);
 DECLARE_UNIQUE_INDEX_PKEY(pg_description_o_c_o_index, 2675, on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops));
 #define DescriptionObjIndexId  2675
 
+/* We do not use BKI_LOOKUP here because it causes problems for genbki.pl */
+DECLARE_FOREIGN_KEY((classoid), pg_class, (oid));
+
 #endif                                                 /* PG_DESCRIPTION_H */
index 5eaf70772c71441a9d9d585d3d70f61bca59a601..78a183b27d4bc1f18752a4ae57b180ee2889b71a 100644 (file)
@@ -31,7 +31,7 @@
 CATALOG(pg_enum,3501,EnumRelationId)
 {
        Oid                     oid;                    /* oid */
-       Oid                     enumtypid;              /* OID of owning enum type */
+       Oid                     enumtypid BKI_LOOKUP(pg_type);  /* OID of owning enum type */
        float4          enumsortorder;  /* sort position of this enum value */
        NameData        enumlabel;              /* text representation of enum value */
 } FormData_pg_enum;
index 6f0266ed0fae2e7be3e152d9c241aa38eadf8e61..eeaa6be51844702d355f0d3df89912813c132e65 100644 (file)
@@ -31,8 +31,9 @@ CATALOG(pg_event_trigger,3466,EventTriggerRelationId)
        Oid                     oid;                    /* oid */
        NameData        evtname;                /* trigger's name */
        NameData        evtevent;               /* trigger's event */
-       Oid                     evtowner;               /* trigger's owner */
-       Oid                     evtfoid;                /* OID of function to be called */
+       Oid                     evtowner BKI_LOOKUP(pg_authid); /* trigger's owner */
+       Oid                     evtfoid BKI_LOOKUP(pg_proc);    /* OID of function to be
+                                                                                                * called */
        char            evtenabled;             /* trigger's firing configuration WRT
                                                                 * session_replication_role */
 
index af119bfea7a8cb0fcb3c387a27b45be82538d6f2..2d6ad9fa888811a1618b17323644826442cc25c7 100644 (file)
@@ -30,14 +30,16 @@ CATALOG(pg_extension,3079,ExtensionRelationId)
 {
        Oid                     oid;                    /* oid */
        NameData        extname;                /* extension name */
-       Oid                     extowner;               /* extension owner */
-       Oid                     extnamespace;   /* namespace of contained objects */
+       Oid                     extowner BKI_LOOKUP(pg_authid); /* extension owner */
+       Oid                     extnamespace BKI_LOOKUP(pg_namespace);  /* namespace of
+                                                                                                                * contained objects */
        bool            extrelocatable; /* if true, allow ALTER EXTENSION SET SCHEMA */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        /* extversion may never be null, but the others can be. */
        text            extversion BKI_FORCE_NOT_NULL;  /* extension version name */
-       Oid                     extconfig[1];   /* dumpable configuration tables */
+       Oid                     extconfig[1] BKI_LOOKUP(pg_class);      /* dumpable configuration
+                                                                                                        * tables */
        text            extcondition[1];        /* WHERE clauses for config tables */
 #endif
 } FormData_pg_extension;
index 0f523a26b9c4ff96566abb5a92cda876767d503f..f6240d9eb326b79a207660549dab4d9a5d993b7c 100644 (file)
@@ -30,9 +30,12 @@ CATALOG(pg_foreign_data_wrapper,2328,ForeignDataWrapperRelationId)
 {
        Oid                     oid;                    /* oid */
        NameData        fdwname;                /* foreign-data wrapper name */
-       Oid                     fdwowner;               /* FDW owner */
-       Oid                     fdwhandler;             /* handler function, or 0 if none */
-       Oid                     fdwvalidator;   /* option validation function, or 0 if none */
+       Oid                     fdwowner BKI_LOOKUP(pg_authid); /* FDW owner */
+       Oid                     fdwhandler BKI_LOOKUP_OPT(pg_proc); /* handler function, or 0
+                                                                                                        * if none */
+       Oid                     fdwvalidator BKI_LOOKUP_OPT(pg_proc);   /* option validation
+                                                                                                                * function, or 0 if
+                                                                                                                * none */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        aclitem         fdwacl[1];              /* access permissions */
index 385b896e970d582b3b256c3053b98c5a9522bea2..a173699aef6bcbec235349b07b9caa9cc08fe68e 100644 (file)
@@ -29,8 +29,8 @@ CATALOG(pg_foreign_server,1417,ForeignServerRelationId)
 {
        Oid                     oid;                    /* oid */
        NameData        srvname;                /* foreign server name */
-       Oid                     srvowner;               /* server owner */
-       Oid                     srvfdw;                 /* server FDW */
+       Oid                     srvowner BKI_LOOKUP(pg_authid); /* server owner */
+       Oid                     srvfdw BKI_LOOKUP(pg_foreign_data_wrapper); /* server FDW */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        text            srvtype;
index 24f7f2998eb80d84ab0f72bce45b854d34dc7436..3b6221b0e64b519801891a6af3b4e2de15e76f97 100644 (file)
@@ -27,8 +27,8 @@
  */
 CATALOG(pg_foreign_table,3118,ForeignTableRelationId)
 {
-       Oid                     ftrelid;                /* OID of foreign table */
-       Oid                     ftserver;               /* OID of foreign server */
+       Oid                     ftrelid BKI_LOOKUP(pg_class);   /* OID of foreign table */
+       Oid                     ftserver BKI_LOOKUP(pg_foreign_server); /* OID of foreign server */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        text            ftoptions[1];   /* FDW-specific options */
index 1a7aef18ce85f5ac1c790bf7c0391ddc16e9517c..00d0b439f5c94f74e0570cb0d2fd07bd3d35d54e 100644 (file)
@@ -28,8 +28,9 @@
  */
 CATALOG(pg_index,2610,IndexRelationId) BKI_SCHEMA_MACRO
 {
-       Oid                     indexrelid;             /* OID of the index */
-       Oid                     indrelid;               /* OID of the relation it indexes */
+       Oid                     indexrelid BKI_LOOKUP(pg_class);        /* OID of the index */
+       Oid                     indrelid BKI_LOOKUP(pg_class);  /* OID of the relation it
+                                                                                                * indexes */
        int16           indnatts;               /* total number of columns in index */
        int16           indnkeyatts;    /* number of key columns in index */
        bool            indisunique;    /* is this a unique index? */
@@ -48,8 +49,8 @@ CATALOG(pg_index,2610,IndexRelationId) BKI_SCHEMA_MACRO
                                                                                         * or 0 */
 
 #ifdef CATALOG_VARLEN
-       oidvector       indcollation BKI_FORCE_NOT_NULL;        /* collation identifiers */
-       oidvector       indclass BKI_FORCE_NOT_NULL;    /* opclass identifiers */
+       oidvector       indcollation BKI_LOOKUP_OPT(pg_collation) BKI_FORCE_NOT_NULL;   /* collation identifiers */
+       oidvector       indclass BKI_LOOKUP(pg_opclass) BKI_FORCE_NOT_NULL; /* opclass identifiers */
        int2vector      indoption BKI_FORCE_NOT_NULL;   /* per-column flags
                                                                                                 * (AM-specific meanings) */
        pg_node_tree indexprs;          /* expression trees for index attributes that
@@ -72,6 +73,9 @@ DECLARE_INDEX(pg_index_indrelid_index, 2678, on pg_index using btree(indrelid oi
 DECLARE_UNIQUE_INDEX_PKEY(pg_index_indexrelid_index, 2679, on pg_index using btree(indexrelid oid_ops));
 #define IndexRelidIndexId  2679
 
+/* indkey can contain zero (InvalidAttrNumber) to represent expressions */
+DECLARE_ARRAY_FOREIGN_KEY_OPT((indrelid, indkey), pg_attribute, (attrelid, attnum));
+
 #ifdef EXPOSE_TO_CLIENT_CODE
 
 /*
index b8147796d855f0f9548692b3cdfe7e1890903eef..2b71cad9a2a48d9f5ed07190f4e946367a0d8c78 100644 (file)
@@ -31,8 +31,8 @@
  */
 CATALOG(pg_inherits,2611,InheritsRelationId)
 {
-       Oid                     inhrelid;
-       Oid                     inhparent;
+       Oid                     inhrelid BKI_LOOKUP(pg_class);
+       Oid                     inhparent BKI_LOOKUP(pg_class);
        int32           inhseqno;
 } FormData_pg_inherits;
 
index 983b1857c0c7d9a22d5149ec0b880d9d1e9feb56..4aafeb246d7e1813d93071f6840e2ddc80634015 100644 (file)
@@ -46,7 +46,8 @@
 CATALOG(pg_init_privs,3394,InitPrivsRelationId)
 {
        Oid                     objoid;                 /* OID of object itself */
-       Oid                     classoid;               /* OID of table containing object */
+       Oid                     classoid BKI_LOOKUP(pg_class);  /* OID of table containing
+                                                                                                * object */
        int32           objsubid;               /* column number, or 0 if not used */
        char            privtype;               /* from initdb or extension? */
 
index b1dcd0a4f579dc92055901ce669381dca6131a7c..e9df9dac09f30ffffbbc924285108752405c274c 100644 (file)
@@ -34,7 +34,7 @@ CATALOG(pg_language,2612,LanguageRelationId)
        NameData        lanname;
 
        /* Language's owner */
-       Oid                     lanowner BKI_DEFAULT(PGUID);
+       Oid                     lanowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* Is a procedural language */
        bool            lanispl BKI_DEFAULT(f);
@@ -43,13 +43,13 @@ CATALOG(pg_language,2612,LanguageRelationId)
        bool            lanpltrusted BKI_DEFAULT(f);
 
        /* Call handler, if it's a PL */
-       Oid                     lanplcallfoid BKI_DEFAULT(0) BKI_LOOKUP(pg_proc);
+       Oid                     lanplcallfoid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc);
 
        /* Optional anonymous-block handler function */
-       Oid                     laninline BKI_DEFAULT(0) BKI_LOOKUP(pg_proc);
+       Oid                     laninline BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc);
 
        /* Optional validation function */
-       Oid                     lanvalidator BKI_DEFAULT(0) BKI_LOOKUP(pg_proc);
+       Oid                     lanvalidator BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc);
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        /* Access privileges */
index f453319322aa760f7183ae807b9952754a97c109..32225f4de7d374d2cf25bfca024797ad564a1a8d 100644 (file)
@@ -28,7 +28,8 @@
  */
 CATALOG(pg_largeobject,2613,LargeObjectRelationId)
 {
-       Oid                     loid;                   /* Identifier of large object */
+       Oid                     loid BKI_LOOKUP(pg_largeobject_metadata);       /* Identifier of large
+                                                                                                                        * object */
        int32           pageno;                 /* Page number (starting from 0) */
 
        /* data has variable length, but we allow direct access; see inv_api.c */
index 220988b0ad600ec7a34251dc39d8aca32705b824..9b689bab849bd8c2fbacc42300aa8b2da0647691 100644 (file)
@@ -31,7 +31,8 @@ CATALOG(pg_largeobject_metadata,2995,LargeObjectMetadataRelationId)
 {
        Oid                     oid;                    /* oid */
 
-       Oid                     lomowner;               /* OID of the largeobject owner */
+       Oid                     lomowner BKI_LOOKUP(pg_authid); /* OID of the largeobject
+                                                                                                * owner */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        aclitem         lomacl[1];              /* access permissions */
index 76257e98fcc9187e0eb92a1afd7b1264a4173cda..2ed136b787ede905ed4785707eef08e7b9bd1111 100644 (file)
 
 { oid => '11', oid_symbol => 'PG_CATALOG_NAMESPACE',
   descr => 'system catalog schema',
-  nspname => 'pg_catalog', nspowner => 'PGUID', nspacl => '_null_' },
+  nspname => 'pg_catalog', nspacl => '_null_' },
 { oid => '99', oid_symbol => 'PG_TOAST_NAMESPACE',
   descr => 'reserved schema for TOAST tables',
-  nspname => 'pg_toast', nspowner => 'PGUID', nspacl => '_null_' },
+  nspname => 'pg_toast', nspacl => '_null_' },
 { oid => '2200', oid_symbol => 'PG_PUBLIC_NAMESPACE',
   descr => 'standard public schema',
-  nspname => 'public', nspowner => 'PGUID', nspacl => '_null_' },
+  nspname => 'public', nspacl => '_null_' },
 
 ]
index 0a68958b1c4c90e613abb0ea711e61115fdbe04d..d920c6cfc64a3b8804a8b39437606400bf342b0f 100644 (file)
@@ -37,7 +37,7 @@ CATALOG(pg_namespace,2615,NamespaceRelationId)
        Oid                     oid;                    /* oid */
 
        NameData        nspname;
-       Oid                     nspowner;
+       Oid                     nspowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        aclitem         nspacl[1];
index d132df1f2f7ee718f5ee73aee6adf64648d6f7b5..9f321f2a85ce508fa628007d7f313b5f24350e56 100644 (file)
@@ -57,10 +57,10 @@ CATALOG(pg_opclass,2616,OperatorClassRelationId)
        NameData        opcname;
 
        /* namespace of this opclass */
-       Oid                     opcnamespace BKI_DEFAULT(PGNSP);
+       Oid                     opcnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* opclass owner */
-       Oid                     opcowner BKI_DEFAULT(PGUID);
+       Oid                     opcowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* containing operator family */
        Oid                     opcfamily BKI_LOOKUP(pg_opfamily);
@@ -71,8 +71,8 @@ CATALOG(pg_opclass,2616,OperatorClassRelationId)
        /* T if opclass is default for opcintype */
        bool            opcdefault BKI_DEFAULT(t);
 
-       /* type of data in index, or InvalidOid */
-       Oid                     opckeytype BKI_DEFAULT(0) BKI_LOOKUP(pg_type);
+       /* type of data in index, or InvalidOid if same as input column type */
+       Oid                     opckeytype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 } FormData_pg_opclass;
 
 /* ----------------
index 3ca57e7c1b4b17c4753f93c5867e00bef4fbc282..7f06abaeec1ef28264c00bdc1a99e2102564f90f 100644 (file)
@@ -36,10 +36,10 @@ CATALOG(pg_operator,2617,OperatorRelationId)
        NameData        oprname;
 
        /* OID of namespace containing this oper */
-       Oid                     oprnamespace BKI_DEFAULT(PGNSP);
+       Oid                     oprnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* operator owner */
-       Oid                     oprowner BKI_DEFAULT(PGUID);
+       Oid                     oprowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* 'l' for prefix or 'b' for infix */
        char            oprkind BKI_DEFAULT(b);
@@ -51,28 +51,28 @@ CATALOG(pg_operator,2617,OperatorRelationId)
        bool            oprcanhash BKI_DEFAULT(f);
 
        /* left arg type, or 0 if prefix operator */
-       Oid                     oprleft BKI_LOOKUP(pg_type);
+       Oid                     oprleft BKI_LOOKUP_OPT(pg_type);
 
        /* right arg type */
        Oid                     oprright BKI_LOOKUP(pg_type);
 
-       /* result datatype */
-       Oid                     oprresult BKI_LOOKUP(pg_type);
+       /* result datatype; can be 0 in a "shell" operator */
+       Oid                     oprresult BKI_LOOKUP_OPT(pg_type);
 
        /* OID of commutator oper, or 0 if none */
-       Oid                     oprcom BKI_DEFAULT(0) BKI_LOOKUP(pg_operator);
+       Oid                     oprcom BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator);
 
        /* OID of negator oper, or 0 if none */
-       Oid                     oprnegate BKI_DEFAULT(0) BKI_LOOKUP(pg_operator);
+       Oid                     oprnegate BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator);
 
-       /* OID of underlying function */
-       regproc         oprcode BKI_LOOKUP(pg_proc);
+       /* OID of underlying function; can be 0 in a "shell" operator */
+       regproc         oprcode BKI_LOOKUP_OPT(pg_proc);
 
        /* OID of restriction estimator, or 0 */
-       regproc         oprrest BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         oprrest BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /* OID of join estimator, or 0 */
-       regproc         oprjoin BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         oprjoin BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 } FormData_pg_operator;
 
 /* ----------------
index 18385a6fd6c095a20ec5f349ac03392ca10a27ac..1a723b76f63923e882551f7f6073048227f5738b 100644 (file)
@@ -37,10 +37,10 @@ CATALOG(pg_opfamily,2753,OperatorFamilyRelationId)
        NameData        opfname;
 
        /* namespace of this opfamily */
-       Oid                     opfnamespace BKI_DEFAULT(PGNSP);
+       Oid                     opfnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* opfamily owner */
-       Oid                     opfowner BKI_DEFAULT(PGUID);
+       Oid                     opfowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 } FormData_pg_opfamily;
 
 /* ----------------
index 038730b00536c9724de45078df161265885382e9..48cbaf30ff8ef268ed0b7da922ae9b3fc66f4e74 100644 (file)
  */
 CATALOG(pg_partitioned_table,3350,PartitionedRelationId)
 {
-       Oid                     partrelid;              /* partitioned table oid */
+       Oid                     partrelid BKI_LOOKUP(pg_class); /* partitioned table oid */
        char            partstrat;              /* partitioning strategy */
        int16           partnatts;              /* number of partition key columns */
-       Oid                     partdefid;              /* default partition oid; InvalidOid if there
-                                                                * isn't one */
+       Oid                     partdefid BKI_LOOKUP_OPT(pg_class); /* default partition oid;
+                                                                                                        * 0 if there isn't one */
 
        /*
         * variable-length fields start here, but we allow direct access to
@@ -48,10 +48,10 @@ CATALOG(pg_partitioned_table,3350,PartitionedRelationId)
                                                                                                 * an expression */
 
 #ifdef CATALOG_VARLEN
-       oidvector       partclass BKI_FORCE_NOT_NULL;   /* operator class to compare
-                                                                                                * keys */
-       oidvector       partcollation BKI_FORCE_NOT_NULL;       /* user-specified
-                                                                                                        * collation for keys */
+       oidvector       partclass BKI_LOOKUP(pg_opclass) BKI_FORCE_NOT_NULL;    /* operator class to
+                                                                                                                                                * compare keys */
+       oidvector       partcollation BKI_LOOKUP_OPT(pg_collation) BKI_FORCE_NOT_NULL;  /* user-specified
+                                                                                                                                                                * collation for keys */
        pg_node_tree partexprs;         /* list of expressions in the partition key;
                                                                 * one item for each zero entry in partattrs[] */
 #endif
@@ -69,4 +69,7 @@ DECLARE_TOAST(pg_partitioned_table, 4165, 4166);
 DECLARE_UNIQUE_INDEX_PKEY(pg_partitioned_table_partrelid_index, 3351, on pg_partitioned_table using btree(partrelid oid_ops));
 #define PartitionedRelidIndexId                         3351
 
+/* partattrs can contain zero (InvalidAttrNumber) to represent expressions */
+DECLARE_ARRAY_FOREIGN_KEY_OPT((partrelid, partattrs), pg_attribute, (attrelid, attnum));
+
 #endif                                                 /* PG_PARTITIONED_TABLE_H */
index 44197613e06bef0a53b1495297b709ae5e284913..645b8fe498c54af4aa3079193dabffdc3c7ad961 100644 (file)
@@ -30,13 +30,14 @@ CATALOG(pg_policy,3256,PolicyRelationId)
 {
        Oid                     oid;                    /* oid */
        NameData        polname;                /* Policy name. */
-       Oid                     polrelid;               /* Oid of the relation with policy. */
+       Oid                     polrelid BKI_LOOKUP(pg_class);  /* Oid of the relation with
+                                                                                                * policy. */
        char            polcmd;                 /* One of ACL_*_CHR, or '*' for all */
        bool            polpermissive;  /* restrictive or permissive policy */
 
 #ifdef CATALOG_VARLEN
-       Oid                     polroles[1] BKI_FORCE_NOT_NULL; /* Roles associated with
-                                                                                                * policy */
+       /* Roles to which the policy is applied; zero means PUBLIC */
+       Oid                     polroles[1] BKI_LOOKUP_OPT(pg_authid) BKI_FORCE_NOT_NULL;
        pg_node_tree polqual;           /* Policy quals. */
        pg_node_tree polwithcheck;      /* WITH CHECK quals. */
 #endif
index f8174061ef359855ef248492b5413200d460e157..4e0c9be58c31474f6d506d7aedb0f37f50d17096 100644 (file)
 { oid => '1215', descr => 'get description for object id and catalog name',
   proname => 'obj_description', prolang => 'sql', procost => '100',
   provolatile => 's', prorettype => 'text', proargtypes => 'oid name',
-  prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP) and objsubid = 0' },
+  prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = \'pg_catalog\'::pg_catalog.regnamespace) and objsubid = 0' },
 { oid => '1216', descr => 'get description for table column',
   proname => 'col_description', prolang => 'sql', procost => '100',
   provolatile => 's', prorettype => 'text', proargtypes => 'oid int4',
   descr => 'get description for object id and shared catalog name',
   proname => 'shobj_description', prolang => 'sql', procost => '100',
   provolatile => 's', prorettype => 'text', proargtypes => 'oid name',
-  prosrc => 'select description from pg_catalog.pg_shdescription where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP)' },
+  prosrc => 'select description from pg_catalog.pg_shdescription where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = \'pg_catalog\'::pg_catalog.regnamespace)' },
 
 { oid => '1217',
   descr => 'truncate timestamp with time zone to specified units',
   proargnames => '{word,catcode,barelabel,catdesc,baredesc}',
   prosrc => 'pg_get_keywords' },
 
+{ oid => '8103', descr => 'list of catalog foreign key relationships',
+  proname => 'pg_get_catalog_foreign_keys', procost => '10', prorows => '250',
+  proretset => 't', provolatile => 's', prorettype => 'record',
+  proargtypes => '', proallargtypes => '{regclass,_text,regclass,_text,bool,bool}',
+  proargmodes => '{o,o,o,o,o,o}',
+  proargnames => '{fktable,fkcols,pktable,pkcols,is_array,is_opt}',
+  prosrc => 'pg_get_catalog_foreign_keys' },
+
 { oid => '2289', descr => 'convert generic options array to name/value table',
   proname => 'pg_options_to_table', prorows => '3', proretset => 't',
   provolatile => 's', prorettype => 'record', proargtypes => '_text',
index 03c8bef42274d56c110ce243eaa50f5205e4e3d8..2f54aa171edd239a8dc63e42b2d7f1bca1879056 100644 (file)
@@ -35,10 +35,10 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce
        NameData        proname;
 
        /* OID of namespace containing this proc */
-       Oid                     pronamespace BKI_DEFAULT(PGNSP);
+       Oid                     pronamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* procedure owner */
-       Oid                     proowner BKI_DEFAULT(PGUID);
+       Oid                     proowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* OID of pg_language entry */
        Oid                     prolang BKI_DEFAULT(internal) BKI_LOOKUP(pg_language);
@@ -49,11 +49,11 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce
        /* estimated # of rows out (if proretset) */
        float4          prorows BKI_DEFAULT(0);
 
-       /* element type of variadic array, or 0 */
-       Oid                     provariadic BKI_DEFAULT(0) BKI_LOOKUP(pg_type);
+       /* element type of variadic array, or 0 if not variadic */
+       Oid                     provariadic BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 
        /* planner support function for this function, or 0 if none */
-       regproc         prosupport BKI_DEFAULT(0) BKI_LOOKUP(pg_proc);
+       regproc         prosupport BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc);
 
        /* see PROKIND_ categories below */
        char            prokind BKI_DEFAULT(f);
@@ -109,7 +109,7 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce
        pg_node_tree proargdefaults BKI_DEFAULT(_null_);
 
        /* types for which to apply transforms */
-       Oid                     protrftypes[1] BKI_DEFAULT(_null_);
+       Oid                     protrftypes[1] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type);
 
        /* procedure source text */
        text            prosrc BKI_FORCE_NOT_NULL;
index 4127611f5a6b5ffa13eb508179dbfec2ab7a4a5d..1b31fee9e3cfab30a152b4382d9ad88c73509e5f 100644 (file)
@@ -32,7 +32,7 @@ CATALOG(pg_publication,6104,PublicationRelationId)
 
        NameData        pubname;                /* name of the publication */
 
-       Oid                     pubowner;               /* publication owner */
+       Oid                     pubowner BKI_LOOKUP(pg_authid); /* publication owner */
 
        /*
         * indicates that this is special publication which should encompass all
index c79b7fb4874a5c5ffb4292dfc988509b2a1a139b..aecf53b3b3976b06c2bd5e92ab2cab4883f2a0ca 100644 (file)
@@ -29,8 +29,8 @@
 CATALOG(pg_publication_rel,6106,PublicationRelRelationId)
 {
        Oid                     oid;                    /* oid */
-       Oid                     prpubid;                /* Oid of the publication */
-       Oid                     prrelid;                /* Oid of the relation */
+       Oid                     prpubid BKI_LOOKUP(pg_publication); /* Oid of the publication */
+       Oid                     prrelid BKI_LOOKUP(pg_class);   /* Oid of the relation */
 } FormData_pg_publication_rel;
 
 /* ----------------
index 2ec6a4b126bb294e54e34cba189970f912652677..5dfa4eef8baf95604518f51c645ecf8d07f24e31 100644 (file)
@@ -38,16 +38,16 @@ CATALOG(pg_range,3541,RangeRelationId)
        Oid                     rngmultitypid BKI_LOOKUP(pg_type);
 
        /* collation for this range type, or 0 */
-       Oid                     rngcollation BKI_DEFAULT(0);
+       Oid                     rngcollation BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_collation);
 
        /* subtype's btree opclass */
        Oid                     rngsubopc BKI_LOOKUP(pg_opclass);
 
        /* canonicalize range, or 0 */
-       regproc         rngcanonical BKI_LOOKUP(pg_proc);
+       regproc         rngcanonical BKI_LOOKUP_OPT(pg_proc);
 
        /* subtype difference as a float8, or 0 */
-       regproc         rngsubdiff BKI_LOOKUP(pg_proc);
+       regproc         rngsubdiff BKI_LOOKUP_OPT(pg_proc);
 } FormData_pg_range;
 
 /* ----------------
index 36f92b1cf1358ffd82c0e7fac9bf990294074ea0..89c72545d0bfba5537b2d7a0614643b7b77dc354 100644 (file)
@@ -33,7 +33,7 @@ CATALOG(pg_rewrite,2618,RewriteRelationId)
 {
        Oid                     oid;                    /* oid */
        NameData        rulename;
-       Oid                     ev_class;
+       Oid                     ev_class BKI_LOOKUP(pg_class);
        char            ev_type;
        char            ev_enabled;
        bool            is_instead;
index b14fd7febe8148960977fc9b745991385035ccf0..0a12225eb70fe25fe1a999548724a68fc00029a4 100644 (file)
@@ -28,7 +28,8 @@
 CATALOG(pg_seclabel,3596,SecLabelRelationId)
 {
        Oid                     objoid;                 /* OID of the object itself */
-       Oid                     classoid;               /* OID of table containing the object */
+       Oid                     classoid BKI_LOOKUP(pg_class);  /* OID of table containing the
+                                                                                                * object */
        int32           objsubid;               /* column number, or 0 if not used */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
index addf21abce95baf1513fa1f38fd32598c3db94cc..8d0a00baf69e8a39b44183149a6bba4308c27756 100644 (file)
@@ -22,8 +22,8 @@
 
 CATALOG(pg_sequence,2224,SequenceRelationId)
 {
-       Oid                     seqrelid;
-       Oid                     seqtypid;
+       Oid                     seqrelid BKI_LOOKUP(pg_class);
+       Oid                     seqtypid BKI_LOOKUP(pg_type);
        int64           seqstart;
        int64           seqincrement;
        int64           seqmax;
index f5863954e9fbf9b77e4dd9c1ea305982f6ba4319..4faa95794db94a5eb117b418fb5a88f9ae8122c7 100644 (file)
@@ -42,8 +42,10 @@ CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION
         * These fields are all zeroes for a DEPENDENCY_PIN entry.  Also, dbid can
         * be zero to denote a shared object.
         */
-       Oid                     dbid;                   /* OID of database containing object */
-       Oid                     classid;                /* OID of table containing object */
+       Oid                     dbid BKI_LOOKUP_OPT(pg_database);       /* OID of database
+                                                                                                        * containing object */
+       Oid                     classid BKI_LOOKUP_OPT(pg_class);       /* OID of table containing
+                                                                                                        * object */
        Oid                     objid;                  /* OID of object itself */
        int32           objsubid;               /* column number, or 0 if not used */
 
@@ -52,7 +54,8 @@ CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION
         * a shared object, so we need no database ID field.  We don't bother with
         * a sub-object ID either.
         */
-       Oid                     refclassid;             /* OID of table containing object */
+       Oid                     refclassid BKI_LOOKUP(pg_class);        /* OID of table containing
+                                                                                                        * object */
        Oid                     refobjid;               /* OID of object itself */
 
        /*
index a37db4fa0b44e953a69f3d625fb3d049022affc7..543e216710b5bfebac30dcd5a340c89b60dcceee 100644 (file)
@@ -62,4 +62,7 @@ DECLARE_TOAST(pg_shdescription, 2846, 2847);
 DECLARE_UNIQUE_INDEX_PKEY(pg_shdescription_o_c_index, 2397, on pg_shdescription using btree(objoid oid_ops, classoid oid_ops));
 #define SharedDescriptionObjIndexId 2397
 
+/* We do not use BKI_LOOKUP here because it causes problems for genbki.pl */
+DECLARE_FOREIGN_KEY((classoid), pg_class, (oid));
+
 #endif                                                 /* PG_SHDESCRIPTION_H */
index 406f5328a70312693510e8d9f2cbae4bb178bd53..5d6864cf8cf0e07ab97dcea951c0e505fa5b3c1f 100644 (file)
@@ -28,7 +28,8 @@
 CATALOG(pg_shseclabel,3592,SharedSecLabelRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(4066,SharedSecLabelRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
        Oid                     objoid;                 /* OID of the shared object itself */
-       Oid                     classoid;               /* OID of table containing the shared object */
+       Oid                     classoid BKI_LOOKUP(pg_class);  /* OID of table containing the
+                                                                                                * shared object */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        text            provider BKI_FORCE_NOT_NULL;    /* name of label provider */
index 4a66bda879ca3508376dd854edb0bfaab4697237..d1827858e2d768f2fa20ece7433c56737bfd1319 100644 (file)
@@ -29,7 +29,8 @@
 CATALOG(pg_statistic,2619,StatisticRelationId)
 {
        /* These fields form the unique key for the entry: */
-       Oid                     starelid;               /* relation containing attribute */
+       Oid                     starelid BKI_LOOKUP(pg_class);  /* relation containing
+                                                                                                * attribute */
        int16           staattnum;              /* attribute (column) stats are for */
        bool            stainherit;             /* true if inheritance children are included */
 
@@ -90,17 +91,17 @@ CATALOG(pg_statistic,2619,StatisticRelationId)
        int16           stakind4;
        int16           stakind5;
 
-       Oid                     staop1;
-       Oid                     staop2;
-       Oid                     staop3;
-       Oid                     staop4;
-       Oid                     staop5;
+       Oid                     staop1 BKI_LOOKUP_OPT(pg_operator);
+       Oid                     staop2 BKI_LOOKUP_OPT(pg_operator);
+       Oid                     staop3 BKI_LOOKUP_OPT(pg_operator);
+       Oid                     staop4 BKI_LOOKUP_OPT(pg_operator);
+       Oid                     staop5 BKI_LOOKUP_OPT(pg_operator);
 
-       Oid                     stacoll1;
-       Oid                     stacoll2;
-       Oid                     stacoll3;
-       Oid                     stacoll4;
-       Oid                     stacoll5;
+       Oid                     stacoll1 BKI_LOOKUP_OPT(pg_collation);
+       Oid                     stacoll2 BKI_LOOKUP_OPT(pg_collation);
+       Oid                     stacoll3 BKI_LOOKUP_OPT(pg_collation);
+       Oid                     stacoll4 BKI_LOOKUP_OPT(pg_collation);
+       Oid                     stacoll5 BKI_LOOKUP_OPT(pg_collation);
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        float4          stanumbers1[1];
@@ -138,6 +139,8 @@ DECLARE_TOAST(pg_statistic, 2840, 2841);
 DECLARE_UNIQUE_INDEX_PKEY(pg_statistic_relid_att_inh_index, 2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops, stainherit bool_ops));
 #define StatisticRelidAttnumInhIndexId 2696
 
+DECLARE_FOREIGN_KEY((starelid, staattnum), pg_attribute, (attrelid, attnum));
+
 #ifdef EXPOSE_TO_CLIENT_CODE
 
 /*
index 10f52f912cb7f464768541f087813511d5e53eb4..29649f58143b8f431d86291283bd6c4a0f701e78 100644 (file)
@@ -34,13 +34,15 @@ CATALOG(pg_statistic_ext,3381,StatisticExtRelationId)
 {
        Oid                     oid;                    /* oid */
 
-       Oid                     stxrelid;               /* relation containing attributes */
+       Oid                     stxrelid BKI_LOOKUP(pg_class);  /* relation containing
+                                                                                                * attributes */
 
        /* These two fields form the unique key for the entry: */
        NameData        stxname;                /* statistics object name */
-       Oid                     stxnamespace;   /* OID of statistics object's namespace */
+       Oid                     stxnamespace BKI_LOOKUP(pg_namespace);  /* OID of statistics
+                                                                                                                * object's namespace */
 
-       Oid                     stxowner;               /* statistics object's owner */
+       Oid                     stxowner BKI_LOOKUP(pg_authid); /* statistics object's owner */
        int32           stxstattarget BKI_DEFAULT(-1);  /* statistics target */
 
        /*
@@ -72,6 +74,8 @@ DECLARE_UNIQUE_INDEX(pg_statistic_ext_name_index, 3997, on pg_statistic_ext usin
 DECLARE_INDEX(pg_statistic_ext_relid_index, 3379, on pg_statistic_ext using btree(stxrelid oid_ops));
 #define StatisticExtRelidIndexId 3379
 
+DECLARE_ARRAY_FOREIGN_KEY((stxrelid, stxkeys), pg_attribute, (attrelid, attnum));
+
 #ifdef EXPOSE_TO_CLIENT_CODE
 
 #define STATS_EXT_NDISTINCT                    'd'
index 6f7a36c14181a9cf73700f2f682906a55c814f66..2f2577c21887754c178c7996c0289769de690ab4 100644 (file)
@@ -30,7 +30,8 @@
  */
 CATALOG(pg_statistic_ext_data,3429,StatisticExtDataRelationId)
 {
-       Oid                     stxoid;                 /* statistics object this data is for */
+       Oid                     stxoid BKI_LOOKUP(pg_statistic_ext);    /* statistics object
+                                                                                                                * this data is for */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
 
index 4e44c291496319a9001d83de28d803f9c142368c..a5d6efdf205b976580383d1c215a0b36e40ba51f 100644 (file)
@@ -40,10 +40,11 @@ CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROW
 {
        Oid                     oid;                    /* oid */
 
-       Oid                     subdbid;                /* Database the subscription is in. */
+       Oid                     subdbid BKI_LOOKUP(pg_database);        /* Database the
+                                                                                                        * subscription is in. */
        NameData        subname;                /* Name of the subscription */
 
-       Oid                     subowner;               /* Owner of the subscription */
+       Oid                     subowner BKI_LOOKUP(pg_authid); /* Owner of the subscription */
 
        bool            subenabled;             /* True if the subscription is enabled (the
                                                                 * worker should be running) */
index ab1202cf9bff8c89881a5f595f635ff1f0f28f97..2bea2c52aa760efa1cde938bd8eff2e87eb744b3 100644 (file)
@@ -30,8 +30,8 @@
  */
 CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId)
 {
-       Oid                     srsubid;                /* Oid of subscription */
-       Oid                     srrelid;                /* Oid of relation */
+       Oid                     srsubid BKI_LOOKUP(pg_subscription);    /* Oid of subscription */
+       Oid                     srrelid BKI_LOOKUP(pg_class);   /* Oid of relation */
        char            srsubstate;             /* state of the relation in subscription */
 
        /*
index 212a0ad07fb5fc1bd31c9a5a7b1bc5f3542afc29..bf0d81d3061a88857acaffc6105ce8b3d89752d1 100644 (file)
 [
 
 { oid => '1663', oid_symbol => 'DEFAULTTABLESPACE_OID',
-  spcname => 'pg_default', spcowner => 'PGUID', spcacl => '_null_',
-  spcoptions => '_null_' },
+  spcname => 'pg_default', spcacl => '_null_', spcoptions => '_null_' },
 { oid => '1664', oid_symbol => 'GLOBALTABLESPACE_OID',
-  spcname => 'pg_global', spcowner => 'PGUID', spcacl => '_null_',
-  spcoptions => '_null_' },
+  spcname => 'pg_global', spcacl => '_null_', spcoptions => '_null_' },
 
 ]
index 6a6c66a61c84856a16048d8996a1142f1d0c941c..ed38e6950ddcb468145444ace67db4a7f59e5c70 100644 (file)
@@ -30,7 +30,7 @@ CATALOG(pg_tablespace,1213,TableSpaceRelationId) BKI_SHARED_RELATION
 {
        Oid                     oid;                    /* oid */
        NameData        spcname;                /* tablespace name */
-       Oid                     spcowner;               /* owner of tablespace */
+       Oid                     spcowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);      /* owner of tablespace */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        aclitem         spcacl[1];              /* access permissions */
index ad25db1841199bdf47d4bea9dbac0cd10396610e..d60324613857f07c981d79a7901198031e199c48 100644 (file)
 CATALOG(pg_transform,3576,TransformRelationId)
 {
        Oid                     oid;                    /* oid */
-       Oid                     trftype;
-       Oid                     trflang;
-       regproc         trffromsql;
-       regproc         trftosql;
+       Oid                     trftype BKI_LOOKUP(pg_type);
+       Oid                     trflang BKI_LOOKUP(pg_language);
+       regproc         trffromsql BKI_LOOKUP_OPT(pg_proc);
+       regproc         trftosql BKI_LOOKUP_OPT(pg_proc);
 } FormData_pg_transform;
 
 /* ----------------
index 55111ed864e9b4f9ba0cbce2040b441d2723fab7..2e3d2338763f3ea8ea3b92217551e4328d391b2a 100644 (file)
 CATALOG(pg_trigger,2620,TriggerRelationId)
 {
        Oid                     oid;                    /* oid */
-       Oid                     tgrelid;                /* relation trigger is attached to */
-       Oid                     tgparentid;             /* OID of parent trigger, if any */
+       Oid                     tgrelid BKI_LOOKUP(pg_class);   /* relation trigger is
+                                                                                                * attached to */
+       Oid                     tgparentid BKI_LOOKUP_OPT(pg_trigger);  /* OID of parent
+                                                                                                                * trigger, if any */
        NameData        tgname;                 /* trigger's name */
-       Oid                     tgfoid;                 /* OID of function to be called */
+       Oid                     tgfoid BKI_LOOKUP(pg_proc); /* OID of function to be called */
        int16           tgtype;                 /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT,
                                                                 * ROW/STATEMENT; see below */
        char            tgenabled;              /* trigger's firing configuration WRT
                                                                 * session_replication_role */
        bool            tgisinternal;   /* trigger is system-generated */
-       Oid                     tgconstrrelid;  /* constraint's FROM table, if any */
-       Oid                     tgconstrindid;  /* constraint's supporting index, if any */
-       Oid                     tgconstraint;   /* associated pg_constraint entry, if any */
+       Oid                     tgconstrrelid BKI_LOOKUP_OPT(pg_class); /* constraint's FROM
+                                                                                                                * table, if any */
+       Oid                     tgconstrindid BKI_LOOKUP_OPT(pg_class); /* constraint's
+                                                                                                                * supporting index, if
+                                                                                                                * any */
+       Oid                     tgconstraint BKI_LOOKUP_OPT(pg_constraint); /* associated
+                                                                                                                        * pg_constraint entry,
+                                                                                                                        * if any */
        bool            tgdeferrable;   /* constraint trigger is deferrable */
        bool            tginitdeferred; /* constraint trigger is deferred initially */
        int16           tgnargs;                /* # of extra arguments in tgargs */
@@ -81,6 +88,8 @@ DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, on pg_trigger using
 DECLARE_UNIQUE_INDEX_PKEY(pg_trigger_oid_index, 2702, on pg_trigger using btree(oid oid_ops));
 #define TriggerOidIndexId  2702
 
+DECLARE_ARRAY_FOREIGN_KEY((tgrelid, tgattr), pg_attribute, (attrelid, attnum));
+
 #ifdef EXPOSE_TO_CLIENT_CODE
 
 /* Bits within tgtype */
index 02ef1a1554404d44dc6d445eca165b93b09706e6..e705899b179e04ba1fec61d71410b91a345445ba 100644 (file)
@@ -36,10 +36,10 @@ CATALOG(pg_ts_config,3602,TSConfigRelationId)
        NameData        cfgname;
 
        /* name space */
-       Oid                     cfgnamespace BKI_DEFAULT(PGNSP);
+       Oid                     cfgnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* owner */
-       Oid                     cfgowner BKI_DEFAULT(PGUID);
+       Oid                     cfgowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* OID of parser */
        Oid                     cfgparser BKI_LOOKUP(pg_ts_parser);
index bfe3378ff893c5b2a17482e9fa1af8464d3d3897..57f626e7b592cadf202d3d0a968ff84aad8bd24b 100644 (file)
@@ -35,10 +35,10 @@ CATALOG(pg_ts_dict,3600,TSDictionaryRelationId)
        NameData        dictname;
 
        /* name space */
-       Oid                     dictnamespace BKI_DEFAULT(PGNSP);
+       Oid                     dictnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* owner */
-       Oid                     dictowner BKI_DEFAULT(PGUID);
+       Oid                     dictowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /* dictionary's template */
        Oid                     dicttemplate BKI_LOOKUP(pg_ts_template);
index f9f22716fd4704cca41b003041a355b3ba96fee5..e0d705fd9ae57d1e189eb62e97087983b6db3c9a 100644 (file)
@@ -34,7 +34,7 @@ CATALOG(pg_ts_parser,3601,TSParserRelationId)
        NameData        prsname;
 
        /* name space */
-       Oid                     prsnamespace BKI_DEFAULT(PGNSP);
+       Oid                     prsnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* init parsing session */
        regproc         prsstart BKI_LOOKUP(pg_proc);
@@ -46,7 +46,7 @@ CATALOG(pg_ts_parser,3601,TSParserRelationId)
        regproc         prsend BKI_LOOKUP(pg_proc);
 
        /* return data for headline creation */
-       regproc         prsheadline BKI_LOOKUP(pg_proc);
+       regproc         prsheadline BKI_LOOKUP_OPT(pg_proc);
 
        /* return descriptions of lexeme's types */
        regproc         prslextype BKI_LOOKUP(pg_proc);
index ae91922688989284aab7966018f24824aadc5e6a..2ee1ae4e85f62ad2029bf7a55a1764ea53f66363 100644 (file)
@@ -34,10 +34,10 @@ CATALOG(pg_ts_template,3764,TSTemplateRelationId)
        NameData        tmplname;
 
        /* name space */
-       Oid                     tmplnamespace BKI_DEFAULT(PGNSP);
+       Oid                     tmplnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* initialization method of dict (may be 0) */
-       regproc         tmplinit BKI_LOOKUP(pg_proc);
+       regproc         tmplinit BKI_LOOKUP_OPT(pg_proc);
 
        /* base method of dictionary */
        regproc         tmpllexize BKI_LOOKUP(pg_proc);
index 0d6981bc879d14a54495c002612d59c81e2cb8e7..1ec860670381155bac4be5e8c5abcebca5342c72 100644 (file)
@@ -41,10 +41,10 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
        NameData        typname;
 
        /* OID of namespace containing this type */
-       Oid                     typnamespace BKI_DEFAULT(PGNSP);
+       Oid                     typnamespace BKI_DEFAULT(PGNSP) BKI_LOOKUP(pg_namespace);
 
        /* type owner */
-       Oid                     typowner BKI_DEFAULT(PGUID);
+       Oid                     typowner BKI_DEFAULT(PGUID) BKI_LOOKUP(pg_authid);
 
        /*
         * For a fixed-size type, typlen is the number of bytes we use to
@@ -98,7 +98,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
        char            typdelim BKI_DEFAULT(',');
 
        /* associated pg_class OID if a composite type, else 0 */
-       Oid                     typrelid BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP(pg_class);
+       Oid                     typrelid BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
        /*
         * Type-specific subscripting handler.  If typsubscript is 0, it means
@@ -106,7 +106,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
         * of the system deem types to be "true" array types only if their
         * typsubscript is array_subscript_handler.
         */
-       regproc         typsubscript BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_subscript_handler) BKI_LOOKUP(pg_proc);
+       regproc         typsubscript BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_subscript_handler) BKI_LOOKUP_OPT(pg_proc);
 
        /*
         * If typelem is not 0 then it identifies another row in pg_type, defining
@@ -117,13 +117,13 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
         * of the element type in this type; so DDL changes on the element type
         * might be restricted by the presence of this type.
         */
-       Oid                     typelem BKI_DEFAULT(0) BKI_LOOKUP(pg_type);
+       Oid                     typelem BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 
        /*
         * If there is a "true" array type having this type as element type,
         * typarray links to it.  Zero if no associated "true" array type.
         */
-       Oid                     typarray BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP(pg_type);
+       Oid                     typarray BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 
        /*
         * I/O conversion procedures for the datatype.
@@ -134,19 +134,19 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
        regproc         typoutput BKI_ARRAY_DEFAULT(array_out) BKI_LOOKUP(pg_proc);
 
        /* binary format (optional) */
-       regproc         typreceive BKI_ARRAY_DEFAULT(array_recv) BKI_LOOKUP(pg_proc);
-       regproc         typsend BKI_ARRAY_DEFAULT(array_send) BKI_LOOKUP(pg_proc);
+       regproc         typreceive BKI_ARRAY_DEFAULT(array_recv) BKI_LOOKUP_OPT(pg_proc);
+       regproc         typsend BKI_ARRAY_DEFAULT(array_send) BKI_LOOKUP_OPT(pg_proc);
 
        /*
         * I/O functions for optional type modifiers.
         */
-       regproc         typmodin BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
-       regproc         typmodout BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+       regproc         typmodin BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
+       regproc         typmodout BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);
 
        /*
         * Custom ANALYZE procedure for the datatype (0 selects the default).
         */
-       regproc         typanalyze BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_typanalyze) BKI_LOOKUP(pg_proc);
+       regproc         typanalyze BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_typanalyze) BKI_LOOKUP_OPT(pg_proc);
 
        /* ----------------
         * typalign is the alignment required when storing a value of this
@@ -205,7 +205,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
         * Domains use typbasetype to show the base (or domain) type that the
         * domain is based on.  Zero if the type is not a domain.
         */
-       Oid                     typbasetype BKI_DEFAULT(0);
+       Oid                     typbasetype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);
 
        /*
         * Domains use typtypmod to record the typmod to be applied to their base
@@ -225,7 +225,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
         * DEFAULT_COLLATION_OID) for collatable base types, possibly some other
         * OID for domains over collatable types
         */
-       Oid                     typcollation BKI_DEFAULT(0) BKI_LOOKUP(pg_collation);
+       Oid                     typcollation BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_collation);
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
 
index cabca048a928b7d866b5f47cd47eb16c2cec15b0..d440c67da191fecdc58434364f4742f61a2233d2 100644 (file)
@@ -29,9 +29,11 @@ CATALOG(pg_user_mapping,1418,UserMappingRelationId)
 {
        Oid                     oid;                    /* oid */
 
-       Oid                     umuser;                 /* Id of the user, InvalidOid if PUBLIC is
-                                                                * wanted */
-       Oid                     umserver;               /* server of this mapping */
+       Oid                     umuser BKI_LOOKUP_OPT(pg_authid);       /* Id of the user,
+                                                                                                        * InvalidOid if PUBLIC is
+                                                                                                        * wanted */
+       Oid                     umserver BKI_LOOKUP(pg_foreign_server); /* server of this
+                                                                                                                * mapping */
 
 #ifdef CATALOG_VARLEN                  /* variable-length fields start here */
        text            umoptions[1];   /* user mapping options */
index 4731dacfbf429eb6446c5a34030cbfe460a5ebe1..50d046d3ef1ad5098d1f1dfddbeb59b55b9f9eed 100644 (file)
 --
--- This is created by pgsql/src/tools/findoidjoins/make_oidjoins_check
+-- Verify system catalog foreign key relationships
 --
-SELECT ctid, aggfnoid
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggfnoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggfnoid);
- ctid | aggfnoid 
-------+----------
-(0 rows)
-
-SELECT ctid, aggtransfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggtransfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggtransfn);
- ctid | aggtransfn 
-------+------------
-(0 rows)
-
-SELECT ctid, aggfinalfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggfinalfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggfinalfn);
- ctid | aggfinalfn 
-------+------------
-(0 rows)
-
-SELECT ctid, aggcombinefn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggcombinefn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggcombinefn);
- ctid | aggcombinefn 
-------+--------------
-(0 rows)
-
-SELECT ctid, aggserialfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggserialfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggserialfn);
- ctid | aggserialfn 
-------+-------------
-(0 rows)
-
-SELECT ctid, aggdeserialfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggdeserialfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggdeserialfn);
- ctid | aggdeserialfn 
-------+---------------
-(0 rows)
-
-SELECT ctid, aggmtransfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggmtransfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggmtransfn);
- ctid | aggmtransfn 
-------+-------------
-(0 rows)
-
-SELECT ctid, aggminvtransfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggminvtransfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggminvtransfn);
- ctid | aggminvtransfn 
-------+----------------
-(0 rows)
-
-SELECT ctid, aggmfinalfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggmfinalfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggmfinalfn);
- ctid | aggmfinalfn 
-------+-------------
-(0 rows)
-
-SELECT ctid, aggsortop
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggsortop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.aggsortop);
- ctid | aggsortop 
-------+-----------
-(0 rows)
-
-SELECT ctid, aggtranstype
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggtranstype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.aggtranstype);
- ctid | aggtranstype 
-------+--------------
-(0 rows)
-
-SELECT ctid, aggmtranstype
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggmtranstype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.aggmtranstype);
- ctid | aggmtranstype 
-------+---------------
-(0 rows)
-
-SELECT ctid, amhandler
-FROM   pg_catalog.pg_am fk
-WHERE  amhandler != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amhandler);
- ctid | amhandler 
-------+-----------
-(0 rows)
-
-SELECT ctid, amopfamily
-FROM   pg_catalog.pg_amop fk
-WHERE  amopfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amopfamily);
- ctid | amopfamily 
-------+------------
-(0 rows)
-
-SELECT ctid, amoplefttype
-FROM   pg_catalog.pg_amop fk
-WHERE  amoplefttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoplefttype);
- ctid | amoplefttype 
-------+--------------
-(0 rows)
-
-SELECT ctid, amoprighttype
-FROM   pg_catalog.pg_amop fk
-WHERE  amoprighttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoprighttype);
- ctid | amoprighttype 
-------+---------------
-(0 rows)
-
-SELECT ctid, amopopr
-FROM   pg_catalog.pg_amop fk
-WHERE  amopopr != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.amopopr);
- ctid | amopopr 
-------+---------
-(0 rows)
-
-SELECT ctid, amopmethod
-FROM   pg_catalog.pg_amop fk
-WHERE  amopmethod != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.amopmethod);
- ctid | amopmethod 
-------+------------
-(0 rows)
-
-SELECT ctid, amopsortfamily
-FROM   pg_catalog.pg_amop fk
-WHERE  amopsortfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amopsortfamily);
- ctid | amopsortfamily 
-------+----------------
-(0 rows)
-
-SELECT ctid, amprocfamily
-FROM   pg_catalog.pg_amproc fk
-WHERE  amprocfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amprocfamily);
- ctid | amprocfamily 
-------+--------------
-(0 rows)
-
-SELECT ctid, amproclefttype
-FROM   pg_catalog.pg_amproc fk
-WHERE  amproclefttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amproclefttype);
- ctid | amproclefttype 
-------+----------------
-(0 rows)
-
-SELECT ctid, amprocrighttype
-FROM   pg_catalog.pg_amproc fk
-WHERE  amprocrighttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocrighttype);
- ctid | amprocrighttype 
-------+-----------------
-(0 rows)
-
-SELECT ctid, amproc
-FROM   pg_catalog.pg_amproc fk
-WHERE  amproc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amproc);
- ctid | amproc 
-------+--------
-(0 rows)
-
-SELECT ctid, adrelid
-FROM   pg_catalog.pg_attrdef fk
-WHERE  adrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.adrelid);
- ctid | adrelid 
-------+---------
-(0 rows)
-
-SELECT ctid, attrelid
-FROM   pg_catalog.pg_attribute fk
-WHERE  attrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.attrelid);
- ctid | attrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, atttypid
-FROM   pg_catalog.pg_attribute fk
-WHERE  atttypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.atttypid);
- ctid | atttypid 
-------+----------
-(0 rows)
-
-SELECT ctid, attcollation
-FROM   pg_catalog.pg_attribute fk
-WHERE  attcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.attcollation);
- ctid | attcollation 
-------+--------------
-(0 rows)
-
-SELECT ctid, roleid
-FROM   pg_catalog.pg_auth_members fk
-WHERE  roleid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.roleid);
- ctid | roleid 
-------+--------
-(0 rows)
-
-SELECT ctid, member
-FROM   pg_catalog.pg_auth_members fk
-WHERE  member != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.member);
- ctid | member 
-------+--------
-(0 rows)
-
-SELECT ctid, grantor
-FROM   pg_catalog.pg_auth_members fk
-WHERE  grantor != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.grantor);
- ctid | grantor 
-------+---------
-(0 rows)
-
-SELECT ctid, castsource
-FROM   pg_catalog.pg_cast fk
-WHERE  castsource != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.castsource);
- ctid | castsource 
-------+------------
-(0 rows)
-
-SELECT ctid, casttarget
-FROM   pg_catalog.pg_cast fk
-WHERE  casttarget != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.casttarget);
- ctid | casttarget 
-------+------------
-(0 rows)
-
-SELECT ctid, castfunc
-FROM   pg_catalog.pg_cast fk
-WHERE  castfunc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.castfunc);
- ctid | castfunc 
-------+----------
-(0 rows)
-
-SELECT ctid, relnamespace
-FROM   pg_catalog.pg_class fk
-WHERE  relnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.relnamespace);
- ctid | relnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, reltype
-FROM   pg_catalog.pg_class fk
-WHERE  reltype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.reltype);
- ctid | reltype 
-------+---------
-(0 rows)
-
-SELECT ctid, reloftype
-FROM   pg_catalog.pg_class fk
-WHERE  reloftype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.reloftype);
- ctid | reloftype 
-------+-----------
-(0 rows)
-
-SELECT ctid, relowner
-FROM   pg_catalog.pg_class fk
-WHERE  relowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.relowner);
- ctid | relowner 
-------+----------
-(0 rows)
-
-SELECT ctid, relam
-FROM   pg_catalog.pg_class fk
-WHERE  relam != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.relam);
- ctid | relam 
-------+-------
-(0 rows)
-
-SELECT ctid, reltablespace
-FROM   pg_catalog.pg_class fk
-WHERE  reltablespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_tablespace pk WHERE pk.oid = fk.reltablespace);
- ctid | reltablespace 
-------+---------------
-(0 rows)
-
-SELECT ctid, reltoastrelid
-FROM   pg_catalog.pg_class fk
-WHERE  reltoastrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.reltoastrelid);
- ctid | reltoastrelid 
-------+---------------
-(0 rows)
-
-SELECT ctid, collnamespace
-FROM   pg_catalog.pg_collation fk
-WHERE  collnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.collnamespace);
- ctid | collnamespace 
-------+---------------
-(0 rows)
-
-SELECT ctid, collowner
-FROM   pg_catalog.pg_collation fk
-WHERE  collowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.collowner);
- ctid | collowner 
-------+-----------
-(0 rows)
-
-SELECT ctid, connamespace
-FROM   pg_catalog.pg_constraint fk
-WHERE  connamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.connamespace);
- ctid | connamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, conrelid
-FROM   pg_catalog.pg_constraint fk
-WHERE  conrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.conrelid);
- ctid | conrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, contypid
-FROM   pg_catalog.pg_constraint fk
-WHERE  contypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.contypid);
- ctid | contypid 
-------+----------
-(0 rows)
-
-SELECT ctid, conindid
-FROM   pg_catalog.pg_constraint fk
-WHERE  conindid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.conindid);
- ctid | conindid 
-------+----------
-(0 rows)
-
-SELECT ctid, conparentid
-FROM   pg_catalog.pg_constraint fk
-WHERE  conparentid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_constraint pk WHERE pk.oid = fk.conparentid);
- ctid | conparentid 
-------+-------------
-(0 rows)
-
-SELECT ctid, confrelid
-FROM   pg_catalog.pg_constraint fk
-WHERE  confrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.confrelid);
- ctid | confrelid 
-------+-----------
-(0 rows)
-
-SELECT ctid, connamespace
-FROM   pg_catalog.pg_conversion fk
-WHERE  connamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.connamespace);
- ctid | connamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, conowner
-FROM   pg_catalog.pg_conversion fk
-WHERE  conowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.conowner);
- ctid | conowner 
-------+----------
-(0 rows)
-
-SELECT ctid, conproc
-FROM   pg_catalog.pg_conversion fk
-WHERE  conproc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.conproc);
- ctid | conproc 
-------+---------
-(0 rows)
-
-SELECT ctid, datdba
-FROM   pg_catalog.pg_database fk
-WHERE  datdba != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.datdba);
- ctid | datdba 
-------+--------
-(0 rows)
-
-SELECT ctid, dattablespace
-FROM   pg_catalog.pg_database fk
-WHERE  dattablespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_tablespace pk WHERE pk.oid = fk.dattablespace);
- ctid | dattablespace 
-------+---------------
-(0 rows)
-
-SELECT ctid, setdatabase
-FROM   pg_catalog.pg_db_role_setting fk
-WHERE  setdatabase != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_database pk WHERE pk.oid = fk.setdatabase);
- ctid | setdatabase 
-------+-------------
-(0 rows)
-
-SELECT ctid, classid
-FROM   pg_catalog.pg_depend fk
-WHERE  classid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classid);
- ctid | classid 
-------+---------
-(0 rows)
-
-SELECT ctid, refclassid
-FROM   pg_catalog.pg_depend fk
-WHERE  refclassid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.refclassid);
- ctid | refclassid 
-------+------------
-(0 rows)
-
-SELECT ctid, classoid
-FROM   pg_catalog.pg_description fk
-WHERE  classoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid);
- ctid | classoid 
-------+----------
-(0 rows)
-
-SELECT ctid, enumtypid
-FROM   pg_catalog.pg_enum fk
-WHERE  enumtypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.enumtypid);
- ctid | enumtypid 
-------+-----------
-(0 rows)
-
-SELECT ctid, extowner
-FROM   pg_catalog.pg_extension fk
-WHERE  extowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.extowner);
- ctid | extowner 
-------+----------
-(0 rows)
-
-SELECT ctid, extnamespace
-FROM   pg_catalog.pg_extension fk
-WHERE  extnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.extnamespace);
- ctid | extnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, fdwowner
-FROM   pg_catalog.pg_foreign_data_wrapper fk
-WHERE  fdwowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.fdwowner);
- ctid | fdwowner 
-------+----------
-(0 rows)
-
-SELECT ctid, srvowner
-FROM   pg_catalog.pg_foreign_server fk
-WHERE  srvowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.srvowner);
- ctid | srvowner 
-------+----------
-(0 rows)
-
-SELECT ctid, srvfdw
-FROM   pg_catalog.pg_foreign_server fk
-WHERE  srvfdw != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_foreign_data_wrapper pk WHERE pk.oid = fk.srvfdw);
- ctid | srvfdw 
-------+--------
-(0 rows)
-
-SELECT ctid, indexrelid
-FROM   pg_catalog.pg_index fk
-WHERE  indexrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.indexrelid);
- ctid | indexrelid 
-------+------------
-(0 rows)
-
-SELECT ctid, indrelid
-FROM   pg_catalog.pg_index fk
-WHERE  indrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.indrelid);
- ctid | indrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, inhrelid
-FROM   pg_catalog.pg_inherits fk
-WHERE  inhrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.inhrelid);
- ctid | inhrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, inhparent
-FROM   pg_catalog.pg_inherits fk
-WHERE  inhparent != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.inhparent);
- ctid | inhparent 
-------+-----------
-(0 rows)
-
-SELECT ctid, classoid
-FROM   pg_catalog.pg_init_privs fk
-WHERE  classoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid);
- ctid | classoid 
-------+----------
-(0 rows)
-
-SELECT ctid, lanowner
-FROM   pg_catalog.pg_language fk
-WHERE  lanowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.lanowner);
- ctid | lanowner 
-------+----------
-(0 rows)
-
-SELECT ctid, lanplcallfoid
-FROM   pg_catalog.pg_language fk
-WHERE  lanplcallfoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.lanplcallfoid);
- ctid | lanplcallfoid 
-------+---------------
-(0 rows)
-
-SELECT ctid, laninline
-FROM   pg_catalog.pg_language fk
-WHERE  laninline != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.laninline);
- ctid | laninline 
-------+-----------
-(0 rows)
-
-SELECT ctid, lanvalidator
-FROM   pg_catalog.pg_language fk
-WHERE  lanvalidator != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.lanvalidator);
- ctid | lanvalidator 
-------+--------------
-(0 rows)
-
-SELECT ctid, loid
-FROM   pg_catalog.pg_largeobject fk
-WHERE  loid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject_metadata pk WHERE pk.oid = fk.loid);
- ctid | loid 
-------+------
-(0 rows)
-
-SELECT ctid, lomowner
-FROM   pg_catalog.pg_largeobject_metadata fk
-WHERE  lomowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.lomowner);
- ctid | lomowner 
-------+----------
-(0 rows)
-
-SELECT ctid, nspowner
-FROM   pg_catalog.pg_namespace fk
-WHERE  nspowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.nspowner);
- ctid | nspowner 
-------+----------
-(0 rows)
-
-SELECT ctid, opcmethod
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcmethod != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opcmethod);
- ctid | opcmethod 
-------+-----------
-(0 rows)
-
-SELECT ctid, opcnamespace
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opcnamespace);
- ctid | opcnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, opcowner
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opcowner);
- ctid | opcowner 
-------+----------
-(0 rows)
-
-SELECT ctid, opcfamily
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.opcfamily);
- ctid | opcfamily 
-------+-----------
-(0 rows)
-
-SELECT ctid, opcintype
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcintype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opcintype);
- ctid | opcintype 
-------+-----------
-(0 rows)
-
-SELECT ctid, opckeytype
-FROM   pg_catalog.pg_opclass fk
-WHERE  opckeytype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opckeytype);
- ctid | opckeytype 
-------+------------
-(0 rows)
-
-SELECT ctid, oprnamespace
-FROM   pg_catalog.pg_operator fk
-WHERE  oprnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.oprnamespace);
- ctid | oprnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, oprowner
-FROM   pg_catalog.pg_operator fk
-WHERE  oprowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.oprowner);
- ctid | oprowner 
-------+----------
-(0 rows)
-
-SELECT ctid, oprleft
-FROM   pg_catalog.pg_operator fk
-WHERE  oprleft != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.oprleft);
- ctid | oprleft 
-------+---------
-(0 rows)
-
-SELECT ctid, oprright
-FROM   pg_catalog.pg_operator fk
-WHERE  oprright != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.oprright);
- ctid | oprright 
-------+----------
-(0 rows)
-
-SELECT ctid, oprresult
-FROM   pg_catalog.pg_operator fk
-WHERE  oprresult != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.oprresult);
- ctid | oprresult 
-------+-----------
-(0 rows)
-
-SELECT ctid, oprcom
-FROM   pg_catalog.pg_operator fk
-WHERE  oprcom != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom);
- ctid | oprcom 
-------+--------
-(0 rows)
-
-SELECT ctid, oprnegate
-FROM   pg_catalog.pg_operator fk
-WHERE  oprnegate != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate);
- ctid | oprnegate 
-------+-----------
-(0 rows)
-
-SELECT ctid, oprcode
-FROM   pg_catalog.pg_operator fk
-WHERE  oprcode != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprcode);
- ctid | oprcode 
-------+---------
-(0 rows)
-
-SELECT ctid, oprrest
-FROM   pg_catalog.pg_operator fk
-WHERE  oprrest != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprrest);
- ctid | oprrest 
-------+---------
-(0 rows)
-
-SELECT ctid, oprjoin
-FROM   pg_catalog.pg_operator fk
-WHERE  oprjoin != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprjoin);
- ctid | oprjoin 
-------+---------
-(0 rows)
-
-SELECT ctid, opfmethod
-FROM   pg_catalog.pg_opfamily fk
-WHERE  opfmethod != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opfmethod);
- ctid | opfmethod 
-------+-----------
-(0 rows)
-
-SELECT ctid, opfnamespace
-FROM   pg_catalog.pg_opfamily fk
-WHERE  opfnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opfnamespace);
- ctid | opfnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, opfowner
-FROM   pg_catalog.pg_opfamily fk
-WHERE  opfowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opfowner);
- ctid | opfowner 
-------+----------
-(0 rows)
-
-SELECT ctid, partrelid
-FROM   pg_catalog.pg_partitioned_table fk
-WHERE  partrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partrelid);
- ctid | partrelid 
-------+-----------
-(0 rows)
-
-SELECT ctid, partdefid
-FROM   pg_catalog.pg_partitioned_table fk
-WHERE  partdefid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partdefid);
- ctid | partdefid 
-------+-----------
-(0 rows)
-
-SELECT ctid, polrelid
-FROM   pg_catalog.pg_policy fk
-WHERE  polrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.polrelid);
- ctid | polrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, pronamespace
-FROM   pg_catalog.pg_proc fk
-WHERE  pronamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.pronamespace);
- ctid | pronamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, proowner
-FROM   pg_catalog.pg_proc fk
-WHERE  proowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.proowner);
- ctid | proowner 
-------+----------
-(0 rows)
-
-SELECT ctid, prolang
-FROM   pg_catalog.pg_proc fk
-WHERE  prolang != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_language pk WHERE pk.oid = fk.prolang);
- ctid | prolang 
-------+---------
-(0 rows)
-
-SELECT ctid, provariadic
-FROM   pg_catalog.pg_proc fk
-WHERE  provariadic != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.provariadic);
- ctid | provariadic 
-------+-------------
-(0 rows)
-
-SELECT ctid, prosupport
-FROM   pg_catalog.pg_proc fk
-WHERE  prosupport != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prosupport);
- ctid | prosupport 
-------+------------
-(0 rows)
-
-SELECT ctid, prorettype
-FROM   pg_catalog.pg_proc fk
-WHERE  prorettype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.prorettype);
- ctid | prorettype 
-------+------------
-(0 rows)
-
-SELECT ctid, rngtypid
-FROM   pg_catalog.pg_range fk
-WHERE  rngtypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.rngtypid);
- ctid | rngtypid 
-------+----------
-(0 rows)
-
-SELECT ctid, rngsubtype
-FROM   pg_catalog.pg_range fk
-WHERE  rngsubtype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.rngsubtype);
- ctid | rngsubtype 
-------+------------
-(0 rows)
-
-SELECT ctid, rngcollation
-FROM   pg_catalog.pg_range fk
-WHERE  rngcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.rngcollation);
- ctid | rngcollation 
-------+--------------
-(0 rows)
-
-SELECT ctid, rngsubopc
-FROM   pg_catalog.pg_range fk
-WHERE  rngsubopc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.rngsubopc);
- ctid | rngsubopc 
-------+-----------
-(0 rows)
-
-SELECT ctid, rngcanonical
-FROM   pg_catalog.pg_range fk
-WHERE  rngcanonical != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.rngcanonical);
- ctid | rngcanonical 
-------+--------------
-(0 rows)
-
-SELECT ctid, rngsubdiff
-FROM   pg_catalog.pg_range fk
-WHERE  rngsubdiff != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.rngsubdiff);
- ctid | rngsubdiff 
-------+------------
-(0 rows)
-
-SELECT ctid, ev_class
-FROM   pg_catalog.pg_rewrite fk
-WHERE  ev_class != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.ev_class);
- ctid | ev_class 
-------+----------
-(0 rows)
-
-SELECT ctid, seqrelid
-FROM   pg_catalog.pg_sequence fk
-WHERE  seqrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.seqrelid);
- ctid | seqrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, seqtypid
-FROM   pg_catalog.pg_sequence fk
-WHERE  seqtypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.seqtypid);
- ctid | seqtypid 
-------+----------
-(0 rows)
-
-SELECT ctid, refclassid
-FROM   pg_catalog.pg_shdepend fk
-WHERE  refclassid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.refclassid);
- ctid | refclassid 
-------+------------
-(0 rows)
-
-SELECT ctid, classoid
-FROM   pg_catalog.pg_shdescription fk
-WHERE  classoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid);
- ctid | classoid 
-------+----------
-(0 rows)
-
-SELECT ctid, starelid
-FROM   pg_catalog.pg_statistic fk
-WHERE  starelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.starelid);
- ctid | starelid 
-------+----------
-(0 rows)
-
-SELECT ctid, staop1
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop1 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop1);
- ctid | staop1 
-------+--------
-(0 rows)
-
-SELECT ctid, staop2
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop2 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop2);
- ctid | staop2 
-------+--------
-(0 rows)
-
-SELECT ctid, staop3
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop3 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop3);
- ctid | staop3 
-------+--------
-(0 rows)
-
-SELECT ctid, staop4
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop4 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop4);
- ctid | staop4 
-------+--------
-(0 rows)
-
-SELECT ctid, staop5
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop5 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop5);
- ctid | staop5 
-------+--------
-(0 rows)
-
-SELECT ctid, stacoll1
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll1 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll1);
- ctid | stacoll1 
-------+----------
-(0 rows)
-
-SELECT ctid, stacoll2
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll2 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll2);
- ctid | stacoll2 
-------+----------
-(0 rows)
-
-SELECT ctid, stacoll3
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll3 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll3);
- ctid | stacoll3 
-------+----------
-(0 rows)
-
-SELECT ctid, stacoll4
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll4 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll4);
- ctid | stacoll4 
-------+----------
-(0 rows)
-
-SELECT ctid, stacoll5
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll5 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll5);
- ctid | stacoll5 
-------+----------
-(0 rows)
-
-SELECT ctid, stxrelid
-FROM   pg_catalog.pg_statistic_ext fk
-WHERE  stxrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.stxrelid);
- ctid | stxrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, stxnamespace
-FROM   pg_catalog.pg_statistic_ext fk
-WHERE  stxnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.stxnamespace);
- ctid | stxnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, stxowner
-FROM   pg_catalog.pg_statistic_ext fk
-WHERE  stxowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.stxowner);
- ctid | stxowner 
-------+----------
-(0 rows)
-
-SELECT ctid, stxoid
-FROM   pg_catalog.pg_statistic_ext_data fk
-WHERE  stxoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_statistic_ext pk WHERE pk.oid = fk.stxoid);
- ctid | stxoid 
-------+--------
-(0 rows)
-
-SELECT ctid, spcowner
-FROM   pg_catalog.pg_tablespace fk
-WHERE  spcowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.spcowner);
- ctid | spcowner 
-------+----------
-(0 rows)
-
-SELECT ctid, trftype
-FROM   pg_catalog.pg_transform fk
-WHERE  trftype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.trftype);
- ctid | trftype 
-------+---------
-(0 rows)
-
-SELECT ctid, trflang
-FROM   pg_catalog.pg_transform fk
-WHERE  trflang != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_language pk WHERE pk.oid = fk.trflang);
- ctid | trflang 
-------+---------
-(0 rows)
-
-SELECT ctid, trffromsql
-FROM   pg_catalog.pg_transform fk
-WHERE  trffromsql != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.trffromsql);
- ctid | trffromsql 
-------+------------
-(0 rows)
-
-SELECT ctid, trftosql
-FROM   pg_catalog.pg_transform fk
-WHERE  trftosql != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.trftosql);
- ctid | trftosql 
-------+----------
-(0 rows)
-
-SELECT ctid, tgrelid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.tgrelid);
- ctid | tgrelid 
-------+---------
-(0 rows)
-
-SELECT ctid, tgparentid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgparentid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_trigger pk WHERE pk.oid = fk.tgparentid);
- ctid | tgparentid 
-------+------------
-(0 rows)
-
-SELECT ctid, tgfoid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgfoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tgfoid);
- ctid | tgfoid 
-------+--------
-(0 rows)
-
-SELECT ctid, tgconstrrelid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgconstrrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.tgconstrrelid);
- ctid | tgconstrrelid 
-------+---------------
-(0 rows)
-
-SELECT ctid, tgconstrindid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgconstrindid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.tgconstrindid);
- ctid | tgconstrindid 
-------+---------------
-(0 rows)
-
-SELECT ctid, tgconstraint
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgconstraint != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_constraint pk WHERE pk.oid = fk.tgconstraint);
- ctid | tgconstraint 
-------+--------------
-(0 rows)
-
-SELECT ctid, cfgnamespace
-FROM   pg_catalog.pg_ts_config fk
-WHERE  cfgnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.cfgnamespace);
- ctid | cfgnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, cfgowner
-FROM   pg_catalog.pg_ts_config fk
-WHERE  cfgowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.cfgowner);
- ctid | cfgowner 
-------+----------
-(0 rows)
-
-SELECT ctid, cfgparser
-FROM   pg_catalog.pg_ts_config fk
-WHERE  cfgparser != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_parser pk WHERE pk.oid = fk.cfgparser);
- ctid | cfgparser 
-------+-----------
-(0 rows)
-
-SELECT ctid, mapcfg
-FROM   pg_catalog.pg_ts_config_map fk
-WHERE  mapcfg != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_config pk WHERE pk.oid = fk.mapcfg);
- ctid | mapcfg 
-------+--------
-(0 rows)
-
-SELECT ctid, mapdict
-FROM   pg_catalog.pg_ts_config_map fk
-WHERE  mapdict != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_dict pk WHERE pk.oid = fk.mapdict);
- ctid | mapdict 
-------+---------
-(0 rows)
-
-SELECT ctid, dictnamespace
-FROM   pg_catalog.pg_ts_dict fk
-WHERE  dictnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.dictnamespace);
- ctid | dictnamespace 
-------+---------------
-(0 rows)
-
-SELECT ctid, dictowner
-FROM   pg_catalog.pg_ts_dict fk
-WHERE  dictowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.dictowner);
- ctid | dictowner 
-------+-----------
-(0 rows)
-
-SELECT ctid, dicttemplate
-FROM   pg_catalog.pg_ts_dict fk
-WHERE  dicttemplate != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_template pk WHERE pk.oid = fk.dicttemplate);
- ctid | dicttemplate 
-------+--------------
-(0 rows)
-
-SELECT ctid, prsnamespace
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.prsnamespace);
- ctid | prsnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, prsstart
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsstart != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsstart);
- ctid | prsstart 
-------+----------
-(0 rows)
-
-SELECT ctid, prstoken
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prstoken != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prstoken);
- ctid | prstoken 
-------+----------
-(0 rows)
-
-SELECT ctid, prsend
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsend != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsend);
- ctid | prsend 
-------+--------
-(0 rows)
-
-SELECT ctid, prsheadline
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsheadline != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsheadline);
- ctid | prsheadline 
-------+-------------
-(0 rows)
-
-SELECT ctid, prslextype
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prslextype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prslextype);
- ctid | prslextype 
-------+------------
-(0 rows)
-
-SELECT ctid, tmplnamespace
-FROM   pg_catalog.pg_ts_template fk
-WHERE  tmplnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.tmplnamespace);
- ctid | tmplnamespace 
-------+---------------
-(0 rows)
-
-SELECT ctid, tmplinit
-FROM   pg_catalog.pg_ts_template fk
-WHERE  tmplinit != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmplinit);
- ctid | tmplinit 
-------+----------
-(0 rows)
-
-SELECT ctid, tmpllexize
-FROM   pg_catalog.pg_ts_template fk
-WHERE  tmpllexize != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmpllexize);
- ctid | tmpllexize 
-------+------------
-(0 rows)
-
-SELECT ctid, typnamespace
-FROM   pg_catalog.pg_type fk
-WHERE  typnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.typnamespace);
- ctid | typnamespace 
-------+--------------
-(0 rows)
-
-SELECT ctid, typowner
-FROM   pg_catalog.pg_type fk
-WHERE  typowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.typowner);
- ctid | typowner 
-------+----------
-(0 rows)
-
-SELECT ctid, typrelid
-FROM   pg_catalog.pg_type fk
-WHERE  typrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.typrelid);
- ctid | typrelid 
-------+----------
-(0 rows)
-
-SELECT ctid, typelem
-FROM   pg_catalog.pg_type fk
-WHERE  typelem != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typelem);
- ctid | typelem 
-------+---------
-(0 rows)
-
-SELECT ctid, typarray
-FROM   pg_catalog.pg_type fk
-WHERE  typarray != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typarray);
- ctid | typarray 
-------+----------
-(0 rows)
-
-SELECT ctid, typinput
-FROM   pg_catalog.pg_type fk
-WHERE  typinput != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typinput);
- ctid | typinput 
-------+----------
-(0 rows)
-
-SELECT ctid, typoutput
-FROM   pg_catalog.pg_type fk
-WHERE  typoutput != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typoutput);
- ctid | typoutput 
-------+-----------
-(0 rows)
-
-SELECT ctid, typreceive
-FROM   pg_catalog.pg_type fk
-WHERE  typreceive != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typreceive);
- ctid | typreceive 
-------+------------
-(0 rows)
-
-SELECT ctid, typsend
-FROM   pg_catalog.pg_type fk
-WHERE  typsend != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typsend);
- ctid | typsend 
-------+---------
-(0 rows)
-
-SELECT ctid, typmodin
-FROM   pg_catalog.pg_type fk
-WHERE  typmodin != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodin);
- ctid | typmodin 
-------+----------
-(0 rows)
-
-SELECT ctid, typmodout
-FROM   pg_catalog.pg_type fk
-WHERE  typmodout != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodout);
- ctid | typmodout 
-------+-----------
-(0 rows)
-
-SELECT ctid, typanalyze
-FROM   pg_catalog.pg_type fk
-WHERE  typanalyze != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typanalyze);
- ctid | typanalyze 
-------+------------
-(0 rows)
-
-SELECT ctid, typbasetype
-FROM   pg_catalog.pg_type fk
-WHERE  typbasetype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typbasetype);
- ctid | typbasetype 
-------+-------------
-(0 rows)
-
-SELECT ctid, typcollation
-FROM   pg_catalog.pg_type fk
-WHERE  typcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.typcollation);
- ctid | typcollation 
-------+--------------
-(0 rows)
-
-SELECT ctid, conpfeqop
-FROM   (SELECT ctid, unnest(conpfeqop) AS conpfeqop FROM pg_catalog.pg_constraint) fk
-WHERE  conpfeqop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conpfeqop);
- ctid | conpfeqop 
-------+-----------
-(0 rows)
-
-SELECT ctid, conppeqop
-FROM   (SELECT ctid, unnest(conppeqop) AS conppeqop FROM pg_catalog.pg_constraint) fk
-WHERE  conppeqop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conppeqop);
- ctid | conppeqop 
-------+-----------
-(0 rows)
-
-SELECT ctid, conffeqop
-FROM   (SELECT ctid, unnest(conffeqop) AS conffeqop FROM pg_catalog.pg_constraint) fk
-WHERE  conffeqop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conffeqop);
- ctid | conffeqop 
-------+-----------
-(0 rows)
-
-SELECT ctid, conexclop
-FROM   (SELECT ctid, unnest(conexclop) AS conexclop FROM pg_catalog.pg_constraint) fk
-WHERE  conexclop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conexclop);
- ctid | conexclop 
-------+-----------
-(0 rows)
-
-SELECT ctid, indcollation
-FROM   (SELECT ctid, unnest(indcollation) AS indcollation FROM pg_catalog.pg_index) fk
-WHERE  indcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.indcollation);
- ctid | indcollation 
-------+--------------
-(0 rows)
-
-SELECT ctid, indclass
-FROM   (SELECT ctid, unnest(indclass) AS indclass FROM pg_catalog.pg_index) fk
-WHERE  indclass != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.indclass);
- ctid | indclass 
-------+----------
-(0 rows)
-
-SELECT ctid, partclass
-FROM   (SELECT ctid, unnest(partclass) AS partclass FROM pg_catalog.pg_partitioned_table) fk
-WHERE  partclass != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.partclass);
- ctid | partclass 
-------+-----------
-(0 rows)
-
-SELECT ctid, partcollation
-FROM   (SELECT ctid, unnest(partcollation) AS partcollation FROM pg_catalog.pg_partitioned_table) fk
-WHERE  partcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.partcollation);
- ctid | partcollation 
-------+---------------
-(0 rows)
-
-SELECT ctid, proargtypes
-FROM   (SELECT ctid, unnest(proargtypes) AS proargtypes FROM pg_catalog.pg_proc) fk
-WHERE  proargtypes != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.proargtypes);
- ctid | proargtypes 
-------+-------------
-(0 rows)
-
-SELECT ctid, proallargtypes
-FROM   (SELECT ctid, unnest(proallargtypes) AS proallargtypes FROM pg_catalog.pg_proc) fk
-WHERE  proallargtypes != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.proallargtypes);
- ctid | proallargtypes 
-------+----------------
-(0 rows)
-
+DO $doblock$
+declare
+  fk record;
+  nkeys integer;
+  cmd text;
+  err record;
+begin
+  for fk in select * from pg_get_catalog_foreign_keys()
+  loop
+    raise notice 'checking % % => % %',
+      fk.fktable, fk.fkcols, fk.pktable, fk.pkcols;
+    nkeys := array_length(fk.fkcols, 1);
+    cmd := 'SELECT ctid';
+    for i in 1 .. nkeys loop
+      cmd := cmd || ', ' || quote_ident(fk.fkcols[i]);
+    end loop;
+    if fk.is_array then
+      cmd := cmd || ' FROM (SELECT ctid';
+      for i in 1 .. nkeys-1 loop
+        cmd := cmd || ', ' || quote_ident(fk.fkcols[i]);
+      end loop;
+      cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]);
+      cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]);
+      cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE ';
+    else
+      cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE ';
+    end if;
+    if fk.is_opt then
+      for i in 1 .. nkeys loop
+        cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND ';
+      end loop;
+    end if;
+    cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE ';
+    for i in 1 .. nkeys loop
+      if i > 1 then cmd := cmd || ' AND '; end if;
+      cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]);
+      cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]);
+    end loop;
+    cmd := cmd || ')';
+    -- raise notice 'cmd = %', cmd;
+    for err in execute cmd loop
+      raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err;
+    end loop;
+  end loop;
+end
+$doblock$;
+NOTICE:  checking pg_proc {pronamespace} => pg_namespace {oid}
+NOTICE:  checking pg_proc {proowner} => pg_authid {oid}
+NOTICE:  checking pg_proc {prolang} => pg_language {oid}
+NOTICE:  checking pg_proc {provariadic} => pg_type {oid}
+NOTICE:  checking pg_proc {prosupport} => pg_proc {oid}
+NOTICE:  checking pg_proc {prorettype} => pg_type {oid}
+NOTICE:  checking pg_proc {proargtypes} => pg_type {oid}
+NOTICE:  checking pg_proc {proallargtypes} => pg_type {oid}
+NOTICE:  checking pg_proc {protrftypes} => pg_type {oid}
+NOTICE:  checking pg_type {typnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_type {typowner} => pg_authid {oid}
+NOTICE:  checking pg_type {typrelid} => pg_class {oid}
+NOTICE:  checking pg_type {typsubscript} => pg_proc {oid}
+NOTICE:  checking pg_type {typelem} => pg_type {oid}
+NOTICE:  checking pg_type {typarray} => pg_type {oid}
+NOTICE:  checking pg_type {typinput} => pg_proc {oid}
+NOTICE:  checking pg_type {typoutput} => pg_proc {oid}
+NOTICE:  checking pg_type {typreceive} => pg_proc {oid}
+NOTICE:  checking pg_type {typsend} => pg_proc {oid}
+NOTICE:  checking pg_type {typmodin} => pg_proc {oid}
+NOTICE:  checking pg_type {typmodout} => pg_proc {oid}
+NOTICE:  checking pg_type {typanalyze} => pg_proc {oid}
+NOTICE:  checking pg_type {typbasetype} => pg_type {oid}
+NOTICE:  checking pg_type {typcollation} => pg_collation {oid}
+NOTICE:  checking pg_attribute {attrelid} => pg_class {oid}
+NOTICE:  checking pg_attribute {atttypid} => pg_type {oid}
+NOTICE:  checking pg_attribute {attcollation} => pg_collation {oid}
+NOTICE:  checking pg_class {relnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_class {reltype} => pg_type {oid}
+NOTICE:  checking pg_class {reloftype} => pg_type {oid}
+NOTICE:  checking pg_class {relowner} => pg_authid {oid}
+NOTICE:  checking pg_class {relam} => pg_am {oid}
+NOTICE:  checking pg_class {reltablespace} => pg_tablespace {oid}
+NOTICE:  checking pg_class {reltoastrelid} => pg_class {oid}
+NOTICE:  checking pg_class {relrewrite} => pg_class {oid}
+NOTICE:  checking pg_attrdef {adrelid} => pg_class {oid}
+NOTICE:  checking pg_attrdef {adrelid,adnum} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_constraint {connamespace} => pg_namespace {oid}
+NOTICE:  checking pg_constraint {conrelid} => pg_class {oid}
+NOTICE:  checking pg_constraint {contypid} => pg_type {oid}
+NOTICE:  checking pg_constraint {conindid} => pg_class {oid}
+NOTICE:  checking pg_constraint {conparentid} => pg_constraint {oid}
+NOTICE:  checking pg_constraint {confrelid} => pg_class {oid}
+NOTICE:  checking pg_constraint {conpfeqop} => pg_operator {oid}
+NOTICE:  checking pg_constraint {conppeqop} => pg_operator {oid}
+NOTICE:  checking pg_constraint {conffeqop} => pg_operator {oid}
+NOTICE:  checking pg_constraint {conexclop} => pg_operator {oid}
+NOTICE:  checking pg_constraint {conrelid,conkey} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_constraint {confrelid,confkey} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_inherits {inhrelid} => pg_class {oid}
+NOTICE:  checking pg_inherits {inhparent} => pg_class {oid}
+NOTICE:  checking pg_index {indexrelid} => pg_class {oid}
+NOTICE:  checking pg_index {indrelid} => pg_class {oid}
+NOTICE:  checking pg_index {indcollation} => pg_collation {oid}
+NOTICE:  checking pg_index {indclass} => pg_opclass {oid}
+NOTICE:  checking pg_index {indrelid,indkey} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_operator {oprnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_operator {oprowner} => pg_authid {oid}
+NOTICE:  checking pg_operator {oprleft} => pg_type {oid}
+NOTICE:  checking pg_operator {oprright} => pg_type {oid}
+NOTICE:  checking pg_operator {oprresult} => pg_type {oid}
+NOTICE:  checking pg_operator {oprcom} => pg_operator {oid}
+NOTICE:  checking pg_operator {oprnegate} => pg_operator {oid}
+NOTICE:  checking pg_operator {oprcode} => pg_proc {oid}
+NOTICE:  checking pg_operator {oprrest} => pg_proc {oid}
+NOTICE:  checking pg_operator {oprjoin} => pg_proc {oid}
+NOTICE:  checking pg_opfamily {opfmethod} => pg_am {oid}
+NOTICE:  checking pg_opfamily {opfnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_opfamily {opfowner} => pg_authid {oid}
+NOTICE:  checking pg_opclass {opcmethod} => pg_am {oid}
+NOTICE:  checking pg_opclass {opcnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_opclass {opcowner} => pg_authid {oid}
+NOTICE:  checking pg_opclass {opcfamily} => pg_opfamily {oid}
+NOTICE:  checking pg_opclass {opcintype} => pg_type {oid}
+NOTICE:  checking pg_opclass {opckeytype} => pg_type {oid}
+NOTICE:  checking pg_am {amhandler} => pg_proc {oid}
+NOTICE:  checking pg_amop {amopfamily} => pg_opfamily {oid}
+NOTICE:  checking pg_amop {amoplefttype} => pg_type {oid}
+NOTICE:  checking pg_amop {amoprighttype} => pg_type {oid}
+NOTICE:  checking pg_amop {amopopr} => pg_operator {oid}
+NOTICE:  checking pg_amop {amopmethod} => pg_am {oid}
+NOTICE:  checking pg_amop {amopsortfamily} => pg_opfamily {oid}
+NOTICE:  checking pg_amproc {amprocfamily} => pg_opfamily {oid}
+NOTICE:  checking pg_amproc {amproclefttype} => pg_type {oid}
+NOTICE:  checking pg_amproc {amprocrighttype} => pg_type {oid}
+NOTICE:  checking pg_amproc {amproc} => pg_proc {oid}
+NOTICE:  checking pg_language {lanowner} => pg_authid {oid}
+NOTICE:  checking pg_language {lanplcallfoid} => pg_proc {oid}
+NOTICE:  checking pg_language {laninline} => pg_proc {oid}
+NOTICE:  checking pg_language {lanvalidator} => pg_proc {oid}
+NOTICE:  checking pg_largeobject_metadata {lomowner} => pg_authid {oid}
+NOTICE:  checking pg_largeobject {loid} => pg_largeobject_metadata {oid}
+NOTICE:  checking pg_aggregate {aggfnoid} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggtransfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggfinalfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggcombinefn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggserialfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggdeserialfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggmtransfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggminvtransfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggmfinalfn} => pg_proc {oid}
+NOTICE:  checking pg_aggregate {aggsortop} => pg_operator {oid}
+NOTICE:  checking pg_aggregate {aggtranstype} => pg_type {oid}
+NOTICE:  checking pg_aggregate {aggmtranstype} => pg_type {oid}
+NOTICE:  checking pg_statistic_ext {stxrelid} => pg_class {oid}
+NOTICE:  checking pg_statistic_ext {stxnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_statistic_ext {stxowner} => pg_authid {oid}
+NOTICE:  checking pg_statistic_ext {stxrelid,stxkeys} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_statistic_ext_data {stxoid} => pg_statistic_ext {oid}
+NOTICE:  checking pg_statistic {starelid} => pg_class {oid}
+NOTICE:  checking pg_statistic {staop1} => pg_operator {oid}
+NOTICE:  checking pg_statistic {staop2} => pg_operator {oid}
+NOTICE:  checking pg_statistic {staop3} => pg_operator {oid}
+NOTICE:  checking pg_statistic {staop4} => pg_operator {oid}
+NOTICE:  checking pg_statistic {staop5} => pg_operator {oid}
+NOTICE:  checking pg_statistic {stacoll1} => pg_collation {oid}
+NOTICE:  checking pg_statistic {stacoll2} => pg_collation {oid}
+NOTICE:  checking pg_statistic {stacoll3} => pg_collation {oid}
+NOTICE:  checking pg_statistic {stacoll4} => pg_collation {oid}
+NOTICE:  checking pg_statistic {stacoll5} => pg_collation {oid}
+NOTICE:  checking pg_statistic {starelid,staattnum} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_rewrite {ev_class} => pg_class {oid}
+NOTICE:  checking pg_trigger {tgrelid} => pg_class {oid}
+NOTICE:  checking pg_trigger {tgparentid} => pg_trigger {oid}
+NOTICE:  checking pg_trigger {tgfoid} => pg_proc {oid}
+NOTICE:  checking pg_trigger {tgconstrrelid} => pg_class {oid}
+NOTICE:  checking pg_trigger {tgconstrindid} => pg_class {oid}
+NOTICE:  checking pg_trigger {tgconstraint} => pg_constraint {oid}
+NOTICE:  checking pg_trigger {tgrelid,tgattr} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_event_trigger {evtowner} => pg_authid {oid}
+NOTICE:  checking pg_event_trigger {evtfoid} => pg_proc {oid}
+NOTICE:  checking pg_description {classoid} => pg_class {oid}
+NOTICE:  checking pg_cast {castsource} => pg_type {oid}
+NOTICE:  checking pg_cast {casttarget} => pg_type {oid}
+NOTICE:  checking pg_cast {castfunc} => pg_proc {oid}
+NOTICE:  checking pg_enum {enumtypid} => pg_type {oid}
+NOTICE:  checking pg_namespace {nspowner} => pg_authid {oid}
+NOTICE:  checking pg_conversion {connamespace} => pg_namespace {oid}
+NOTICE:  checking pg_conversion {conowner} => pg_authid {oid}
+NOTICE:  checking pg_conversion {conproc} => pg_proc {oid}
+NOTICE:  checking pg_depend {classid} => pg_class {oid}
+NOTICE:  checking pg_depend {refclassid} => pg_class {oid}
+NOTICE:  checking pg_database {datdba} => pg_authid {oid}
+NOTICE:  checking pg_database {dattablespace} => pg_tablespace {oid}
+NOTICE:  checking pg_db_role_setting {setdatabase} => pg_database {oid}
+NOTICE:  checking pg_db_role_setting {setrole} => pg_authid {oid}
+NOTICE:  checking pg_tablespace {spcowner} => pg_authid {oid}
+NOTICE:  checking pg_auth_members {roleid} => pg_authid {oid}
+NOTICE:  checking pg_auth_members {member} => pg_authid {oid}
+NOTICE:  checking pg_auth_members {grantor} => pg_authid {oid}
+NOTICE:  checking pg_shdepend {dbid} => pg_database {oid}
+NOTICE:  checking pg_shdepend {classid} => pg_class {oid}
+NOTICE:  checking pg_shdepend {refclassid} => pg_class {oid}
+NOTICE:  checking pg_shdescription {classoid} => pg_class {oid}
+NOTICE:  checking pg_ts_config {cfgnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_ts_config {cfgowner} => pg_authid {oid}
+NOTICE:  checking pg_ts_config {cfgparser} => pg_ts_parser {oid}
+NOTICE:  checking pg_ts_config_map {mapcfg} => pg_ts_config {oid}
+NOTICE:  checking pg_ts_config_map {mapdict} => pg_ts_dict {oid}
+NOTICE:  checking pg_ts_dict {dictnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_ts_dict {dictowner} => pg_authid {oid}
+NOTICE:  checking pg_ts_dict {dicttemplate} => pg_ts_template {oid}
+NOTICE:  checking pg_ts_parser {prsnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_ts_parser {prsstart} => pg_proc {oid}
+NOTICE:  checking pg_ts_parser {prstoken} => pg_proc {oid}
+NOTICE:  checking pg_ts_parser {prsend} => pg_proc {oid}
+NOTICE:  checking pg_ts_parser {prsheadline} => pg_proc {oid}
+NOTICE:  checking pg_ts_parser {prslextype} => pg_proc {oid}
+NOTICE:  checking pg_ts_template {tmplnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_ts_template {tmplinit} => pg_proc {oid}
+NOTICE:  checking pg_ts_template {tmpllexize} => pg_proc {oid}
+NOTICE:  checking pg_extension {extowner} => pg_authid {oid}
+NOTICE:  checking pg_extension {extnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_extension {extconfig} => pg_class {oid}
+NOTICE:  checking pg_foreign_data_wrapper {fdwowner} => pg_authid {oid}
+NOTICE:  checking pg_foreign_data_wrapper {fdwhandler} => pg_proc {oid}
+NOTICE:  checking pg_foreign_data_wrapper {fdwvalidator} => pg_proc {oid}
+NOTICE:  checking pg_foreign_server {srvowner} => pg_authid {oid}
+NOTICE:  checking pg_foreign_server {srvfdw} => pg_foreign_data_wrapper {oid}
+NOTICE:  checking pg_user_mapping {umuser} => pg_authid {oid}
+NOTICE:  checking pg_user_mapping {umserver} => pg_foreign_server {oid}
+NOTICE:  checking pg_foreign_table {ftrelid} => pg_class {oid}
+NOTICE:  checking pg_foreign_table {ftserver} => pg_foreign_server {oid}
+NOTICE:  checking pg_policy {polrelid} => pg_class {oid}
+NOTICE:  checking pg_policy {polroles} => pg_authid {oid}
+NOTICE:  checking pg_default_acl {defaclrole} => pg_authid {oid}
+NOTICE:  checking pg_default_acl {defaclnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_init_privs {classoid} => pg_class {oid}
+NOTICE:  checking pg_seclabel {classoid} => pg_class {oid}
+NOTICE:  checking pg_shseclabel {classoid} => pg_class {oid}
+NOTICE:  checking pg_collation {collnamespace} => pg_namespace {oid}
+NOTICE:  checking pg_collation {collowner} => pg_authid {oid}
+NOTICE:  checking pg_partitioned_table {partrelid} => pg_class {oid}
+NOTICE:  checking pg_partitioned_table {partdefid} => pg_class {oid}
+NOTICE:  checking pg_partitioned_table {partclass} => pg_opclass {oid}
+NOTICE:  checking pg_partitioned_table {partcollation} => pg_collation {oid}
+NOTICE:  checking pg_partitioned_table {partrelid,partattrs} => pg_attribute {attrelid,attnum}
+NOTICE:  checking pg_range {rngtypid} => pg_type {oid}
+NOTICE:  checking pg_range {rngsubtype} => pg_type {oid}
+NOTICE:  checking pg_range {rngmultitypid} => pg_type {oid}
+NOTICE:  checking pg_range {rngcollation} => pg_collation {oid}
+NOTICE:  checking pg_range {rngsubopc} => pg_opclass {oid}
+NOTICE:  checking pg_range {rngcanonical} => pg_proc {oid}
+NOTICE:  checking pg_range {rngsubdiff} => pg_proc {oid}
+NOTICE:  checking pg_transform {trftype} => pg_type {oid}
+NOTICE:  checking pg_transform {trflang} => pg_language {oid}
+NOTICE:  checking pg_transform {trffromsql} => pg_proc {oid}
+NOTICE:  checking pg_transform {trftosql} => pg_proc {oid}
+NOTICE:  checking pg_sequence {seqrelid} => pg_class {oid}
+NOTICE:  checking pg_sequence {seqtypid} => pg_type {oid}
+NOTICE:  checking pg_publication {pubowner} => pg_authid {oid}
+NOTICE:  checking pg_publication_rel {prpubid} => pg_publication {oid}
+NOTICE:  checking pg_publication_rel {prrelid} => pg_class {oid}
+NOTICE:  checking pg_subscription {subdbid} => pg_database {oid}
+NOTICE:  checking pg_subscription {subowner} => pg_authid {oid}
+NOTICE:  checking pg_subscription_rel {srsubid} => pg_subscription {oid}
+NOTICE:  checking pg_subscription_rel {srrelid} => pg_class {oid}
index e0e1ef71dd790df542dc28ba7ecc5f810d58f45a..12bb67e4911882cd7d91df54ce81abe255cc2219 100644 (file)
@@ -29,7 +29,7 @@ test: strings numerology point lseg line box path polygon circle date time timet
 # geometry depends on point, lseg, box, path, polygon and circle
 # horology depends on interval, timetz, timestamp, timestamptz
 # ----------
-test: geometry horology regex oidjoins type_sanity opr_sanity misc_sanity comments expressions unicode xid
+test: geometry horology regex type_sanity opr_sanity misc_sanity comments expressions unicode xid
 
 # ----------
 # These four each depend on the previous one
@@ -117,7 +117,8 @@ test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion tr
 test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain
 
 # event triggers cannot run concurrently with any test that runs DDL
-test: event_trigger
+# oidjoins is read-only, though, and should run late for best coverage
+test: event_trigger oidjoins
 # this test also uses event triggers, so likewise run it by itself
 test: fast_default
 
index 081fce32e75b616e55eee9f515478a03ad6624b7..59b416fd80cb4a80d769ce711e152f8118edbd91 100644 (file)
@@ -45,7 +45,6 @@ test: tstypes
 test: geometry
 test: horology
 test: regex
-test: oidjoins
 test: type_sanity
 test: opr_sanity
 test: misc_sanity
@@ -201,5 +200,6 @@ test: partition_info
 test: tuplesort
 test: explain
 test: event_trigger
+test: oidjoins
 test: fast_default
 test: stats
index f6d2d3c68c36f70e15cf89b5b607079b2076455b..8b22e6d10c5eca68c208b2c9598fe2b689a508c1 100644 (file)
 --
--- This is created by pgsql/src/tools/findoidjoins/make_oidjoins_check
+-- Verify system catalog foreign key relationships
 --
-SELECT ctid, aggfnoid
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggfnoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggfnoid);
-SELECT ctid, aggtransfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggtransfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggtransfn);
-SELECT ctid, aggfinalfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggfinalfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggfinalfn);
-SELECT ctid, aggcombinefn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggcombinefn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggcombinefn);
-SELECT ctid, aggserialfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggserialfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggserialfn);
-SELECT ctid, aggdeserialfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggdeserialfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggdeserialfn);
-SELECT ctid, aggmtransfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggmtransfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggmtransfn);
-SELECT ctid, aggminvtransfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggminvtransfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggminvtransfn);
-SELECT ctid, aggmfinalfn
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggmfinalfn != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.aggmfinalfn);
-SELECT ctid, aggsortop
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggsortop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.aggsortop);
-SELECT ctid, aggtranstype
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggtranstype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.aggtranstype);
-SELECT ctid, aggmtranstype
-FROM   pg_catalog.pg_aggregate fk
-WHERE  aggmtranstype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.aggmtranstype);
-SELECT ctid, amhandler
-FROM   pg_catalog.pg_am fk
-WHERE  amhandler != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amhandler);
-SELECT ctid, amopfamily
-FROM   pg_catalog.pg_amop fk
-WHERE  amopfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amopfamily);
-SELECT ctid, amoplefttype
-FROM   pg_catalog.pg_amop fk
-WHERE  amoplefttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoplefttype);
-SELECT ctid, amoprighttype
-FROM   pg_catalog.pg_amop fk
-WHERE  amoprighttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoprighttype);
-SELECT ctid, amopopr
-FROM   pg_catalog.pg_amop fk
-WHERE  amopopr != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.amopopr);
-SELECT ctid, amopmethod
-FROM   pg_catalog.pg_amop fk
-WHERE  amopmethod != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.amopmethod);
-SELECT ctid, amopsortfamily
-FROM   pg_catalog.pg_amop fk
-WHERE  amopsortfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amopsortfamily);
-SELECT ctid, amprocfamily
-FROM   pg_catalog.pg_amproc fk
-WHERE  amprocfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amprocfamily);
-SELECT ctid, amproclefttype
-FROM   pg_catalog.pg_amproc fk
-WHERE  amproclefttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amproclefttype);
-SELECT ctid, amprocrighttype
-FROM   pg_catalog.pg_amproc fk
-WHERE  amprocrighttype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocrighttype);
-SELECT ctid, amproc
-FROM   pg_catalog.pg_amproc fk
-WHERE  amproc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amproc);
-SELECT ctid, adrelid
-FROM   pg_catalog.pg_attrdef fk
-WHERE  adrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.adrelid);
-SELECT ctid, attrelid
-FROM   pg_catalog.pg_attribute fk
-WHERE  attrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.attrelid);
-SELECT ctid, atttypid
-FROM   pg_catalog.pg_attribute fk
-WHERE  atttypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.atttypid);
-SELECT ctid, attcollation
-FROM   pg_catalog.pg_attribute fk
-WHERE  attcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.attcollation);
-SELECT ctid, roleid
-FROM   pg_catalog.pg_auth_members fk
-WHERE  roleid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.roleid);
-SELECT ctid, member
-FROM   pg_catalog.pg_auth_members fk
-WHERE  member != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.member);
-SELECT ctid, grantor
-FROM   pg_catalog.pg_auth_members fk
-WHERE  grantor != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.grantor);
-SELECT ctid, castsource
-FROM   pg_catalog.pg_cast fk
-WHERE  castsource != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.castsource);
-SELECT ctid, casttarget
-FROM   pg_catalog.pg_cast fk
-WHERE  casttarget != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.casttarget);
-SELECT ctid, castfunc
-FROM   pg_catalog.pg_cast fk
-WHERE  castfunc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.castfunc);
-SELECT ctid, relnamespace
-FROM   pg_catalog.pg_class fk
-WHERE  relnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.relnamespace);
-SELECT ctid, reltype
-FROM   pg_catalog.pg_class fk
-WHERE  reltype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.reltype);
-SELECT ctid, reloftype
-FROM   pg_catalog.pg_class fk
-WHERE  reloftype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.reloftype);
-SELECT ctid, relowner
-FROM   pg_catalog.pg_class fk
-WHERE  relowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.relowner);
-SELECT ctid, relam
-FROM   pg_catalog.pg_class fk
-WHERE  relam != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.relam);
-SELECT ctid, reltablespace
-FROM   pg_catalog.pg_class fk
-WHERE  reltablespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_tablespace pk WHERE pk.oid = fk.reltablespace);
-SELECT ctid, reltoastrelid
-FROM   pg_catalog.pg_class fk
-WHERE  reltoastrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.reltoastrelid);
-SELECT ctid, collnamespace
-FROM   pg_catalog.pg_collation fk
-WHERE  collnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.collnamespace);
-SELECT ctid, collowner
-FROM   pg_catalog.pg_collation fk
-WHERE  collowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.collowner);
-SELECT ctid, connamespace
-FROM   pg_catalog.pg_constraint fk
-WHERE  connamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.connamespace);
-SELECT ctid, conrelid
-FROM   pg_catalog.pg_constraint fk
-WHERE  conrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.conrelid);
-SELECT ctid, contypid
-FROM   pg_catalog.pg_constraint fk
-WHERE  contypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.contypid);
-SELECT ctid, conindid
-FROM   pg_catalog.pg_constraint fk
-WHERE  conindid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.conindid);
-SELECT ctid, conparentid
-FROM   pg_catalog.pg_constraint fk
-WHERE  conparentid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_constraint pk WHERE pk.oid = fk.conparentid);
-SELECT ctid, confrelid
-FROM   pg_catalog.pg_constraint fk
-WHERE  confrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.confrelid);
-SELECT ctid, connamespace
-FROM   pg_catalog.pg_conversion fk
-WHERE  connamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.connamespace);
-SELECT ctid, conowner
-FROM   pg_catalog.pg_conversion fk
-WHERE  conowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.conowner);
-SELECT ctid, conproc
-FROM   pg_catalog.pg_conversion fk
-WHERE  conproc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.conproc);
-SELECT ctid, datdba
-FROM   pg_catalog.pg_database fk
-WHERE  datdba != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.datdba);
-SELECT ctid, dattablespace
-FROM   pg_catalog.pg_database fk
-WHERE  dattablespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_tablespace pk WHERE pk.oid = fk.dattablespace);
-SELECT ctid, setdatabase
-FROM   pg_catalog.pg_db_role_setting fk
-WHERE  setdatabase != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_database pk WHERE pk.oid = fk.setdatabase);
-SELECT ctid, classid
-FROM   pg_catalog.pg_depend fk
-WHERE  classid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classid);
-SELECT ctid, refclassid
-FROM   pg_catalog.pg_depend fk
-WHERE  refclassid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.refclassid);
-SELECT ctid, classoid
-FROM   pg_catalog.pg_description fk
-WHERE  classoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid);
-SELECT ctid, enumtypid
-FROM   pg_catalog.pg_enum fk
-WHERE  enumtypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.enumtypid);
-SELECT ctid, extowner
-FROM   pg_catalog.pg_extension fk
-WHERE  extowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.extowner);
-SELECT ctid, extnamespace
-FROM   pg_catalog.pg_extension fk
-WHERE  extnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.extnamespace);
-SELECT ctid, fdwowner
-FROM   pg_catalog.pg_foreign_data_wrapper fk
-WHERE  fdwowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.fdwowner);
-SELECT ctid, srvowner
-FROM   pg_catalog.pg_foreign_server fk
-WHERE  srvowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.srvowner);
-SELECT ctid, srvfdw
-FROM   pg_catalog.pg_foreign_server fk
-WHERE  srvfdw != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_foreign_data_wrapper pk WHERE pk.oid = fk.srvfdw);
-SELECT ctid, indexrelid
-FROM   pg_catalog.pg_index fk
-WHERE  indexrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.indexrelid);
-SELECT ctid, indrelid
-FROM   pg_catalog.pg_index fk
-WHERE  indrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.indrelid);
-SELECT ctid, inhrelid
-FROM   pg_catalog.pg_inherits fk
-WHERE  inhrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.inhrelid);
-SELECT ctid, inhparent
-FROM   pg_catalog.pg_inherits fk
-WHERE  inhparent != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.inhparent);
-SELECT ctid, classoid
-FROM   pg_catalog.pg_init_privs fk
-WHERE  classoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid);
-SELECT ctid, lanowner
-FROM   pg_catalog.pg_language fk
-WHERE  lanowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.lanowner);
-SELECT ctid, lanplcallfoid
-FROM   pg_catalog.pg_language fk
-WHERE  lanplcallfoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.lanplcallfoid);
-SELECT ctid, laninline
-FROM   pg_catalog.pg_language fk
-WHERE  laninline != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.laninline);
-SELECT ctid, lanvalidator
-FROM   pg_catalog.pg_language fk
-WHERE  lanvalidator != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.lanvalidator);
-SELECT ctid, loid
-FROM   pg_catalog.pg_largeobject fk
-WHERE  loid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject_metadata pk WHERE pk.oid = fk.loid);
-SELECT ctid, lomowner
-FROM   pg_catalog.pg_largeobject_metadata fk
-WHERE  lomowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.lomowner);
-SELECT ctid, nspowner
-FROM   pg_catalog.pg_namespace fk
-WHERE  nspowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.nspowner);
-SELECT ctid, opcmethod
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcmethod != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opcmethod);
-SELECT ctid, opcnamespace
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opcnamespace);
-SELECT ctid, opcowner
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opcowner);
-SELECT ctid, opcfamily
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcfamily != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.opcfamily);
-SELECT ctid, opcintype
-FROM   pg_catalog.pg_opclass fk
-WHERE  opcintype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opcintype);
-SELECT ctid, opckeytype
-FROM   pg_catalog.pg_opclass fk
-WHERE  opckeytype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opckeytype);
-SELECT ctid, oprnamespace
-FROM   pg_catalog.pg_operator fk
-WHERE  oprnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.oprnamespace);
-SELECT ctid, oprowner
-FROM   pg_catalog.pg_operator fk
-WHERE  oprowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.oprowner);
-SELECT ctid, oprleft
-FROM   pg_catalog.pg_operator fk
-WHERE  oprleft != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.oprleft);
-SELECT ctid, oprright
-FROM   pg_catalog.pg_operator fk
-WHERE  oprright != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.oprright);
-SELECT ctid, oprresult
-FROM   pg_catalog.pg_operator fk
-WHERE  oprresult != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.oprresult);
-SELECT ctid, oprcom
-FROM   pg_catalog.pg_operator fk
-WHERE  oprcom != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom);
-SELECT ctid, oprnegate
-FROM   pg_catalog.pg_operator fk
-WHERE  oprnegate != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate);
-SELECT ctid, oprcode
-FROM   pg_catalog.pg_operator fk
-WHERE  oprcode != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprcode);
-SELECT ctid, oprrest
-FROM   pg_catalog.pg_operator fk
-WHERE  oprrest != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprrest);
-SELECT ctid, oprjoin
-FROM   pg_catalog.pg_operator fk
-WHERE  oprjoin != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprjoin);
-SELECT ctid, opfmethod
-FROM   pg_catalog.pg_opfamily fk
-WHERE  opfmethod != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opfmethod);
-SELECT ctid, opfnamespace
-FROM   pg_catalog.pg_opfamily fk
-WHERE  opfnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opfnamespace);
-SELECT ctid, opfowner
-FROM   pg_catalog.pg_opfamily fk
-WHERE  opfowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opfowner);
-SELECT ctid, partrelid
-FROM   pg_catalog.pg_partitioned_table fk
-WHERE  partrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partrelid);
-SELECT ctid, partdefid
-FROM   pg_catalog.pg_partitioned_table fk
-WHERE  partdefid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partdefid);
-SELECT ctid, polrelid
-FROM   pg_catalog.pg_policy fk
-WHERE  polrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.polrelid);
-SELECT ctid, pronamespace
-FROM   pg_catalog.pg_proc fk
-WHERE  pronamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.pronamespace);
-SELECT ctid, proowner
-FROM   pg_catalog.pg_proc fk
-WHERE  proowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.proowner);
-SELECT ctid, prolang
-FROM   pg_catalog.pg_proc fk
-WHERE  prolang != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_language pk WHERE pk.oid = fk.prolang);
-SELECT ctid, provariadic
-FROM   pg_catalog.pg_proc fk
-WHERE  provariadic != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.provariadic);
-SELECT ctid, prosupport
-FROM   pg_catalog.pg_proc fk
-WHERE  prosupport != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prosupport);
-SELECT ctid, prorettype
-FROM   pg_catalog.pg_proc fk
-WHERE  prorettype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.prorettype);
-SELECT ctid, rngtypid
-FROM   pg_catalog.pg_range fk
-WHERE  rngtypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.rngtypid);
-SELECT ctid, rngsubtype
-FROM   pg_catalog.pg_range fk
-WHERE  rngsubtype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.rngsubtype);
-SELECT ctid, rngcollation
-FROM   pg_catalog.pg_range fk
-WHERE  rngcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.rngcollation);
-SELECT ctid, rngsubopc
-FROM   pg_catalog.pg_range fk
-WHERE  rngsubopc != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.rngsubopc);
-SELECT ctid, rngcanonical
-FROM   pg_catalog.pg_range fk
-WHERE  rngcanonical != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.rngcanonical);
-SELECT ctid, rngsubdiff
-FROM   pg_catalog.pg_range fk
-WHERE  rngsubdiff != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.rngsubdiff);
-SELECT ctid, ev_class
-FROM   pg_catalog.pg_rewrite fk
-WHERE  ev_class != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.ev_class);
-SELECT ctid, seqrelid
-FROM   pg_catalog.pg_sequence fk
-WHERE  seqrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.seqrelid);
-SELECT ctid, seqtypid
-FROM   pg_catalog.pg_sequence fk
-WHERE  seqtypid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.seqtypid);
-SELECT ctid, refclassid
-FROM   pg_catalog.pg_shdepend fk
-WHERE  refclassid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.refclassid);
-SELECT ctid, classoid
-FROM   pg_catalog.pg_shdescription fk
-WHERE  classoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid);
-SELECT ctid, starelid
-FROM   pg_catalog.pg_statistic fk
-WHERE  starelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.starelid);
-SELECT ctid, staop1
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop1 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop1);
-SELECT ctid, staop2
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop2 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop2);
-SELECT ctid, staop3
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop3 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop3);
-SELECT ctid, staop4
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop4 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop4);
-SELECT ctid, staop5
-FROM   pg_catalog.pg_statistic fk
-WHERE  staop5 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop5);
-SELECT ctid, stacoll1
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll1 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll1);
-SELECT ctid, stacoll2
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll2 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll2);
-SELECT ctid, stacoll3
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll3 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll3);
-SELECT ctid, stacoll4
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll4 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll4);
-SELECT ctid, stacoll5
-FROM   pg_catalog.pg_statistic fk
-WHERE  stacoll5 != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.stacoll5);
-SELECT ctid, stxrelid
-FROM   pg_catalog.pg_statistic_ext fk
-WHERE  stxrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.stxrelid);
-SELECT ctid, stxnamespace
-FROM   pg_catalog.pg_statistic_ext fk
-WHERE  stxnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.stxnamespace);
-SELECT ctid, stxowner
-FROM   pg_catalog.pg_statistic_ext fk
-WHERE  stxowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.stxowner);
-SELECT ctid, stxoid
-FROM   pg_catalog.pg_statistic_ext_data fk
-WHERE  stxoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_statistic_ext pk WHERE pk.oid = fk.stxoid);
-SELECT ctid, spcowner
-FROM   pg_catalog.pg_tablespace fk
-WHERE  spcowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.spcowner);
-SELECT ctid, trftype
-FROM   pg_catalog.pg_transform fk
-WHERE  trftype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.trftype);
-SELECT ctid, trflang
-FROM   pg_catalog.pg_transform fk
-WHERE  trflang != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_language pk WHERE pk.oid = fk.trflang);
-SELECT ctid, trffromsql
-FROM   pg_catalog.pg_transform fk
-WHERE  trffromsql != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.trffromsql);
-SELECT ctid, trftosql
-FROM   pg_catalog.pg_transform fk
-WHERE  trftosql != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.trftosql);
-SELECT ctid, tgrelid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.tgrelid);
-SELECT ctid, tgparentid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgparentid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_trigger pk WHERE pk.oid = fk.tgparentid);
-SELECT ctid, tgfoid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgfoid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tgfoid);
-SELECT ctid, tgconstrrelid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgconstrrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.tgconstrrelid);
-SELECT ctid, tgconstrindid
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgconstrindid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.tgconstrindid);
-SELECT ctid, tgconstraint
-FROM   pg_catalog.pg_trigger fk
-WHERE  tgconstraint != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_constraint pk WHERE pk.oid = fk.tgconstraint);
-SELECT ctid, cfgnamespace
-FROM   pg_catalog.pg_ts_config fk
-WHERE  cfgnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.cfgnamespace);
-SELECT ctid, cfgowner
-FROM   pg_catalog.pg_ts_config fk
-WHERE  cfgowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.cfgowner);
-SELECT ctid, cfgparser
-FROM   pg_catalog.pg_ts_config fk
-WHERE  cfgparser != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_parser pk WHERE pk.oid = fk.cfgparser);
-SELECT ctid, mapcfg
-FROM   pg_catalog.pg_ts_config_map fk
-WHERE  mapcfg != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_config pk WHERE pk.oid = fk.mapcfg);
-SELECT ctid, mapdict
-FROM   pg_catalog.pg_ts_config_map fk
-WHERE  mapdict != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_dict pk WHERE pk.oid = fk.mapdict);
-SELECT ctid, dictnamespace
-FROM   pg_catalog.pg_ts_dict fk
-WHERE  dictnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.dictnamespace);
-SELECT ctid, dictowner
-FROM   pg_catalog.pg_ts_dict fk
-WHERE  dictowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.dictowner);
-SELECT ctid, dicttemplate
-FROM   pg_catalog.pg_ts_dict fk
-WHERE  dicttemplate != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_template pk WHERE pk.oid = fk.dicttemplate);
-SELECT ctid, prsnamespace
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.prsnamespace);
-SELECT ctid, prsstart
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsstart != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsstart);
-SELECT ctid, prstoken
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prstoken != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prstoken);
-SELECT ctid, prsend
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsend != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsend);
-SELECT ctid, prsheadline
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prsheadline != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsheadline);
-SELECT ctid, prslextype
-FROM   pg_catalog.pg_ts_parser fk
-WHERE  prslextype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prslextype);
-SELECT ctid, tmplnamespace
-FROM   pg_catalog.pg_ts_template fk
-WHERE  tmplnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.tmplnamespace);
-SELECT ctid, tmplinit
-FROM   pg_catalog.pg_ts_template fk
-WHERE  tmplinit != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmplinit);
-SELECT ctid, tmpllexize
-FROM   pg_catalog.pg_ts_template fk
-WHERE  tmpllexize != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmpllexize);
-SELECT ctid, typnamespace
-FROM   pg_catalog.pg_type fk
-WHERE  typnamespace != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.typnamespace);
-SELECT ctid, typowner
-FROM   pg_catalog.pg_type fk
-WHERE  typowner != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.typowner);
-SELECT ctid, typrelid
-FROM   pg_catalog.pg_type fk
-WHERE  typrelid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.typrelid);
-SELECT ctid, typelem
-FROM   pg_catalog.pg_type fk
-WHERE  typelem != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typelem);
-SELECT ctid, typarray
-FROM   pg_catalog.pg_type fk
-WHERE  typarray != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typarray);
-SELECT ctid, typinput
-FROM   pg_catalog.pg_type fk
-WHERE  typinput != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typinput);
-SELECT ctid, typoutput
-FROM   pg_catalog.pg_type fk
-WHERE  typoutput != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typoutput);
-SELECT ctid, typreceive
-FROM   pg_catalog.pg_type fk
-WHERE  typreceive != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typreceive);
-SELECT ctid, typsend
-FROM   pg_catalog.pg_type fk
-WHERE  typsend != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typsend);
-SELECT ctid, typmodin
-FROM   pg_catalog.pg_type fk
-WHERE  typmodin != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodin);
-SELECT ctid, typmodout
-FROM   pg_catalog.pg_type fk
-WHERE  typmodout != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodout);
-SELECT ctid, typanalyze
-FROM   pg_catalog.pg_type fk
-WHERE  typanalyze != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typanalyze);
-SELECT ctid, typbasetype
-FROM   pg_catalog.pg_type fk
-WHERE  typbasetype != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typbasetype);
-SELECT ctid, typcollation
-FROM   pg_catalog.pg_type fk
-WHERE  typcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.typcollation);
-SELECT ctid, conpfeqop
-FROM   (SELECT ctid, unnest(conpfeqop) AS conpfeqop FROM pg_catalog.pg_constraint) fk
-WHERE  conpfeqop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conpfeqop);
-SELECT ctid, conppeqop
-FROM   (SELECT ctid, unnest(conppeqop) AS conppeqop FROM pg_catalog.pg_constraint) fk
-WHERE  conppeqop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conppeqop);
-SELECT ctid, conffeqop
-FROM   (SELECT ctid, unnest(conffeqop) AS conffeqop FROM pg_catalog.pg_constraint) fk
-WHERE  conffeqop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conffeqop);
-SELECT ctid, conexclop
-FROM   (SELECT ctid, unnest(conexclop) AS conexclop FROM pg_catalog.pg_constraint) fk
-WHERE  conexclop != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.conexclop);
-SELECT ctid, indcollation
-FROM   (SELECT ctid, unnest(indcollation) AS indcollation FROM pg_catalog.pg_index) fk
-WHERE  indcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.indcollation);
-SELECT ctid, indclass
-FROM   (SELECT ctid, unnest(indclass) AS indclass FROM pg_catalog.pg_index) fk
-WHERE  indclass != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.indclass);
-SELECT ctid, partclass
-FROM   (SELECT ctid, unnest(partclass) AS partclass FROM pg_catalog.pg_partitioned_table) fk
-WHERE  partclass != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.partclass);
-SELECT ctid, partcollation
-FROM   (SELECT ctid, unnest(partcollation) AS partcollation FROM pg_catalog.pg_partitioned_table) fk
-WHERE  partcollation != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_collation pk WHERE pk.oid = fk.partcollation);
-SELECT ctid, proargtypes
-FROM   (SELECT ctid, unnest(proargtypes) AS proargtypes FROM pg_catalog.pg_proc) fk
-WHERE  proargtypes != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.proargtypes);
-SELECT ctid, proallargtypes
-FROM   (SELECT ctid, unnest(proallargtypes) AS proallargtypes FROM pg_catalog.pg_proc) fk
-WHERE  proallargtypes != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.proallargtypes);
+DO $doblock$
+declare
+  fk record;
+  nkeys integer;
+  cmd text;
+  err record;
+begin
+  for fk in select * from pg_get_catalog_foreign_keys()
+  loop
+    raise notice 'checking % % => % %',
+      fk.fktable, fk.fkcols, fk.pktable, fk.pkcols;
+    nkeys := array_length(fk.fkcols, 1);
+    cmd := 'SELECT ctid';
+    for i in 1 .. nkeys loop
+      cmd := cmd || ', ' || quote_ident(fk.fkcols[i]);
+    end loop;
+    if fk.is_array then
+      cmd := cmd || ' FROM (SELECT ctid';
+      for i in 1 .. nkeys-1 loop
+        cmd := cmd || ', ' || quote_ident(fk.fkcols[i]);
+      end loop;
+      cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]);
+      cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]);
+      cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE ';
+    else
+      cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE ';
+    end if;
+    if fk.is_opt then
+      for i in 1 .. nkeys loop
+        cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND ';
+      end loop;
+    end if;
+    cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE ';
+    for i in 1 .. nkeys loop
+      if i > 1 then cmd := cmd || ' AND '; end if;
+      cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]);
+      cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]);
+    end loop;
+    cmd := cmd || ')';
+    -- raise notice 'cmd = %', cmd;
+    for err in execute cmd loop
+      raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err;
+    end loop;
+  end loop;
+end
+$doblock$;
index 1c0c92fcd2c2f058edb26c6a3d79210fe853d320..2aa062b2c9ecbfe3d614b333542e7c84e19eae2c 100644 (file)
@@ -818,6 +818,9 @@ EOF
                copyFile(
                        'src/backend/catalog/schemapg.h',
                        'src/include/catalog/schemapg.h');
+               copyFile(
+                       'src/backend/catalog/system_fk_info.h',
+                       'src/include/catalog/system_fk_info.h');
                open(my $chs, '>', 'src/include/catalog/header-stamp')
                  || confess "Could not touch header-stamp";
                close($chs);
index 4575e3f95f69cdec585ead0aab81c7594c2e9b17..d0d79a09325737883790ce665d1c8c7e3f6f1845 100755 (executable)
@@ -47,6 +47,7 @@ if exist src\include\utils\fmgrprotos.h del /q src\include\utils\fmgrprotos.h
 if exist src\include\storage\lwlocknames.h del /q src\include\storage\lwlocknames.h
 if exist src\include\utils\probes.h del /q src\include\utils\probes.h
 if exist src\include\catalog\schemapg.h del /q src\include\catalog\schemapg.h
+if exist src\include\catalog\system_fk_info.h del /q src\include\catalog\system_fk_info.h
 if exist src\include\catalog\pg_*_d.h del /q src\include\catalog\pg_*_d.h
 if exist src\include\catalog\header-stamp del /q src\include\catalog\header-stamp
 if exist doc\src\sgml\version.sgml del /q doc\src\sgml\version.sgml
@@ -73,6 +74,7 @@ if %DIST%==1 if exist src\interfaces\ecpg\preproc\preproc.y del /q src\interface
 if %DIST%==1 if exist src\backend\catalog\postgres.bki del /q src\backend\catalog\postgres.bki
 if %DIST%==1 if exist src\backend\catalog\system_constraints.sql del /q src\backend\catalog\system_constraints.sql
 if %DIST%==1 if exist src\backend\catalog\schemapg.h del /q src\backend\catalog\schemapg.h
+if %DIST%==1 if exist src\backend\catalog\system_fk_info.h del /q src\backend\catalog\system_fk_info.h
 if %DIST%==1 if exist src\backend\catalog\pg_*_d.h del /q src\backend\catalog\pg_*_d.h
 if %DIST%==1 if exist src\backend\catalog\bki-stamp del /q src\backend\catalog\bki-stamp
 if %DIST%==1 if exist src\backend\parser\scan.c del /q src\backend\parser\scan.c