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

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

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

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

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