OSDN Git Service

Replace the hard-wired type knowledge in TypeCategory() and IsPreferredType()
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 30 Jul 2008 17:05:05 +0000 (17:05 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 30 Jul 2008 17:05:05 +0000 (17:05 +0000)
with system catalog lookups, as was foreseen to be necessary almost since
their creation.  Instead put the information into two new pg_type columns,
typcategory and typispreferred.  Add support for setting these when
creating a user-defined base type.

The category column is just a "char" (i.e. a poor man's enum), allowing
a crude form of user extensibility of the category list: just use an
otherwise-unused character.  This seems sufficient for foreseen uses,
but we could upgrade to having an actual category catalog someday, if
there proves to be a huge demand for custom type categories.

In this patch I have attempted to hew exactly to the behavior of the
previous hardwired logic, except for introducing new type categories for
arrays, composites, and enums.  In particular the default preferred state
for user-defined types remains TRUE.  That seems worth revisiting, but it
should be done as a separate patch from introducing the infrastructure.
Likewise, any adjustment of the standard set of categories should be done
separately.

20 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/create_type.sgml
doc/src/sgml/typeconv.sgml
src/backend/catalog/heap.c
src/backend/catalog/pg_type.c
src/backend/commands/indexcmds.c
src/backend/commands/typecmds.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_func.c
src/backend/utils/cache/lsyscache.c
src/bin/pg_dump/pg_dump.c
src/include/catalog/catversion.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_class.h
src/include/catalog/pg_type.h
src/include/catalog/pg_type_fn.h
src/include/parser/parse_coerce.h
src/include/utils/lsyscache.h
src/test/regress/expected/create_type.out
src/test/regress/sql/create_type.sql

index a7a3cea..f756830 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.171 2008/07/18 03:32:51 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.172 2008/07/30 17:05:04 tgl Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
       <entry><type>int4</type></entry>
       <entry></entry>
       <entry>
-       The number of direct ancestors this column has.  A column with a 
+       The number of direct ancestors this column has.  A column with a
        nonzero number of ancestors cannot be dropped nor renamed
       </entry>
      </row>
 
   <para>
    In a dropped column's <structname>pg_attribute</structname> entry,
-   <structfield>atttypid</structfield> is reset to zero, but 
+   <structfield>atttypid</structfield> is reset to zero, but
    <structfield>attlen</structfield> and the other fields copied from
    <structname>pg_type</> are still valid.  This arrangement is needed
    to cope with the situation where the dropped column's data type was
       <entry><structfield>rolconnlimit</structfield></entry>
       <entry><type>int4</type></entry>
       <entry>
-       For roles that can log in, this sets maximum number of concurrent 
+       For roles that can log in, this sets maximum number of concurrent
        connections this role can make.  -1 means no limit
       </entry>
      </row>
       <entry><type>int4</type></entry>
       <entry></entry>
       <entry>
-       Sets maximum number of concurrent connections that can be made 
+       Sets maximum number of concurrent connections that can be made
        to this database.  -1 means no limit
       </entry>
      </row>
 
   <para>
    The catalog <structname>pg_type</structname> stores information about data
-   types.  Base types (scalar types) are created with
+   types.  Base types and enum types (scalar types) are created with
    <xref linkend="sql-createtype" endterm="sql-createtype-title">, and
    domains with
    <xref linkend="sql-createdomain" endterm="sql-createdomain-title">.
        where Datum is 8 bytes).
        Variable-length types are always passed by reference. Note that
        <structfield>typbyval</structfield> can be false even if the
-       length would allow pass-by-value; this is currently true for
-       type <type>float4</type>, for example
+       length would allow pass-by-value
       </entry>
      </row>
 
      </row>
 
      <row>
+      <entry><structfield>typcategory</structfield></entry>
+      <entry><type>char</type></entry>
+      <entry></entry>
+      <entry>
+       <structfield>typcategory</structfield> is an arbitrary classification
+       of data types that is used by the parser to determine which implicit
+       casts should be <quote>preferred</>.
+       See <xref linkend="catalog-typcategory-table">
+      </entry>
+     </row>
+
+     <row>
+      <entry><structfield>typispreferred</structfield></entry>
+      <entry><type>bool</type></entry>
+      <entry></entry>
+      <entry>
+       True if the type is a preferred cast target within its
+       <structfield>typcategory</structfield>
+      </entry>
+     </row>
+
+     <row>
       <entry><structfield>typisdefined</structfield></entry>
       <entry><type>bool</type></entry>
       <entry></entry>
     </tbody>
    </tgroup>
   </table>
+
+  <para>
+   <xref linkend="catalog-typcategory-table"> lists the system-defined values
+   of <structfield>typcategory</>.  Any future additions to this list will
+   also be upper-case ASCII letters.  All other ASCII characters are reserved
+   for user-defined categories.
+  </para>
+
+  <table id="catalog-typcategory-table">
+   <title><structfield>typcategory</> Codes</title>
+
+   <tgroup cols=2>
+    <thead>
+     <row>
+      <entry>Code</entry>
+      <entry>Category</entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry><literal>A</literal></entry>
+      <entry>Array types</entry>
+     </row>
+     <row>
+      <entry><literal>B</literal></entry>
+      <entry>Boolean types</entry>
+     </row>
+     <row>
+      <entry><literal>C</literal></entry>
+      <entry>Composite types</entry>
+     </row>
+     <row>
+      <entry><literal>D</literal></entry>
+      <entry>Date/time types</entry>
+     </row>
+     <row>
+      <entry><literal>E</literal></entry>
+      <entry>Enum types</entry>
+     </row>
+     <row>
+      <entry><literal>G</literal></entry>
+      <entry>Geometric types</entry>
+     </row>
+     <row>
+      <entry><literal>I</literal></entry>
+      <entry>Network address types</entry>
+     </row>
+     <row>
+      <entry><literal>N</literal></entry>
+      <entry>Numeric types</entry>
+     </row>
+     <row>
+      <entry><literal>P</literal></entry>
+      <entry>Pseudo-types</entry>
+     </row>
+     <row>
+      <entry><literal>S</literal></entry>
+      <entry>String types</entry>
+     </row>
+     <row>
+      <entry><literal>T</literal></entry>
+      <entry>Timespan types</entry>
+     </row>
+     <row>
+      <entry><literal>U</literal></entry>
+      <entry>User-defined types</entry>
+     </row>
+     <row>
+      <entry><literal>V</literal></entry>
+      <entry>Bit-string types</entry>
+     </row>
+     <row>
+      <entry><literal>X</literal></entry>
+      <entry><type>unknown</> type</entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+
  </sect1>
 
  <sect1 id="views-overview">
    for another transaction, it does so by attempting to acquire share lock on
    the other transaction ID (either virtual or permanent ID depending on the
    situation). That will succeed only when the other transaction
-   terminates and releases its locks. 
+   terminates and releases its locks.
   </para>
 
   <para>
   <para>
    The view <structname>pg_roles</structname> provides access to
    information about database roles.  This is simply a publicly
-   readable view of 
+   readable view of
    <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>
    that blanks out the password field.
   </para>
       <entry><type>int4</type></entry>
       <entry></entry>
       <entry>
-       For roles that can log in, this sets maximum number of concurrent 
+       For roles that can log in, this sets maximum number of concurrent
        connections this role can make.  -1 means no limit
       </entry>
      </row>
     </tbody>
    </tgroup>
   </table>
-  
+
   <para>
    The <structname>pg_settings</structname> view cannot be inserted into or
    deleted from, but it can be updated.  An <command>UPDATE</command> applied
   <para>
    The view <structname>pg_user</structname> provides access to
    information about database users.  This is simply a publicly
-   readable view of 
+   readable view of
    <link linkend="view-pg-shadow"><structname>pg_shadow</structname></link>
    that blanks out the password field.
   </para>
index e643f09..8002e2c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.74 2008/05/27 18:05:13 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.75 2008/07/30 17:05:04 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -38,6 +38,8 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
     [ , PASSEDBYVALUE ]
     [ , ALIGNMENT = <replaceable class="parameter">alignment</replaceable> ]
     [ , STORAGE = <replaceable class="parameter">storage</replaceable> ]
+    [ , CATEGORY = <replaceable class="parameter">category</replaceable> ]
+    [ , PREFERRED = <replaceable class="parameter">preferred</replaceable> ]
     [ , DEFAULT = <replaceable class="parameter">default</replaceable> ]
     [ , ELEMENT = <replaceable class="parameter">element</replaceable> ]
     [ , DELIMITER = <replaceable class="parameter">delimiter</replaceable> ]
@@ -282,6 +284,27 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
   </para>
 
   <para>
+   The <replaceable class="parameter">category</replaceable> and
+   <replaceable class="parameter">preferred</replaceable> parameters can be
+   used to help control which implicit cast will be applied in ambiguous
+   situations.  Each data type belongs to a category named by a single ASCII
+   character, and each type is either <quote>preferred</> or not within its
+   category.  The parser will prefer casting to preferred types (but only from
+   other types within the same category) when this rule is helpful in
+   resolving overloaded functions or operators.  For more details see <xref
+   linkend="typeconv">.  For types that have no implicit casts to or from any
+   other types, it is sufficient to leave these settings at the defaults.
+   However, for a group of related types that have implicit casts, it is often
+   helpful to mark them all as belonging to a category and select one or two
+   of the <quote>most general</> types as being preferred within the category.
+   The <replaceable class="parameter">category</replaceable> parameter is
+   especially useful when adding a user-defined type to an existing built-in
+   category, such as the numeric or string types.  However, it is also
+   possible to create new entirely-user-defined type categories.  Select any
+   ASCII character other than an upper-case letter to name such a category.
+  </para>
+
+  <para>
    A default value can be specified, in case a user wants columns of the
    data type to default to something other than the null value.
    Specify the default with the <literal>DEFAULT</literal> key word.
@@ -495,6 +518,31 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
    </varlistentry>
 
    <varlistentry>
+    <term><replaceable class="parameter">category</replaceable></term>
+    <listitem>
+     <para>
+      The category code (a single ASCII character) for this type.
+      The default is <literal>'U'</> for <quote>user-defined type</>.
+      Other standard category codes can be found in
+      <xref linkend="catalog-typcategory-table">.  You may also choose
+      other ASCII characters in order to create custom categories.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><replaceable class="parameter">preferred</replaceable></term>
+    <listitem>
+     <para>
+      True if this type is a preferred type within its type category,
+      else false.  The default is true (which is appropriate for
+      all entries in category <literal>U</>, but is usually not
+      appropriate for new types in other categories &mdash; beware!).
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="parameter">default</replaceable></term>
     <listitem>
      <para>
index 4f04801..c9f9632 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.55 2008/07/16 01:30:21 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.56 2008/07/30 17:05:04 tgl Exp $ -->
 
 <chapter Id="typeconv">
 <title>Type Conversion</title>
@@ -10,7 +10,7 @@
 
 <para>
 <acronym>SQL</acronym> statements can, intentionally or not, require
-mixing of different data types in the same expression. 
+mixing of different data types in the same expression.
 <productname>PostgreSQL</productname> has extensive facilities for
 evaluating mixed-type expressions.
 </para>
@@ -153,19 +153,32 @@ altered.)
 
 <para>
 An additional heuristic is provided in the parser to allow better guesses
