Teach genbki.pl to auto-generate pg_type entries for array types.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 20 Sep 2018 19:14:46 +0000 (15:14 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 20 Sep 2018 19:14:46 +0000 (15:14 -0400)
This eliminates some more tedium in adding new catalog entries,
specifically the need to set up an array type when adding a new
built-in data type.  Now it's sufficient to assign an OID for the
array type and write it in an "array_type_oid" metadata field.
You don't have to fill the base type's typarray link explicitly, either.

No catversion bump since the contents of pg_type aren't changed.
(Well, their order might be different, but that doesn't matter.)

John Naylor, reviewed and whacked around a bit by
Dagfinn Ilmari MannsÃ¥ker, and some more by me.

Discussion: https://postgr.es/m/CAJVSVGVTb6m9pJF49b3SuA8J+T-THO9c0hxOmoyv-yGKh-FbNg@mail.gmail.com

doc/src/sgml/bki.sgml
src/backend/catalog/Catalog.pm
src/backend/catalog/genbki.pl
src/include/catalog/genbki.h
src/include/catalog/pg_type.dat
src/include/catalog/pg_type.h
src/include/catalog/reformat_dat_file.pl

index e3ba73a9a8dd24997d1e25d070f9f16206b84d86..0fb309a1bd9773471884466827973ed004d23c45 100644 (file)
       <replaceable>value</replaceable> pairs.  The
       allowed <replaceable>key</replaceable>s are the names of the catalog's
       columns, plus the metadata keys <literal>oid</literal>,
-      <literal>oid_symbol</literal>, and <literal>descr</literal>.
+      <literal>oid_symbol</literal>,
+      <literal>array_type_oid</literal>, and <literal>descr</literal>.
       (The use of <literal>oid</literal> and <literal>oid_symbol</literal>
-      is described in <xref linkend="system-catalog-oid-assignment"/>
-      below.  <literal>descr</literal> supplies a description string for
-      the object, which will be inserted
-      into <structname>pg_description</structname>
+      is described in <xref linkend="system-catalog-oid-assignment"/> below,
+      while <literal>array_type_oid</literal> is described in
+      <xref linkend="system-catalog-auto-array-types"/>.
+      <literal>descr</literal> supplies a description string for the object,
+      which will be inserted into <structname>pg_description</structname>
       or <structname>pg_shdescription</structname> as appropriate.)
       While the metadata keys are optional, the catalog's defined columns
       must all be provided, except when the catalog's <literal>.h</literal>
         <para>
          Within each pair of curly braces, the metadata
          fields <literal>oid</literal>, <literal>oid_symbol</literal>,
-         and <literal>descr</literal> (if present) come first, in that
-         order, then the catalog's own fields appear in their defined order.
+         <literal>array_type_oid</literal>, and <literal>descr</literal>
+         (if present) come first, in that order, then the catalog's own
+         fields appear in their defined order.
         </para>
        </listitem>
 
    </para>
   </sect2>
 
+  <sect2 id="system-catalog-auto-array-types">
+   <title>Automatic Creation of Array Types</title>
+
+   <para>
+    Most scalar data types should have a corresponding array type (that is,
+    a standard varlena array type whose element type is the scalar type, and
+    which is referenced by the <structfield>typarray</structfield> field of
+    the scalar type's <structname>pg_type</structname>
+    entry).  <filename>genbki.pl</filename> is able to generate
+    the <structname>pg_type</structname> entry for the array type
+    automatically in most cases.
+   </para>
+
+   <para>
+    To use this facility, just write an <literal>array_type_oid
+    =&gt; <replaceable>nnnn</replaceable></literal> metadata field in the
+    scalar type's <structname>pg_type</structname> entry, specifying the OID
+    to use for the array type.  You may then omit
+    the <structfield>typarray</structfield> field, since it will be filled
+    automatically with that OID.
+   </para>
+
+   <para>
+    The generated array type's name is the scalar type's name with an
+    underscore prepended.  The array entry's other fields are filled from
+    <literal>BKI_ARRAY_DEFAULT(<replaceable>value</replaceable>)</literal>
+    annotations in <filename>pg_type.h</filename>, or if there isn't one,
+    copied from the scalar type.  (There's also a special case
+    for <structfield>typalign</structfield>.)  Then
+    the <structfield>typelem</structfield>
+    and <structfield>typarray</structfield> fields of the two entries are
+    set to cross-reference each other.
+   </para>
+  </sect2>
+
   <sect2 id="system-catalog-recipes">
    <title>Recipes for Editing Data Files</title>
 
index ae5b499b6adca3029b61b01be3027e7f06749166..d2f48d1d0d502903fdea963fb98de0df066d4eed 100644 (file)
@@ -191,6 +191,11 @@ sub ParseHeader
                    {
                        $column{default} = $1;
                    }
+                   elsif (
+                       $attopt =~ /BKI_ARRAY_DEFAULT\(['"]?([^'"]+)['"]?\)/)
+                   {
+                       $column{array_default} = $1;
+                   }
                    elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/)
                    {
                        $column{lookup} = $1;
@@ -277,12 +282,16 @@ sub ParseData
            }
        }
 
-       # If we found a hash reference, keep it.
-       # Only keep non-data strings if we
-       # are told to preserve formatting.
+       # If we found a hash reference, keep it, unless it is marked as
+       # autogenerated; in that case it'd duplicate an entry we'll
+       # autogenerate below.  (This makes it safe for reformat_dat_file.pl
+       # with --full-tuples to print autogenerated entries, which seems like
+       # useful behavior for debugging.)
+       #
+       # Only keep non-data strings if we are told to preserve formatting.
        if (defined $hash_ref)
        {
-           push @$data, $hash_ref;
+           push @$data, $hash_ref if !$hash_ref->{autogenerated};
        }
        elsif ($preserve_formatting)
        {
@@ -290,6 +299,10 @@ sub ParseData
        }
    }
    close $ifd;
+
+   # If this is pg_type, auto-generate array types too.
+   GenerateArrayTypes($schema, $data) if $catname eq 'pg_type';
+
    return $data;
 }
 
@@ -343,6 +356,63 @@ sub AddDefaultValues
    }
 }
 
+# If a pg_type entry has an array_type_oid metadata field,
+# auto-generate an entry for its array type.
+sub GenerateArrayTypes
+{
+   my $pgtype_schema = shift;
+   my $types         = shift;
+   my @array_types;
+
+   foreach my $elem_type (@$types)
+   {
+       next if !(ref $elem_type eq 'HASH');
+       next if !defined($elem_type->{array_type_oid});
+
+       my %array_type;
+
+       # Set up metadata fields for array type.
+       $array_type{oid}           = $elem_type->{array_type_oid};
+       $array_type{autogenerated} = 1;
+       $array_type{line_number}   = $elem_type->{line_number};
+
+       # Set up column values derived from the element type.
+       $array_type{typname} = '_' . $elem_type->{typname};
+       $array_type{typelem} = $elem_type->{typname};
+
+       # Arrays require INT alignment, unless the element type requires
+       # DOUBLE alignment.
+       $array_type{typalign} = $elem_type->{typalign} eq 'd' ? 'd' : 'i';
+
+       # Fill in the rest of the array entry's fields.
+       foreach my $column (@$pgtype_schema)
+       {
+           my $attname = $column->{name};
+
+           # Skip if we already set it above.
+           next if defined $array_type{$attname};
+
+           # Apply the BKI_ARRAY_DEFAULT setting if there is one,
+           # otherwise copy the field from the element type.
+           if (defined $column->{array_default})
+           {
+               $array_type{$attname} = $column->{array_default};
+           }
+           else
+           {
+               $array_type{$attname} = $elem_type->{$attname};
+           }
+       }
+
+       # Lastly, cross-link the array to the element type.
+       $elem_type->{typarray} = $array_type{typname};
+
+       push @array_types, \%array_type;
+   }
+
+   push @$types, @array_types;
+}
+
 # Rename temporary files to final names.
 # Call this function with the final file name and the .tmp extension.
 #
index 9be51d28b038d25037639b300a4ab63f661505df..649200260a4e0d36d2c377190301852a7eef1b02 100644 (file)
@@ -394,7 +394,9 @@ EOM
            next
              if $key eq "oid"
              || $key eq "oid_symbol"
