Re: Recording foreign key relationships for the system catalogs

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: Recording foreign key relationships for the system catalogs
Дата
Msg-id 3683750.1612236462@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: Recording foreign key relationships for the system catalogs  ("Joel Jacobson" <joel@compiler.org>)
Ответы Re: Recording foreign key relationships for the system catalogs
Список pgsql-hackers
"Joel Jacobson" <joel@compiler.org> writes:
> Could it be an idea to also add
>    OUT can_be_zero boolean
> to pg_get_catalog_foreign_keys()'s out parameters?

I was initially feeling resistant to that idea, but warmed to it
once I realized that a majority of the FK referencing columns
actually should not contain zeroes.  So we can get a useful
improvement in the strictness of the test coverage if we make this
distinction --- and we can enforce it in the initial catalog data,
too.

So here's a v2 that does that.  In the interests of brevity,
I spelled the declaration macros that allow a zero as BKI_LOOKUP_OPT,
DECLARE_FOREIGN_KEY_OPT, etc; and thus the output column is
also is_opt.  I'm not wedded to that term but I think we need
something pretty short.

This also moves the oidjoins regression test to run near the
end of the test suite.  As I commented earlier, that test was
originally mainly meant to validate the handwritten initial
data; but nowadays it's hard to see what it would catch that
genbki.pl doesn't.  So the usefulness is in looking at rows
that get added later, and therefore we ought to run it after
the regression tests have created stuff.  I've tried here
to run it in parallel with event_triggers, which might be
foolish.

I also added some documentation.  I feel like this might
be committable at this point.

            regards, tom lane

diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 036a72c81e..6d3c5be67f 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -474,10 +474,15 @@

     <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>
@@ -554,6 +559,22 @@
     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">
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 865e826fb0..5da82a4846 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -5588,7 +5588,8 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
        (references <link
linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
       </para>
       <para>
-       The roles to which the policy is applied
+       The roles to which the policy is applied;
+       zero means <literal>PUBLIC</literal>
       </para></entry>
      </row>

@@ -7836,7 +7837,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
       <para>
        The OID of the function to use when converting the data type for input
        to the procedural language (e.g., function parameters).  Zero is stored
-       if this operation is not supported.
+       if the default behavior should be used.
       </para></entry>
      </row>

@@ -7848,7 +7849,7 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
       <para>
        The OID of the function to use when converting output from the
        procedural language (e.g., return values) to the data type.  Zero is
-       stored if this operation is not supported.
+       stored if the default behavior should be used.
       </para></entry>
      </row>
     </tbody>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 081f04ce1a..b7150510ab 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -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>
diff --git a/src/backend/catalog/.gitignore b/src/backend/catalog/.gitignore
index 4bd3ee9d7f..237ff54165 100644
--- a/src/backend/catalog/.gitignore
+++ b/src/backend/catalog/.gitignore
@@ -1,5 +1,6 @@
 /postgres.bki
 /schemapg.h
+/system_fk_info.h
 /system_constraints.sql
 /pg_*_d.h
 /bki-stamp
diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index 061f3d8c21..b44d568b54 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -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
                     {
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 995ddf1285..70bc2123df 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -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))

diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index b68c1752c0..5bdc7adc44 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -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;
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 4096faff9a..634f574d7e 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -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.
  */
diff --git a/src/include/Makefile b/src/include/Makefile
index c557375ae3..5f257a958c 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -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
diff --git a/src/include/catalog/.gitignore b/src/include/catalog/.gitignore
index 6c8da5401d..6b83d4c7e6 100644
--- a/src/include/catalog/.gitignore
+++ b/src/include/catalog/.gitignore
@@ -1,3 +1,4 @@
 /schemapg.h
+/system_fk_info.h
 /pg_*_d.h
 /header-stamp