-at proper behavior for <acronym>SQL</acronym> standard types. There are
-several basic <firstterm>type categories</firstterm> defined: <type>boolean</type>,
-<type>numeric</type>, <type>string</type>, <type>bitstring</type>, <type>datetime</type>, <type>timespan</type>, <type>geometric</type>, <type>network</type>,
-and user-defined. Each category, with the exception of user-defined, has
-one or more <firstterm>preferred types</firstterm> which are preferentially
-selected when there is ambiguity.
-In the user-defined category, each type is its own preferred type.
-Ambiguous expressions (those with multiple candidate parsing solutions)
-can therefore often be resolved when there are multiple possible built-in types, but
-they will raise an error when there are multiple choices for user-defined
-types.
+at proper casting behavior among groups of types that have implicit casts.
+Data types are divided into several basic <firstterm>type
+categories</firstterm>, including <type>boolean</type>, <type>numeric</type>,
+<type>string</type>, <type>bitstring</type>, <type>datetime</type>,
+<type>timespan</type>, <type>geometric</type>, <type>network</type>, and
+user-defined.  (For a list see <xref linkend="catalog-typcategory-table">;
+but note it is also possible to create custom type categories.)  Within each
+category there are one or more <firstterm>preferred types</firstterm>, which
+are preferentially selected when there is ambiguity.  With careful selection
+of preferred types and available implicit casts, it is possible to ensure that
+ambiguous expressions (those with multiple candidate parsing solutions) can be
+resolved in a useful way.
 </para>
 
+<note>
+ <para>
+  For what are now historical reasons, types in the <quote>user-defined</>
+  category are normally always marked as <quote>preferred</>.  Since all types
+  in this category are preferred, the heuristic that favors preferred types
+  accomplishes nothing, and thus this situation is equivalent to treating them
+  all as non-preferred.  The <quote>preferred</> marking is useful within the
+  system-defined type categories, and can be useful within custom type
+  categories.
+ </para>
+</note>
+
 <para>
 All type conversion rules are designed with several principles in mind:
 
@@ -178,23 +191,6 @@ Implicit conversions should never have surprising or unpredictable outcomes.
 
 <listitem>
 <para>
-User-defined types, of which the parser has no <foreignphrase>a priori</> knowledge, should be
-<quote>higher</quote> in the type hierarchy. In mixed-type expressions, native types shall always
-be converted to a user-defined type (of course, only if conversion is necessary).
-</para>
-</listitem>
-
-<listitem>
-<para>
-User-defined types are not related. Currently, <productname>PostgreSQL</productname>
-does not have information available to it on relationships between types, other than
-hardcoded heuristics for built-in types and implicit relationships based on
-available functions and casts.
-</para>
-</listitem>
-
-<listitem>
-<para>
 There should be no extra overhead from the parser or executor
 if a query does not need implicit type conversion.
 That is, if a query is well formulated and the types already match up, then the query should proceed
@@ -317,7 +313,7 @@ all the remaining candidates accept the same type category, select that
 category; otherwise fail because the correct choice cannot be deduced
 without more clues.  Now discard
 candidates that do not accept the selected type category.  Furthermore,
-if any candidate accepts a preferred type at a given argument position,
+if any candidate accepts a preferred type in that category,
 discard candidates that accept non-preferred types for that argument.
 </para>
 </step>
@@ -341,7 +337,7 @@ Some examples follow.
 
 <para>
 There is only one factorial operator (postfix <literal>!</>)
-defined in the standard catalog, and it takes an argument of type 
+defined in the standard catalog, and it takes an argument of type
 <type>bigint</type>.
 The scanner assigns an initial type of <type>integer</type> to the argument
 in this query expression:
@@ -407,7 +403,7 @@ In this case there is no initial hint for which type to use, since no types
 are specified in the query. So, the parser looks for all candidate operators
 and finds that there are candidates accepting both string-category and
 bit-string-category inputs.  Since string category is preferred when available,
-that category is selected, and then the 
+that category is selected, and then the
 preferred type for strings, <type>text</type>, is used as the specific
 type to resolve the unknown literals to.
 </para>
@@ -585,7 +581,7 @@ If only one candidate remains, use it; else continue to the next step.
 <step performance="required">
 <para>
 If any input arguments are <type>unknown</type>, check the type categories