+             || $key eq "array_type_oid"
              || $key eq "descr"
+             || $key eq "autogenerated"
              || $key eq "line_number";
            die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n",
              $key, $catname, $bki_values{line_number}
index b1e2cbdb6290355da43ed270cf42b1738320cddf..8a4277b7c8740bf8144d79e86f661f5de191964f 100644 (file)
@@ -34,6 +34,8 @@
 #define BKI_FORCE_NOT_NULL
 /* Specifies a default value for a catalog field */
 #define BKI_DEFAULT(value)
+/* Specifies a default value for auto-generated array types */
+#define BKI_ARRAY_DEFAULT(value)
 /* Indicates how to perform name lookups for an OID or OID-array field */
 #define BKI_LOOKUP(catalog)
 
index 48e01cd694767f4875731a7907365c601665b6ef..67dd0ce8b336cafdb784284fe1234ce8cc2df06a 100644 (file)
 # The only oid_symbol entries in this file are for names that don't match
 # this rule, and are grandfathered in.
 
+# To autogenerate an array type, add 'array_type_oid => 'nnnn' to the element
+# type, which will instruct genbki.pl to generate a BKI entry for it.
+# In a few cases, the array type's properties don't match the normal pattern
+# so it can't be autogenerated; in such cases do not write array_type_oid.
+
 # Once upon a time these entries were ordered by OID.  Lately it's often
 # been the custom to insert new entries adjacent to related older entries.
 # Try to do one or the other though, don't just insert entries at random.
 
 # OIDS 1 - 99
 
