Обсуждение: generating bootstrap entries for array types

Поиск
Список
Период
Сортировка

generating bootstrap entries for array types

От
John Naylor
Дата:
I wrote [1]:

> On 4/26/18, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> if I counted correctly.  (Array entries should be ignored for this
>> purpose; maybe we'll autogenerate them someday.)
>
> Hmm, that wouldn't be too hard. Add a new metadata field called
> 'array_type_oid', then if it finds such an OID, teach genbki.pl to
> construct a tuple for the corresponding array type by consulting
> something like
>
> char    typcategory    BKI_ARRAY(A);
> char    typstorage      BKI_ARRAY(x);
> ...etc
>
> in the header file, plus copying typalign from the element type. I'll
> whip this up sometime and add it to the next commitfest.

This turned out to be slightly more complicated than that, but still
pretty straightforward. The script is for information only, it doesn't
need to be run.

-typalign for arrays is 'i' unless the element type is 'd', in which
case it's 'd'.
-If future array-like types are created that break the model and so
can't be generated from the element type, they have an escape hatch of
having their own full entry. Currently this includes  _record, since
it's a pseudotype, and of course the special types oidvector and
int2vector.
-I've kept the current convention of duplicating typdelim in the array
type, although I'm not sure it's used anywhere.

If you sort the before and after postgres.bki, it should result in a clean diff.

Will add to next commitfest.

--
[1] https://www.postgresql.org/message-id/CAJVSVGW-D7OobzU%3DdybVT2JqZAx-4X1yvBJdavBmqQL05Q6CLw%40mail.gmail.com

-John Naylor

Вложения

Re: generating bootstrap entries for array types

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
Hi John,

John Naylor <jcnaylor@gmail.com> writes:

>> On 4/26/18, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>>> if I counted correctly.  (Array entries should be ignored for this
>>> purpose; maybe we'll autogenerate them someday.)
>>
>> Hmm, that wouldn't be too hard. Add a new metadata field called
>> 'array_type_oid', then if it finds such an OID, teach genbki.pl to
>> construct a tuple for the corresponding array type by consulting
>> something like
>>
>> char    typcategory    BKI_ARRAY(A);
>> char    typstorage      BKI_ARRAY(x);
>> ...etc
>>
>> in the header file, plus copying typalign from the element type. I'll
>> whip this up sometime and add it to the next commitfest.
>
> This turned out to be slightly more complicated than that, but still
> pretty straightforward.

Doing this in genbki.pl makes DBD::Pg lose its array type information,
since it uses Catalog::ParseData() to get it
(https://github.com/bucardo/dbdpg/blob/master/types.c#L439).  May I
suggest moving gen_array_types() to Catalog.pm and calling it from
ParseData() if the input file is pg_type.dat, so that it always returns
complete data?

Thanks,

- ilmari
-- 
"A disappointingly low fraction of the human race is,
 at any given time, on fire." - Stig Sandbeck Mathisen


Re: generating bootstrap entries for array types

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
Hi again John,

ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:

> Doing this in genbki.pl makes DBD::Pg lose its array type information,
> since it uses Catalog::ParseData() to get it
> (https://github.com/bucardo/dbdpg/blob/master/types.c#L439).  May I
> suggest moving gen_array_types() to Catalog.pm and calling it from
> ParseData() if the input file is pg_type.dat, so that it always returns
> complete data?

Attached is a proposed revision of this patch that does the above.  It
passes check-world, reformat_dat_file.pl still works, and DBD::Pg is
still able to get the array type information.

Thanks,

- ilmari
-- 
"I use RMS as a guide in the same way that a boat captain would use
 a lighthouse.  It's good to know where it is, but you generally
 don't want to find yourself in the same spot." - Tollef Fog Heen

From 947e5102d37219a3b008272be2caae3151bbd641 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Thu, 20 Sep 2018 12:43:35 +0100
Subject: [PATCH v2] Generate bootstrap entries for array types

Add a new metadata field called 'array_type_oid', which instructs
Catalog::ParseData to generate an array type from the given element type.
This allows most array type entries to be deleted from pg_type.dat.
The lone exception is _record, since it's a pseudotype.
---
 src/backend/catalog/Catalog.pm           |  57 +++
 src/backend/catalog/genbki.pl            |   3 +-
 src/include/catalog/genbki.h             |   2 +
 src/include/catalog/pg_type.dat          | 471 ++++-------------------
 src/include/catalog/pg_type.h            |  24 +-
 src/include/catalog/reformat_dat_file.pl |   2 +-
 6 files changed, 154 insertions(+), 405 deletions(-)

diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index ae5b499b6a..12b142928a 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -191,6 +191,10 @@ sub ParseHeader
                     {
                         $column{default} = $1;
                     }
+                    elsif ($attopt =~ /BKI_ARRAY_TYPE\(['"]?([^'"]+)['"]?\)/)
+                    {
+                        $column{array} = $1;
+                    }
                     elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/)
                     {
                         $column{lookup} = $1;
@@ -290,6 +294,10 @@ sub ParseData
         }
     }
     close $ifd;
+
+    # Generate array types unless we're just reformatting the file
+    Catalog::GenArrayTypes($schema, $data)
+        if $catname eq 'pg_type' and !$preserve_formatting;
     return $data;
 }
 
@@ -448,6 +456,8 @@ sub FindAllOidsFromHeaders
             foreach my $row (@$catdata)
             {
                 push @oids, $row->{oid} if defined $row->{oid};
+                push @oids, $row->{array_type_oid}
+                    if defined $row->{array_type_oid};
             }
         }
 