diff --git a/src/include/catalog/genbki.h b/src/include/catalog/genbki.h
index 5d05fafb5d..b1fee54d3c 100644
--- a/src/include/catalog/genbki.h
+++ b/src/include/catalog/genbki.h
@@ -36,10 +36,15 @@
 /* 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
@@ -75,6 +80,33 @@
 #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. */

 /*
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 8b03cdeea2..25feb41678 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -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);
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 554fc41497..e1cca35e31 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -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;

 /* ----------------
diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
index 03efaaded9..d689ca20c8 100644
--- a/src/include/catalog/pg_attrdef.h
+++ b/src/include/catalog/pg_attrdef.h
@@ -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 */
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index ba0efff08c..3db42abf08 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -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. */
diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h
index e90c395640..76ab90c939 100644
--- a/src/include/catalog/pg_auth_members.h
+++ b/src/include/catalog/pg_auth_members.h
@@ -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;

diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index 2d36628c20..f64a9df54c 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -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;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index eca306ca98..bb6938caa2 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -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 */
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index ad57b0fa6d..6e0ab1ab4b 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -14,18 +14,15 @@

 { 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' },

 ]
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 3c496ea914..3bd7873c68 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -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" */
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index 6449937b35..63f0f8bf41 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -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 */
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index b02dfe0c3f..96bb92f251 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -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);
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index b7a0b6a381..f0240c58cf 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -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;
diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h
index f18819d670..705f698ae7 100644
--- a/src/include/catalog/pg_db_role_setting.h
+++ b/src/include/catalog/pg_db_role_setting.h
@@ -33,8 +33,11 @@
  */
 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 */
diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h
index bb7db32cd6..156fc0712d 100644
--- a/src/include/catalog/pg_default_acl.h
+++ b/src/include/catalog/pg_default_acl.h
@@ -30,8 +30,10 @@
 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 */
diff --git a/src/include/catalog/pg_depend.h b/src/include/catalog/pg_depend.h
index b083790180..606a2a8e19 100644
--- a/src/include/catalog/pg_depend.h
+++ b/src/include/catalog/pg_depend.h
@@ -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 */

diff --git a/src/include/catalog/pg_description.h b/src/include/catalog/pg_description.h
index ad9de5e0a0..adc06a854d 100644
--- a/src/include/catalog/pg_description.h
+++ b/src/include/catalog/pg_description.h
@@ -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 */
diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h
index 5eaf70772c..78a183b27d 100644
--- a/src/include/catalog/pg_enum.h
+++ b/src/include/catalog/pg_enum.h
@@ -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;
diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h
index 6f0266ed0f..eeaa6be518 100644
--- a/src/include/catalog/pg_event_trigger.h
+++ b/src/include/catalog/pg_event_trigger.h
@@ -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 */

diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h
index af119bfea7..2d6ad9fa88 100644
--- a/src/include/catalog/pg_extension.h
+++ b/src/include/catalog/pg_extension.h
@@ -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;
diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h
index 0f523a26b9..f6240d9eb3 100644
--- a/src/include/catalog/pg_foreign_data_wrapper.h
+++ b/src/include/catalog/pg_foreign_data_wrapper.h
@@ -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 */
diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h
index 385b896e97..a173699aef 100644
--- a/src/include/catalog/pg_foreign_server.h
+++ b/src/include/catalog/pg_foreign_server.h
@@ -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;
diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h
index 24f7f2998e..3b6221b0e6 100644
--- a/src/include/catalog/pg_foreign_table.h
+++ b/src/include/catalog/pg_foreign_table.h
@@ -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 */
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index 1a7aef18ce..00d0b439f5 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -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

 /*
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index b8147796d8..2b71cad9a2 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -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;

diff --git a/src/include/catalog/pg_init_privs.h b/src/include/catalog/pg_init_privs.h
index 983b1857c0..4aafeb246d 100644
--- a/src/include/catalog/pg_init_privs.h
+++ b/src/include/catalog/pg_init_privs.h
@@ -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? */

diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h
index b1dcd0a4f5..e9df9dac09 100644
--- a/src/include/catalog/pg_language.h
+++ b/src/include/catalog/pg_language.h
@@ -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 */
diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h
index f453319322..32225f4de7 100644
--- a/src/include/catalog/pg_largeobject.h
+++ b/src/include/catalog/pg_largeobject.h
@@ -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 */
diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h
index 220988b0ad..9b689bab84 100644
--- a/src/include/catalog/pg_largeobject_metadata.h
+++ b/src/include/catalog/pg_largeobject_metadata.h
@@ -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 */
diff --git a/src/include/catalog/pg_namespace.dat b/src/include/catalog/pg_namespace.dat
index 76257e98fc..2ed136b787 100644
--- a/src/include/catalog/pg_namespace.dat
+++ b/src/include/catalog/pg_namespace.dat
@@ -14,12 +14,12 @@

 { 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_' },

 ]
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index 0a68958b1c..d920c6cfc6 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -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];
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index d132df1f2f..9f321f2a85 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -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;

 /* ----------------
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 3ca57e7c1b..7f06abaeec 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -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;

 /* ----------------
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index 18385a6fd6..1a723b76f6 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -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;

 /* ----------------
diff --git a/src/include/catalog/pg_partitioned_table.h b/src/include/catalog/pg_partitioned_table.h
index 038730b005..48cbaf30ff 100644
--- a/src/include/catalog/pg_partitioned_table.h
+++ b/src/include/catalog/pg_partitioned_table.h
@@ -29,11 +29,11 @@
  */
 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 */
diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h
index 44197613e0..645b8fe498 100644
--- a/src/include/catalog/pg_policy.h
+++ b/src/include/catalog/pg_policy.h
@@ -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
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index f8174061ef..4e0c9be58c 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -2405,7 +2405,7 @@
 { 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_classwhere 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_classwhere 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',
@@ -2414,7 +2414,7 @@
   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_classwhere relname = $2 and relnamespace = PGNSP)' }, 
+  prosrc => 'select description from pg_catalog.pg_shdescription where objoid = $1 and classoid = (select oid from
pg_catalog.pg_classwhere relname = $2 and relnamespace = \'pg_catalog\'::pg_catalog.regnamespace)' }, 

 { oid => '1217',
   descr => 'truncate timestamp with time zone to specified units',
@@ -3698,6 +3698,14 @@
   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',
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 03c8bef422..2f54aa171e 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -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;
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index 4127611f5a..1b31fee9e3 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -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
diff --git a/src/include/catalog/pg_publication_rel.h b/src/include/catalog/pg_publication_rel.h
index c79b7fb487..aecf53b3b3 100644
--- a/src/include/catalog/pg_publication_rel.h
+++ b/src/include/catalog/pg_publication_rel.h
@@ -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;

 /* ----------------
diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h
index 2ec6a4b126..5dfa4eef8b 100644
--- a/src/include/catalog/pg_range.h
+++ b/src/include/catalog/pg_range.h
@@ -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;

 /* ----------------
diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h
index 36f92b1cf1..89c72545d0 100644
--- a/src/include/catalog/pg_rewrite.h
+++ b/src/include/catalog/pg_rewrite.h
@@ -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;
diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h
index b14fd7febe..0a12225eb7 100644
--- a/src/include/catalog/pg_seclabel.h
+++ b/src/include/catalog/pg_seclabel.h
@@ -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 */
diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h
index addf21abce..8d0a00baf6 100644
--- a/src/include/catalog/pg_sequence.h
+++ b/src/include/catalog/pg_sequence.h
@@ -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;
diff --git a/src/include/catalog/pg_shdepend.h b/src/include/catalog/pg_shdepend.h
index f5863954e9..4faa95794d 100644
--- a/src/include/catalog/pg_shdepend.h
+++ b/src/include/catalog/pg_shdepend.h
@@ -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 */

     /*
diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h
index a37db4fa0b..543e216710 100644
--- a/src/include/catalog/pg_shdescription.h
+++ b/src/include/catalog/pg_shdescription.h
@@ -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 */
diff --git a/src/include/catalog/pg_shseclabel.h b/src/include/catalog/pg_shseclabel.h
index 406f5328a7..5d6864cf8c 100644
--- a/src/include/catalog/pg_shseclabel.h
+++ b/src/include/catalog/pg_shseclabel.h
@@ -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 */
diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
index 4a66bda879..d1827858e2 100644
--- a/src/include/catalog/pg_statistic.h
+++ b/src/include/catalog/pg_statistic.h
@@ -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,
staattnumint2_ops, stainherit bool_ops)); 
 #define StatisticRelidAttnumInhIndexId    2696