-{ oid => '16', descr => 'boolean, \'true\'/\'false\'',
+{ oid => '16', array_type_oid => '1000',
+  descr => 'boolean, \'true\'/\'false\'',
   typname => 'bool', typlen => '1', typbyval => 't', typcategory => 'B',
-  typispreferred => 't', typarray => '_bool', typinput => 'boolin',
-  typoutput => 'boolout', typreceive => 'boolrecv', typsend => 'boolsend',
-  typalign => 'c' },
-{ oid => '17', descr => 'variable-length string, binary values escaped',
+  typispreferred => 't', typinput => 'boolin', typoutput => 'boolout',
+  typreceive => 'boolrecv', typsend => 'boolsend', typalign => 'c' },
+{ oid => '17', array_type_oid => '1001',
+  descr => 'variable-length string, binary values escaped',
   typname => 'bytea', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_bytea', typinput => 'byteain', typoutput => 'byteaout',
-  typreceive => 'bytearecv', typsend => 'byteasend', typalign => 'i',
-  typstorage => 'x' },
-{ oid => '18', descr => 'single character',
+  typinput => 'byteain', typoutput => 'byteaout', typreceive => 'bytearecv',
+  typsend => 'byteasend', typalign => 'i', typstorage => 'x' },
+{ oid => '18', array_type_oid => '1002', descr => 'single character',
   typname => 'char', typlen => '1', typbyval => 't', typcategory => 'S',
-  typarray => '_char', typinput => 'charin', typoutput => 'charout',
-  typreceive => 'charrecv', typsend => 'charsend', typalign => 'c' },
-{ oid => '19', descr => '63-byte type for storing system identifiers',
+  typinput => 'charin', typoutput => 'charout', typreceive => 'charrecv',
+  typsend => 'charsend', typalign => 'c' },
+{ oid => '19', array_type_oid => '1003',
+  descr => '63-byte type for storing system identifiers',
   typname => 'name', typlen => 'NAMEDATALEN', typbyval => 'f',
-  typcategory => 'S', typelem => 'char', typarray => '_name',
-  typinput => 'namein', typoutput => 'nameout', typreceive => 'namerecv',
-  typsend => 'namesend', typalign => 'c' },
-{ oid => '20', descr => '~18 digit integer, 8-byte storage',
+  typcategory => 'S', typelem => 'char', typinput => 'namein',
+  typoutput => 'nameout', typreceive => 'namerecv', typsend => 'namesend',
+  typalign => 'c' },
+{ oid => '20', array_type_oid => '1016',
+  descr => '~18 digit integer, 8-byte storage',
   typname => 'int8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'N', typarray => '_int8', typinput => 'int8in',
-  typoutput => 'int8out', typreceive => 'int8recv', typsend => 'int8send',
-  typalign => 'd' },
-{ oid => '21', descr => '-32 thousand to 32 thousand, 2-byte storage',
+  typcategory => 'N', typinput => 'int8in', typoutput => 'int8out',
+  typreceive => 'int8recv', typsend => 'int8send', typalign => 'd' },
+{ oid => '21', array_type_oid => '1005',
+  descr => '-32 thousand to 32 thousand, 2-byte storage',
   typname => 'int2', typlen => '2', typbyval => 't', typcategory => 'N',
-  typarray => '_int2', typinput => 'int2in', typoutput => 'int2out',
-  typreceive => 'int2recv', typsend => 'int2send', typalign => 's' },
-{ oid => '22', descr => 'array of int2, used in system tables',
+  typinput => 'int2in', typoutput => 'int2out', typreceive => 'int2recv',
+  typsend => 'int2send', typalign => 's' },
+{ oid => '22', array_type_oid => '1006',
+  descr => 'array of int2, used in system tables',
   typname => 'int2vector', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int2', typarray => '_int2vector', typinput => 'int2vectorin',
-  typoutput => 'int2vectorout', typreceive => 'int2vectorrecv',
-  typsend => 'int2vectorsend', typalign => 'i' },
-{ oid => '23', descr => '-2 billion to 2 billion integer, 4-byte storage',
+  typelem => 'int2', typinput => 'int2vectorin', typoutput => 'int2vectorout',
+  typreceive => 'int2vectorrecv', typsend => 'int2vectorsend',
+  typalign => 'i' },
+{ oid => '23', array_type_oid => '1007',
+  descr => '-2 billion to 2 billion integer, 4-byte storage',
   typname => 'int4', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_int4', typinput => 'int4in', typoutput => 'int4out',
-  typreceive => 'int4recv', typsend => 'int4send', typalign => 'i' },
-{ oid => '24', descr => 'registered procedure',
+  typinput => 'int4in', typoutput => 'int4out', typreceive => 'int4recv',
+  typsend => 'int4send', typalign => 'i' },
+{ oid => '24', array_type_oid => '1008', descr => 'registered procedure',
   typname => 'regproc', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regproc', typinput => 'regprocin', typoutput => 'regprocout',
+  typinput => 'regprocin', typoutput => 'regprocout',
   typreceive => 'regprocrecv', typsend => 'regprocsend', typalign => 'i' },
-{ oid => '25', descr => 'variable-length string, no limit specified',
+{ oid => '25', array_type_oid => '1009',
+  descr => 'variable-length string, no limit specified',
   typname => 'text', typlen => '-1', typbyval => 'f', typcategory => 'S',
-  typispreferred => 't', typarray => '_text', typinput => 'textin',
-  typoutput => 'textout', typreceive => 'textrecv', typsend => 'textsend',
-  typalign => 'i', typstorage => 'x', typcollation => '100' },
-{ oid => '26', descr => 'object identifier(oid), maximum 4 billion',
+  typispreferred => 't', typinput => 'textin', typoutput => 'textout',
+  typreceive => 'textrecv', typsend => 'textsend', typalign => 'i',
+  typstorage => 'x', typcollation => '100' },
+{ oid => '26', array_type_oid => '1028',
+  descr => 'object identifier(oid), maximum 4 billion',
   typname => 'oid', typlen => '4', typbyval => 't', typcategory => 'N',
-  typispreferred => 't', typarray => '_oid', typinput => 'oidin',
-  typoutput => 'oidout', typreceive => 'oidrecv', typsend => 'oidsend',
-  typalign => 'i' },
-{ oid => '27', descr => '(block, offset), physical location of tuple',
+  typispreferred => 't', typinput => 'oidin', typoutput => 'oidout',
+  typreceive => 'oidrecv', typsend => 'oidsend', typalign => 'i' },
+{ oid => '27', array_type_oid => '1010',
+  descr => '(block, offset), physical location of tuple',
   typname => 'tid', typlen => '6', typbyval => 'f', typcategory => 'U',
-  typarray => '_tid', typinput => 'tidin', typoutput => 'tidout',
-  typreceive => 'tidrecv', typsend => 'tidsend', typalign => 's' },
-{ oid => '28', descr => 'transaction id',
+  typinput => 'tidin', typoutput => 'tidout', typreceive => 'tidrecv',
+  typsend => 'tidsend', typalign => 's' },
+{ oid => '28', array_type_oid => '1011', descr => 'transaction id',
   typname => 'xid', typlen => '4', typbyval => 't', typcategory => 'U',
-  typarray => '_xid', typinput => 'xidin', typoutput => 'xidout',
-  typreceive => 'xidrecv', typsend => 'xidsend', typalign => 'i' },
-{ oid => '29', descr => 'command identifier type, sequence in transaction id',
+  typinput => 'xidin', typoutput => 'xidout', typreceive => 'xidrecv',
+  typsend => 'xidsend', typalign => 'i' },
+{ oid => '29', array_type_oid => '1012',
+  descr => 'command identifier type, sequence in transaction id',
   typname => 'cid', typlen => '4', typbyval => 't', typcategory => 'U',
-  typarray => '_cid', typinput => 'cidin', typoutput => 'cidout',
-  typreceive => 'cidrecv', typsend => 'cidsend', typalign => 'i' },
-{ oid => '30', descr => 'array of oids, used in system tables',
+  typinput => 'cidin', typoutput => 'cidout', typreceive => 'cidrecv',
+  typsend => 'cidsend', typalign => 'i' },
+{ oid => '30', array_type_oid => '1013',
+  descr => 'array of oids, used in system tables',
   typname => 'oidvector', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'oid', typarray => '_oidvector', typinput => 'oidvectorin',
-  typoutput => 'oidvectorout', typreceive => 'oidvectorrecv',
-  typsend => 'oidvectorsend', typalign => 'i' },
+  typelem => 'oid', typinput => 'oidvectorin', typoutput => 'oidvectorout',
+  typreceive => 'oidvectorrecv', typsend => 'oidvectorsend', typalign => 'i' },
 
 # hand-built rowtype entries for bootstrapped catalogs
 # NB: OIDs assigned here must match the BKI_ROWTYPE_OID declarations
 
 # OIDS 100 - 199
 
-{ oid => '114',
+{ oid => '114', array_type_oid => '199',
   typname => 'json', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_json', typinput => 'json_in', typoutput => 'json_out',
-  typreceive => 'json_recv', typsend => 'json_send', typalign => 'i',
-  typstorage => 'x' },
-{ oid => '142', descr => 'XML content',
+  typinput => 'json_in', typoutput => 'json_out', typreceive => 'json_recv',
+  typsend => 'json_send', typalign => 'i', typstorage => 'x' },
+{ oid => '142', array_type_oid => '143', descr => 'XML content',
   typname => 'xml', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_xml', typinput => 'xml_in', typoutput => 'xml_out',
-  typreceive => 'xml_recv', typsend => 'xml_send', typalign => 'i',
-  typstorage => 'x' },
-{ oid => '143',
-  typname => '_xml', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'xml', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '199',
-  typname => '_json', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'json', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
+  typinput => 'xml_in', typoutput => 'xml_out', typreceive => 'xml_recv',
+  typsend => 'xml_send', typalign => 'i', typstorage => 'x' },
 { oid => '194', oid_symbol => 'PGNODETREEOID',
   descr => 'string representing an internal node tree',
   typname => 'pg_node_tree', typlen => '-1', typbyval => 'f',
 
 # OIDS 600 - 699
 
-{ oid => '600', descr => 'geometric point \'(x, y)\'',
+{ oid => '600', array_type_oid => '1017',
+  descr => 'geometric point \'(x, y)\'',
   typname => 'point', typlen => '16', typbyval => 'f', typcategory => 'G',
-  typelem => 'float8', typarray => '_point', typinput => 'point_in',
-  typoutput => 'point_out', typreceive => 'point_recv', typsend => 'point_send',
-  typalign => 'd' },
-{ oid => '601', descr => 'geometric line segment \'(pt1,pt2)\'',
+  typelem => 'float8', typinput => 'point_in', typoutput => 'point_out',
+  typreceive => 'point_recv', typsend => 'point_send', typalign => 'd' },
+{ oid => '601', array_type_oid => '1018',
+  descr => 'geometric line segment \'(pt1,pt2)\'',
   typname => 'lseg', typlen => '32', typbyval => 'f', typcategory => 'G',
-  typelem => 'point', typarray => '_lseg', typinput => 'lseg_in',
-  typoutput => 'lseg_out', typreceive => 'lseg_recv', typsend => 'lseg_send',
-  typalign => 'd' },
-{ oid => '602', descr => 'geometric path \'(pt1,...)\'',
+  typelem => 'point', typinput => 'lseg_in', typoutput => 'lseg_out',
+  typreceive => 'lseg_recv', typsend => 'lseg_send', typalign => 'd' },
+{ oid => '602', array_type_oid => '1019',
+  descr => 'geometric path \'(pt1,...)\'',
   typname => 'path', typlen => '-1', typbyval => 'f', typcategory => 'G',
-  typarray => '_path', typinput => 'path_in', typoutput => 'path_out',
-  typreceive => 'path_recv', typsend => 'path_send', typalign => 'd',
-  typstorage => 'x' },
-{ oid => '603', descr => 'geometric box \'(lower left,upper right)\'',
+  typinput => 'path_in', typoutput => 'path_out', typreceive => 'path_recv',
+  typsend => 'path_send', typalign => 'd', typstorage => 'x' },
+{ oid => '603', array_type_oid => '1020',
+  descr => 'geometric box \'(lower left,upper right)\'',
   typname => 'box', typlen => '32', typbyval => 'f', typcategory => 'G',
-  typdelim => ';', typelem => 'point', typarray => '_box', typinput => 'box_in',
+  typdelim => ';', typelem => 'point', typinput => 'box_in',
   typoutput => 'box_out', typreceive => 'box_recv', typsend => 'box_send',
   typalign => 'd' },
-{ oid => '604', descr => 'geometric polygon \'(pt1,...)\'',
+{ oid => '604', array_type_oid => '1027',
+  descr => 'geometric polygon \'(pt1,...)\'',
   typname => 'polygon', typlen => '-1', typbyval => 'f', typcategory => 'G',
-  typarray => '_polygon', typinput => 'poly_in', typoutput => 'poly_out',
-  typreceive => 'poly_recv', typsend => 'poly_send', typalign => 'd',
-  typstorage => 'x' },
-{ oid => '628', descr => 'geometric line',
+  typinput => 'poly_in', typoutput => 'poly_out', typreceive => 'poly_recv',
+  typsend => 'poly_send', typalign => 'd', typstorage => 'x' },
+{ oid => '628', array_type_oid => '629', descr => 'geometric line',
   typname => 'line', typlen => '24', typbyval => 'f', typcategory => 'G',
-  typelem => 'float8', typarray => '_line', typinput => 'line_in',
-  typoutput => 'line_out', typreceive => 'line_recv', typsend => 'line_send',
-  typalign => 'd' },
-{ oid => '629',
-  typname => '_line', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'line', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
+  typelem => 'float8', typinput => 'line_in', typoutput => 'line_out',
+  typreceive => 'line_recv', typsend => 'line_send', typalign => 'd' },
 
 # OIDS 700 - 799
 
-{ oid => '700',
+{ oid => '700', array_type_oid => '1021',
   descr => 'single-precision floating point number, 4-byte storage',
   typname => 'float4', typlen => '4', typbyval => 'FLOAT4PASSBYVAL',
-  typcategory => 'N', typarray => '_float4', typinput => 'float4in',
-  typoutput => 'float4out', typreceive => 'float4recv', typsend => 'float4send',
-  typalign => 'i' },
-{ oid => '701',
+  typcategory => 'N', typinput => 'float4in', typoutput => 'float4out',
+  typreceive => 'float4recv', typsend => 'float4send', typalign => 'i' },
+{ oid => '701', array_type_oid => '1022',
   descr => 'double-precision floating point number, 8-byte storage',
   typname => 'float8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'N', typispreferred => 't', typarray => '_float8',
-  typinput => 'float8in', typoutput => 'float8out', typreceive => 'float8recv',
-  typsend => 'float8send', typalign => 'd' },
-{ oid => '702',
+  typcategory => 'N', typispreferred => 't', typinput => 'float8in',
+  typoutput => 'float8out', typreceive => 'float8recv', typsend => 'float8send',
+  typalign => 'd' },
+{ oid => '702', array_type_oid => '1023',
   descr => 'absolute, limited-range date and time (Unix system time)',
   typname => 'abstime', typlen => '4', typbyval => 't', typcategory => 'D',
-  typarray => '_abstime', typinput => 'abstimein', typoutput => 'abstimeout',
+  typinput => 'abstimein', typoutput => 'abstimeout',
   typreceive => 'abstimerecv', typsend => 'abstimesend', typalign => 'i' },
-{ oid => '703',
+{ oid => '703', array_type_oid => '1024',
   descr => 'relative, limited-range time interval (Unix delta time)',
   typname => 'reltime', typlen => '4', typbyval => 't', typcategory => 'T',
-  typarray => '_reltime', typinput => 'reltimein', typoutput => 'reltimeout',
+  typinput => 'reltimein', typoutput => 'reltimeout',
   typreceive => 'reltimerecv', typsend => 'reltimesend', typalign => 'i' },
-{ oid => '704', descr => '(abstime,abstime), time interval',
+{ oid => '704', array_type_oid => '1025',
+  descr => '(abstime,abstime), time interval',
   typname => 'tinterval', typlen => '12', typbyval => 'f', typcategory => 'T',
-  typarray => '_tinterval', typinput => 'tintervalin',
-  typoutput => 'tintervalout', typreceive => 'tintervalrecv',
-  typsend => 'tintervalsend', typalign => 'i' },
+  typinput => 'tintervalin', typoutput => 'tintervalout',
+  typreceive => 'tintervalrecv', typsend => 'tintervalsend', typalign => 'i' },
 { oid => '705',
   typname => 'unknown', typlen => '-2', typbyval => 'f', typtype => 'p',
   typcategory => 'X', typinput => 'unknownin', typoutput => 'unknownout',
   typreceive => 'unknownrecv', typsend => 'unknownsend', typalign => 'c' },
-{ oid => '718', descr => 'geometric circle \'(center,radius)\'',
+{ oid => '718', array_type_oid => '719',
+  descr => 'geometric circle \'(center,radius)\'',
   typname => 'circle', typlen => '24', typbyval => 'f', typcategory => 'G',
-  typarray => '_circle', typinput => 'circle_in', typoutput => 'circle_out',
+  typinput => 'circle_in', typoutput => 'circle_out',
   typreceive => 'circle_recv', typsend => 'circle_send', typalign => 'd' },
-{ oid => '719',
-  typname => '_circle', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'circle', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '790', oid_symbol => 'CASHOID',
+{ oid => '790', oid_symbol => 'CASHOID', array_type_oid => '791',
   descr => 'monetary amounts, $d,ddd.cc',
   typname => 'money', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'N', typarray => '_money', typinput => 'cash_in',
-  typoutput => 'cash_out', typreceive => 'cash_recv', typsend => 'cash_send',
-  typalign => 'd' },
-{ oid => '791',
-  typname => '_money', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'money', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
+  typcategory => 'N', typinput => 'cash_in', typoutput => 'cash_out',
+  typreceive => 'cash_recv', typsend => 'cash_send', typalign => 'd' },
 
 # OIDS 800 - 899
 
-{ oid => '829', descr => 'XX:XX:XX:XX:XX:XX, MAC address',
+{ oid => '829', array_type_oid => '1040',
+  descr => 'XX:XX:XX:XX:XX:XX, MAC address',
   typname => 'macaddr', typlen => '6', typbyval => 'f', typcategory => 'U',
-  typarray => '_macaddr', typinput => 'macaddr_in', typoutput => 'macaddr_out',
+  typinput => 'macaddr_in', typoutput => 'macaddr_out',
   typreceive => 'macaddr_recv', typsend => 'macaddr_send', typalign => 'i' },
-{ oid => '869', descr => 'IP address/netmask, host address, netmask optional',
+{ oid => '869', array_type_oid => '1041',
+  descr => 'IP address/netmask, host address, netmask optional',
   typname => 'inet', typlen => '-1', typbyval => 'f', typcategory => 'I',
-  typispreferred => 't', typarray => '_inet', typinput => 'inet_in',
-  typoutput => 'inet_out', typreceive => 'inet_recv', typsend => 'inet_send',
-  typalign => 'i', typstorage => 'm' },
-{ oid => '650', descr => 'network IP address/netmask, network address',
-  typname => 'cidr', typlen => '-1', typbyval => 'f', typcategory => 'I',
-  typarray => '_cidr', typinput => 'cidr_in', typoutput => 'cidr_out',
-  typreceive => 'cidr_recv', typsend => 'cidr_send', typalign => 'i',
+  typispreferred => 't', typinput => 'inet_in', typoutput => 'inet_out',
+  typreceive => 'inet_recv', typsend => 'inet_send', typalign => 'i',
   typstorage => 'm' },
-{ oid => '774', descr => 'XX:XX:XX:XX:XX:XX:XX:XX, MAC address',
+{ oid => '650', array_type_oid => '651',
+  descr => 'network IP address/netmask, network address',
+  typname => 'cidr', typlen => '-1', typbyval => 'f', typcategory => 'I',
+  typinput => 'cidr_in', typoutput => 'cidr_out', typreceive => 'cidr_recv',
+  typsend => 'cidr_send', typalign => 'i', typstorage => 'm' },
+{ oid => '774', array_type_oid => '775',
+  descr => 'XX:XX:XX:XX:XX:XX:XX:XX, MAC address',
   typname => 'macaddr8', typlen => '8', typbyval => 'f', typcategory => 'U',
-  typarray => '_macaddr8', typinput => 'macaddr8_in',
-  typoutput => 'macaddr8_out', typreceive => 'macaddr8_recv',
-  typsend => 'macaddr8_send', typalign => 'i' },
+  typinput => 'macaddr8_in', typoutput => 'macaddr8_out',
+  typreceive => 'macaddr8_recv', typsend => 'macaddr8_send', typalign => 'i' },
 
 # OIDS 1000 - 1099
 
-{ oid => '1000',
-  typname => '_bool', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'bool', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1001',
-  typname => '_bytea', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'bytea', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1002',
-  typname => '_char', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'char', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1003',
-  typname => '_name', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'name', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1005',
-  typname => '_int2', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int2', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1006',
-  typname => '_int2vector', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int2vector', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1007',
-  typname => '_int4', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int4', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1008',
-  typname => '_regproc', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'regproc', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1009',
-  typname => '_text', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'text', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x',
-  typcollation => '100' },
-{ oid => '1028',
-  typname => '_oid', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'oid', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1010',
-  typname => '_tid', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'tid', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1011',
-  typname => '_xid', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'xid', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1012',
-  typname => '_cid', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'cid', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1013',
-  typname => '_oidvector', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'oidvector', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1014',
-  typname => '_bpchar', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'bpchar', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'bpchartypmodin', typmodout => 'bpchartypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x',
-  typcollation => '100' },
-{ oid => '1015',
-  typname => '_varchar', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'varchar', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'varchartypmodin', typmodout => 'varchartypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x',
-  typcollation => '100' },
-{ oid => '1016',
-  typname => '_int8', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int8', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1017',
-  typname => '_point', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'point', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1018',
-  typname => '_lseg', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'lseg', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1019',
-  typname => '_path', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'path', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1020',
-  typname => '_box', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typdelim => ';', typelem => 'box', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1021',
-  typname => '_float4', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'float4', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1022',
-  typname => '_float8', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'float8', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1023',
-  typname => '_abstime', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'abstime', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1024',
-  typname => '_reltime', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'reltime', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1025',
-  typname => '_tinterval', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'tinterval', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1027',
-  typname => '_polygon', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'polygon', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1033', descr => 'access control list',
+{ oid => '1033', array_type_oid => '1034', descr => 'access control list',
   typname => 'aclitem', typlen => '12', typbyval => 'f', typcategory => 'U',
-  typarray => '_aclitem', typinput => 'aclitemin', typoutput => 'aclitemout',
-  typreceive => '-', typsend => '-', typalign => 'i' },
-{ oid => '1034',
-  typname => '_aclitem', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'aclitem', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1040',
-  typname => '_macaddr', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'macaddr', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '775',
-  typname => '_macaddr8', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'macaddr8', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1041',
-  typname => '_inet', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'inet', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '651',
-  typname => '_cidr', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'cidr', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1263',
-  typname => '_cstring', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'cstring', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1042',
+  typinput => 'aclitemin', typoutput => 'aclitemout', typreceive => '-',
+  typsend => '-', typalign => 'i' },
+{ oid => '1042', array_type_oid => '1014',
   descr => 'char(length), blank-padded string, fixed storage length',
   typname => 'bpchar', typlen => '-1', typbyval => 'f', typcategory => 'S',
-  typarray => '_bpchar', typinput => 'bpcharin', typoutput => 'bpcharout',
-  typreceive => 'bpcharrecv', typsend => 'bpcharsend',
-  typmodin => 'bpchartypmodin', typmodout => 'bpchartypmodout', typalign => 'i',
-  typstorage => 'x', typcollation => '100' },
-{ oid => '1043',
+  typinput => 'bpcharin', typoutput => 'bpcharout', typreceive => 'bpcharrecv',
+  typsend => 'bpcharsend', typmodin => 'bpchartypmodin',
+  typmodout => 'bpchartypmodout', typalign => 'i', typstorage => 'x',
+  typcollation => '100' },
+{ oid => '1043', array_type_oid => '1015',
   descr => 'varchar(length), non-blank-padded string, variable storage length',
   typname => 'varchar', typlen => '-1', typbyval => 'f', typcategory => 'S',
-  typarray => '_varchar', typinput => 'varcharin', typoutput => 'varcharout',
+  typinput => 'varcharin', typoutput => 'varcharout',
   typreceive => 'varcharrecv', typsend => 'varcharsend',
   typmodin => 'varchartypmodin', typmodout => 'varchartypmodout',
   typalign => 'i', typstorage => 'x', typcollation => '100' },
-{ oid => '1082', descr => 'date',
+{ oid => '1082', array_type_oid => '1182', descr => 'date',
   typname => 'date', typlen => '4', typbyval => 't', typcategory => 'D',
-  typarray => '_date', typinput => 'date_in', typoutput => 'date_out',
-  typreceive => 'date_recv', typsend => 'date_send', typalign => 'i' },
-{ oid => '1083', descr => 'time of day',
+  typinput => 'date_in', typoutput => 'date_out', typreceive => 'date_recv',
+  typsend => 'date_send', typalign => 'i' },
+{ oid => '1083', array_type_oid => '1183', descr => 'time of day',
   typname => 'time', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'D', typarray => '_time', typinput => 'time_in',
-  typoutput => 'time_out', typreceive => 'time_recv', typsend => 'time_send',
-  typmodin => 'timetypmodin', typmodout => 'timetypmodout', typalign => 'd' },
+  typcategory => 'D', typinput => 'time_in', typoutput => 'time_out',
+  typreceive => 'time_recv', typsend => 'time_send', typmodin => 'timetypmodin',
+  typmodout => 'timetypmodout', typalign => 'd' },
 
 # OIDS 1100 - 1199
 
-{ oid => '1114', descr => 'date and time',
+{ oid => '1114', array_type_oid => '1115', descr => 'date and time',
   typname => 'timestamp', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'D', typarray => '_timestamp', typinput => 'timestamp_in',
-  typoutput => 'timestamp_out', typreceive => 'timestamp_recv',
-  typsend => 'timestamp_send', typmodin => 'timestamptypmodin',
-  typmodout => 'timestamptypmodout', typalign => 'd' },
-{ oid => '1115',
-  typname => '_timestamp', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'timestamp', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
+  typcategory => 'D', typinput => 'timestamp_in', typoutput => 'timestamp_out',
+  typreceive => 'timestamp_recv', typsend => 'timestamp_send',
   typmodin => 'timestamptypmodin', typmodout => 'timestamptypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1182',
-  typname => '_date', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'date', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1183',
-  typname => '_time', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'time', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'timetypmodin', typmodout => 'timetypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1184', descr => 'date and time with time zone',
-  typname => 'timestamptz', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'D', typispreferred => 't', typarray => '_timestamptz',
-  typinput => 'timestamptz_in', typoutput => 'timestamptz_out',
-  typreceive => 'timestamptz_recv', typsend => 'timestamptz_send',
-  typmodin => 'timestamptztypmodin', typmodout => 'timestamptztypmodout',
   typalign => 'd' },
-{ oid => '1185',
-  typname => '_timestamptz', typlen => '-1', typbyval => 'f',
-  typcategory => 'A', typelem => 'timestamptz', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'timestamptztypmodin', typmodout => 'timestamptztypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '1186', descr => '@ <number> <units>, time interval',
+{ oid => '1184', array_type_oid => '1185',
+  descr => 'date and time with time zone',
+  typname => 'timestamptz', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typcategory => 'D', typispreferred => 't', typinput => 'timestamptz_in',
+  typoutput => 'timestamptz_out', typreceive => 'timestamptz_recv',
+  typsend => 'timestamptz_send', typmodin => 'timestamptztypmodin',
+  typmodout => 'timestamptztypmodout', typalign => 'd' },
+{ oid => '1186', array_type_oid => '1187',
+  descr => '@ <number> <units>, time interval',
   typname => 'interval', typlen => '16', typbyval => 'f', typcategory => 'T',
-  typispreferred => 't', typarray => '_interval', typinput => 'interval_in',
-  typoutput => 'interval_out', typreceive => 'interval_recv',
-  typsend => 'interval_send', typmodin => 'intervaltypmodin',
-  typmodout => 'intervaltypmodout', typalign => 'd' },
-{ oid => '1187',
-  typname => '_interval', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'interval', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
+  typispreferred => 't', typinput => 'interval_in', typoutput => 'interval_out',
+  typreceive => 'interval_recv', typsend => 'interval_send',
   typmodin => 'intervaltypmodin', typmodout => 'intervaltypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
+  typalign => 'd' },
 
 # OIDS 1200 - 1299
 
-{ oid => '1231',
-  typname => '_numeric', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'numeric', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'numerictypmodin', typmodout => 'numerictypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1266', descr => 'time of day with time zone',
+{ oid => '1266', array_type_oid => '1270',
+  descr => 'time of day with time zone',
   typname => 'timetz', typlen => '12', typbyval => 'f', typcategory => 'D',
-  typarray => '_timetz', typinput => 'timetz_in', typoutput => 'timetz_out',
+  typinput => 'timetz_in', typoutput => 'timetz_out',
   typreceive => 'timetz_recv', typsend => 'timetz_send',
   typmodin => 'timetztypmodin', typmodout => 'timetztypmodout',
   typalign => 'd' },
-{ oid => '1270',
-  typname => '_timetz', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'timetz', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'timetztypmodin', typmodout => 'timetztypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
 
 # OIDS 1500 - 1599
 
-{ oid => '1560', descr => 'fixed-length bit string',
+{ oid => '1560', array_type_oid => '1561', descr => 'fixed-length bit string',
   typname => 'bit', typlen => '-1', typbyval => 'f', typcategory => 'V',
-  typarray => '_bit', typinput => 'bit_in', typoutput => 'bit_out',
-  typreceive => 'bit_recv', typsend => 'bit_send', typmodin => 'bittypmodin',
-  typmodout => 'bittypmodout', typalign => 'i', typstorage => 'x' },
-{ oid => '1561',
-  typname => '_bit', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'bit', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'bittypmodin', typmodout => 'bittypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '1562', descr => 'variable-length bit string',
+  typinput => 'bit_in', typoutput => 'bit_out', typreceive => 'bit_recv',
+  typsend => 'bit_send', typmodin => 'bittypmodin', typmodout => 'bittypmodout',
+  typalign => 'i', typstorage => 'x' },
+{ oid => '1562', array_type_oid => '1563',
+  descr => 'variable-length bit string',
   typname => 'varbit', typlen => '-1', typbyval => 'f', typcategory => 'V',
-  typispreferred => 't', typarray => '_varbit', typinput => 'varbit_in',
-  typoutput => 'varbit_out', typreceive => 'varbit_recv',
-  typsend => 'varbit_send', typmodin => 'varbittypmodin',
-  typmodout => 'varbittypmodout', typalign => 'i', typstorage => 'x' },
-{ oid => '1563',
-  typname => '_varbit', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'varbit', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typmodin => 'varbittypmodin', typmodout => 'varbittypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
+  typispreferred => 't', typinput => 'varbit_in', typoutput => 'varbit_out',
+  typreceive => 'varbit_recv', typsend => 'varbit_send',
+  typmodin => 'varbittypmodin', typmodout => 'varbittypmodout', typalign => 'i',
+  typstorage => 'x' },
 
 # OIDS 1700 - 1799
 
-{ oid => '1700',
+{ oid => '1700', array_type_oid => '1231',
   descr => 'numeric(precision, decimal), arbitrary precision number',
   typname => 'numeric', typlen => '-1', typbyval => 'f', typcategory => 'N',
-  typarray => '_numeric', typinput => 'numeric_in', typoutput => 'numeric_out',
+  typinput => 'numeric_in', typoutput => 'numeric_out',
   typreceive => 'numeric_recv', typsend => 'numeric_send',
   typmodin => 'numerictypmodin', typmodout => 'numerictypmodout',
   typalign => 'i', typstorage => 'm' },
 
-{ oid => '1790', descr => 'reference to cursor (portal name)',
+{ oid => '1790', array_type_oid => '2201',
+  descr => 'reference to cursor (portal name)',
   typname => 'refcursor', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_refcursor', typinput => 'textin', typoutput => 'textout',
-  typreceive => 'textrecv', typsend => 'textsend', typalign => 'i',
-  typstorage => 'x' },
+  typinput => 'textin', typoutput => 'textout', typreceive => 'textrecv',
+  typsend => 'textsend', typalign => 'i', typstorage => 'x' },
 
 # OIDS 2200 - 2299
 
-{ oid => '2201',
-  typname => '_refcursor', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'refcursor', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-
-{ oid => '2202', descr => 'registered procedure (with args)',
+{ oid => '2202', array_type_oid => '2207',
+  descr => 'registered procedure (with args)',
   typname => 'regprocedure', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regprocedure', typinput => 'regprocedurein',
-  typoutput => 'regprocedureout', typreceive => 'regprocedurerecv',
-  typsend => 'regproceduresend', typalign => 'i' },
-{ oid => '2203', descr => 'registered operator',
+  typinput => 'regprocedurein', typoutput => 'regprocedureout',
+  typreceive => 'regprocedurerecv', typsend => 'regproceduresend',
+  typalign => 'i' },
+{ oid => '2203', array_type_oid => '2208', descr => 'registered operator',
   typname => 'regoper', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regoper', typinput => 'regoperin', typoutput => 'regoperout',
+  typinput => 'regoperin', typoutput => 'regoperout',
   typreceive => 'regoperrecv', typsend => 'regopersend', typalign => 'i' },
-{ oid => '2204', descr => 'registered operator (with args)',
+{ oid => '2204', array_type_oid => '2209',
+  descr => 'registered operator (with args)',
   typname => 'regoperator', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regoperator', typinput => 'regoperatorin',
-  typoutput => 'regoperatorout', typreceive => 'regoperatorrecv',
-  typsend => 'regoperatorsend', typalign => 'i' },
-{ oid => '2205', descr => 'registered class',
+  typinput => 'regoperatorin', typoutput => 'regoperatorout',
+  typreceive => 'regoperatorrecv', typsend => 'regoperatorsend',
+  typalign => 'i' },
+{ oid => '2205', array_type_oid => '2210', descr => 'registered class',
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regclass', typinput => 'regclassin', typoutput => 'regclassout',
+  typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
-{ oid => '2206', descr => 'registered type',
+{ oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regtype', typinput => 'regtypein', typoutput => 'regtypeout',
+  typinput => 'regtypein', typoutput => 'regtypeout',
   typreceive => 'regtyperecv', typsend => 'regtypesend', typalign => 'i' },
-{ oid => '4096', descr => 'registered role',
+{ oid => '4096', array_type_oid => '4097', descr => 'registered role',
   typname => 'regrole', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regrole', typinput => 'regrolein', typoutput => 'regroleout',
+  typinput => 'regrolein', typoutput => 'regroleout',
   typreceive => 'regrolerecv', typsend => 'regrolesend', typalign => 'i' },
-{ oid => '4089', descr => 'registered namespace',
+{ oid => '4089', array_type_oid => '4090', descr => 'registered namespace',
   typname => 'regnamespace', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regnamespace', typinput => 'regnamespacein',
-  typoutput => 'regnamespaceout', typreceive => 'regnamespacerecv',
-  typsend => 'regnamespacesend', typalign => 'i' },
-{ oid => '2207',
-  typname => '_regprocedure', typlen => '-1', typbyval => 'f',
-  typcategory => 'A', typelem => 'regprocedure', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '2208',
-  typname => '_regoper', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'regoper', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '2209',
-  typname => '_regoperator', typlen => '-1', typbyval => 'f',
-  typcategory => 'A', typelem => 'regoperator', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '2210',
-  typname => '_regclass', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'regclass', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '2211',
-  typname => '_regtype', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'regtype', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '4097',
-  typname => '_regrole', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'regrole', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '4090',
-  typname => '_regnamespace', typlen => '-1', typbyval => 'f',
-  typcategory => 'A', typelem => 'regnamespace', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
+  typinput => 'regnamespacein', typoutput => 'regnamespaceout',
+  typreceive => 'regnamespacerecv', typsend => 'regnamespacesend',
+  typalign => 'i' },
 
 # uuid
-{ oid => '2950', descr => 'UUID datatype',
+{ oid => '2950', array_type_oid => '2951', descr => 'UUID datatype',
   typname => 'uuid', typlen => '16', typbyval => 'f', typcategory => 'U',
-  typarray => '_uuid', typinput => 'uuid_in', typoutput => 'uuid_out',
-  typreceive => 'uuid_recv', typsend => 'uuid_send', typalign => 'c' },
-{ oid => '2951',
-  typname => '_uuid', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'uuid', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
+  typinput => 'uuid_in', typoutput => 'uuid_out', typreceive => 'uuid_recv',
+  typsend => 'uuid_send', typalign => 'c' },
 
 # pg_lsn
-{ oid => '3220', oid_symbol => 'LSNOID', descr => 'PostgreSQL LSN datatype',
+{ oid => '3220', oid_symbol => 'LSNOID', array_type_oid => '3221',
+  descr => 'PostgreSQL LSN datatype',
   typname => 'pg_lsn', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
-  typcategory => 'U', typarray => '_pg_lsn', typinput => 'pg_lsn_in',
-  typoutput => 'pg_lsn_out', typreceive => 'pg_lsn_recv',
-  typsend => 'pg_lsn_send', typalign => 'd' },
-{ oid => '3221',
-  typname => '_pg_lsn', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'pg_lsn', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
+  typcategory => 'U', typinput => 'pg_lsn_in', typoutput => 'pg_lsn_out',
+  typreceive => 'pg_lsn_recv', typsend => 'pg_lsn_send', typalign => 'd' },
 
 # text search
-{ oid => '3614', descr => 'text representation for text search',
+{ oid => '3614', array_type_oid => '3643',
+  descr => 'text representation for text search',
   typname => 'tsvector', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_tsvector', typinput => 'tsvectorin', typoutput => 'tsvectorout',
+  typinput => 'tsvectorin', typoutput => 'tsvectorout',
   typreceive => 'tsvectorrecv', typsend => 'tsvectorsend',
   typanalyze => 'ts_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3642',
+{ oid => '3642', array_type_oid => '3644',
   descr => 'GiST index internal text representation for text search',
   typname => 'gtsvector', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_gtsvector', typinput => 'gtsvectorin',
-  typoutput => 'gtsvectorout', typreceive => '-', typsend => '-',
-  typalign => 'i' },
-{ oid => '3615', descr => 'query representation for text search',
+  typinput => 'gtsvectorin', typoutput => 'gtsvectorout', typreceive => '-',
+  typsend => '-', typalign => 'i' },
+{ oid => '3615', array_type_oid => '3645',
+  descr => 'query representation for text search',
   typname => 'tsquery', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_tsquery', typinput => 'tsqueryin', typoutput => 'tsqueryout',
+  typinput => 'tsqueryin', typoutput => 'tsqueryout',
   typreceive => 'tsqueryrecv', typsend => 'tsquerysend', typalign => 'i' },
-{ oid => '3734', descr => 'registered text search configuration',
+{ oid => '3734', array_type_oid => '3735',
+  descr => 'registered text search configuration',
   typname => 'regconfig', typlen => '4', typbyval => 't', typcategory => 'N',
-  typarray => '_regconfig', typinput => 'regconfigin',
-  typoutput => 'regconfigout', typreceive => 'regconfigrecv',
-  typsend => 'regconfigsend', typalign => 'i' },
-{ oid => '3769', descr => 'registered text search dictionary',
+  typinput => 'regconfigin', typoutput => 'regconfigout',
+  typreceive => 'regconfigrecv', typsend => 'regconfigsend', typalign => 'i' },
+{ oid => '3769', array_type_oid => '3770',
+  descr => 'registered text search dictionary',
   typname => 'regdictionary', typlen => '4', typbyval => 't',
-  typcategory => 'N', typarray => '_regdictionary',
-  typinput => 'regdictionaryin', typoutput => 'regdictionaryout',
-  typreceive => 'regdictionaryrecv', typsend => 'regdictionarysend',
-  typalign => 'i' },
-
-{ oid => '3643',
-  typname => '_tsvector', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'tsvector', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3644',
-  typname => '_gtsvector', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'gtsvector', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3645',
-  typname => '_tsquery', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'tsquery', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3735',
-  typname => '_regconfig', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'regconfig', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3770',
-  typname => '_regdictionary', typlen => '-1', typbyval => 'f',
-  typcategory => 'A', typelem => 'regdictionary', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
+  typcategory => 'N', typinput => 'regdictionaryin',
+  typoutput => 'regdictionaryout', typreceive => 'regdictionaryrecv',
+  typsend => 'regdictionarysend', typalign => 'i' },
 
 # jsonb
-{ oid => '3802', descr => 'Binary JSON',
+{ oid => '3802', array_type_oid => '3807', descr => 'Binary JSON',
   typname => 'jsonb', typlen => '-1', typbyval => 'f', typcategory => 'U',
-  typarray => '_jsonb', typinput => 'jsonb_in', typoutput => 'jsonb_out',
-  typreceive => 'jsonb_recv', typsend => 'jsonb_send', typalign => 'i',
-  typstorage => 'x' },
-{ oid => '3807',
-  typname => '_jsonb', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'jsonb', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
+  typinput => 'jsonb_in', typoutput => 'jsonb_out', typreceive => 'jsonb_recv',
+  typsend => 'jsonb_send', typalign => 'i', typstorage => 'x' },
 
-{ oid => '2970', descr => 'txid snapshot',
+{ oid => '2970', array_type_oid => '2949', descr => 'txid snapshot',
   typname => 'txid_snapshot', typlen => '-1', typbyval => 'f',
-  typcategory => 'U', typarray => '_txid_snapshot',
-  typinput => 'txid_snapshot_in', typoutput => 'txid_snapshot_out',
-  typreceive => 'txid_snapshot_recv', typsend => 'txid_snapshot_send',
-  typalign => 'd', typstorage => 'x' },
-{ oid => '2949',
-  typname => '_txid_snapshot', typlen => '-1', typbyval => 'f',
-  typcategory => 'A', typelem => 'txid_snapshot', typinput => 'array_in',
-  typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
+  typcategory => 'U', typinput => 'txid_snapshot_in',
+  typoutput => 'txid_snapshot_out', typreceive => 'txid_snapshot_recv',
+  typsend => 'txid_snapshot_send', typalign => 'd', typstorage => 'x' },
 
 # range types
-{ oid => '3904', descr => 'range of integers',
+{ oid => '3904', array_type_oid => '3905', descr => 'range of integers',
   typname => 'int4range', typlen => '-1', typbyval => 'f', typtype => 'r',
-  typcategory => 'R', typarray => '_int4range', typinput => 'range_in',
-  typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send',
+  typcategory => 'R', typinput => 'range_in', typoutput => 'range_out',
+  typreceive => 'range_recv', typsend => 'range_send',
   typanalyze => 'range_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3905',
-  typname => '_int4range', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int4range', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3906', descr => 'range of numerics',
+{ oid => '3906', array_type_oid => '3907', descr => 'range of numerics',
   typname => 'numrange', typlen => '-1', typbyval => 'f', typtype => 'r',
-  typcategory => 'R', typarray => '_numrange', typinput => 'range_in',
-  typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send',
+  typcategory => 'R', typinput => 'range_in', typoutput => 'range_out',
+  typreceive => 'range_recv', typsend => 'range_send',
   typanalyze => 'range_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3907',
-  typname => '_numrange', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'numrange', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3908', descr => 'range of timestamps without time zone',
+{ oid => '3908', array_type_oid => '3909',
+  descr => 'range of timestamps without time zone',
   typname => 'tsrange', typlen => '-1', typbyval => 'f', typtype => 'r',
-  typcategory => 'R', typarray => '_tsrange', typinput => 'range_in',
-  typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send',
+  typcategory => 'R', typinput => 'range_in', typoutput => 'range_out',
+  typreceive => 'range_recv', typsend => 'range_send',
   typanalyze => 'range_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '3909',
-  typname => '_tsrange', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'tsrange', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '3910', descr => 'range of timestamps with time zone',
+{ oid => '3910', array_type_oid => '3911',
+  descr => 'range of timestamps with time zone',
   typname => 'tstzrange', typlen => '-1', typbyval => 'f', typtype => 'r',
-  typcategory => 'R', typarray => '_tstzrange', typinput => 'range_in',
-  typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send',
+  typcategory => 'R', typinput => 'range_in', typoutput => 'range_out',
+  typreceive => 'range_recv', typsend => 'range_send',
   typanalyze => 'range_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '3911',
-  typname => '_tstzrange', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'tstzrange', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '3912', descr => 'range of dates',
+{ oid => '3912', array_type_oid => '3913', descr => 'range of dates',
   typname => 'daterange', typlen => '-1', typbyval => 'f', typtype => 'r',
-  typcategory => 'R', typarray => '_daterange', typinput => 'range_in',
-  typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send',
+  typcategory => 'R', typinput => 'range_in', typoutput => 'range_out',
+  typreceive => 'range_recv', typsend => 'range_send',
   typanalyze => 'range_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3913',
-  typname => '_daterange', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'daterange', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' },
-{ oid => '3926', descr => 'range of bigints',
+{ oid => '3926', array_type_oid => '3927', descr => 'range of bigints',
   typname => 'int8range', typlen => '-1', typbyval => 'f', typtype => 'r',
-  typcategory => 'R', typarray => '_int8range', typinput => 'range_in',
-  typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send',
+  typcategory => 'R', typinput => 'range_in', typoutput => 'range_out',
+  typreceive => 'range_recv', typsend => 'range_send',
   typanalyze => 'range_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '3927',
-  typname => '_int8range', typlen => '-1', typbyval => 'f', typcategory => 'A',
-  typelem => 'int8range', typinput => 'array_in', typoutput => 'array_out',
-  typreceive => 'array_recv', typsend => 'array_send',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
 
 # pseudo-types
 # types with typtype='p' represent various special cases in the type system.
   typcategory => 'P', typarray => '_record', typinput => 'record_in',
   typoutput => 'record_out', typreceive => 'record_recv',
   typsend => 'record_send', typalign => 'd', typstorage => 'x' },
+# Arrays of records have typcategory P, so they can't be autogenerated.
 { oid => '2287',
   typname => '_record', typlen => '-1', typbyval => 'f', typtype => 'p',
   typcategory => 'P', typelem => 'record', typinput => 'array_in',
   typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send',
   typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
-{ oid => '2275',
+{ oid => '2275', array_type_oid => '1263',
   typname => 'cstring', typlen => '-2', typbyval => 'f', typtype => 'p',
-  typcategory => 'P', typarray => '_cstring', typinput => 'cstring_in',
-  typoutput => 'cstring_out', typreceive => 'cstring_recv',
-  typsend => 'cstring_send', typalign => 'c' },
+  typcategory => 'P', typinput => 'cstring_in', typoutput => 'cstring_out',
+  typreceive => 'cstring_recv', typsend => 'cstring_send', typalign => 'c' },
 { oid => '2276',
   typname => 'any', typlen => '4', typbyval => 't', typtype => 'p',
   typcategory => 'P', typinput => 'any_in', typoutput => 'any_out',
index 1e9cea70e2f07a8009784e32d522596fc856278e..76f3297e1d9f2489a907c66e7086e58d3111c20c 100644 (file)
@@ -52,7 +52,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     * "varlena" type (one that has a length word), -2 to indicate a
     * null-terminated C string.
     */
-   int16       typlen;
+   int16       typlen BKI_ARRAY_DEFAULT(-1);
 
    /*
     * typbyval determines whether internal Postgres routines pass a value of
@@ -62,7 +62,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     * typbyval can be false even if the length would allow pass-by-value; for
     * example, type macaddr8 is pass-by-ref even when Datum is 8 bytes.
     */
-   bool        typbyval;
+   bool        typbyval BKI_ARRAY_DEFAULT(f);
 
    /*
     * typtype is 'b' for a base type, 'c' for a composite type (e.g., a
@@ -71,7 +71,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     *
     * If typtype is 'c', typrelid is the OID of the class' entry in pg_class.
     */
-   char        typtype BKI_DEFAULT(b);
+   char        typtype BKI_DEFAULT(b) BKI_ARRAY_DEFAULT(b);
 
    /*
     * typcategory and typispreferred help the parser distinguish preferred
@@ -81,10 +81,10 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     */
 
    /* arbitrary type classification */
-   char        typcategory;
+   char        typcategory BKI_ARRAY_DEFAULT(A);
 
    /* is type "preferred" within its category? */
-   bool        typispreferred BKI_DEFAULT(f);
+   bool        typispreferred BKI_DEFAULT(f) BKI_ARRAY_DEFAULT(f);
 
    /*
     * If typisdefined is false, the entry is only a placeholder (forward
@@ -97,7 +97,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);
+   Oid         typrelid BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0);
 
    /*
     * If typelem is not 0 then it identifies another row in pg_type. The
@@ -116,19 +116,19 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     * 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_LOOKUP(pg_type);
+   Oid         typarray BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP(pg_type);
 
    /*
     * I/O conversion procedures for the datatype.
     */
 
    /* text format (required) */
-   regproc     typinput BKI_LOOKUP(pg_proc);
-   regproc     typoutput BKI_LOOKUP(pg_proc);
+   regproc     typinput BKI_ARRAY_DEFAULT(array_in) BKI_LOOKUP(pg_proc);
+   regproc     typoutput BKI_ARRAY_DEFAULT(array_out) BKI_LOOKUP(pg_proc);
 
    /* binary format (optional) */
-   regproc     typreceive BKI_LOOKUP(pg_proc);
-   regproc     typsend BKI_LOOKUP(pg_proc);
+   regproc     typreceive BKI_ARRAY_DEFAULT(array_recv) BKI_LOOKUP(pg_proc);
+   regproc     typsend BKI_ARRAY_DEFAULT(array_send) BKI_LOOKUP(pg_proc);
 
    /*
     * I/O functions for optional type modifiers.
@@ -139,7 +139,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
    /*
     * Custom ANALYZE procedure for the datatype (0 selects the default).
     */
-   regproc     typanalyze BKI_DEFAULT(-) BKI_LOOKUP(pg_proc);
+   regproc     typanalyze BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_typanalyze) BKI_LOOKUP(pg_proc);
 
    /* ----------------
     * typalign is the alignment required when storing a value of this
@@ -177,7 +177,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     * 'm' MAIN       like 'x' but try to keep in main tuple
     * ----------------
     */
-   char        typstorage BKI_DEFAULT(p);
+   char        typstorage BKI_DEFAULT(p) BKI_ARRAY_DEFAULT(x);
 
    /*
     * This flag represents a "NOT NULL" constraint against this datatype.
@@ -221,7 +221,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     * a default expression for the type.  Currently this is only used for
     * domains.
     */
-   pg_node_tree typdefaultbin BKI_DEFAULT(_null_);
+   pg_node_tree typdefaultbin BKI_DEFAULT(_null_) BKI_ARRAY_DEFAULT(_null_);
 
    /*
     * typdefault is NULL if the type has no associated default value. If
@@ -231,7 +231,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
     * external representation of the type's default value, which may be fed
     * to the type's input converter to produce a constant.
     */
-   text        typdefault BKI_DEFAULT(_null_);
+   text        typdefault BKI_DEFAULT(_null_) BKI_ARRAY_DEFAULT(_null_);
 
    /*
     * Access permissions
index 687aca0b16484c31784a1f36581e0df918087492..ca20fb86da1782732fc26c9da9f3cdd49f42f953 100755 (executable)
@@ -5,9 +5,9 @@
 #    Perl script that reads in catalog data file(s) and writes out
 #    functionally equivalent file(s) in a standard format.
 #
-#    In each entry of a reformatted file, metadata fields (if any) come
-#    first, with normal attributes starting on the following line, in
-#    the same order as the columns of the corresponding catalog.
+#    In each entry of a reformatted file, metadata fields (if present)
+#    come first, with normal attributes starting on the following line,
+#    in the same order as the columns of the corresponding catalog.
 #    Comments and blank lines are preserved.
 #
 # Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
@@ -26,6 +26,11 @@ use FindBin;
 use lib "$FindBin::RealBin/../../backend/catalog/";
 use Catalog;
 
+# Names of the metadata fields of a catalog entry.  (line_number is also
+# a metadata field, but we never write it out, so it's not listed here.)
+my @METADATA =
+  ('oid', 'oid_symbol', 'array_type_oid', 'descr', 'autogenerated');
+
 my @input_files;
 my $output_path = '';
 my $full_tuples = 0;
@@ -62,9 +67,6 @@ if ($output_path ne '' && substr($output_path, -1) ne '/')
    $output_path .= '/';
 }
 
-# Metadata of a catalog entry
-my @METADATA = ('oid', 'oid_symbol', 'descr');
-
 # Read all the input files into internal data structures.
 # We pass data file names as arguments and then look for matching
 # headers to parse the schema from.
@@ -142,6 +144,9 @@ foreach my $catname (@catnames)
 
            if (!$full_tuples)
            {
+               # If it's an autogenerated entry, drop it completely.
+               next if $values{autogenerated};
+               # Else, just drop any default/computed fields.
                strip_default_values(\%values, $schema, $catname);
            }
 
@@ -162,10 +167,6 @@ foreach my $catname (@catnames)
            print $dat " },\n";
        }
 
-       # Strings -- handle accordingly or ignore. It was necessary to
-       # ignore bare commas during the initial data conversion. This
-       # should be a no-op now, but we may as well keep that behavior.
-
        # Preserve blank lines.
        elsif ($data =~ /^\s*$/)
        {
@@ -207,6 +208,14 @@ sub strip_default_values
    {
        delete $row->{pronargs} if defined $row->{proargtypes};
    }
+
+   # If a pg_type entry has an auto-generated array type, then its
+   # typarray field is a computed value too (see GenerateArrayTypes).
+   if ($catname eq 'pg_type')
+   {
+       delete $row->{typarray} if defined $row->{array_type_oid};
+   }
+
    return;
 }