@@ -464,4 +474,51 @@ sub FindAllOidsFromHeaders
     return \@oids;
 }
 
+# If the type specifies an array type OID, generate an entry for the array
+# type using values from the element type, plus some values that are needed
+# for all array types.
+sub GenArrayTypes
+{
+    my $pgtype_schema = shift;
+    my $types = shift;
+    my @array_types;
+
+    foreach my $elem_type (@$types)
+    {
+        next if !exists $elem_type->{array_type_oid};
+        my %array_type;
+
+        # Specific values derived from the element type.
+        $array_type{oid}     = $elem_type->{array_type_oid};
+        $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 values.
+        foreach my $column (@$pgtype_schema)
+        {
+            my $attname = $column->{name};
+
+            # Skip if we already set it above.
+            next if defined $array_type{$attname};
+
+            # If we have a value needed for all arrays, use it, otherwise
+            # copy the value from the element type.
+            if (defined $column->{array})
+            {
+                $array_type{$attname} = $column->{array};
+            }
+            else
+            {
+                $array_type{$attname} = $elem_type->{$attname};
+            }
+        }
+        push @array_types, \%array_type;
+    }
+    push @$types, @array_types;
+}
+
 1;
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 9be51d28b0..053d1ee00d 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -395,7 +395,8 @@ EOM
               if $key eq "oid"
               || $key eq "oid_symbol"
               || $key eq "descr"
-              || $key eq "line_number";
+              || $key eq "line_number"
+              || $key eq "array_type_oid";
             die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n",
               $key, $catname, $bki_values{line_number}
               if (!exists($attnames{$key}));
diff --git a/src/include/catalog/genbki.h b/src/include/catalog/genbki.h
index b1e2cbdb62..a5fc03f3f4 100644
--- a/src/include/catalog/genbki.h
+++ b/src/include/catalog/genbki.h
@@ -34,6 +34,8 @@
 #define BKI_FORCE_NOT_NULL
 /* Specifies a default value for a catalog field */
 #define BKI_DEFAULT(value)
+/* Specifies a value needed for array types */
+#define BKI_ARRAY_TYPE(value)
 /* Indicates how to perform name lookups for an OID or OID-array field */
 #define BKI_LOOKUP(catalog)
 
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index 48e01cd694..785e8f43ad 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -15,6 +15,12 @@
 # For types used in the system catalogs, make sure the values here match
 # TypInfo[] in bootstrap.c.
 