+DECLARE_FOREIGN_KEY((starelid, staattnum), pg_attribute, (attrelid, attnum));
+
 #ifdef EXPOSE_TO_CLIENT_CODE

 /*
diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h
index 10f52f912c..29649f5814 100644
--- a/src/include/catalog/pg_statistic_ext.h
+++ b/src/include/catalog/pg_statistic_ext.h
@@ -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'
diff --git a/src/include/catalog/pg_statistic_ext_data.h b/src/include/catalog/pg_statistic_ext_data.h
index 6f7a36c141..2f2577c218 100644
--- a/src/include/catalog/pg_statistic_ext_data.h
+++ b/src/include/catalog/pg_statistic_ext_data.h
@@ -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 */

diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h
index 4e44c29149..a5d6efdf20 100644
--- a/src/include/catalog/pg_subscription.h
+++ b/src/include/catalog/pg_subscription.h
@@ -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) */
diff --git a/src/include/catalog/pg_subscription_rel.h b/src/include/catalog/pg_subscription_rel.h
index ab1202cf9b..2bea2c52aa 100644
--- a/src/include/catalog/pg_subscription_rel.h
+++ b/src/include/catalog/pg_subscription_rel.h
@@ -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 */

     /*
diff --git a/src/include/catalog/pg_tablespace.dat b/src/include/catalog/pg_tablespace.dat
index 212a0ad07f..bf0d81d306 100644
--- a/src/include/catalog/pg_tablespace.dat
+++ b/src/include/catalog/pg_tablespace.dat
@@ -13,10 +13,8 @@
 [

 { 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_' },

 ]
diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h
index 6a6c66a61c..ed38e6950d 100644
--- a/src/include/catalog/pg_tablespace.h
+++ b/src/include/catalog/pg_tablespace.h
@@ -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 */
diff --git a/src/include/catalog/pg_transform.h b/src/include/catalog/pg_transform.h
index ad25db1841..d603246138 100644
--- a/src/include/catalog/pg_transform.h
+++ b/src/include/catalog/pg_transform.h
@@ -29,10 +29,10 @@
 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;

 /* ----------------
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 55111ed864..2e3d233876 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -34,18 +34,25 @@
 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 */
diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h
index 02ef1a1554..e705899b17 100644
--- a/src/include/catalog/pg_ts_config.h
+++ b/src/include/catalog/pg_ts_config.h
@@ -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);
diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h
index bfe3378ff8..57f626e7b5 100644
--- a/src/include/catalog/pg_ts_dict.h
+++ b/src/include/catalog/pg_ts_dict.h
@@ -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);
diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h
index f9f22716fd..e0d705fd9a 100644
--- a/src/include/catalog/pg_ts_parser.h
+++ b/src/include/catalog/pg_ts_parser.h
@@ -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);
diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h
index ae91922688..2ee1ae4e85 100644
--- a/src/include/catalog/pg_ts_template.h
+++ b/src/include/catalog/pg_ts_template.h
@@ -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);
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 0d6981bc87..1ec8606703 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -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 */

diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h
index cabca048a9..d440c67da1 100644
--- a/src/include/catalog/pg_user_mapping.h
+++ b/src/include/catalog/pg_user_mapping.h
@@ -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 */
diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out
index 4731dacfbf..bc24949616 100644
--- a/src/test/regress/expected/oidjoins.out
+++ b/src/test/regress/expected/oidjoins.out
@@ -1,1451 +1,266 @@
 --
--- 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 notice '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}
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index e0e1ef71dd..12bb67e491 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -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

diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 081fce32e7..59b416fd80 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -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
diff --git a/src/test/regress/sql/oidjoins.sql b/src/test/regress/sql/oidjoins.sql
index f6d2d3c68c..07a9a74190 100644
--- a/src/test/regress/sql/oidjoins.sql
+++ b/src/test/regress/sql/oidjoins.sql
@@ -1,727 +1,49 @@
 --
--- 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 notice 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err;
+    end loop;
+  end loop;
+end
+$doblock$;
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1c0c92fcd2..2aa062b2c9 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -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);
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index 4575e3f95f..d0d79a0932 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -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

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Geoghegan
Дата:
Сообщение: Re: New IndexAM API controlling index vacuum strategies
Следующее
От: Fujii Masao
Дата:
Сообщение: Re: [PATCH] postgres_fdw connection caching - cause remote sessions linger till the local session exit