-accepted 
+accepted
 at those argument positions by the remaining candidates.  At each position,
 select the <type>string</type> category if any candidate accepts that category.
 (This bias towards string
@@ -594,9 +590,8 @@ Otherwise, if all the remaining candidates accept the same type category,
 select that category; otherwise fail because
 the correct choice cannot be deduced without more clues.
 Now discard candidates that do not accept the selected type category.
-Furthermore, if any candidate accepts a preferred type at a given argument
-position, discard candidates that accept non-preferred types for that
-argument.
+Furthermore, if any candidate accepts a preferred type in that category,
+discard candidates that accept non-preferred types for that argument.
 </para>
 </step>
 <step performance="required">
index 797bee8..5510e72 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.334 2008/05/12 00:00:46 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.335 2008/07/30 17:05:04 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -761,6 +761,8 @@ AddNewRelationType(const char *typeName,
                                   new_rel_kind,        /* relation kind */
                                   -1,                  /* internal size (varlena) */
                                   TYPTYPE_COMPOSITE,   /* type-type (composite) */
+                                  TYPCATEGORY_COMPOSITE, /* type-category (ditto) */
+                                  true,                /* all composite types are preferred */
                                   DEFAULT_TYPDELIM,    /* default array delimiter */
                                   F_RECORD_IN, /* input procedure */
                                   F_RECORD_OUT,        /* output procedure */
@@ -938,6 +940,8 @@ heap_create_with_catalog(const char *relname,
                                   0,                   /* relkind, also N/A here */
                                   -1,                  /* Internal size (varlena) */
                                   TYPTYPE_BASE,        /* Not composite - typelem is */
+                                  TYPCATEGORY_ARRAY, /* type-category (array) */
+                                  true,                /* all array types are preferred */
                                   DEFAULT_TYPDELIM,    /* default array delimiter */
                                   F_ARRAY_IN,  /* array input proc */
                                   F_ARRAY_OUT, /* array output proc */
index 42caacc..a6aec62 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.119 2008/06/19 00:46:04 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.120 2008/07/30 17:05:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,6 +91,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
        values[i++] = Int16GetDatum(sizeof(int4));      /* typlen */
        values[i++] = BoolGetDatum(true);       /* typbyval */
        values[i++] = CharGetDatum(TYPTYPE_PSEUDO); /* typtype */
+       values[i++] = CharGetDatum(TYPCATEGORY_PSEUDOTYPE); /* typcategory */
+       values[i++] = BoolGetDatum(false);      /* typispreferred */
        values[i++] = BoolGetDatum(false);      /* typisdefined */
        values[i++] = CharGetDatum(DEFAULT_TYPDELIM);           /* typdelim */
        values[i++] = ObjectIdGetDatum(InvalidOid); /* typrelid */
@@ -173,6 +175,8 @@ TypeCreate(Oid newTypeOid,
                   char relationKind,   /* ditto */
                   int16 internalSize,
                   char typeType,
+                  char typeCategory,
+                  bool typePreferred,
                   char typDelim,
                   Oid inputProcedure,
                   Oid outputProcedure,
@@ -253,6 +257,8 @@ TypeCreate(Oid newTypeOid,
        values[i++] = Int16GetDatum(internalSize);      /* typlen */
        values[i++] = BoolGetDatum(passedByValue);      /* typbyval */
        values[i++] = CharGetDatum(typeType);           /* typtype */
+       values[i++] = CharGetDatum(typeCategory);       /* typcategory */
+       values[i++] = BoolGetDatum(typePreferred);      /* typispreferred */
        values[i++] = BoolGetDatum(true);       /* typisdefined */
        values[i++] = CharGetDatum(typDelim);           /* typdelim */
        values[i++] = ObjectIdGetDatum(relationOid);            /* typrelid */
index a8a78b5..1427b2a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.177 2008/06/14 18:04:33 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.178 2008/07/30 17:05:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1012,7 +1012,7 @@ GetDefaultOpClass(Oid type_id, Oid am_id)
        ScanKeyData skey[1];
        SysScanDesc scan;
        HeapTuple       tup;
-       CATEGORY        tcategory;
+       TYPCATEGORY     tcategory;
 
        /* If it's a domain, look at the base type instead */
        type_id = getBaseType(type_id);
index 793e926..84d8036 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.119 2008/06/14 18:04:33 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.120 2008/07/30 17:05:04 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -111,6 +111,8 @@ DefineType(List *names, List *parameters)
        List       *analyzeName = NIL;
        char       *defaultValue = NULL;
        bool            byValue = false;
+       char            category = TYPCATEGORY_USER;
+       bool            preferred = true;
        char            delimiter = DEFAULT_TYPDELIM;
        char            alignment = 'i';        /* default alignment */
        char            storage = 'p';  /* default TOAST storage method */
@@ -188,8 +190,6 @@ DefineType(List *names, List *parameters)
 
                if (pg_strcasecmp(defel->defname, "internallength") == 0)
                        internalLength = defGetTypeLength(defel);
-               else if (pg_strcasecmp(defel->defname, "externallength") == 0)
-                       ;                                       /* ignored -- remove after 7.3 */
                else if (pg_strcasecmp(defel->defname, "input") == 0)
                        inputName = defGetQualifiedName(defel);
                else if (pg_strcasecmp(defel->defname, "output") == 0)
@@ -205,11 +205,26 @@ DefineType(List *names, List *parameters)
                else if (pg_strcasecmp(defel->defname, "analyze") == 0 ||
                                 pg_strcasecmp(defel->defname, "analyse") == 0)
                        analyzeName = defGetQualifiedName(defel);
+               else if (pg_strcasecmp(defel->defname, "category") == 0)
+               {
+                       char       *p = defGetString(defel);
+
+                       category = p[0];
+                       /* restrict to non-control ASCII */
+                       if (category < 32 || category > 126)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                                errmsg("invalid type category \"%s\": must be simple ASCII",
+                                                               p)));
+               }
+               else if (pg_strcasecmp(defel->defname, "preferred") == 0)
+                       preferred = defGetBoolean(defel);
                else if (pg_strcasecmp(defel->defname, "delimiter") == 0)
                {
                        char       *p = defGetString(defel);
 
                        delimiter = p[0];
+                       /* XXX shouldn't we restrict the delimiter? */
                }
                else if (pg_strcasecmp(defel->defname, "element") == 0)
                {
@@ -421,6 +436,8 @@ DefineType(List *names, List *parameters)
                                   0,                   /* relation kind (ditto) */
                                   internalLength,              /* internal size */
                                   TYPTYPE_BASE,        /* type-type (base type) */
+                                  category,    /* type-category */
+                                  preferred,   /* is it a preferred type? */
                                   delimiter,   /* array element delimiter */
                                   inputOid,    /* input procedure */
                                   outputOid,   /* output procedure */
@@ -457,6 +474,8 @@ DefineType(List *names, List *parameters)
                           0,                           /* relation kind (ditto) */
                           -1,                          /* internal size (always varlena) */
                           TYPTYPE_BASE,        /* type-type (base type) */
+                          TYPCATEGORY_ARRAY, /* type-category (array) */
+                          true,                        /* all array types are preferred */
                           DEFAULT_TYPDELIM,    /* array element delimiter */
                           F_ARRAY_IN,          /* input procedure */
                           F_ARRAY_OUT,         /* output procedure */
@@ -624,6 +643,7 @@ DefineDomain(CreateDomainStmt *stmt)
        Oid                     analyzeProcedure;
        bool            byValue;
        Oid                     typelem;
+       char            category;
        char            delimiter;
        char            alignment;
        char            storage;
@@ -705,6 +725,9 @@ DefineDomain(CreateDomainStmt *stmt)
        /* Storage Length */
        internalLength = baseType->typlen;
 
+       /* Type Category */
+       category = baseType->typcategory;
+
        /* Array element type (in case base type is an array) */
        typelem = baseType->typelem;
 
@@ -895,6 +918,8 @@ DefineDomain(CreateDomainStmt *stmt)
                                   0,                   /* relation kind (ditto) */
                                   internalLength,              /* internal size */
                                   TYPTYPE_DOMAIN,              /* type-type (domain type) */
+                                  category,    /* type-category */
+                                  false,               /* domains are never preferred types */
                                   delimiter,   /* array element delimiter */
                                   inputProcedure,              /* input procedure */
                                   outputProcedure,             /* output procedure */
@@ -1006,6 +1031,8 @@ DefineEnum(CreateEnumStmt *stmt)
                                   0,                   /* relation kind (ditto) */
                                   sizeof(Oid), /* internal size */
                                   TYPTYPE_ENUM,        /* type-type (enum type) */
+                                  TYPCATEGORY_ENUM,    /* type-category (enum type) */
+                                  true,                /* all enum types are preferred */
                                   DEFAULT_TYPDELIM,    /* array element delimiter */
                                   F_ENUM_IN,   /* input procedure */
                                   F_ENUM_OUT,  /* output procedure */
@@ -1042,6 +1069,8 @@ DefineEnum(CreateEnumStmt *stmt)
                           0,                           /* relation kind (ditto) */
                           -1,                          /* internal size (always varlena) */
                           TYPTYPE_BASE,        /* type-type (base type) */
+                          TYPCATEGORY_ARRAY, /* type-category (array) */
+                          true,                        /* all array types are preferred */
                           DEFAULT_TYPDELIM,    /* array element delimiter */
                           F_ARRAY_IN,          /* input procedure */
                           F_ARRAY_OUT,         /* output procedure */
index 2467640..df5ad09 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.161 2008/01/11 18:39:40 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.162 2008/07/30 17:05:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -967,7 +967,8 @@ Oid
 select_common_type(List *typeids, const char *context)
 {
        Oid                     ptype;
-       CATEGORY        pcategory;
+       TYPCATEGORY     pcategory;
+       bool            pispreferred;
        ListCell   *type_item;
 
        Assert(typeids != NIL);
@@ -993,7 +994,7 @@ select_common_type(List *typeids, const char *context)
 
        /* Nope, so set up for the full algorithm */
        ptype = getBaseType(ptype);
-       pcategory = TypeCategory(ptype);
+       get_type_category_preferred(ptype, &pcategory, &pispreferred);
 
        for_each_cell(type_item, lnext(list_head(typeids)))
        {
@@ -1002,13 +1003,18 @@ select_common_type(List *typeids, const char *context)
                /* move on to next one if no new information... */
                if (ntype != UNKNOWNOID && ntype != ptype)
                {
+                       TYPCATEGORY     ncategory;
+                       bool            nispreferred;
+
+                       get_type_category_preferred(ntype, &ncategory, &nispreferred);
                        if (ptype == UNKNOWNOID)
                        {
                                /* so far, only unknowns so take anything... */
                                ptype = ntype;
-                               pcategory = TypeCategory(ptype);
+                               pcategory = ncategory;
+                               pispreferred = nispreferred;
                        }
-                       else if (TypeCategory(ntype) != pcategory)
+                       else if (ncategory != pcategory)
                        {
                                /*
                                 * both types in different categories? then not much hope...
@@ -1023,7 +1029,7 @@ select_common_type(List *typeids, const char *context)
                                                                format_type_be(ptype),
                                                                format_type_be(ntype))));
                        }
-                       else if (!IsPreferredType(pcategory, ptype) &&
+                       else if (!pispreferred &&
                                         can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
                                         !can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
                        {
@@ -1032,7 +1038,8 @@ select_common_type(List *typeids, const char *context)
                                 * other way; but if we have a preferred type, stay on it.
                                 */
                                ptype = ntype;
-                               pcategory = TypeCategory(ptype);
+                               pcategory = ncategory;
+                               pispreferred = nispreferred;
                        }
                }
        }
@@ -1549,202 +1556,39 @@ resolve_generic_type(Oid declared_type,
 /* TypeCategory()
  *             Assign a category to the specified type OID.
  *
- * NB: this must not return INVALID_TYPE.
- *
- * XXX This should be moved to system catalog lookups
- * to allow for better type extensibility.
- * - thomas 2001-09-30
+ * NB: this must not return TYPCATEGORY_INVALID.
  */
-CATEGORY
-TypeCategory(Oid inType)
+TYPCATEGORY
+TypeCategory(Oid type)
 {
-       CATEGORY        result;
+       char            typcategory;
+       bool            typispreferred;
 
-       switch (inType)
-       {
-               case (BOOLOID):
-                       result = BOOLEAN_TYPE;
-                       break;
-
-               case (CHAROID):
-               case (NAMEOID):
-               case (BPCHAROID):
-               case (VARCHAROID):
-               case (TEXTOID):
-                       result = STRING_TYPE;
-                       break;
-
-               case (BITOID):
-               case (VARBITOID):
-                       result = BITSTRING_TYPE;
-                       break;
-
-               case (OIDOID):
-               case (REGPROCOID):
-               case (REGPROCEDUREOID):
-               case (REGOPEROID):
-               case (REGOPERATOROID):
-               case (REGCLASSOID):
-               case (REGTYPEOID):
-               case (REGCONFIGOID):
-               case (REGDICTIONARYOID):
-               case (INT2OID):
-               case (INT4OID):
-               case (INT8OID):
-               case (FLOAT4OID):
-               case (FLOAT8OID):
-               case (NUMERICOID):
-               case (CASHOID):
-                       result = NUMERIC_TYPE;
-                       break;
-
-               case (DATEOID):
-               case (TIMEOID):
-               case (TIMETZOID):
-               case (ABSTIMEOID):
-               case (TIMESTAMPOID):
-               case (TIMESTAMPTZOID):
-                       result = DATETIME_TYPE;
-                       break;
-
-               case (RELTIMEOID):
-               case (TINTERVALOID):
-               case (INTERVALOID):
-                       result = TIMESPAN_TYPE;
-                       break;
-
-               case (POINTOID):
-               case (LSEGOID):
-               case (PATHOID):
-               case (BOXOID):
-               case (POLYGONOID):
-               case (LINEOID):
-               case (CIRCLEOID):
-                       result = GEOMETRIC_TYPE;
-                       break;
-
-               case (INETOID):
-               case (CIDROID):
-                       result = NETWORK_TYPE;
-                       break;
-
-               case (UNKNOWNOID):
-               case (InvalidOid):
-                       result = UNKNOWN_TYPE;
-                       break;
-
-               case (RECORDOID):
-               case (CSTRINGOID):
-               case (ANYOID):
-               case (ANYARRAYOID):
-               case (VOIDOID):
-               case (TRIGGEROID):
-               case (LANGUAGE_HANDLEROID):
-               case (INTERNALOID):
-               case (OPAQUEOID):
-               case (ANYELEMENTOID):
-               case (ANYNONARRAYOID):
-               case (ANYENUMOID):
-                       result = GENERIC_TYPE;
-                       break;
-
-               default:
-                       result = USER_TYPE;
-                       break;
-       }
-       return result;
-}      /* TypeCategory() */
+       get_type_category_preferred(type, &typcategory, &typispreferred);
+       Assert(typcategory != TYPCATEGORY_INVALID);
+       return (TYPCATEGORY) typcategory;
+}
 
 
 /* IsPreferredType()
  *             Check if this type is a preferred type for the given category.
  *
- * If category is INVALID_TYPE, then we'll return TRUE for preferred types
- * of any category; otherwise, only for preferred types of that category.
- *
- * XXX This should be moved to system catalog lookups
- * to allow for better type extensibility.
- * - thomas 2001-09-30
+ * If category is TYPCATEGORY_INVALID, then we'll return TRUE for preferred
+ * types of any category; otherwise, only for preferred types of that
+ * category.
  */
 bool
-IsPreferredType(CATEGORY category, Oid type)
+IsPreferredType(TYPCATEGORY category, Oid type)
 {
-       Oid                     preftype;
+       char            typcategory;
+       bool            typispreferred;
 
-       if (category == INVALID_TYPE)
-               category = TypeCategory(type);
-       else if (category != TypeCategory(type))
+       get_type_category_preferred(type, &typcategory, &typispreferred);
+       if (category == typcategory || category == TYPCATEGORY_INVALID)
+               return typispreferred;
+       else
                return false;
-
-       /*
-        * This switch should agree with TypeCategory(), above.  Note that at this
-        * point, category certainly matches the type.
-        */
-       switch (category)
-       {
-               case (UNKNOWN_TYPE):
-               case (GENERIC_TYPE):
-                       preftype = UNKNOWNOID;
-                       break;
-
-               case (BOOLEAN_TYPE):
-                       preftype = BOOLOID;
-                       break;
-
-               case (STRING_TYPE):
-                       preftype = TEXTOID;
-                       break;
-
-               case (BITSTRING_TYPE):
-                       preftype = VARBITOID;
-                       break;
-
-               case (NUMERIC_TYPE):
-                       if (type == OIDOID ||
-                               type == REGPROCOID ||
-                               type == REGPROCEDUREOID ||
-                               type == REGOPEROID ||
-                               type == REGOPERATOROID ||
-                               type == REGCLASSOID ||
-                               type == REGTYPEOID ||
-                               type == REGCONFIGOID ||
-                               type == REGDICTIONARYOID)
-                               preftype = OIDOID;
-                       else
-                               preftype = FLOAT8OID;
-                       break;
-
-               case (DATETIME_TYPE):
-                       if (type == DATEOID)
-                               preftype = TIMESTAMPOID;
-                       else
-                               preftype = TIMESTAMPTZOID;
-                       break;
-
-               case (TIMESPAN_TYPE):
-                       preftype = INTERVALOID;
-                       break;
-
-               case (GEOMETRIC_TYPE):
-                       preftype = type;
-                       break;
-
-               case (NETWORK_TYPE):
-                       preftype = INETOID;
-                       break;
-
-               case (USER_TYPE):
-                       preftype = type;
-                       break;
-
-               default:
-                       elog(ERROR, "unrecognized type category: %d", (int) category);
-                       preftype = UNKNOWNOID;
-                       break;
-       }
-
-       return (type == preftype);
-}      /* IsPreferredType() */
+}
 
 
 /* IsBinaryCoercible()
index 3bb5c45..785e881 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.203 2008/07/16 01:30:22 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.204 2008/07/30 17:05:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -439,8 +439,9 @@ func_select_candidate(int nargs,
        int                     nbestMatch,
                                nmatch;
        Oid                     input_base_typeids[FUNC_MAX_ARGS];
-       CATEGORY        slot_category[FUNC_MAX_ARGS],
+       TYPCATEGORY     slot_category[FUNC_MAX_ARGS],
                                current_category;
+       bool            current_is_preferred;
        bool            slot_has_preferred_type[FUNC_MAX_ARGS];
        bool            resolved_unknowns;
 
@@ -591,7 +592,7 @@ func_select_candidate(int nargs,
                if (input_base_typeids[i] != UNKNOWNOID)
                        continue;
                resolved_unknowns = true;               /* assume we can do it */
-               slot_category[i] = INVALID_TYPE;
+               slot_category[i] = TYPCATEGORY_INVALID;
                slot_has_preferred_type[i] = false;
                have_conflict = false;
                for (current_candidate = candidates;
@@ -600,29 +601,28 @@ func_select_candidate(int nargs,
                {
                        current_typeids = current_candidate->args;
                        current_type = current_typeids[i];
-                       current_category = TypeCategory(current_type);
-                       if (slot_category[i] == INVALID_TYPE)
+                       get_type_category_preferred(current_type,
+                                                                               &current_category,
+                                                                               &current_is_preferred);
+                       if (slot_category[i] == TYPCATEGORY_INVALID)
                        {
                                /* first candidate */
                                slot_category[i] = current_category;
-                               slot_has_preferred_type[i] =
-                                       IsPreferredType(current_category, current_type);
+                               slot_has_preferred_type[i] = current_is_preferred;
                        }
                        else if (current_category == slot_category[i])
                        {
                                /* more candidates in same category */
-                               slot_has_preferred_type[i] |=
-                                       IsPreferredType(current_category, current_type);
+                               slot_has_preferred_type[i] |= current_is_preferred;
                        }
                        else
                        {
                                /* category conflict! */
-                               if (current_category == STRING_TYPE)
+                               if (current_category == TYPCATEGORY_STRING)
                                {
                                        /* STRING always wins if available */
                                        slot_category[i] = current_category;
-                                       slot_has_preferred_type[i] =
-                                               IsPreferredType(current_category, current_type);
+                                       slot_has_preferred_type[i] = current_is_preferred;
                                }
                                else
                                {
@@ -633,7 +633,7 @@ func_select_candidate(int nargs,
                                }
                        }
                }
-               if (have_conflict && slot_category[i] != STRING_TYPE)
+               if (have_conflict && slot_category[i] != TYPCATEGORY_STRING)
                {
                        /* Failed to resolve category conflict at this position */
                        resolved_unknowns = false;
@@ -658,14 +658,15 @@ func_select_candidate(int nargs,
                                if (input_base_typeids[i] != UNKNOWNOID)
                                        continue;
                                current_type = current_typeids[i];
-                               current_category = TypeCategory(current_type);
+                               get_type_category_preferred(current_type,
+                                                                                       &current_category,
+                                                                                       &current_is_preferred);
                                if (current_category != slot_category[i])
                                {
                                        keepit = false;
                                        break;
                                }
-                               if (slot_has_preferred_type[i] &&
-                                       !IsPreferredType(current_category, current_type))
+                               if (slot_has_preferred_type[i] && !current_is_preferred)
                                {
                                        keepit = false;
                                        break;
index e17bd49..7936244 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.157 2008/04/13 20:51:21 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.158 2008/07/30 17:05:04 tgl Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -2168,6 +2168,29 @@ type_is_enum(Oid typid)
 }
 
 /*
+ * get_type_category_preferred
+ *
+ *             Given the type OID, fetch its category and preferred-type status.
+ *             Throws error on failure.
+ */
+void
+get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
+{
+       HeapTuple       tp;
+       Form_pg_type typtup;
+
+       tp = SearchSysCache(TYPEOID,
+                                               ObjectIdGetDatum(typid),
+                                               0, 0, 0);
+       if (!HeapTupleIsValid(tp))
+               elog(ERROR, "cache lookup failed for type %u", typid);
+       typtup = (Form_pg_type) GETSTRUCT(tp);
+       *typcategory = typtup->typcategory;
+       *typispreferred = typtup->typispreferred;
+       ReleaseSysCache(tp);
+}
+
+/*
  * get_typ_typrelid
  *
  *             Given the type OID, get the typrelid (InvalidOid if not a complex
index c4a01c5..3a20397 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.497 2008/07/20 18:43:30 tgl Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.498 2008/07/30 17:05:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -5736,6 +5736,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        Oid                     typmodinoid;
        Oid                     typmodoutoid;
        Oid                     typanalyzeoid;
+       char       *typcategory;
+       char       *typispreferred;
        char       *typdelim;
        char       *typbyval;
        char       *typalign;
@@ -5747,7 +5749,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        selectSourceSchema(tinfo->dobj.namespace->dobj.name);
 
        /* Fetch type-specific details */
-       if (fout->remoteVersion >= 80300)
+       if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query, "SELECT typlen, "
                                                  "typinput, typoutput, typreceive, typsend, "
@@ -5759,6 +5761,26 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typmodin::pg_catalog.oid as typmodinoid, "
                                                  "typmodout::pg_catalog.oid as typmodoutoid, "
                                                  "typanalyze::pg_catalog.oid as typanalyzeoid, "
+                                                 "typcategory, typispreferred, "
+                                                 "typdelim, typbyval, typalign, typstorage, "
+                                                 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
+                                                 "FROM pg_catalog.pg_type "
+                                                 "WHERE oid = '%u'::pg_catalog.oid",
+                                                 tinfo->dobj.catId.oid);
+       }
+       else if (fout->remoteVersion >= 80300)
+       {
+               appendPQExpBuffer(query, "SELECT typlen, "
+                                                 "typinput, typoutput, typreceive, typsend, "
+                                                 "typmodin, typmodout, typanalyze, "
+                                                 "typinput::pg_catalog.oid as typinputoid, "
+                                                 "typoutput::pg_catalog.oid as typoutputoid, "
+                                                 "typreceive::pg_catalog.oid as typreceiveoid, "
+                                                 "typsend::pg_catalog.oid as typsendoid, "
+                                                 "typmodin::pg_catalog.oid as typmodinoid, "
+                                                 "typmodout::pg_catalog.oid as typmodoutoid, "
+                                                 "typanalyze::pg_catalog.oid as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, typstorage, "
                                                  "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                                  "FROM pg_catalog.pg_type "
@@ -5777,6 +5799,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typsend::pg_catalog.oid as typsendoid, "
                                                  "0 as typmodinoid, 0 as typmodoutoid, "
                                                  "typanalyze::pg_catalog.oid as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, typstorage, "
                                                  "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                                  "FROM pg_catalog.pg_type "
@@ -5795,6 +5818,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typsend::pg_catalog.oid as typsendoid, "
                                                  "0 as typmodinoid, 0 as typmodoutoid, "
                                                  "0 as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, typstorage, "
                                                  "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                                  "FROM pg_catalog.pg_type "
@@ -5813,6 +5837,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typmodinoid, 0 as typmodoutoid, "
                                                  "0 as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, typstorage, "
                                                  "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                                  "FROM pg_catalog.pg_type "
@@ -5835,6 +5860,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typmodinoid, 0 as typmodoutoid, "
                                                  "0 as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, typstorage, "
                                                  "NULL as typdefaultbin, typdefault "
                                                  "FROM pg_type "
@@ -5857,6 +5883,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typmodinoid, 0 as typmodoutoid, "
                                                  "0 as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, typstorage, "
                                                  "NULL as typdefaultbin, NULL as typdefault "
                                                  "FROM pg_type "
@@ -5875,6 +5902,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typmodinoid, 0 as typmodoutoid, "
                                                  "0 as typanalyzeoid, "
+                                                 "'U' as typcategory, true as typispreferred, "
                                                  "typdelim, typbyval, typalign, "
                                                  "'p'::char as typstorage, "
                                                  "NULL as typdefaultbin, NULL as typdefault "
@@ -5910,6 +5938,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
        typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
        typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
+       typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
+       typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
        typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
        typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
        typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
@@ -5986,6 +6016,15 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                free(elemType);
        }
 
+       if (strcmp(typcategory, "U") != 0)
+       {
+               appendPQExpBuffer(q, ",\n    CATEGORY = ");
+               appendStringLiteralAH(q, typcategory, fout);
+       }
+
+       if (strcmp(typispreferred, "f") == 0)
+               appendPQExpBuffer(q, ",\n    PREFERRED = false");
+
        if (typdelim && strcmp(typdelim, ",") != 0)
        {
                appendPQExpBuffer(q, ",\n    DELIMITER = ");
index 6fadd8b..a5eaf53 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.471 2008/07/18 03:32:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.472 2008/07/30 17:05:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200807171
+#define CATALOG_VERSION_NO     200807291
 
 #endif
index 074c070..365f45b 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.139 2008/07/16 16:55:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.140 2008/07/30 17:05:05 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -223,26 +223,28 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 { 1247, {"typlen"},               21, -1,      2,      4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
 { 1247, {"typbyval"},     16, -1,      1,      5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
 { 1247, {"typtype"},      18, -1,      1,      6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typisdefined"},  16, -1,     1,      7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typdelim"},     18, -1,      1,      8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typrelid"},     26, -1,      4,      9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typelem"},      26, -1,      4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typarray"},     26, -1,      4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typinput"},     24, -1,      4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typoutput"},    24, -1,      4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typreceive"},    24, -1,     4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typsend"},      24, -1,      4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typmodin"},     24, -1,      4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typmodout"},    24, -1,      4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typanalyze"},    24, -1,     4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typalign"},     18, -1,      1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typstorage"},    18, -1,     1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typnotnull"},    16, -1,     1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typbasetype"},   26, -1,     4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typtypmod"},    23, -1,      4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typndims"},     23, -1,      4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typdefaultbin"}, 25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
-{ 1247, {"typdefault"},    25, -1, -1, 26, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
+{ 1247, {"typcategory"},   18, -1,     1,      7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typispreferred"},16, -1,     1,      8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typisdefined"},  16, -1,     1,      9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typdelim"},     18, -1,      1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typrelid"},     26, -1,      4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typelem"},      26, -1,      4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typarray"},     26, -1,      4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typinput"},     24, -1,      4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typoutput"},    24, -1,      4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typreceive"},    24, -1,     4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typsend"},      24, -1,      4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typmodin"},     24, -1,      4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typmodout"},    24, -1,      4, 19, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typanalyze"},    24, -1,     4, 20, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typalign"},     18, -1,      1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typstorage"},    18, -1,     1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typnotnull"},    16, -1,     1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1247, {"typbasetype"},   26, -1,     4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typtypmod"},    23, -1,      4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typndims"},     23, -1,      4, 26, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typdefaultbin"}, 25, -1, -1, 27, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
+{ 1247, {"typdefault"},    25, -1, -1, 28, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
 
 DATA(insert ( 1247 typname                     19 -1 NAMEDATALEN       1 0 -1 -1 f p c t f f t 0));
 DATA(insert ( 1247 typnamespace                26 -1 4   2 0 -1 -1 t p i t f f t 0));
@@ -250,26 +252,28 @@ DATA(insert ( 1247 typowner                       26 -1 4   3 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1247 typlen                      21 -1 2   4 0 -1 -1 t p s t f f t 0));
 DATA(insert ( 1247 typbyval                    16 -1 1   5 0 -1 -1 t p c t f f t 0));
 DATA(insert ( 1247 typtype                     18 -1 1   6 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typisdefined                16 -1 1   7 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typdelim                    18 -1 1   8 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typrelid                    26 -1 4   9 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typelem                     26 -1 4  10 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typarray                    26 -1 4  11 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typinput                    24 -1 4  12 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typoutput           24 -1 4  13 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typreceive          24 -1 4  14 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typsend                     24 -1 4  15 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typmodin                    24 -1 4  16 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typmodout           24 -1 4  17 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typanalyze          24 -1 4  18 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typalign                    18 -1 1  19 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typstorage          18 -1 1  20 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typnotnull          16 -1 1  21 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typbasetype         26 -1 4  22 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typtypmod           23 -1 4  23 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typndims                    23 -1 4  24 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typdefaultbin       25 -1 -1 25 0 -1 -1 f x i f f f t 0));
-DATA(insert ( 1247 typdefault          25 -1 -1 26 0 -1 -1 f x i f f f t 0));
+DATA(insert ( 1247 typcategory         18 -1 1   7 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typispreferred      16 -1 1   8 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typisdefined                16 -1 1   9 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typdelim                    18 -1 1  10 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typrelid                    26 -1 4  11 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typelem                     26 -1 4  12 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typarray                    26 -1 4  13 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typinput                    24 -1 4  14 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typoutput           24 -1 4  15 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typreceive          24 -1 4  16 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typsend                     24 -1 4  17 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typmodin                    24 -1 4  18 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typmodout           24 -1 4  19 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typanalyze          24 -1 4  20 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typalign                    18 -1 1  21 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typstorage          18 -1 1  22 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typnotnull          16 -1 1  23 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1247 typbasetype         26 -1 4  24 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typtypmod           23 -1 4  25 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typndims                    23 -1 4  26 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typdefaultbin       25 -1 -1 27 0 -1 -1 f x i f f f t 0));
+DATA(insert ( 1247 typdefault          25 -1 -1 28 0 -1 -1 f x i f f f t 0));
 DATA(insert ( 1247 ctid                                27 0  6  -1 0 -1 -1 f p s t f f t 0));
 DATA(insert ( 1247 oid                         26 0  4  -2 0 -1 -1 t p i t f f t 0));
 DATA(insert ( 1247 xmin                                28 0  4  -3 0 -1 -1 t p i t f f t 0));
index 454b907..7f418aa 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.106 2008/07/16 16:55:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.107 2008/07/30 17:05:05 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -127,7 +127,7 @@ typedef FormData_pg_class *Form_pg_class;
  */
 
 /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
-DATA(insert OID = 1247 (  pg_type              PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 26 0 0 0 0 0 t f f f 3   _null_ _null_ ));
+DATA(insert OID = 1247 (  pg_type              PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 28 0 0 0 0 0 t f f f 3   _null_ _null_ ));
 DESCR("");
 DATA(insert OID = 1249 (  pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ ));
 DESCR("");
index f170a4c..69cbc03 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.197 2008/07/14 00:51:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.198 2008/07/30 17:05:05 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -68,6 +68,16 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP
        char            typtype;
 
        /*
+        * typcategory and typispreferred help the parser distinguish preferred
+        * and non-preferred coercions.  The category can be any single ASCII
+        * character (but not \0).  The categories used for built-in types are
+        * identified by the TYPCATEGORY macros below.
+        */
+       char            typcategory;    /* arbitrary type classification */
+
+       bool            typispreferred; /* is type "preferred" within its category? */
+
+       /*
         * If typisdefined is false, the entry is only a placeholder (forward
         * reference).  We know the type name, but not yet anything else about it.
         */
@@ -75,7 +85,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP
 
        char            typdelim;               /* delimiter for arrays of this type */
 
-       Oid                     typrelid;               /* 0 if not a complex type */
+       Oid                     typrelid;               /* 0 if not a composite type */
 
        /*
         * If typelem is not 0 then it identifies another row in pg_type. The
@@ -213,33 +223,35 @@ typedef FormData_pg_type *Form_pg_type;
  *             compiler constants for pg_type
  * ----------------
  */
-#define Natts_pg_type                                  26
+#define Natts_pg_type                                  28
 #define Anum_pg_type_typname                   1
 #define Anum_pg_type_typnamespace              2
 #define Anum_pg_type_typowner                  3
 #define Anum_pg_type_typlen                            4
 #define Anum_pg_type_typbyval                  5
 #define Anum_pg_type_typtype                   6
-#define Anum_pg_type_typisdefined              7
-#define Anum_pg_type_typdelim                  8
-#define Anum_pg_type_typrelid                  9
-#define Anum_pg_type_typelem                   10
-#define Anum_pg_type_typarray                  11
-#define Anum_pg_type_typinput                  12
-#define Anum_pg_type_typoutput                 13
-#define Anum_pg_type_typreceive                        14
-#define Anum_pg_type_typsend                   15
-#define Anum_pg_type_typmodin                  16
-#define Anum_pg_type_typmodout                 17
-#define Anum_pg_type_typanalyze                        18
-#define Anum_pg_type_typalign                  19
-#define Anum_pg_type_typstorage                        20
-#define Anum_pg_type_typnotnull                        21
-#define Anum_pg_type_typbasetype               22
-#define Anum_pg_type_typtypmod                 23
-#define Anum_pg_type_typndims                  24
-#define Anum_pg_type_typdefaultbin             25
-#define Anum_pg_type_typdefault                        26
+#define Anum_pg_type_typcategory               7
+#define Anum_pg_type_typispreferred            8
+#define Anum_pg_type_typisdefined              9
+#define Anum_pg_type_typdelim                  10
+#define Anum_pg_type_typrelid                  11
+#define Anum_pg_type_typelem                   12
+#define Anum_pg_type_typarray                  13
+#define Anum_pg_type_typinput                  14
+#define Anum_pg_type_typoutput                 15
+#define Anum_pg_type_typreceive                        16
+#define Anum_pg_type_typsend                   17
+#define Anum_pg_type_typmodin                  18
+#define Anum_pg_type_typmodout                 19
+#define Anum_pg_type_typanalyze                        20
+#define Anum_pg_type_typalign                  21
+#define Anum_pg_type_typstorage                        22
+#define Anum_pg_type_typnotnull                        23
+#define Anum_pg_type_typbasetype               24
+#define Anum_pg_type_typtypmod                 25
+#define Anum_pg_type_typndims                  26
+#define Anum_pg_type_typdefaultbin             27
+#define Anum_pg_type_typdefault                        28
 
 
 /* ----------------
@@ -247,94 +259,97 @@ typedef FormData_pg_type *Form_pg_type;
  * ----------------
  */
 
-/* keep the following ordered by OID so that later changes can be made more easily */
-
-/* Make sure the typlen, typbyval, and typalign values here match the initial
-   values for attlen, attbyval, and attalign in both places in pg_attribute.h
-   for every instance.
-*/
+/*
+ * Keep the following ordered by OID so that later changes can be made more
+ * easily.
+ *
+ * For types used in the system catalogs, make sure the typlen, typbyval, and
+ * typalign values here match the initial values for attlen, attbyval, and
+ * attalign in both places in pg_attribute.h for every instance.  Also see
+ * TypInfo[] in bootstrap.c.
+ */
 
 /* OIDS 1 - 99 */
-DATA(insert OID = 16 ( bool       PGNSP PGUID  1 t b t \054 0   0 1000 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 16 ( bool       PGNSP PGUID  1 t b B t t \054 0       0 1000 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 _null_ _null_ ));
 DESCR("boolean, 'true'/'false'");
 #define BOOLOID                        16
 
-DATA(insert OID = 17 ( bytea      PGNSP PGUID -1 f b t \054 0  0 1001 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 17 ( bytea      PGNSP PGUID -1 f b U t t \054 0      0 1001 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 _null_ _null_ ));
 DESCR("variable-length string, binary values escaped");
 #define BYTEAOID               17
 
-DATA(insert OID = 18 ( char       PGNSP PGUID  1 t b t \054 0   0 1002 charin charout charrecv charsend - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 18 ( char       PGNSP PGUID  1 t b S f t \054 0       0 1002 charin charout charrecv charsend - - - c p f 0 -1 0 _null_ _null_ ));
 DESCR("single character");
 #define CHAROID                        18
 
-DATA(insert OID = 19 ( name       PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 19 ( name       PGNSP PGUID NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 _null_ _null_ ));
 DESCR("63-character type for storing system identifiers");
 #define NAMEOID                        19
 
-DATA(insert OID = 20 ( int8       PGNSP PGUID  8 FLOAT8PASSBYVAL b t \054 0     0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 20 ( int8       PGNSP PGUID  8 FLOAT8PASSBYVAL b N f t \054 0         0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("~18 digit integer, 8-byte storage");
 #define INT8OID                        20
 
-DATA(insert OID = 21 ( int2       PGNSP PGUID  2 t b t \054 0   0 1005 int2in int2out int2recv int2send - - - s p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 21 ( int2       PGNSP PGUID  2 t b N f t \054 0       0 1005 int2in int2out int2recv int2send - - - s p f 0 -1 0 _null_ _null_ ));
 DESCR("-32 thousand to 32 thousand, 2-byte storage");
 #define INT2OID                        21
 
-DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b t \054 0  21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b A t t \054 0      21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("array of int2, used in system tables");
 #define INT2VECTOROID  22
 
-DATA(insert OID = 23 ( int4       PGNSP PGUID  4 t b t \054 0   0 1007 int4in int4out int4recv int4send - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 23 ( int4       PGNSP PGUID  4 t b N f t \054 0       0 1007 int4in int4out int4recv int4send - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("-2 billion to 2 billion integer, 4-byte storage");
 #define INT4OID                        23
 
-DATA(insert OID = 24 ( regproc    PGNSP PGUID  4 t b t \054 0   0 1008 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 24 ( regproc    PGNSP PGUID  4 t b N f t \054 0       0 1008 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered procedure");
 #define REGPROCOID             24
 
-DATA(insert OID = 25 ( text       PGNSP PGUID -1 f b t \054 0  0 1009 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 25 ( text       PGNSP PGUID -1 f b S t t \054 0      0 1009 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
 DESCR("variable-length string, no limit specified");
 #define TEXTOID                        25
 
-DATA(insert OID = 26 ( oid                PGNSP PGUID  4 t b t \054 0   0 1028 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 26 ( oid                PGNSP PGUID  4 t b N t t \054 0       0 1028 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("object identifier(oid), maximum 4 billion");
 #define OIDOID                 26
 
-DATA(insert OID = 27 ( tid                PGNSP PGUID  6 f b t \054 0   0 1010 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 27 ( tid                PGNSP PGUID  6 f b U t t \054 0       0 1010 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 _null_ _null_ ));
 DESCR("(block, offset), physical location of tuple");
 #define TIDOID         27
 
-DATA(insert OID = 28 ( xid                PGNSP PGUID  4 t b t \054 0   0 1011 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 28 ( xid                PGNSP PGUID  4 t b U t t \054 0       0 1011 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("transaction id");
 #define XIDOID 28
 
-DATA(insert OID = 29 ( cid                PGNSP PGUID  4 t b t \054 0   0 1012 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 29 ( cid                PGNSP PGUID  4 t b U t t \054 0       0 1012 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("command identifier type, sequence in transaction id");
 #define CIDOID 29
 
-DATA(insert OID = 30 ( oidvector  PGNSP PGUID -1 f b t \054 0  26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 30 ( oidvector  PGNSP PGUID -1 f b A t t \054 0      26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("array of oids, used in system tables");
 #define OIDVECTOROID   30
 
 /* hand-built rowtype entries for bootstrapped catalogs: */
 
-DATA(insert OID = 71 ( pg_type                 PGNSP PGUID -1 f c t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 71 ( pg_type                 PGNSP PGUID -1 f c C t t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
 #define PG_TYPE_RELTYPE_OID 71
-DATA(insert OID = 75 ( pg_attribute    PGNSP PGUID -1 f c t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 75 ( pg_attribute    PGNSP PGUID -1 f c C t t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
 #define PG_ATTRIBUTE_RELTYPE_OID 75
-DATA(insert OID = 81 ( pg_proc                 PGNSP PGUID -1 f c t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 81 ( pg_proc                 PGNSP PGUID -1 f c C t t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
 #define PG_PROC_RELTYPE_OID 81
-DATA(insert OID = 83 ( pg_class                PGNSP PGUID -1 f c t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 83 ( pg_class                PGNSP PGUID -1 f c C t t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
 #define PG_CLASS_RELTYPE_OID 83
 
 /* OIDS 100 - 199 */
-DATA(insert OID = 142 ( xml               PGNSP PGUID -1 f b t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 142 ( xml               PGNSP PGUID -1 f b U t t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 _null_ _null_ ));
 DESCR("XML content");
 #define XMLOID 142
-DATA(insert OID = 143 ( _xml      PGNSP PGUID -1 f b t \054 0 142 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 143 ( _xml      PGNSP PGUID -1 f b A t t \054 0 142 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 200 - 299 */
 
-DATA(insert OID = 210 (  smgr     PGNSP PGUID 2 t b t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 210 (  smgr     PGNSP PGUID 2 t b U t t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
 DESCR("storage manager");
 
 /* OIDS 300 - 399 */
@@ -344,230 +359,230 @@ DESCR("storage manager");
 /* OIDS 500 - 599 */
 
 /* OIDS 600 - 699 */
-DATA(insert OID = 600 (  point    PGNSP PGUID 16 f b t \054 0 701 1017 point_in point_out point_recv point_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 600 (  point    PGNSP PGUID 16 f b G t t \054 0 701 1017 point_in point_out point_recv point_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric point '(x, y)'");
 #define POINTOID               600
-DATA(insert OID = 601 (  lseg     PGNSP PGUID 32 f b t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 601 (  lseg     PGNSP PGUID 32 f b G t t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric line segment '(pt1,pt2)'");
 #define LSEGOID                        601
-DATA(insert OID = 602 (  path     PGNSP PGUID -1 f b t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 602 (  path     PGNSP PGUID -1 f b G t t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f 0 -1 0 _null_ _null_ ));
 DESCR("geometric path '(pt1,...)'");
 #define PATHOID                        602
-DATA(insert OID = 603 (  box      PGNSP PGUID 32 f b t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 603 (  box      PGNSP PGUID 32 f b G t t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric box '(lower left,upper right)'");
 #define BOXOID                 603
-DATA(insert OID = 604 (  polygon   PGNSP PGUID -1 f b t \054 0  0 1027 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 604 (  polygon   PGNSP PGUID -1 f b G t t \054 0      0 1027 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 _null_ _null_ ));
 DESCR("geometric polygon '(pt1,...)'");
 #define POLYGONOID             604
 
-DATA(insert OID = 628 (  line     PGNSP PGUID 32 f b t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 628 (  line     PGNSP PGUID 32 f b G t t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric line (not implemented)'");
 #define LINEOID                        628
-DATA(insert OID = 629 (  _line    PGNSP PGUID  -1 f b t \054 0 628 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 629 (  _line    PGNSP PGUID  -1 f b A t t \054 0 628 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
 DESCR("");
 
 /* OIDS 700 - 799 */
 
-DATA(insert OID = 700 (  float4    PGNSP PGUID 4 FLOAT4PASSBYVAL b t \054 0     0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 700 (  float4    PGNSP PGUID 4 FLOAT4PASSBYVAL b N f t \054 0         0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("single-precision floating point number, 4-byte storage");
 #define FLOAT4OID 700
-DATA(insert OID = 701 (  float8    PGNSP PGUID 8 FLOAT8PASSBYVAL b t \054 0     0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 701 (  float8    PGNSP PGUID 8 FLOAT8PASSBYVAL b N t t \054 0         0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("double-precision floating point number, 8-byte storage");
 #define FLOAT8OID 701
-DATA(insert OID = 702 (  abstime   PGNSP PGUID 4 t b t \054 0   0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 702 (  abstime   PGNSP PGUID 4 t b D f t \054 0       0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("absolute, limited-range date and time (Unix system time)");
 #define ABSTIMEOID             702
-DATA(insert OID = 703 (  reltime   PGNSP PGUID 4 t b t \054 0   0 1024 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 703 (  reltime   PGNSP PGUID 4 t b T f t \054 0       0 1024 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("relative, limited-range time interval (Unix delta time)");
 #define RELTIMEOID             703
-DATA(insert OID = 704 (  tinterval PGNSP PGUID 12 f b t \054 0  0 1025 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 704 (  tinterval PGNSP PGUID 12 f b T f t \054 0      0 1025 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("(abstime,abstime), time interval");
 #define TINTERVALOID   704
-DATA(insert OID = 705 (  unknown   PGNSP PGUID -2 f b t \054 0  0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 705 (  unknown   PGNSP PGUID -2 f b X t t \054 0      0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 _null_ _null_ ));
 DESCR("");
 #define UNKNOWNOID             705
 
-DATA(insert OID = 718 (  circle    PGNSP PGUID 24 f b t \054 0 0 719 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 718 (  circle    PGNSP PGUID 24 f b G t t \054 0 0 719 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric circle '(center,radius)'");
 #define CIRCLEOID              718
-DATA(insert OID = 719 (  _circle   PGNSP PGUID -1 f b t \054 0  718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 790 (  money    PGNSP PGUID   8 FLOAT8PASSBYVAL b t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 719 (  _circle   PGNSP PGUID -1 f b A t t \054 0  718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 790 (  money    PGNSP PGUID   8 FLOAT8PASSBYVAL b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 _null_ _null_ ));
 DESCR("monetary amounts, $d,ddd.cc");
 #define CASHOID 790
-DATA(insert OID = 791 (  _money    PGNSP PGUID -1 f b t \054 0  790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 791 (  _money    PGNSP PGUID -1 f b A t t \054 0  790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 800 - 899 */
-DATA(insert OID = 829 ( macaddr    PGNSP PGUID 6 f b t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 829 ( macaddr    PGNSP PGUID 6 f b U t t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("XX:XX:XX:XX:XX:XX, MAC address");
 #define MACADDROID 829
-DATA(insert OID = 869 ( inet      PGNSP PGUID  -1 f b t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 869 ( inet      PGNSP PGUID  -1 f b I t t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 _null_ _null_ ));
 DESCR("IP address/netmask, host address, netmask optional");
 #define INETOID 869
-DATA(insert OID = 650 ( cidr      PGNSP PGUID  -1 f b t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 650 ( cidr      PGNSP PGUID  -1 f b I f t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 _null_ _null_ ));
 DESCR("network IP address/netmask, network address");
 #define CIDROID 650
 
 /* OIDS 900 - 999 */
 
 /* OIDS 1000 - 1099 */
-DATA(insert OID = 1000 (  _bool                 PGNSP PGUID -1 f b t \054 0    16 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1001 (  _bytea        PGNSP PGUID -1 f b t \054 0    17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1002 (  _char                 PGNSP PGUID -1 f b t \054 0    18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1003 (  _name                 PGNSP PGUID -1 f b t \054 0    19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1005 (  _int2                 PGNSP PGUID -1 f b t \054 0    21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1006 (  _int2vector PGNSP PGUID -1 f b t \054 0      22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1007 (  _int4                 PGNSP PGUID -1 f b t \054 0    23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1000 (  _bool                 PGNSP PGUID -1 f b A t t \054 0        16 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1001 (  _bytea        PGNSP PGUID -1 f b A t t \054 0        17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1002 (  _char                 PGNSP PGUID -1 f b A t t \054 0        18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1003 (  _name                 PGNSP PGUID -1 f b A t t \054 0        19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1005 (  _int2                 PGNSP PGUID -1 f b A t t \054 0        21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1006 (  _int2vector PGNSP PGUID -1 f b A t t \054 0  22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1007 (  _int4                 PGNSP PGUID -1 f b A t t \054 0        23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 #define INT4ARRAYOID           1007
-DATA(insert OID = 1008 (  _regproc      PGNSP PGUID -1 f b t \054 0    24 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1009 (  _text                 PGNSP PGUID -1 f b t \054 0    25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1028 (  _oid          PGNSP PGUID -1 f b t \054 0    26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1010 (  _tid          PGNSP PGUID -1 f b t \054 0    27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1011 (  _xid          PGNSP PGUID -1 f b t \054 0    28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1012 (  _cid          PGNSP PGUID -1 f b t \054 0    29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1013 (  _oidvector PGNSP PGUID -1 f b t \054 0       30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1014 (  _bpchar       PGNSP PGUID -1 f b t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1015 (  _varchar      PGNSP PGUID -1 f b t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1016 (  _int8                 PGNSP PGUID -1 f b t \054 0    20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1017 (  _point        PGNSP PGUID -1 f b t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1018 (  _lseg                 PGNSP PGUID -1 f b t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1019 (  _path                 PGNSP PGUID -1 f b t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1020 (  _box          PGNSP PGUID -1 f b t \073 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1021 (  _float4       PGNSP PGUID -1 f b t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1008 (  _regproc      PGNSP PGUID -1 f b A t t \054 0        24 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1009 (  _text                 PGNSP PGUID -1 f b A t t \054 0        25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1028 (  _oid          PGNSP PGUID -1 f b A t t \054 0        26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1010 (  _tid          PGNSP PGUID -1 f b A t t \054 0        27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1011 (  _xid          PGNSP PGUID -1 f b A t t \054 0        28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1012 (  _cid          PGNSP PGUID -1 f b A t t \054 0        29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1013 (  _oidvector PGNSP PGUID -1 f b A t t \054 0   30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1014 (  _bpchar       PGNSP PGUID -1 f b A t t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1015 (  _varchar      PGNSP PGUID -1 f b A t t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1016 (  _int8                 PGNSP PGUID -1 f b A t t \054 0        20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1017 (  _point        PGNSP PGUID -1 f b A t t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1018 (  _lseg                 PGNSP PGUID -1 f b A t t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1019 (  _path                 PGNSP PGUID -1 f b A t t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1020 (  _box          PGNSP PGUID -1 f b A t t \054 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1021 (  _float4       PGNSP PGUID -1 f b A t t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 #define FLOAT4ARRAYOID 1021
-DATA(insert OID = 1022 (  _float8       PGNSP PGUID -1 f b t \054 0 701 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1023 (  _abstime      PGNSP PGUID -1 f b t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1024 (  _reltime      PGNSP PGUID -1 f b t \054 0 703 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1025 (  _tinterval PGNSP PGUID -1 f b t \054 0 704 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1027 (  _polygon      PGNSP PGUID -1 f b t \054 0 604 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1033 (  aclitem       PGNSP PGUID 12 f b t \054 0 0 1034 aclitemin aclitemout - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1022 (  _float8       PGNSP PGUID -1 f b A t t \054 0 701 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1023 (  _abstime      PGNSP PGUID -1 f b A t t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1024 (  _reltime      PGNSP PGUID -1 f b A t t \054 0 703 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1025 (  _tinterval PGNSP PGUID -1 f b A t t \054 0 704 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1027 (  _polygon      PGNSP PGUID -1 f b A t t \054 0 604 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1033 (  aclitem       PGNSP PGUID 12 f b U t t \054 0 0 1034 aclitemin aclitemout - - - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("access control list");
 #define ACLITEMOID             1033
-DATA(insert OID = 1034 (  _aclitem      PGNSP PGUID -1 f b t \054 0 1033 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1040 (  _macaddr      PGNSP PGUID -1 f b t \054 0  829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1041 (  _inet                 PGNSP PGUID -1 f b t \054 0  869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 651  (  _cidr                 PGNSP PGUID -1 f b t \054 0  650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1263 (  _cstring      PGNSP PGUID -1 f b t \054 0 2275 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1034 (  _aclitem      PGNSP PGUID -1 f b A t t \054 0 1033 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1040 (  _macaddr      PGNSP PGUID -1 f b A t t \054 0  829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1041 (  _inet                 PGNSP PGUID -1 f b A t t \054 0  869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 651  (  _cidr                 PGNSP PGUID -1 f b A t t \054 0  650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1263 (  _cstring      PGNSP PGUID -1 f b A t t \054 0 2275 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 #define CSTRINGARRAYOID                1263
 
-DATA(insert OID = 1042 ( bpchar                 PGNSP PGUID -1 f b t \054 0    0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1042 ( bpchar                 PGNSP PGUID -1 f b S f t \054 0        0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
 DESCR("char(length), blank-padded string, fixed storage length");
 #define BPCHAROID              1042
-DATA(insert OID = 1043 ( varchar        PGNSP PGUID -1 f b t \054 0    0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1043 ( varchar        PGNSP PGUID -1 f b S f t \054 0        0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
 DESCR("varchar(length), non-blank-padded string, variable storage length");
 #define VARCHAROID             1043
 
-DATA(insert OID = 1082 ( date           PGNSP PGUID    4 t b t \054 0  0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1082 ( date           PGNSP PGUID    4 t b D f t \054 0      0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("ANSI SQL date");
 #define DATEOID                        1082
-DATA(insert OID = 1083 ( time           PGNSP PGUID    8 FLOAT8PASSBYVAL b t \054 0    0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1083 ( time           PGNSP PGUID    8 FLOAT8PASSBYVAL b D f t \054 0        0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMEOID                        1083
 
 /* OIDS 1100 - 1199 */
-DATA(insert OID = 1114 ( timestamp      PGNSP PGUID    8 FLOAT8PASSBYVAL b t \054 0    0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1114 ( timestamp      PGNSP PGUID    8 FLOAT8PASSBYVAL b D f t \054 0        0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("date and time");
 #define TIMESTAMPOID   1114
-DATA(insert OID = 1115 ( _timestamp  PGNSP PGUID       -1 f b t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1182 ( _date          PGNSP PGUID    -1 f b t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1183 ( _time          PGNSP PGUID    -1 f b t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1184 ( timestamptz PGNSP PGUID       8 FLOAT8PASSBYVAL b t \054 0    0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1115 ( _timestamp  PGNSP PGUID       -1 f b A t t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1182 ( _date          PGNSP PGUID    -1 f b A t t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1183 ( _time          PGNSP PGUID    -1 f b A t t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1184 ( timestamptz PGNSP PGUID       8 FLOAT8PASSBYVAL b D t t \054 0        0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("date and time with time zone");
 #define TIMESTAMPTZOID 1184
-DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0      1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1186 ( interval       PGNSP PGUID 16 f b t \054 0    0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b A t t \054 0  1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1186 ( interval       PGNSP PGUID 16 f b T t t \054 0        0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("@ <number> <units>, time interval");
 #define INTERVALOID            1186
-DATA(insert OID = 1187 ( _interval      PGNSP PGUID    -1 f b t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1187 ( _interval      PGNSP PGUID    -1 f b A t t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 1200 - 1299 */
-DATA(insert OID = 1231 (  _numeric      PGNSP PGUID -1 f b t \054 0    1700 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1266 ( timetz                 PGNSP PGUID 12 f b t \054 0    0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1231 (  _numeric      PGNSP PGUID -1 f b A t t \054 0        1700 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1266 ( timetz                 PGNSP PGUID 12 f b D f t \054 0        0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMETZOID              1266
-DATA(insert OID = 1270 ( _timetz        PGNSP PGUID -1 f b t \054 0    1266 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1270 ( _timetz        PGNSP PGUID -1 f b A t t \054 0        1266 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 1500 - 1599 */
-DATA(insert OID = 1560 ( bit            PGNSP PGUID -1 f b t \054 0    0 1561 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1560 ( bit            PGNSP PGUID -1 f b V f t \054 0        0 1561 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
 DESCR("fixed-length bit string");
 #define BITOID  1560
-DATA(insert OID = 1561 ( _bit           PGNSP PGUID -1 f b t \054 0    1560 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1562 ( varbit                 PGNSP PGUID -1 f b t \054 0    0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1561 ( _bit           PGNSP PGUID -1 f b A t t \054 0        1560 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1562 ( varbit                 PGNSP PGUID -1 f b V t t \054 0        0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
 DESCR("variable-length bit string");
 #define VARBITOID        1562
-DATA(insert OID = 1563 ( _varbit        PGNSP PGUID -1 f b t \054 0    1562 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1563 ( _varbit        PGNSP PGUID -1 f b A t t \054 0        1562 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 1600 - 1699 */
 
 /* OIDS 1700 - 1799 */
-DATA(insert OID = 1700 ( numeric          PGNSP PGUID -1 f b t \054 0  0 1231 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1700 ( numeric          PGNSP PGUID -1 f b N f t \054 0      0 1231 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 _null_ _null_ ));
 DESCR("numeric(precision, decimal), arbitrary precision number");
 #define NUMERICOID             1700
 
-DATA(insert OID = 1790 ( refcursor        PGNSP PGUID -1 f b t \054 0  0 2201 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1790 ( refcursor        PGNSP PGUID -1 f b U t t \054 0      0 2201 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
 DESCR("reference cursor (portal name)");
 #define REFCURSOROID   1790
 
 /* OIDS 2200 - 2299 */
-DATA(insert OID = 2201 ( _refcursor    PGNSP PGUID -1 f b t \054 0 1790 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2201 ( _refcursor    PGNSP PGUID -1 f b A t t \054 0 1790 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 
-DATA(insert OID = 2202 ( regprocedure  PGNSP PGUID     4 t b t \054 0   0 2207 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2202 ( regprocedure  PGNSP PGUID     4 t b N f t \054 0       0 2207 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered procedure (with args)");
 #define REGPROCEDUREOID 2202
 
-DATA(insert OID = 2203 ( regoper          PGNSP PGUID  4 t b t \054 0   0 2208 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2203 ( regoper          PGNSP PGUID  4 t b N f t \054 0       0 2208 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered operator");
 #define REGOPEROID             2203
 
-DATA(insert OID = 2204 ( regoperator   PGNSP PGUID     4 t b t \054 0   0 2209 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2204 ( regoperator   PGNSP PGUID     4 t b N f t \054 0       0 2209 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered operator (with args)");
 #define REGOPERATOROID 2204
 
-DATA(insert OID = 2205 ( regclass         PGNSP PGUID  4 t b t \054 0   0 2210 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2205 ( regclass         PGNSP PGUID  4 t b N f t \054 0       0 2210 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered class");
 #define REGCLASSOID            2205
 
-DATA(insert OID = 2206 ( regtype          PGNSP PGUID  4 t b t \054 0   0 2211 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2206 ( regtype          PGNSP PGUID  4 t b N f t \054 0       0 2211 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered type");
 #define REGTYPEOID             2206
 
-DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 2208 ( _regoper         PGNSP PGUID -1 f b t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 2209 ( _regoperator  PGNSP PGUID -1 f b t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 2210 ( _regclass        PGNSP PGUID -1 f b t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 2211 ( _regtype         PGNSP PGUID -1 f b t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b A t t \054 0 2202 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2208 ( _regoper         PGNSP PGUID -1 f b A t t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2209 ( _regoperator  PGNSP PGUID -1 f b A t t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2210 ( _regclass        PGNSP PGUID -1 f b A t t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2211 ( _regtype         PGNSP PGUID -1 f b A t t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 #define REGTYPEARRAYOID 2211
 
 /* uuid */
-DATA(insert OID = 2950 ( uuid                  PGNSP PGUID 16 f b t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2950 ( uuid                  PGNSP PGUID 16 f b U t t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 _null_ _null_ ));
 DESCR("UUID datatype");
-DATA(insert OID = 2951 ( _uuid                 PGNSP PGUID -1 f b t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2951 ( _uuid                 PGNSP PGUID -1 f b A t t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 
 /* text search */
-DATA(insert OID = 3614 ( tsvector              PGNSP PGUID -1 f b t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3614 ( tsvector              PGNSP PGUID -1 f b U t t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 _null_ _null_ ));
 DESCR("text representation for text search");
 #define TSVECTOROID            3614
-DATA(insert OID = 3642 ( gtsvector             PGNSP PGUID -1 f b t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3642 ( gtsvector             PGNSP PGUID -1 f b U t t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("GiST index internal text representation for text search");
 #define GTSVECTOROID   3642
-DATA(insert OID = 3615 ( tsquery               PGNSP PGUID -1 f b t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3615 ( tsquery               PGNSP PGUID -1 f b U t t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("query representation for text search");
 #define TSQUERYOID             3615
-DATA(insert OID = 3734 ( regconfig             PGNSP PGUID 4 t b t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3734 ( regconfig             PGNSP PGUID 4 t b N f t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered text search configuration");
 #define REGCONFIGOID   3734
-DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b N f t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered text search dictionary");
 #define REGDICTIONARYOID       3769
 
-DATA(insert OID = 3643 ( _tsvector             PGNSP PGUID -1 f b t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 3644 ( _gtsvector            PGNSP PGUID -1 f b t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 3645 ( _tsquery              PGNSP PGUID -1 f b t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 3735 ( _regconfig            PGNSP PGUID -1 f b t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3643 ( _tsvector             PGNSP PGUID -1 f b A t t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3644 ( _gtsvector            PGNSP PGUID -1 f b A t t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3645 ( _tsquery              PGNSP PGUID -1 f b A t t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3735 ( _regconfig            PGNSP PGUID -1 f b A t t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A t t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 
-DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b U t t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 _null_ _null_ ));
 DESCR("txid snapshot");
-DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A t t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
 
 /*
  * pseudo-types
@@ -582,29 +597,29 @@ DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b t \054 0 2970 0 array
  * but there is now support for it in records and arrays.  Perhaps we should
  * just treat it as a regular base type?
  */
-DATA(insert OID = 2249 ( record                        PGNSP PGUID -1 f p t \054 0 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2249 ( record                        PGNSP PGUID -1 f p P f t \054 0 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
 #define RECORDOID              2249
-DATA(insert OID = 2275 ( cstring               PGNSP PGUID -2 f p t \054 0 0 1263 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2275 ( cstring               PGNSP PGUID -2 f p P f t \054 0 0 1263 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 _null_ _null_ ));
 #define CSTRINGOID             2275
-DATA(insert OID = 2276 ( any                   PGNSP PGUID  4 t p t \054 0 0 0 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2276 ( any                   PGNSP PGUID  4 t p P f t \054 0 0 0 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define ANYOID                 2276
-DATA(insert OID = 2277 ( anyarray              PGNSP PGUID -1 f p t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2277 ( anyarray              PGNSP PGUID -1 f p P f t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 _null_ _null_ ));
 #define ANYARRAYOID            2277
-DATA(insert OID = 2278 ( void                  PGNSP PGUID  4 t p t \054 0 0 0 void_in void_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2278 ( void                  PGNSP PGUID  4 t p P f t \054 0 0 0 void_in void_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define VOIDOID                        2278
-DATA(insert OID = 2279 ( trigger               PGNSP PGUID  4 t p t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2279 ( trigger               PGNSP PGUID  4 t p P f t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define TRIGGEROID             2279
-DATA(insert OID = 2280 ( language_handler      PGNSP PGUID  4 t p t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2280 ( language_handler      PGNSP PGUID  4 t p P f t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define LANGUAGE_HANDLEROID            2280
-DATA(insert OID = 2281 ( internal              PGNSP PGUID  4 t p t \054 0 0 0 internal_in internal_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2281 ( internal              PGNSP PGUID  4 t p P f t \054 0 0 0 internal_in internal_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define INTERNALOID            2281
-DATA(insert OID = 2282 ( opaque                        PGNSP PGUID  4 t p t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2282 ( opaque                        PGNSP PGUID  4 t p P f t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define OPAQUEOID              2282
-DATA(insert OID = 2283 ( anyelement            PGNSP PGUID  4 t p t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2283 ( anyelement            PGNSP PGUID  4 t p P f t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define ANYELEMENTOID  2283
-DATA(insert OID = 2776 ( anynonarray   PGNSP PGUID  4 t p t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2776 ( anynonarray   PGNSP PGUID  4 t p P f t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define ANYNONARRAYOID 2776
-DATA(insert OID = 3500 ( anyenum               PGNSP PGUID  4 t p t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3500 ( anyenum               PGNSP PGUID  4 t p P f t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define ANYENUMOID             3500
 
 
@@ -617,6 +632,22 @@ DATA(insert OID = 3500 ( anyenum           PGNSP PGUID  4 t p t \054 0 0 0 anyenum_in any
 #define  TYPTYPE_ENUM          'e' /* enumerated type */
 #define  TYPTYPE_PSEUDO                'p' /* pseudo-type */
 
+#define  TYPCATEGORY_INVALID   '\0'    /* not an allowed category */
+#define  TYPCATEGORY_ARRAY             'A'
+#define  TYPCATEGORY_BOOLEAN   'B'
+#define  TYPCATEGORY_COMPOSITE 'C'
+#define  TYPCATEGORY_DATETIME  'D'
+#define  TYPCATEGORY_ENUM              'E'
+#define  TYPCATEGORY_GEOMETRIC 'G'
+#define  TYPCATEGORY_NETWORK   'I'             /* think INET */
+#define  TYPCATEGORY_NUMERIC   'N'
+#define  TYPCATEGORY_PSEUDOTYPE        'P'
+#define  TYPCATEGORY_STRING            'S'
+#define  TYPCATEGORY_TIMESPAN  'T'
+#define  TYPCATEGORY_USER              'U'
+#define  TYPCATEGORY_BITSTRING 'V'             /* er ... "varbit"? */
+#define  TYPCATEGORY_UNKNOWN   'X'
+
 /* Is a type OID a polymorphic pseudotype?     (Beware of multiple evaluation) */
 #define IsPolymorphicType(typid)  \
        ((typid) == ANYELEMENTOID || \
index 8c06ca9..f48eab2 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type_fn.h,v 1.1 2008/03/27 03:57:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type_fn.h,v 1.2 2008/07/30 17:05:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,6 +26,8 @@ extern Oid TypeCreate(Oid newTypeOid,
                   char relationKind,
                   int16 internalSize,
                   char typeType,
+                  char typeCategory,
+                  bool typePreferred,
                   char typDelim,
                   Oid inputProcedure,
                   Oid outputProcedure,
index ab36a0c..68d5173 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.75 2008/01/11 18:39:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.76 2008/07/30 17:05:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "parser/parse_node.h"
 
 
-/* Type categories (kluge ... ought to be extensible) */
-typedef enum CATEGORY
-{
-       INVALID_TYPE,
-       UNKNOWN_TYPE,
-       GENERIC_TYPE,
-       BOOLEAN_TYPE,
-       STRING_TYPE,
-       BITSTRING_TYPE,
-       NUMERIC_TYPE,
-       DATETIME_TYPE,
-       TIMESPAN_TYPE,
-       GEOMETRIC_TYPE,
-       NETWORK_TYPE,
-       USER_TYPE
-} CATEGORY;
+/* Type categories (see TYPCATEGORY_xxx symbols in catalog/pg_type.h) */
+typedef char TYPCATEGORY;
 
 /* Result codes for find_coercion_pathway */
 typedef enum CoercionPathType
@@ -46,8 +32,8 @@ typedef enum CoercionPathType
 
 
 extern bool IsBinaryCoercible(Oid srctype, Oid targettype);
-extern bool IsPreferredType(CATEGORY category, Oid type);
-extern CATEGORY TypeCategory(Oid type);
+extern bool IsPreferredType(TYPCATEGORY category, Oid type);
+extern TYPCATEGORY TypeCategory(Oid type);
 
 extern Node *coerce_to_target_type(ParseState *pstate,
                                          Node *expr, Oid exprtype,
index b1d5648..66e035c 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.123 2008/04/13 20:51:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.124 2008/07/30 17:05:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -106,6 +106,9 @@ extern Node *get_typdefault(Oid typid);
 extern char get_typtype(Oid typid);
 extern bool type_is_rowtype(Oid typid);
 extern bool type_is_enum(Oid typid);
+extern void get_type_category_preferred(Oid typid,
+                                                                               char *typcategory,
+                                                                               bool *typispreferred);
 extern Oid     get_typ_typrelid(Oid typid);
 extern Oid     get_element_type(Oid typid);
 extern Oid     get_array_type(Oid typid);
index 133ad85..6ea1ceb 100644 (file)
@@ -18,7 +18,9 @@ CREATE TYPE city_budget (
    internallength = 16, 
    input = int44in, 
    output = int44out, 
-   element = int4
+   element = int4,
+   category = 'x',   -- just to verify the system will take it
+   preferred = false -- ditto
 );
 -- Test creation and destruction of shell types
 CREATE TYPE shell;
index c6e391d..ec295e3 100644 (file)
@@ -20,7 +20,9 @@ CREATE TYPE city_budget (
    internallength = 16, 
    input = int44in, 
    output = int44out, 
-   element = int4
+   element = int4,
+   category = 'x',   -- just to verify the system will take it
+   preferred = false -- ditto
 );
 
 -- Test creation and destruction of shell types