+# To create an array type, add 'array_type_oid => 'nnnn' to the element
+# type, which will instruct genbki.pl to generate a BKI entry for it.
+# The values used can be found in pg_type.h. If you want to add an array
+# type that needs any values different from normal array types, it will
+# need its own entry in this file, e.g. _record.
+
 # OID symbol macro names for pg_type OIDs are generated by genbki.pl
 # according to the following rule, so you don't need to specify them
 # here:
@@ -31,69 +37,81 @@
 # OIDS 1 - 99
 
 { oid => '16', descr => 'boolean, \'true\'/\'false\'',
+  array_type_oid => '1000',
   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',
+  array_type_oid => '1001',
   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',
+{ oid => '18', descr => 'single character', array_type_oid => '1002',
   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',
+  array_type_oid => '1003',
   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',
+  array_type_oid => '1016',
   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',
+  array_type_oid => '1005',
   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',
+  array_type_oid => '1006',
   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',
+  array_type_oid => '1007',
   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',
+{ oid => '24', descr => 'registered procedure', array_type_oid => '1008',
   typname => 'regproc', typlen => '4', typbyval => 't', typcategory => 'N',
   typarray => '_regproc', typinput => 'regprocin', typoutput => 'regprocout',
   typreceive => 'regprocrecv', typsend => 'regprocsend', typalign => 'i' },
 { oid => '25', descr => 'variable-length string, no limit specified',
+  array_type_oid => '1009',
   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',
+  array_type_oid => '1028',
   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',
+  array_type_oid => '1010',
   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',
+{ oid => '28', descr => 'transaction id', array_type_oid => '1011',
   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',
+  array_type_oid => '1012',
   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',
+  array_type_oid => '1013',
   typname => 'oidvector', typlen => '-1', typbyval => 'f', typcategory => 'A',
   typelem => 'oid', typarray => '_oidvector', typinput => 'oidvectorin',
   typoutput => 'oidvectorout', typreceive => 'oidvectorrecv',
@@ -124,26 +142,16 @@
 
 # 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',
+{ oid => '142', descr => 'XML content', array_type_oid => '143',
   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' },
 { oid => '194', oid_symbol => 'PGNODETREEOID',
   descr => 'string representing an internal node tree',
   typname => 'pg_node_tree', typlen => '-1', typbyval => 'f',
@@ -182,66 +190,71 @@
 # OIDS 600 - 699
 
 { oid => '600', descr => 'geometric point \'(x, y)\'',
+  array_type_oid => '1017',
   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)\'',
+  array_type_oid => '1018',
   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,...)\'',
+  array_type_oid => '1019',
   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)\'',
+  array_type_oid => '1020',
   typname => 'box', typlen => '32', typbyval => 'f', typcategory => 'G',
   typdelim => ';', typelem => 'point', typarray => '_box', typinput => 'box_in',
   typoutput => 'box_out', typreceive => 'box_recv', typsend => 'box_send',
   typalign => 'd' },
 { oid => '604', descr => 'geometric polygon \'(pt1,...)\'',
+  array_type_oid => '1027',
   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',
+{ oid => '628', descr => 'geometric line', array_type_oid => '629',
   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' },
 
 # OIDS 700 - 799
 
 { oid => '700',
   descr => 'single-precision floating point number, 4-byte storage',
+  array_type_oid => '1021',
   typname => 'float4', typlen => '4', typbyval => 'FLOAT4PASSBYVAL',
   typcategory => 'N', typarray => '_float4', typinput => 'float4in',
   typoutput => 'float4out', typreceive => 'float4recv', typsend => 'float4send',
   typalign => 'i' },
 { oid => '701',
   descr => 'double-precision floating point number, 8-byte storage',
+  array_type_oid => '1022',
   typname => 'float8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
   typcategory => 'N', typispreferred => 't', typarray => '_float8',
   typinput => 'float8in', typoutput => 'float8out', typreceive => 'float8recv',
   typsend => 'float8send', typalign => 'd' },
 { oid => '702',
   descr => 'absolute, limited-range date and time (Unix system time)',
+  array_type_oid => '1023',
   typname => 'abstime', typlen => '4', typbyval => 't', typcategory => 'D',
   typarray => '_abstime', typinput => 'abstimein', typoutput => 'abstimeout',
   typreceive => 'abstimerecv', typsend => 'abstimesend', typalign => 'i' },
 { oid => '703',
   descr => 'relative, limited-range time interval (Unix delta time)',
+  array_type_oid => '1024',
   typname => 'reltime', typlen => '4', typbyval => 't', typcategory => 'T',
   typarray => '_reltime', typinput => 'reltimein', typoutput => 'reltimeout',
   typreceive => 'reltimerecv', typsend => 'reltimesend', typalign => 'i' },
 { oid => '704', descr => '(abstime,abstime), time interval',
+  array_type_oid => '1025',
   typname => 'tinterval', typlen => '12', typbyval => 'f', typcategory => 'T',
   typarray => '_tinterval', typinput => 'tintervalin',
   typoutput => 'tintervalout', typreceive => 'tintervalrecv',
@@ -251,43 +264,38 @@
   typcategory => 'X', typinput => 'unknownin', typoutput => 'unknownout',
   typreceive => 'unknownrecv', typsend => 'unknownsend', typalign => 'c' },
 { oid => '718', descr => 'geometric circle \'(center,radius)\'',
+  array_type_oid => '719',
   typname => 'circle', typlen => '24', typbyval => 'f', typcategory => 'G',
   typarray => '_circle', 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',
-  descr => 'monetary amounts, $d,ddd.cc',
+{ oid => '790', oid_symbol => 'CASHOID', descr => 'monetary amounts, $d,ddd.cc',
+  array_type_oid => '791',
   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' },
 
 # OIDS 800 - 899
 
 { oid => '829', descr => 'XX:XX:XX:XX:XX:XX, MAC address',
+  array_type_oid => '1040',
   typname => 'macaddr', typlen => '6', typbyval => 'f', typcategory => 'U',
   typarray => '_macaddr', typinput => 'macaddr_in', typoutput => 'macaddr_out',
   typreceive => 'macaddr_recv', typsend => 'macaddr_send', typalign => 'i' },
 { oid => '869', descr => 'IP address/netmask, host address, netmask optional',
+  array_type_oid => '1041',
   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',
+  array_type_oid => '651',
   typname => 'cidr', typlen => '-1', typbyval => 'f', typcategory => 'I',
   typarray => '_cidr', typinput => 'cidr_in', typoutput => 'cidr_out',
   typreceive => 'cidr_recv', typsend => 'cidr_send', typalign => 'i',
   typstorage => 'm' },
 { oid => '774', descr => 'XX:XX:XX:XX:XX:XX:XX:XX, MAC address',
+  array_type_oid => '775',
   typname => 'macaddr8', typlen => '8', typbyval => 'f', typcategory => 'U',
   typarray => '_macaddr8', typinput => 'macaddr8_in',
   typoutput => 'macaddr8_out', typreceive => 'macaddr8_recv',
@@ -295,182 +303,13 @@
 
 # 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', descr => 'access control list', array_type_oid => '1034',
   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',
   descr => 'char(length), blank-padded string, fixed storage length',
+  array_type_oid => '1014',
   typname => 'bpchar', typlen => '-1', typbyval => 'f', typcategory => 'S',
   typarray => '_bpchar', typinput => 'bpcharin', typoutput => 'bpcharout',
   typreceive => 'bpcharrecv', typsend => 'bpcharsend',
@@ -478,16 +317,17 @@
   typstorage => 'x', typcollation => '100' },
 { oid => '1043',
   descr => 'varchar(length), non-blank-padded string, variable storage length',
+  array_type_oid => '1015',
   typname => 'varchar', typlen => '-1', typbyval => 'f', typcategory => 'S',
   typarray => '_varchar', typinput => 'varcharin', typoutput => 'varcharout',
   typreceive => 'varcharrecv', typsend => 'varcharsend',
   typmodin => 'varchartypmodin', typmodout => 'varchartypmodout',
   typalign => 'i', typstorage => 'x', typcollation => '100' },
-{ oid => '1082', descr => 'date',
+{ oid => '1082', descr => 'date', array_type_oid => '1182',
   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',
+{ oid => '1083', descr => 'time of day', array_type_oid => '1183',
   typname => 'time', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
   typcategory => 'D', typarray => '_time', typinput => 'time_in',
   typoutput => 'time_out', typreceive => 'time_recv', typsend => 'time_send',
@@ -495,106 +335,58 @@
 
 # OIDS 1100 - 1199
 
-{ oid => '1114', descr => 'date and time',
+{ oid => '1114', descr => 'date and time', array_type_oid => '1115',
   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',
-  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',
+  array_type_oid => '1185',
   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',
+  array_type_oid => '1187',
   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',
-  typmodin => 'intervaltypmodin', typmodout => 'intervaltypmodout',
-  typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' },
 
 # 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',
+  array_type_oid => '1270',
   typname => 'timetz', typlen => '12', typbyval => 'f', typcategory => 'D',
   typarray => '_timetz', 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', descr => 'fixed-length bit string', array_type_oid => '1561',
   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',
+  array_type_oid => '1563',
   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' },
 
 # OIDS 1700 - 1799
 
 { oid => '1700',
   descr => 'numeric(precision, decimal), arbitrary precision number',
+  array_type_oid => '1231',
   typname => 'numeric', typlen => '-1', typbyval => 'f', typcategory => 'N',
   typarray => '_numeric', typinput => 'numeric_in', typoutput => 'numeric_out',
   typreceive => 'numeric_recv', typsend => 'numeric_send',
@@ -602,6 +394,7 @@
   typalign => 'i', typstorage => 'm' },
 
 { oid => '1790', descr => 'reference to cursor (portal name)',
+  array_type_oid => '2201',
   typname => 'refcursor', typlen => '-1', typbyval => 'f', typcategory => 'U',
   typarray => '_refcursor', typinput => 'textin', typoutput => 'textout',
   typreceive => 'textrecv', typsend => 'textsend', typalign => 'i',
@@ -609,241 +402,134 @@
 
 # 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)',
+  array_type_oid => '2207',
   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',
+{ oid => '2203', descr => 'registered operator', array_type_oid => '2208',
   typname => 'regoper', typlen => '4', typbyval => 't', typcategory => 'N',
   typarray => '_regoper', typinput => 'regoperin', typoutput => 'regoperout',
   typreceive => 'regoperrecv', typsend => 'regopersend', typalign => 'i' },
 { oid => '2204', descr => 'registered operator (with args)',
+  array_type_oid => '2209',
   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',
+{ oid => '2205', descr => 'registered class', array_type_oid => '2210',
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typarray => '_regclass', typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
-{ oid => '2206', descr => 'registered type',
+{ oid => '2206', descr => 'registered type', array_type_oid => '2211',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typarray => '_regtype', typinput => 'regtypein', typoutput => 'regtypeout',
   typreceive => 'regtyperecv', typsend => 'regtypesend', typalign => 'i' },
-{ oid => '4096', descr => 'registered role',
+{ oid => '4096', descr => 'registered role', array_type_oid => '4097',
   typname => 'regrole', typlen => '4', typbyval => 't', typcategory => 'N',
   typarray => '_regrole', typinput => 'regrolein', typoutput => 'regroleout',
   typreceive => 'regrolerecv', typsend => 'regrolesend', typalign => 'i' },
-{ oid => '4089', descr => 'registered namespace',
+{ oid => '4089', descr => 'registered namespace', array_type_oid => '4090',
   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' },
 
 # uuid
-{ oid => '2950', descr => 'UUID datatype',
+{ oid => '2950', descr => 'UUID datatype', array_type_oid => '2951',
   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' },
 
 # pg_lsn
 { oid => '3220', oid_symbol => 'LSNOID', descr => 'PostgreSQL LSN datatype',
+  array_type_oid => '3221',
   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' },
 
 # text search
 { oid => '3614', descr => 'text representation for text search',
+  array_type_oid => '3643',
   typname => 'tsvector', typlen => '-1', typbyval => 'f', typcategory => 'U',
   typarray => '_tsvector', typinput => 'tsvectorin', typoutput => 'tsvectorout',
   typreceive => 'tsvectorrecv', typsend => 'tsvectorsend',
   typanalyze => 'ts_typanalyze', typalign => 'i', typstorage => 'x' },
 { oid => '3642',
   descr => 'GiST index internal text representation for text search',
+  array_type_oid => '3644',
   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',
+  array_type_oid => '3645',
   typname => 'tsquery', typlen => '-1', typbyval => 'f', typcategory => 'U',
   typarray => '_tsquery', typinput => 'tsqueryin', typoutput => 'tsqueryout',
   typreceive => 'tsqueryrecv', typsend => 'tsquerysend', typalign => 'i' },
 { oid => '3734', descr => 'registered text search configuration',
+  array_type_oid => '3735',
   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',
+  array_type_oid => '3770',
   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' },
-
 # jsonb
-{ oid => '3802', descr => 'Binary JSON',
+{ oid => '3802', descr => 'Binary JSON', array_type_oid => '3807',
   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' },
 
-{ oid => '2970', descr => 'txid snapshot',
+{ oid => '2970', descr => 'txid snapshot', array_type_oid => '2949',
   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' },
 
 # range types
-{ oid => '3904', descr => 'range of integers',
+{ oid => '3904', descr => 'range of integers', array_type_oid => '3905',
   typname => 'int4range', typlen => '-1', typbyval => 'f', typtype => 'r',
   typcategory => 'R', typarray => '_int4range', 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', descr => 'range of numerics', array_type_oid => '3907',
   typname => 'numrange', typlen => '-1', typbyval => 'f', typtype => 'r',
   typcategory => 'R', typarray => '_numrange', 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',
+  array_type_oid => '3909',
   typname => 'tsrange', typlen => '-1', typbyval => 'f', typtype => 'r',
   typcategory => 'R', typarray => '_tsrange', 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',
+  array_type_oid => '3911',
   typname => 'tstzrange', typlen => '-1', typbyval => 'f', typtype => 'r',
   typcategory => 'R', typarray => '_tstzrange', 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', descr => 'range of dates', array_type_oid => '3913',
   typname => 'daterange', typlen => '-1', typbyval => 'f', typtype => 'r',
   typcategory => 'R', typarray => '_daterange', 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', descr => 'range of bigints', array_type_oid => '3927',
   typname => 'int8range', typlen => '-1', typbyval => 'f', typtype => 'r',
   typcategory => 'R', typarray => '_int8range', 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.
@@ -859,12 +545,15 @@
   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 generated.
 { 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',
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 1e9cea70e2..a345044bbf 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -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_TYPE(-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_TYPE(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_TYPE(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_TYPE(A);
 
     /* is type "preferred" within its category? */
-    bool        typispreferred BKI_DEFAULT(f);
+    bool        typispreferred BKI_DEFAULT(f) BKI_ARRAY_TYPE(f);
 
     /*
      * If typisdefined is false, the entry is only a placeholder (forward
@@ -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_TYPE(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_TYPE(array_in) BKI_LOOKUP(pg_proc);
+    regproc        typoutput BKI_ARRAY_TYPE(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_TYPE(array_recv) BKI_LOOKUP(pg_proc);
+    regproc        typsend BKI_ARRAY_TYPE(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_TYPE(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_TYPE(x);
 
     /*
      * This flag represents a "NOT NULL" constraint against this datatype.
diff --git a/src/include/catalog/reformat_dat_file.pl b/src/include/catalog/reformat_dat_file.pl
index 687aca0b16..24d9d18637 100755
--- a/src/include/catalog/reformat_dat_file.pl
+++ b/src/include/catalog/reformat_dat_file.pl
@@ -63,7 +63,7 @@ if ($output_path ne '' && substr($output_path, -1) ne '/')
 }
 
 # Metadata of a catalog entry
-my @METADATA = ('oid', 'oid_symbol', 'descr');
+my @METADATA = ('oid', 'oid_symbol', 'descr', 'array_type_oid');
 
 # Read all the input files into internal data structures.
 # We pass data file names as arguments and then look for matching
-- 
2.18.0


Re: generating bootstrap entries for array types

От
Dagfinn Ilmari Mannsåker
Дата:
The following review has been posted through the commitfest application:
make installcheck-world:  tested, passed
Implements feature:       tested, passed
Spec compliant:           not tested
Documentation:            tested, passed

The v2 patch is IMO ready to commit.

The documentation in the form of source comments is updated,
and having Catalog::ParseData() do the expansion instead of
genbki.pl is more in line with what bki.sgml says: 

      If you want to add a new method of making the data representation
      smaller, you must implement it
      in <filename>reformat_dat_file.pl</filename> and also
      teach <function>Catalog::ParseData()</function> how to expand the
      data back into the full representation.

- ilmari

The new status of this patch is: Ready for Committer

Re: generating bootstrap entries for array types

От
Tom Lane
Дата:
ilmari@ilmari.org (Dagfinn Ilmari =?utf-8?Q?Manns=C3=A5ker?=) writes:
> ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:
>> Doing this in genbki.pl makes DBD::Pg lose its array type information,
>> since it uses Catalog::ParseData() to get it
>> (https://github.com/bucardo/dbdpg/blob/master/types.c#L439).  May I
>> suggest moving gen_array_types() to Catalog.pm and calling it from
>> ParseData() if the input file is pg_type.dat, so that it always returns
>> complete data?

> Attached is a proposed revision of this patch that does the above.  It
> passes check-world, reformat_dat_file.pl still works, and DBD::Pg is
> still able to get the array type information.

I find the way you did that (making the call dependent on
$preserve_formatting) to be a mighty ugly kluge.  It causes ParseData
to know far more than it should about what callers are likely to do with
the data.

I'm inclined to think the right way is to do the expansion always,
and teach reformat_dat_file.pl to drop autogenerated array types
on the way out, making this work more like the existing facilities
for default/computed fields.

The easiest way to make that happen seems to be to invent another, purely
internal metadata field, along the lines of "is_autogenerated_entry".
Fooling with that now ...

            regards, tom lane


Re: generating bootstrap entries for array types

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
Tom Lane <tgl@sss.pgh.pa.us> writes:

> ilmari@ilmari.org (Dagfinn Ilmari =?utf-8?Q?Manns=C3=A5ker?=) writes:
>> ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:
>>> Doing this in genbki.pl makes DBD::Pg lose its array type information,
>>> since it uses Catalog::ParseData() to get it
>>> (https://github.com/bucardo/dbdpg/blob/master/types.c#L439).  May I
>>> suggest moving gen_array_types() to Catalog.pm and calling it from
>>> ParseData() if the input file is pg_type.dat, so that it always returns
>>> complete data?
>
>> Attached is a proposed revision of this patch that does the above.  It
>> passes check-world, reformat_dat_file.pl still works, and DBD::Pg is
>> still able to get the array type information.
>
> I find the way you did that (making the call dependent on
> $preserve_formatting) to be a mighty ugly kluge.  It causes ParseData
> to know far more than it should about what callers are likely to do with
> the data.
>
> I'm inclined to think the right way is to do the expansion always,
> and teach reformat_dat_file.pl to drop autogenerated array types
> on the way out, making this work more like the existing facilities
> for default/computed fields.
>
> The easiest way to make that happen seems to be to invent another, purely
> internal metadata field, along the lines of "is_autogenerated_entry".
> Fooling with that now ...

Something like this, on top of the v2 patch?

diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index 12b142928a..7286c5b673 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -297,7 +297,7 @@ sub ParseData
 
     # Generate array types unless we're just reformatting the file
     Catalog::GenArrayTypes($schema, $data)
-        if $catname eq 'pg_type' and !$preserve_formatting;
+        if $catname eq 'pg_type';
     return $data;
 }
 
@@ -485,6 +485,7 @@ sub GenArrayTypes
 
     foreach my $elem_type (@$types)
     {
+        next if ref $elem_type ne 'HASH';
         next if !exists $elem_type->{array_type_oid};
         my %array_type;
 
@@ -493,6 +494,9 @@ sub GenArrayTypes
         $array_type{typname} = '_' . $elem_type->{typname};
         $array_type{typelem} = $elem_type->{typname};
 
+        # Stops this entry being output when reformatting the .dat files
+        $array_type{is_auto_generated_entry} = 1;
+
         # Arrays require INT alignment, unless the element type requires
         # DOUBLE alignment.
         $array_type{typalign} = $elem_type->{typalign} eq 'd' ? 'd' : 'i';
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 053d1ee00d..3859d46043 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -396,7 +396,8 @@ EOM
               || $key eq "oid_symbol"
               || $key eq "descr"
               || $key eq "line_number"
-              || $key eq "array_type_oid";
+              || $key eq "array_type_oid"
+              || $key eq "is_auto_generated_entry";
             die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n",
               $key, $catname, $bki_values{line_number}
               if (!exists($attnames{$key}));
diff --git a/src/include/catalog/reformat_dat_file.pl b/src/include/catalog/reformat_dat_file.pl
index 24d9d18637..78c0f3e103 100755
--- a/src/include/catalog/reformat_dat_file.pl
+++ b/src/include/catalog/reformat_dat_file.pl
@@ -132,6 +132,7 @@ foreach my $catname (@catnames)
         if (ref $data eq 'HASH')
         {
             my %values = %$data;
+            next if $values{is_auto_generated_entry};
 
             ############################################################
             # At this point we have the full tuple in memory as a hash

- ilmari
-- 
"The surreality of the universe tends towards a maximum" -- Skud's Law
"Never formulate a law or axiom that you're not prepared to live with
 the consequences of."                              -- Skud's Meta-Law


Re: generating bootstrap entries for array types

От
John Naylor
Дата:
On 9/20/18, Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> wrote:
> Hi again John,

Hi Ilmari,
My apologies -- your messages ended up in my spam folder. I only saw
this thread again when Tom replied. Thanks for the review! I'll keep a
look out for any future messages.

-John Naylor


Re: generating bootstrap entries for array types

От
Tom Lane
Дата:
ilmari@ilmari.org (Dagfinn Ilmari =?utf-8?Q?Manns=C3=A5ker?=) writes:
> Tom Lane <tgl@sss.pgh.pa.us> writes:
>> I'm inclined to think the right way is to do the expansion always,
>> and teach reformat_dat_file.pl to drop autogenerated array types
>> on the way out, making this work more like the existing facilities
>> for default/computed fields.
>> 
>> The easiest way to make that happen seems to be to invent another, purely
>> internal metadata field, along the lines of "is_autogenerated_entry".
>> Fooling with that now ...

> Something like this, on top of the v2 patch?

Yeah, that's pretty close to what I came up with, except that I thought
it'd be good if "reformat_dat_file.pl --full-tuples" would print
autogenerated entries; seems useful for debug purposes if nothing else.
So that requires also teaching ParseData to ignore autogenerated entries
on read-in, else you end up with duplicates.

I did some other minor hacking (mostly, fixing the documentation)
and pushed it.

            regards, tom lane


Re: generating bootstrap entries for array types

От
Tom Lane
Дата:
I wrote:
> I did some other minor hacking (mostly, fixing the documentation)
> and pushed it.

BTW, I hadn't thought to measure before, but this patch cut the
size of pg_type.dat by almost 40%.  Nice!

            regards, tom lane


Re: generating bootstrap entries for array types

От
John Naylor
Дата:
On 9/21/18, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> I did some other minor hacking (mostly, fixing the documentation)
> and pushed it.

Thank you.

-John Naylor