Support arrays of composite types, including the rowtypes of regular tables
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 11 May 2007 17:57:14 +0000 (17:57 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 11 May 2007 17:57:14 +0000 (17:57 +0000)
and views (but not system catalogs, nor sequences or toast tables).  Get rid
of the hardwired convention that a type's array type is named exactly "_type",
instead using a new column pg_type.typarray to provide the linkage.  (It still
will be named "_type", though, except in odd corner cases such as
maximum-length type names.)

Along the way, make tracking of owner and schema dependencies for types more
uniform: a type directly created by the user has these dependencies, while a
table rowtype or auto-generated array type does not have them, but depends on
its parent object instead.

David Fetter, Andrew Dunstan, Tom Lane

25 files changed:
doc/src/sgml/array.sgml
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/create_type.sgml
doc/src/sgml/syntax.sgml
src/backend/catalog/README
src/backend/catalog/heap.c
src/backend/catalog/pg_shdepend.c
src/backend/catalog/pg_type.c
src/backend/commands/tablecmds.c
src/backend/commands/typecmds.c
src/backend/parser/parse_type.c
src/backend/utils/cache/lsyscache.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
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/commands/typecmds.h
src/test/regress/expected/alter_table.out
src/test/regress/expected/oidjoins.out
src/test/regress/expected/type_sanity.out
src/test/regress/sql/oidjoins.sql
src/test/regress/sql/type_sanity.sql
src/tools/findoidjoins/README

index ec59d8e6a884f794cca3ce450b6e4c00de8d80f6..9646e1ab00f352c1d004182bcfe42b6916d72b1b 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.60 2007/04/06 19:22:38 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.61 2007/05/11 17:57:11 tgl Exp $ -->
 
 <sect1 id="arrays">
  <title>Arrays</title>
@@ -10,8 +10,9 @@
  <para>
   <productname>PostgreSQL</productname> allows columns of a table to be
   defined as variable-length multidimensional arrays. Arrays of any
-  built-in or user-defined base type or enum type can be created.
-  (Arrays of composite types or domains are not yet supported, however.)
+  built-in or user-defined base type, enum type, or composite type
+  can be created.
+  Arrays of domains are not yet supported.
  </para>
 
  <sect2>
index 8243dd8d046781bc5ec93bb0e9f9ada53fdabfaf..2da4abc340755d02238d2e1e41b1c9e24c8b6bc0 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.150 2007/04/06 22:33:41 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.151 2007/05/11 17:57:11 tgl Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
       </entry>
      </row>
 
+     <row>
+      <entry><structfield>typarray</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
+      <entry>
+       If <structfield>typarray</structfield> is not 0 then it
+       identifies another row in <structname>pg_type</structname>, which
+       is the <quote>true</quote> array type having this type as element
+      </entry>
+     </row>
+
      <row>
       <entry><structfield>typinput</structfield></entry>
       <entry><type>regproc</type></entry>
       <entry></entry>
       <entry><para>
        <structfield>typndims</structfield> is the number of array dimensions
-       for a domain that is an array (that is, <structfield>typbasetype</> is an array type;
-       the domain's <structfield>typelem</> will match the base type's <structfield>typelem</structfield>).
-       Zero for types other than array domains
+       for a domain that is an array (that is, <structfield>typbasetype</> is
+       an array type; the domain's <structfield>typelem</> will match the base
+       type's <structfield>typelem</structfield>).
+       Zero for types other than domains over array types
        </para></entry>
      </row>
 
index 9be57d7fcdee11e8284b28ba9fc68ea31abe1f57..08f4c1464c703b61359f6e64032626c745b10132 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.69 2007/04/02 03:49:37 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.70 2007/05/11 17:57:11 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -312,15 +312,17 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
    <title>Array Types</title>
 
    <para>
-    Whenever a user-defined base or enum data type is created,
+    Whenever a user-defined type is created,
     <productname>PostgreSQL</productname> automatically creates an
     associated array type, whose name consists of the base type's
-    name prepended with an underscore.  The parser understands this
-    naming convention, and translates requests for columns of type
-    <literal>foo[]</> into requests for type <literal>_foo</>.
-    The implicitly-created array type is variable length and uses the
+    name prepended with an underscore, and truncated if necessary to keep
+    it less than <symbol>NAMEDATALEN</symbol> bytes long.  (If the name
+    so generated collides with an existing type name, the process is
+    repeated until a non-colliding name is found.)
+    This implicitly-created array type is variable length and uses the
     built-in input and output functions <literal>array_in</> and
-    <literal>array_out</>.
+    <literal>array_out</>.  The array type tracks any changes in its
+    element type's owner or schema, and is dropped if the element type is.
    </para>
 
    <para>
@@ -330,10 +332,9 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
     making a fixed-length type that happens to be internally an array of a number of
     identical things, and you want to allow these things to be accessed
     directly by subscripting, in addition to whatever operations you plan
-    to provide for the type as a whole.  For example, type <type>name</>
-    allows its constituent <type>char</> elements to be accessed this way.
-    A 2-D <type>point</> type could allow its two component numbers to be
-    accessed like <literal>point[0]</> and <literal>point[1]</>.
+    to provide for the type as a whole.  For example, type <type>point</>
+    is represented as just two floating-point numbers, which it allows to be
+    accessed as <literal>point[0]</> and <literal>point[1]</>.
     Note that
     this facility only works for fixed-length types whose internal form
     is exactly a sequence of identical fixed-length fields.  A subscriptable
@@ -529,12 +530,15 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
   <title>Notes</title>
 
   <para>
-   User-defined type names should not begin with the underscore character
-   (<literal>_</literal>) and should only be 62 characters
-   long (or in general <symbol>NAMEDATALEN</symbol> - 2, rather than
-   the <symbol>NAMEDATALEN</symbol> - 1 characters allowed for other
-   names).  Type names beginning with underscore are reserved for
-   internally-created array type names.
+   It is best to avoid using type names that begin with the underscore
+   character (<literal>_</literal>).  <productname>PostgreSQL</productname>
+   forms the name of an array type by prepending one or more underscores
+   to the element type's name, and these names may collide with user-defined
+   type names that begin with underscore.  While the system will modify
+   generated array type names to avoid collisions, this does not help if the
+   conflicting array type already exists when you try to create your type.
+   Also, various old client software may assume that names beginning with
+   underscores always represent arrays.
   </para>
 
   <para>
index 7bb9c669820303f5bdca93c7c54ccf54954d1edd..f1b5fe9411e90a6dcbec0106ccdbb9074c759030 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.117 2007/02/20 14:04:50 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.118 2007/05/11 17:57:11 tgl Exp $ -->
 
 <chapter id="sql-syntax">
  <title>SQL Syntax</title>
@@ -131,10 +131,10 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there');
    <para>
     <indexterm><primary>identifier</primary><secondary>length</secondary></indexterm>
     The system uses no more than <symbol>NAMEDATALEN</symbol>-1
-    characters of an identifier; longer names can be written in
+    bytes of an identifier; longer names can be written in
     commands, but they will be truncated.  By default,
     <symbol>NAMEDATALEN</symbol> is 64 so the maximum identifier
-    length is 63. If this limit is problematic, it can be raised by
+    length is 63 bytes. If this limit is problematic, it can be raised by
     changing the <symbol>NAMEDATALEN</symbol> constant in
     <filename>src/include/pg_config_manual.h</filename>.
    </para>
index 3cbcc3d45eef62b58ade01ea699f93a5f4a518b8..89c6e0305aeee282fcac23906cbe348c361f20b2 100644 (file)
@@ -1,4 +1,4 @@
-$PostgreSQL: pgsql/src/backend/catalog/README,v 1.10 2006/07/31 01:16:36 tgl Exp $
+$PostgreSQL: pgsql/src/backend/catalog/README,v 1.11 2007/05/11 17:57:11 tgl Exp $
 
 This directory contains .c files that manipulate the system catalogs;
 src/include/catalog contains the .h files that define the structure
@@ -86,9 +86,9 @@ general) assumes that the fixed-length portions of all system catalog
 tuples are in fact present, because it maps C struct declarations onto
 them.  Thus, the variable-length fields must all be at the end, and
 only the variable-length fields of a catalog tuple are permitted to be
-NULL.  For example, if you set pg_type.typdelim to be NULL, a
-piece of code will likely perform "typetup->typdelim" (or, worse,
-"typetyp->typelem", which follows typdelim).  This will result in
+NULL.  For example, if you set pg_type.typrelid to be NULL, a
+piece of code will likely perform "typetup->typrelid" (or, worse,
+"typetyp->typelem", which follows typrelid).  This will result in
 random errors or even segmentation violations.  Hence, do NOT insert
 catalog tuples that contain NULL attributes except in their
 variable-length portions!  (The bootstrapping code is fairly good about
index e6404ecd0b56b4fccecb57338f961d7bb9c81f12..8b34d685d8511522a1d607d70ab3ecd9aa6334ca 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.318 2007/04/02 03:49:37 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.319 2007/05/11 17:57:11 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -45,6 +45,7 @@
 #include "catalog/pg_statistic.h"
 #include "catalog/pg_type.h"
 #include "commands/tablecmds.h"
+#include "commands/typecmds.h"
 #include "miscadmin.h"
 #include "optimizer/clauses.h"
 #include "optimizer/var.h"
@@ -69,7 +70,8 @@ static void AddNewRelationTuple(Relation pg_class_desc,
 static Oid AddNewRelationType(const char *typeName,
                   Oid typeNamespace,
                   Oid new_rel_oid,
-                  char new_rel_kind);
+                  char new_rel_kind,
+                  Oid new_array_type);
 static void RelationRemoveInheritance(Oid relid);
 static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
 static void StoreConstraints(Relation rel, TupleDesc tupdesc);
@@ -401,26 +403,55 @@ CheckAttributeType(const char *attname, Oid atttypid)
 {
    char        att_typtype = get_typtype(atttypid);
 
-   /*
-    * Warn user, but don't fail, if column to be created has UNKNOWN type
-    * (usually as a result of a 'retrieve into' - jolly)
-    *
-    * Refuse any attempt to create a pseudo-type column.
-    */
    if (atttypid == UNKNOWNOID)
+   {
+       /*
+        * Warn user, but don't fail, if column to be created has UNKNOWN type
+        *    (usually as a result of a 'retrieve into' - jolly)
+        */
        ereport(WARNING,
                (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                 errmsg("column \"%s\" has type \"unknown\"", attname),
                 errdetail("Proceeding with relation creation anyway.")));
+   }
    else if (att_typtype == TYPTYPE_PSEUDO)
    {
-       /* Special hack for pg_statistic: allow ANYARRAY during initdb */
+       /*
+        * Refuse any attempt to create a pseudo-type column, except for 
+        * a special hack for pg_statistic: allow ANYARRAY during initdb
+        */
        if (atttypid != ANYARRAYOID || IsUnderPostmaster)
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                     errmsg("column \"%s\" has pseudo-type %s",
                            attname, format_type_be(atttypid))));
    }
+   else if (att_typtype == TYPTYPE_COMPOSITE)
+   {
+       /*
+        * For a composite type, recurse into its attributes.  You might
+        * think this isn't necessary, but since we allow system catalogs
+        * to break the rule, we have to guard against the case.
+        */
+       Relation relation;
+       TupleDesc tupdesc;
+       int i;
+
+       relation = relation_open(get_typ_typrelid(atttypid), AccessShareLock);
+
+       tupdesc = RelationGetDescr(relation);
+
+       for (i = 0; i < tupdesc->natts; i++)
+       {
+           Form_pg_attribute attr = tupdesc->attrs[i];
+
+           if (attr->attisdropped)
+               continue;
+           CheckAttributeType(NameStr(attr->attname), attr->atttypid);
+       }
+
+       relation_close(relation, AccessShareLock);
+   }
 }
 
 /* --------------------------------
@@ -710,16 +741,18 @@ static Oid
 AddNewRelationType(const char *typeName,
                   Oid typeNamespace,
                   Oid new_rel_oid,
-                  char new_rel_kind)
+                  char new_rel_kind,
+                  Oid new_array_type)
 {
    return
-       TypeCreate(typeName,    /* type name */
+       TypeCreate(InvalidOid,  /* no predetermined OID */
+                  typeName,    /* type name */
                   typeNamespace,       /* type namespace */
                   new_rel_oid, /* relation oid */
                   new_rel_kind,    /* relation kind */
                   -1,          /* internal size (varlena) */
                   TYPTYPE_COMPOSITE,   /* type-type (composite) */
-                  ',',         /* default array delimiter */
+                  DEFAULT_TYPDELIM,    /* default array delimiter */
                   F_RECORD_IN, /* input procedure */
                   F_RECORD_OUT,    /* output procedure */
                   F_RECORD_RECV,       /* receive procedure */
@@ -728,6 +761,8 @@ AddNewRelationType(const char *typeName,
                   InvalidOid,  /* typmodout procedure - none */
                   InvalidOid,  /* analyze procedure - default */
                   InvalidOid,  /* array element type - irrelevant */
+                  false,       /* this is not an array type */
+                  new_array_type,  /* array type if any */
                   InvalidOid,  /* domain base type - irrelevant */
                   NULL,        /* default value - none */
                   NULL,        /* default binary representation */
@@ -763,6 +798,7 @@ heap_create_with_catalog(const char *relname,
    Relation    pg_class_desc;
    Relation    new_rel_desc;
    Oid         new_type_oid;
+   Oid         new_array_oid = InvalidOid;
 
    pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
 
@@ -805,7 +841,24 @@ heap_create_with_catalog(const char *relname,
    Assert(relid == RelationGetRelid(new_rel_desc));
 
    /*
-    * since defining a relation also defines a complex type, we add a new
+    * Decide whether to create an array type over the relation's rowtype.
+    * We do not create any array types for system catalogs (ie, those made
+    * during initdb).  We create array types for regular relations, views,
+    * and composite types ... but not, eg, for toast tables or sequences.
+    */
+   if (IsUnderPostmaster && (relkind == RELKIND_RELATION ||
+                             relkind == RELKIND_VIEW ||
+                             relkind == RELKIND_COMPOSITE_TYPE))
+   {
+       /* OK, so pre-assign a type OID for the array type */
+       Relation pg_type = heap_open(TypeRelationId, AccessShareLock);  
+
+       new_array_oid = GetNewOid(pg_type);
+       heap_close(pg_type, AccessShareLock);
+   }
+
+   /*
+    * Since defining a relation also defines a complex type, we add a new
     * system type corresponding to the new relation.
     *
     * NOTE: we could get a unique-index failure here, in case the same name
@@ -814,7 +867,47 @@ heap_create_with_catalog(const char *relname,
    new_type_oid = AddNewRelationType(relname,
                                      relnamespace,
                                      relid,
-                                     relkind);
+                                     relkind,
+                                     new_array_oid);
+   /*
+    * Now make the array type if wanted.
+    */
+   if (OidIsValid(new_array_oid))
+   {
+       char       *relarrayname;
+
+       relarrayname = makeArrayTypeName(relname, relnamespace);
+
+       TypeCreate(new_array_oid,       /* force the type's OID to this */
+                  relarrayname,        /* Array type name */
+                  relnamespace,        /* Same namespace as parent */
+                  InvalidOid,          /* Not composite, no relationOid */
+                  0,                   /* relkind, also N/A here */
+                  -1,                  /* Internal size (varlena) */
+                  TYPTYPE_BASE,        /* Not composite - typelem is */
+                  DEFAULT_TYPDELIM,    /* default array delimiter */
+                  F_ARRAY_IN,          /* array input proc */
+                  F_ARRAY_OUT,         /* array output proc */
+                  F_ARRAY_RECV,        /* array recv (bin) proc */
+                  F_ARRAY_SEND,        /* array send (bin) proc */
+                  InvalidOid,          /* typmodin procedure - none */
+                  InvalidOid,          /* typmodout procedure - none */
+                  InvalidOid,          /* analyze procedure - default */
+                  new_type_oid,        /* array element type - the rowtype */
+                  true,                /* yes, this is an array type */
+                  InvalidOid,          /* this has no array type */
+                  InvalidOid,          /* domain base type - irrelevant */
+                  NULL,                /* default value - none */
+                  NULL,                /* default binary representation */
+                  false,               /* passed by reference */
+                  'd',                 /* alignment - must be the largest! */
+                  'x',                 /* fully TOASTable */
+                  -1,                  /* typmod */
+                  0,                   /* array dimensions for typBaseType */
+                  false);              /* Type NOT NULL */
+
+       pfree(relarrayname);
+   }
 
    /*
     * now create an entry in pg_class for the relation.
@@ -838,13 +931,15 @@ heap_create_with_catalog(const char *relname,
                          oidislocal, oidinhcount);
 
    /*
-    * make a dependency link to force the relation to be deleted if its
-    * namespace is.  Skip this in bootstrap mode, since we don't make
-    * dependencies while bootstrapping.
+    * Make a dependency link to force the relation to be deleted if its
+    * namespace is.  Also make a dependency link to its owner.
     *
-    * Also make a dependency link to its owner.
+    * For composite types, these dependencies are tracked for the pg_type
+    * entry, so we needn't record them here.  Also, skip this in bootstrap
+    * mode, since we don't make dependencies while bootstrapping.
     */
-   if (!IsBootstrapProcessingMode())
+   if (relkind != RELKIND_COMPOSITE_TYPE &&
+       !IsBootstrapProcessingMode())
    {
        ObjectAddress myself,
                    referenced;
@@ -857,13 +952,7 @@ heap_create_with_catalog(const char *relname,
        referenced.objectSubId = 0;
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
 
-       /*
-        * For composite types, the dependency on owner is tracked for the
-        * pg_type entry, so don't record it here.  All other relkinds need
-        * their ownership tracked.
-        */
-       if (relkind != RELKIND_COMPOSITE_TYPE)
-           recordDependencyOnOwner(RelationRelationId, relid, ownerid);
+       recordDependencyOnOwner(RelationRelationId, relid, ownerid);
    }
 
    /*
index 9ad012db49f9e1e554418450273e839a192371d9..e3de61344bb439d584483035f2037b8635b2e26f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.17 2007/03/03 19:32:54 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.18 2007/05/11 17:57:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1254,7 +1254,7 @@ shdepReassignOwned(List *roleids, Oid newrole)
                    break;
 
                case TypeRelationId:
-                   AlterTypeOwnerInternal(sdepForm->objid, newrole);
+                   AlterTypeOwnerInternal(sdepForm->objid, newrole, true);
                    break;
 
                case OperatorRelationId:
index efc3b8de0993659f90f0fb8ec7e9571989e90675..836014960437d2b54244cc33c48134048da678ef 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.111 2007/04/02 03:49:37 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.112 2007/05/11 17:57:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "catalog/pg_type.h"
 #include "commands/typecmds.h"
 #include "miscadmin.h"
+#include "parser/scansup.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -90,6 +91,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
    values[i++] = CharGetDatum(DEFAULT_TYPDELIM);       /* typdelim */
    values[i++] = ObjectIdGetDatum(InvalidOid); /* typrelid */
    values[i++] = ObjectIdGetDatum(InvalidOid); /* typelem */
+   values[i++] = ObjectIdGetDatum(InvalidOid); /* typarray */
    values[i++] = ObjectIdGetDatum(F_SHELL_IN); /* typinput */
    values[i++] = ObjectIdGetDatum(F_SHELL_OUT);        /* typoutput */
    values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */
@@ -135,6 +137,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
                                 InvalidOid,
                                 InvalidOid,
                                 InvalidOid,
+                                false,
                                 InvalidOid,
                                 NULL,
                                 false);
@@ -153,13 +156,16 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
  *
  *     This does all the necessary work needed to define a new type.
  *
- *     Returns the OID assigned to the new type.
+ *     Returns the OID assigned to the new type.  If newTypeOid is
+ *     zero (the normal case), a new OID is created; otherwise we
+ *     use exactly that OID.
  * ----------------------------------------------------------------
  */
 Oid
-TypeCreate(const char *typeName,
+TypeCreate(Oid newTypeOid,
+          const char *typeName,
           Oid typeNamespace,
-          Oid relationOid,     /* only for composite types */
+          Oid relationOid,     /* only for relation rowtypes */
           char relationKind,   /* ditto */
           int16 internalSize,
           char typeType,
@@ -172,6 +178,8 @@ TypeCreate(const char *typeName,
           Oid typmodoutProcedure,
           Oid analyzeProcedure,
           Oid elementType,
+          bool isImplicitArray,
+          Oid arrayType,
           Oid baseType,
           const char *defaultTypeValue,        /* human readable rep */
           char *defaultTypeBin,    /* cooked rep */
@@ -243,9 +251,9 @@ TypeCreate(const char *typeName,
    values[i++] = CharGetDatum(typeType);       /* typtype */
    values[i++] = BoolGetDatum(true);   /* typisdefined */
    values[i++] = CharGetDatum(typDelim);       /* typdelim */
-   values[i++] = ObjectIdGetDatum(typeType == TYPTYPE_COMPOSITE ?
-                                  relationOid : InvalidOid); /* typrelid */
+   values[i++] = ObjectIdGetDatum(relationOid);        /* typrelid */
    values[i++] = ObjectIdGetDatum(elementType);        /* typelem */
+   values[i++] = ObjectIdGetDatum(arrayType);          /* typarray */
    values[i++] = ObjectIdGetDatum(inputProcedure);     /* typinput */
    values[i++] = ObjectIdGetDatum(outputProcedure);    /* typoutput */
    values[i++] = ObjectIdGetDatum(receiveProcedure);   /* typreceive */
@@ -310,6 +318,10 @@ TypeCreate(const char *typeName,
        if (((Form_pg_type) GETSTRUCT(tup))->typowner != GetUserId())
            aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, typeName);
 
+       /* trouble if caller wanted to force the OID */
+       if (OidIsValid(newTypeOid))
+           elog(ERROR, "cannot assign new OID to existing shell type");
+
        /*
         * Okay to update existing shell type tuple
         */
@@ -331,6 +343,10 @@ TypeCreate(const char *typeName,
                             values,
                             nulls);
 
+       /* Force the OID if requested by caller, else heap_insert does it */
+       if (OidIsValid(newTypeOid))
+           HeapTupleSetOid(tup, newTypeOid);
+
        typeObjectId = simple_heap_insert(pg_type_desc, tup);
    }
 
@@ -354,6 +370,7 @@ TypeCreate(const char *typeName,
                                 typmodoutProcedure,
                                 analyzeProcedure,
                                 elementType,
+                                isImplicitArray,
                                 baseType,
                                 (defaultTypeBin ?
                                  stringToNode(defaultTypeBin) :
@@ -378,8 +395,8 @@ TypeCreate(const char *typeName,
 void
 GenerateTypeDependencies(Oid typeNamespace,
                         Oid typeObjectId,
-                        Oid relationOid,       /* only for composite types */
-                        char relationKind,     /* ditto */
+                        Oid relationOid,   /* only for relation rowtypes */
+                        char relationKind, /* ditto */
                         Oid owner,
                         Oid inputProcedure,
                         Oid outputProcedure,
@@ -389,6 +406,7 @@ GenerateTypeDependencies(Oid typeNamespace,
                         Oid typmodoutProcedure,
                         Oid analyzeProcedure,
                         Oid elementType,
+                        bool isImplicitArray,
                         Oid baseType,
                         Node *defaultExpr,
                         bool rebuild)
@@ -406,14 +424,23 @@ GenerateTypeDependencies(Oid typeNamespace,
    myself.objectId = typeObjectId;
    myself.objectSubId = 0;
 
-   /* dependency on namespace */
-   /* skip for relation rowtype, since we have indirect dependency */
-   if (!OidIsValid(relationOid))
+   /*
+    * Make dependency on namespace and shared dependency on owner.
+    *
+    * For a relation rowtype (that's not a composite type), we should skip
+    * these because we'll depend on them indirectly through the pg_class
+    * entry.  Likewise, skip for implicit arrays since we'll depend on them
+    * through the element type.
+    */
+   if ((!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE) &&
+       !isImplicitArray)
    {
        referenced.classId = NamespaceRelationId;
        referenced.objectId = typeNamespace;
        referenced.objectSubId = 0;
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+       recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
    }
 
    /* Normal dependencies on the I/O functions */
@@ -495,17 +522,17 @@ GenerateTypeDependencies(Oid typeNamespace,
    }
 
    /*
-    * If the type is an array type, mark it auto-dependent on the base type.
-    * (This is a compromise between the typical case where the array type is
-    * automatically generated and the case where it is manually created: we'd
-    * prefer INTERNAL for the former case and NORMAL for the latter.)
+    * If the type is an implicitly-created array type, mark it as internally
+    * dependent on the element type.  Otherwise, if it has an element type,
+    * the dependency is a normal one.
     */
    if (OidIsValid(elementType))
    {
        referenced.classId = TypeRelationId;
        referenced.objectId = elementType;
        referenced.objectSubId = 0;
-       recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
+       recordDependencyOn(&myself, &referenced,
+                   isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL);
    }
 
    /* Normal dependency from a domain to its base type. */
@@ -520,9 +547,6 @@ GenerateTypeDependencies(Oid typeNamespace,
    /* Normal dependency on the default expression. */
    if (defaultExpr)
        recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
-
-   /* Shared dependency on owner. */
-   recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
 }
 
 /*
@@ -570,21 +594,47 @@ TypeRename(const char *oldTypeName, Oid typeNamespace,
    heap_close(pg_type_desc, RowExclusiveLock);
 }
 
+
 /*
- * makeArrayTypeName(typeName);
- *   - given a base type name, make an array of type name out of it
+ * makeArrayTypeName(typeName)
+ *   - given a base type name, make an array type name for it
  *
  * the caller is responsible for pfreeing the result
  */
 char *
-makeArrayTypeName(const char *typeName)
+makeArrayTypeName(const char *typeName, Oid typeNamespace)
 {
    char       *arr;
+   int        i;
+   Relation    pg_type_desc;
 
-   if (!typeName)
-       return NULL;
+   /*
+    * The idea is to prepend underscores as needed until we make a name
+    * that doesn't collide with anything...
+    */
    arr = palloc(NAMEDATALEN);
-   snprintf(arr, NAMEDATALEN,
-            "_%.*s", NAMEDATALEN - 2, typeName);
+
+   pg_type_desc = heap_open(TypeRelationId, AccessShareLock);
+
+   for (i = 1; i < NAMEDATALEN - 1; i++)
+   {
+       arr[i - 1] = '_';
+       strlcpy(arr + i, typeName, NAMEDATALEN - i);
+       truncate_identifier(arr, strlen(arr), false);
+       if (!SearchSysCacheExists(TYPENAMENSP,
+                                 CStringGetDatum(arr),
+                                 ObjectIdGetDatum(typeNamespace),
+                                 0, 0))
+           break;
+   }
+
+   heap_close(pg_type_desc, AccessShareLock);
+
+   if (i >= NAMEDATALEN-1)
+       ereport(ERROR,
+               (errcode(ERRCODE_DUPLICATE_OBJECT),
+                errmsg("could not form array type name for type \"%s\"", 
+                       typeName)));
+
    return arr;
 }
index 8043799b88721ba937293991202f973cbf5abca0..a1bbf1778932b3c00f2671f6eea3dfdb4b4bbc21 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.219 2007/04/08 01:26:32 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.220 2007/05/11 17:57:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2827,6 +2827,7 @@ find_composite_type_dependencies(Oid typeOid, const char *origTblName)
    ScanKeyData key[2];
    SysScanDesc depScan;
    HeapTuple   depTup;
+   Oid         arrayOid;
 
    /*
     * We scan pg_depend to find those things that depend on the rowtype. (We
@@ -2886,6 +2887,14 @@ find_composite_type_dependencies(Oid typeOid, const char *origTblName)
    systable_endscan(depScan);
 
    relation_close(depRel, AccessShareLock);
+
+   /*
+    * If there's an array type for the rowtype, must check for uses of it,
+    * too.
+    */
+   arrayOid = get_array_type(typeOid);
+   if (OidIsValid(arrayOid))
+       find_composite_type_dependencies(arrayOid, origTblName);
 }
 
 
@@ -5299,6 +5308,9 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
  * be changed separately from the parent table.  Also, we can skip permission
  * checks (this is necessary not just an optimization, else we'd fail to
  * handle toast tables properly).
+ *
+ * recursing is also true if ALTER TYPE OWNER is calling us to fix up a
+ * free-standing composite type.
  */
 void
 ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
@@ -5370,6 +5382,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
            }
            break;
        case RELKIND_TOASTVALUE:
+       case RELKIND_COMPOSITE_TYPE:
            if (recursing)
                break;
            /* FALL THRU */
@@ -5448,14 +5461,22 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
 
        heap_freetuple(newtuple);
 
-       /* Update owner dependency reference */
-       changeDependencyOnOwner(RelationRelationId, relationOid, newOwnerId);
+       /*
+        * Update owner dependency reference, if any.  A composite type has
+        * none, because it's tracked for the pg_type entry instead of here;
+        * indexes don't have their own entries either.
+        */
+       if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE &&
+           tuple_class->relkind != RELKIND_INDEX)
+           changeDependencyOnOwner(RelationRelationId, relationOid,
+                                   newOwnerId);
 
        /*
         * Also change the ownership of the table's rowtype, if it has one
         */
        if (tuple_class->relkind != RELKIND_INDEX)
-           AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId);
+           AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId,
+                           tuple_class->relkind == RELKIND_COMPOSITE_TYPE);
 
        /*
         * If we are operating on a table, also change the ownership of any
@@ -6462,7 +6483,7 @@ AlterTableNamespace(RangeVar *relation, const char *newschema)
    AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true);
 
    /* Fix the table's rowtype too */
-   AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false);
+   AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false);
 
    /* Fix other dependent stuff */
    if (rel->rd_rel->relkind == RELKIND_RELATION)
@@ -6625,7 +6646,7 @@ AlterSeqNamespaces(Relation classRel, Relation rel,
         * them to the new namespace, too.
         */
        AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
-                                  newNspOid, false);
+                                  newNspOid, false, false);
 
        /* Now we can close it.  Keep the lock till end of transaction. */
        relation_close(seqRel, NoLock);
index 5c1b9f6f0e6868616a3e138de545d79af101eecb..7911f6df3a559b89b1b2da64232e2107388c7408 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.101 2007/04/02 03:49:38 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.102 2007/05/11 17:57:12 tgl Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
@@ -34,6 +34,7 @@
 #include "access/genam.h"
 #include "access/heapam.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/heap.h"
 #include "catalog/indexing.h"
@@ -118,10 +119,12 @@ DefineType(List *names, List *parameters)
    Oid         typmodinOid = InvalidOid;
    Oid         typmodoutOid = InvalidOid;
    Oid         analyzeOid = InvalidOid;
-   char       *shadow_type;
+   char       *array_type;
+   Oid         array_oid;
    ListCell   *pl;
    Oid         typoid;
    Oid         resulttype;
+   Relation    pg_type;
 
    /* Convert list of names to a name and namespace */
    typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName);
@@ -132,16 +135,6 @@ DefineType(List *names, List *parameters)
        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                       get_namespace_name(typeNamespace));
 
-   /*
-    * Type names must be one character shorter than other names, allowing
-    * room to create the corresponding array type name with prepended "_".
-    */
-   if (strlen(typeName) > (NAMEDATALEN - 2))
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_NAME),
-                errmsg("type names must be %d characters or less",
-                       NAMEDATALEN - 2)));
-
    /*
     * Look to see if type already exists (presumably as a shell; if not,
     * TypeCreate will complain).  If it doesn't, create it as a shell, so
@@ -396,11 +389,17 @@ DefineType(List *names, List *parameters)
        aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
                       NameListToString(analyzeName));
 
+   /* Preassign array type OID so we can insert it in pg_type.typarray */
+   pg_type = heap_open(TypeRelationId, AccessShareLock);   
+   array_oid = GetNewOid(pg_type);
+   heap_close(pg_type, AccessShareLock);
+
    /*
     * now have TypeCreate do all the real work.
     */
    typoid =
-       TypeCreate(typeName,    /* type name */
+       TypeCreate(InvalidOid,  /* no predetermined type OID */
+                  typeName,    /* type name */
                   typeNamespace,       /* namespace */
                   InvalidOid,  /* relation oid (n/a here) */
                   0,           /* relation kind (ditto) */
@@ -415,6 +414,8 @@ DefineType(List *names, List *parameters)
                   typmodoutOid,/* typmodout procedure */
                   analyzeOid,  /* analyze procedure */
                   elemType,    /* element type ID */
+                  false,       /* this is not an array type */
+                  array_oid,   /* array type we are about to create */
                   InvalidOid,  /* base type ID (only for domains) */
                   defaultValue,    /* default type value */
                   NULL,        /* no binary form available */
@@ -426,19 +427,19 @@ DefineType(List *names, List *parameters)
                   false);      /* Type NOT NULL */
 
    /*
-    * When we create a base type (as opposed to a complex type) we need to
-    * have an array entry for it in pg_type as well.
+    * Create the array type that goes with it.
     */
-   shadow_type = makeArrayTypeName(typeName);
+   array_type = makeArrayTypeName(typeName, typeNamespace);
 
    /* alignment must be 'i' or 'd' for arrays */
    alignment = (alignment == 'd') ? 'd' : 'i';
 
-   TypeCreate(shadow_type,     /* type name */
+   TypeCreate(array_oid,       /* force assignment of this type OID */
+              array_type,      /* type name */
               typeNamespace,   /* namespace */
               InvalidOid,      /* relation oid (n/a here) */
               0,               /* relation kind (ditto) */
-              -1,              /* internal size */
+              -1,              /* internal size (always varlena) */
               TYPTYPE_BASE,    /* type-type (base type) */
               DEFAULT_TYPDELIM,    /* array element delimiter */
               F_ARRAY_IN,      /* input procedure */
@@ -449,6 +450,8 @@ DefineType(List *names, List *parameters)
               typmodoutOid,    /* typmodout procedure */
               InvalidOid,      /* analyze procedure - default */
               typoid,          /* element type ID */
+              true,            /* yes this is an array type */
+              InvalidOid,      /* no further array type */
               InvalidOid,      /* base type ID */
               NULL,            /* never a default type value */
               NULL,            /* binary default isn't sent either */
@@ -459,7 +462,7 @@ DefineType(List *names, List *parameters)
               0,               /* Array dimensions of typbasetype */
               false);          /* Type NOT NULL */
 
-   pfree(shadow_type);
+   pfree(array_type);
 }
 
 
@@ -474,6 +477,7 @@ RemoveType(List *names, DropBehavior behavior, bool missing_ok)
    Oid         typeoid;
    HeapTuple   tup;
    ObjectAddress object;
+   Form_pg_type typ;
 
    /* Make a TypeName so we can use standard type lookup machinery */
    typename = makeTypeNameFromNameList(names);
@@ -504,14 +508,19 @@ RemoveType(List *names, DropBehavior behavior, bool missing_ok)
                         0, 0, 0);
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "cache lookup failed for type %u", typeoid);
+   typ = (Form_pg_type) GETSTRUCT(tup);
 
    /* Permission check: must own type or its namespace */
    if (!pg_type_ownercheck(typeoid, GetUserId()) &&
-     !pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace,
-                              GetUserId()))
+       !pg_namespace_ownercheck(typ->typnamespace, GetUserId()))
        aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
                       TypeNameToString(typename));
 
+   /*
+    * Note: we need no special check for array types here, as the normal
+    * treatment of internal dependencies handles it just fine
+    */
+
    ReleaseSysCache(tup);
 
    /*
@@ -607,19 +616,6 @@ DefineDomain(CreateDomainStmt *stmt)
        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                       get_namespace_name(domainNamespace));
 
-   /*
-    * Domainnames, unlike typenames don't need to account for the '_' prefix.
-    * So they can be one character longer.  (This test is presently useless
-    * since the parser will have truncated the name to fit.  But leave it
-    * here since we may someday support arrays of domains, in which case
-    * we'll be back to needing to enforce NAMEDATALEN-2.)
-    */
-   if (strlen(domainName) > (NAMEDATALEN - 1))
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_NAME),
-                errmsg("domain names must be %d characters or less",
-                       NAMEDATALEN - 1)));
-
    /*
     * Look up the base type.
     */
@@ -805,7 +801,8 @@ DefineDomain(CreateDomainStmt *stmt)
     * Have TypeCreate do all the real work.
     */
    domainoid =
-       TypeCreate(domainName,  /* type name */
+       TypeCreate(InvalidOid,  /* no predetermined type OID */
+                  domainName,  /* type name */
                   domainNamespace,     /* namespace */
                   InvalidOid,  /* relation oid (n/a here) */
                   0,           /* relation kind (ditto) */
@@ -820,6 +817,8 @@ DefineDomain(CreateDomainStmt *stmt)
                   InvalidOid,          /* typmodout procedure - none */
                   analyzeProcedure,    /* analyze procedure */
                   typelem,     /* element type ID */
+                  false,       /* this isn't an array */
+                  InvalidOid,  /* no arrays for domains (yet) */
                   basetypeoid, /* base type ID */
                   defaultValue,    /* default type value (text) */
                   defaultValueBin,     /* default type value (binary) */
@@ -949,6 +948,8 @@ DefineEnum(CreateEnumStmt *stmt)
    Oid     enumNamespace;
    Oid     enumTypeOid;
    AclResult   aclresult;
+   Oid     enumArrayOid;
+   Relation pg_type;
 
    /* Convert list of names to a name and namespace */
    enumNamespace = QualifiedNameGetCreationNamespace(stmt->typename,
@@ -960,19 +961,15 @@ DefineEnum(CreateEnumStmt *stmt)
        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                       get_namespace_name(enumNamespace));
 
-   /*
-    * Type names must be one character shorter than other names, allowing
-    * room to create the corresponding array type name with prepended "_".
-    */
-   if (strlen(enumName) > (NAMEDATALEN - 2))
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_NAME),
-                errmsg("type names must be %d characters or less",
-                       NAMEDATALEN - 2)));
+   /* Preassign array type OID so we can insert it in pg_type.typarray */
+   pg_type = heap_open(TypeRelationId, AccessShareLock);   
+   enumArrayOid = GetNewOid(pg_type);
+   heap_close(pg_type, AccessShareLock);
 
    /* Create the pg_type entry */
    enumTypeOid = 
-       TypeCreate(enumName,        /* type name */
+       TypeCreate(InvalidOid,      /* no predetermined type OID */
+                  enumName,        /* type name */
                   enumNamespace,   /* namespace */
                   InvalidOid,      /* relation oid (n/a here) */
                   0,               /* relation kind (ditto) */
@@ -987,6 +984,8 @@ DefineEnum(CreateEnumStmt *stmt)
                   InvalidOid,      /* typmodout procedure - none */
                   InvalidOid,      /* analyze procedure - default */
                   InvalidOid,      /* element type ID */
+                  false,           /* this is not an array type */
+                  enumArrayOid,    /* array type we are about to create */
                   InvalidOid,      /* base type ID (only for domains) */
                   NULL,            /* never a default type value */
                   NULL,            /* binary default isn't sent either */
@@ -1000,14 +999,17 @@ DefineEnum(CreateEnumStmt *stmt)
    /* Enter the enum's values into pg_enum */
    EnumValuesCreate(enumTypeOid, stmt->vals);
 
-   /* Create array type for enum */
-   enumArrayName = makeArrayTypeName(enumName);
+   /*
+    * Create the array type that goes with it.
+    */
+   enumArrayName = makeArrayTypeName(enumName, enumNamespace);
 
-   TypeCreate(enumArrayName,   /* type name */
+   TypeCreate(enumArrayOid,    /* force assignment of this type OID */
+              enumArrayName,   /* type name */
               enumNamespace,   /* namespace */
               InvalidOid,      /* relation oid (n/a here) */
               0,               /* relation kind (ditto) */
-              -1,              /* internal size */
+              -1,              /* internal size (always varlena) */
               TYPTYPE_BASE,    /* type-type (base type) */
               DEFAULT_TYPDELIM,    /* array element delimiter */
               F_ARRAY_IN,      /* input procedure */
@@ -1018,6 +1020,8 @@ DefineEnum(CreateEnumStmt *stmt)
               InvalidOid,      /* typmodout procedure - none */
               InvalidOid,      /* analyze procedure - default */
               enumTypeOid,     /* element type ID */
+              true,            /* yes this is an array type */
+              InvalidOid,      /* no further array type */
               InvalidOid,      /* base type ID */
               NULL,            /* never a default type value */
               NULL,            /* binary default isn't sent either */
@@ -1026,7 +1030,7 @@ DefineEnum(CreateEnumStmt *stmt)
               'x',             /* ARRAY is always toastable */
               -1,              /* typMod (Domains only) */
                0,               /* Array dimensions of typbasetype */
-              false);          /* Type NOT NULL */
+              false);          /* Type NOT NULL */
 
    pfree(enumArrayName);
 }
@@ -1435,7 +1439,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
    /* Rebuild dependencies */
    GenerateTypeDependencies(typTup->typnamespace,
                             domainoid,
-                            typTup->typrelid,
+                            InvalidOid, /* typrelid is n/a */
                             0, /* relation kind is n/a */
                             typTup->typowner,
                             typTup->typinput,
@@ -1446,6 +1450,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
                             typTup->typmodout,
                             typTup->typanalyze,
                             typTup->typelem,
+                            false,     /* a domain isn't an implicit array */
                             typTup->typbasetype,
                             defaultExpr,
                             true);     /* Rebuild is true */
@@ -2251,7 +2256,7 @@ AlterTypeOwner(List *names, Oid newOwnerId)
 
    /*
     * If it's a composite type, we need to check that it really is a
-    * free-standing composite type, and not a table's underlying type. We
+    * free-standing composite type, and not a table's rowtype. We
     * want people to use ALTER TABLE not ALTER TYPE for that case.
     */
    if (typTup->typtype == TYPTYPE_COMPOSITE &&
@@ -2261,6 +2266,16 @@ AlterTypeOwner(List *names, Oid newOwnerId)
                 errmsg("\"%s\" is a table's row type",
                        TypeNameToString(typename))));
 
+   /* don't allow direct alteration of array types, either */
+   if (OidIsValid(typTup->typelem) &&
+       get_array_type(typTup->typelem) == typeOid)
+       ereport(ERROR,
+               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                errmsg("cannot alter array type %s",
+                       format_type_be(typeOid)),
+                errhint("You can alter type %s, which will alter the array type as well.",
+                        format_type_be(typTup->typelem))));
+
    /*
     * If the new owner is the same as the existing owner, consider the
     * command to have succeeded.  This is for dump restoration purposes.
@@ -2288,16 +2303,32 @@ AlterTypeOwner(List *names, Oid newOwnerId)
        }
 
        /*
-        * Modify the owner --- okay to scribble on typTup because it's a copy
+        * If it's a composite type, invoke ATExecChangeOwner so that we
+        * fix up the pg_class entry properly.  That will call back to
+        * AlterTypeOwnerInternal to take care of the pg_type entry(s).
         */
-       typTup->typowner = newOwnerId;
+       if (typTup->typtype == TYPTYPE_COMPOSITE)
+           ATExecChangeOwner(typTup->typrelid, newOwnerId, true);
+       else
+       {
+           /*
+            * We can just apply the modification directly.
+            *
+            * okay to scribble on typTup because it's a copy
+            */
+           typTup->typowner = newOwnerId;
 
-       simple_heap_update(rel, &tup->t_self, tup);
+           simple_heap_update(rel, &tup->t_self, tup);
 
-       CatalogUpdateIndexes(rel, tup);
+           CatalogUpdateIndexes(rel, tup);
 
-       /* Update owner dependency reference */
-       changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
+           /* Update owner dependency reference */
+           changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
+
+           /* If it has an array type, update that too */
+           if (OidIsValid(typTup->typarray))
+               AlterTypeOwnerInternal(typTup->typarray, newOwnerId, false);
+       }
    }
 
    /* Clean up */
@@ -2307,12 +2338,17 @@ AlterTypeOwner(List *names, Oid newOwnerId)
 /*
  * AlterTypeOwnerInternal - change type owner unconditionally
  *
- * This is currently only used to propagate ALTER TABLE OWNER to the
- * table's rowtype, and to implement REASSIGN OWNED BY.  It assumes the
- * caller has done all needed checks.
+ * This is currently only used to propagate ALTER TABLE/TYPE OWNER to a 
+ * table's rowtype or an array type, and to implement REASSIGN OWNED BY.
+ * It assumes the caller has done all needed checks.  The function will
+ * automatically recurse to an array type if the type has one.
+ *
+ * hasDependEntry should be TRUE if type is expected to have a pg_shdepend
+ * entry (ie, it's not a table rowtype nor an array type).
  */
 void
-AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId)
+AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId,
+                      bool hasDependEntry)
 {
    Relation    rel;
    HeapTuple   tup;
@@ -2336,8 +2372,13 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId)
 
    CatalogUpdateIndexes(rel, tup);
 
-   /* Update owner dependency reference */
-   changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
+   /* Update owner dependency reference, if it has one */
+   if (hasDependEntry)
+       changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
+
+   /* If it has an array type, update that too */
+   if (OidIsValid(typTup->typarray))
+       AlterTypeOwnerInternal(typTup->typarray, newOwnerId, false);
 
    /* Clean up */
    heap_close(rel, RowExclusiveLock);
@@ -2352,6 +2393,7 @@ AlterTypeNamespace(List *names, const char *newschema)
    TypeName   *typename;
    Oid         typeOid;
    Oid         nspOid;
+   Oid         elemOid;
 
    /* Make a TypeName so we can use standard type lookup machinery */
    typename = makeTypeNameFromNameList(names);
@@ -2365,8 +2407,18 @@ AlterTypeNamespace(List *names, const char *newschema)
    /* get schema OID and check its permissions */
    nspOid = LookupCreationNamespace(newschema);
 
+   /* don't allow direct alteration of array types */
+   elemOid = get_element_type(typeOid);
+   if (OidIsValid(elemOid) && get_array_type(elemOid) == typeOid)
+       ereport(ERROR,
+               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                errmsg("cannot alter array type %s",
+                       format_type_be(typeOid)),
+                errhint("You can alter type %s, which will alter the array type as well.",
+                        format_type_be(elemOid))));
+
    /* and do the work */
-   AlterTypeNamespaceInternal(typeOid, nspOid, true);
+   AlterTypeNamespaceInternal(typeOid, nspOid, false, true);
 }
 
 /*
@@ -2374,18 +2426,24 @@ AlterTypeNamespace(List *names, const char *newschema)
  *
  * Caller must have already checked privileges.
  *
+ * The function automatically recurses to process the type's array type,
+ * if any.  isImplicitArray should be TRUE only when doing this internal
+ * recursion (outside callers must never try to move an array type directly).
+ *
  * If errorOnTableType is TRUE, the function errors out if the type is
  * a table type.  ALTER TABLE has to be used to move a table to a new
  * namespace.
  */
 void
 AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
+                          bool isImplicitArray,
                           bool errorOnTableType)
 {
    Relation    rel;
    HeapTuple   tup;
    Form_pg_type typform;
    Oid         oldNspOid;
+   Oid         arrayOid;
    bool        isCompositeType;
 
    rel = heap_open(TypeRelationId, RowExclusiveLock);
@@ -2398,6 +2456,7 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
    typform = (Form_pg_type) GETSTRUCT(tup);
 
    oldNspOid = typform->typnamespace;
+   arrayOid = typform->typarray;
 
    if (oldNspOid == nspOid)
        ereport(ERROR,
@@ -2463,13 +2522,9 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
 
        classRel = heap_open(RelationRelationId, RowExclusiveLock);
 
-       /*
-        * The dependency on the schema is listed under the pg_class entry, so
-        * tell AlterRelationNamespaceInternal to fix it.
-        */
        AlterRelationNamespaceInternal(classRel, typform->typrelid,
                                       oldNspOid, nspOid,
-                                      true);
+                                      false);
 
        heap_close(classRel, RowExclusiveLock);
 
@@ -2485,19 +2540,24 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
        /* If it's a domain, it might have constraints */
        if (typform->typtype == TYPTYPE_DOMAIN)
            AlterConstraintNamespaces(typeOid, oldNspOid, nspOid, true);
+   }
 
-       /*
-        * Update dependency on schema, if any --- a table rowtype has not got
-        * one.
-        */
-       if (typform->typtype != TYPTYPE_COMPOSITE)
-           if (changeDependencyFor(TypeRelationId, typeOid,
+   /*
+    * Update dependency on schema, if any --- a table rowtype has not got
+    * one, and neither does an implicit array.
+    */
+   if ((isCompositeType || typform->typtype != TYPTYPE_COMPOSITE) &&
+       !isImplicitArray)
+       if (changeDependencyFor(TypeRelationId, typeOid,
                                NamespaceRelationId, oldNspOid, nspOid) != 1)
-               elog(ERROR, "failed to change schema dependency for type %s",
-                    format_type_be(typeOid));
-   }
+           elog(ERROR, "failed to change schema dependency for type %s",
+                format_type_be(typeOid));
 
    heap_freetuple(tup);
 
    heap_close(rel, RowExclusiveLock);
+
+   /* Recursively alter the associated array type, if any */
+   if (OidIsValid(arrayOid))
+       AlterTypeNamespaceInternal(arrayOid, nspOid, true, true);
 }
index 0263386d2a23de957e60a32a1f26085a720c6389..d3198f0496a7226d4d96b672d6cce822c3eea1e6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.89 2007/04/27 22:05:48 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.90 2007/05/11 17:57:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -116,10 +116,6 @@ LookupTypeName(ParseState *pstate, const TypeName *typename)
        /* deconstruct the name list */
        DeconstructQualifiedName(typename->names, &schemaname, &typname);
 
-       /* If an array reference, look up the array type instead */
-       if (typename->arrayBounds != NIL)
-           typname = makeArrayTypeName(typname);
-
        if (schemaname)
        {
            /* Look in specific schema only */
@@ -136,6 +132,10 @@ LookupTypeName(ParseState *pstate, const TypeName *typename)
            /* Unqualified type name, so search the search path */
            restype = TypenameGetTypid(typname);
        }
+
+       /* If an array reference, return the array type instead */
+       if (typename->arrayBounds != NIL)
+           restype = get_array_type(restype);
    }
 
    return restype;
index 391870c3a6909f89ee79c9fad47e95a0afa3195a..d86a70521e3c2674b82c78b1fe0274805ba38581 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.151 2007/04/02 03:49:39 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.152 2007/05/11 17:57:12 tgl Exp $
  *
  * NOTES
  *   Eventually, the index information should go through here, too.
@@ -2203,50 +2203,24 @@ get_element_type(Oid typid)
 /*
  * get_array_type
  *
- *     Given the type OID, get the corresponding array type.
+ *     Given the type OID, get the corresponding "true" array type.
  *     Returns InvalidOid if no array type can be found.
- *
- * NB: this only considers varlena arrays to be true arrays.
  */
 Oid
 get_array_type(Oid typid)
 {
    HeapTuple   tp;
+   Oid result = InvalidOid;
 
    tp = SearchSysCache(TYPEOID,
                        ObjectIdGetDatum(typid),
                        0, 0, 0);
    if (HeapTupleIsValid(tp))
    {
-       Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
-       char       *array_typename;
-       Oid         namespaceId;
-
-       array_typename = makeArrayTypeName(NameStr(typtup->typname));
-       namespaceId = typtup->typnamespace;
+       result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
        ReleaseSysCache(tp);
-
-       tp = SearchSysCache(TYPENAMENSP,
-                           PointerGetDatum(array_typename),
-                           ObjectIdGetDatum(namespaceId),
-                           0, 0);
-
-       pfree(array_typename);
-
-       if (HeapTupleIsValid(tp))
-       {
-           Oid         result;
-
-           typtup = (Form_pg_type) GETSTRUCT(tp);
-           if (typtup->typlen == -1 && typtup->typelem == typid)
-               result = HeapTupleGetOid(tp);
-           else
-               result = InvalidOid;
-           ReleaseSysCache(tp);
-           return result;
-       }
    }
-   return InvalidOid;
+   return result;
 }
 
 /*
index 65595062634cab727cc07b6cb609bbf2d40e9037..64c26c16fbea927b35a4ae682c043880fee48575 100644 (file)
@@ -12,7 +12,7 @@
  * by PostgreSQL
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.467 2007/04/16 18:42:10 tgl Exp $
+ *   $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.468 2007/05/11 17:57:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -963,9 +963,8 @@ selectDumpableType(TypeInfo *tinfo)
    else if (!tinfo->isDefined)
        tinfo->dobj.dump = false;
 
-   /* skip all array types that start w/ underscore */
-   else if ((tinfo->dobj.name[0] == '_') &&
-            OidIsValid(tinfo->typelem))
+   /* skip auto-generated array types */
+   else if (tinfo->isArray)
        tinfo->dobj.dump = false;
 
    else
@@ -1963,6 +1962,7 @@ getTypes(int *numTypes)
    int         i_typrelkind;
    int         i_typtype;
    int         i_typisdefined;
+   int         i_isarray;
 
    /*
     * we include even the built-in types because those may be used as array
@@ -1970,13 +1970,20 @@ getTypes(int *numTypes)
     *
     * we filter out the built-in types when we dump out the types
     *
-    * same approach for undefined (shell) types
+    * same approach for undefined (shell) types and array types
+    *
+    * Note: as of 8.3 we can reliably detect whether a type is an
+    * auto-generated array type by checking the element type's typarray.
+    * (Before that the test is capable of generating false positives.)
+    * We still check for name beginning with '_', though, so as to avoid
+    * the cost of the subselect probe for all standard types.  This would
+    * have to be revisited if the backend ever allows renaming of array types.
     */
 
    /* Make sure we are in proper schema */
    selectSourceSchema("pg_catalog");
 
-   if (g_fout->remoteVersion >= 70300)
+   if (g_fout->remoteVersion >= 80300)
    {
        appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
                          "typnamespace, "
@@ -1985,7 +1992,23 @@ getTypes(int *numTypes)
                          "typoutput::oid as typoutput, typelem, typrelid, "
                          "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                          "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
-                         "typtype, typisdefined "
+                         "typtype, typisdefined, "
+                         "typname[0] = '_' AND typelem != 0 AND "
+                         "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
+                         "FROM pg_type",
+                         username_subquery);
+   }
+   else if (g_fout->remoteVersion >= 70300)
+   {
+       appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
+                         "typnamespace, "
+                         "(%s typowner) as rolname, "
+                         "typinput::oid as typinput, "
+                         "typoutput::oid as typoutput, typelem, typrelid, "
+                         "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
+                         "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
+                         "typtype, typisdefined, "
+                         "typname[0] = '_' AND typelem != 0 AS isarray "
                          "FROM pg_type",
                          username_subquery);
    }
@@ -1998,7 +2021,8 @@ getTypes(int *numTypes)
                          "typoutput::oid as typoutput, typelem, typrelid, "
                          "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                          "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
-                         "typtype, typisdefined "
+                         "typtype, typisdefined, "
+                         "typname[0] = '_' AND typelem != 0 AS isarray "
                          "FROM pg_type",
                          username_subquery);
    }
@@ -2013,7 +2037,8 @@ getTypes(int *numTypes)
                          "typoutput::oid as typoutput, typelem, typrelid, "
                          "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                          "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
-                         "typtype, typisdefined "
+                         "typtype, typisdefined, "
+                         "typname[0] = '_' AND typelem != 0 AS isarray "
                          "FROM pg_type",
                          username_subquery);
    }
@@ -2037,6 +2062,7 @@ getTypes(int *numTypes)
    i_typrelkind = PQfnumber(res, "typrelkind");
    i_typtype = PQfnumber(res, "typtype");
    i_typisdefined = PQfnumber(res, "typisdefined");
+   i_isarray = PQfnumber(res, "isarray");
 
    for (i = 0; i < ntups; i++)
    {
@@ -2064,20 +2090,16 @@ getTypes(int *numTypes)
            tinfo[i].typrelkind != RELKIND_COMPOSITE_TYPE)
            tinfo[i].dobj.objType = DO_TABLE_TYPE;
 
-       /*
-        * check for user-defined array types, omit system generated ones
-        */
-       if (OidIsValid(tinfo[i].typelem) &&
-           tinfo[i].dobj.name[0] != '_')
-           tinfo[i].isArray = true;
-       else
-           tinfo[i].isArray = false;
-
        if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
            tinfo[i].isDefined = true;
        else
            tinfo[i].isDefined = false;
 
+       if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
+           tinfo[i].isArray = true;
+       else
+           tinfo[i].isArray = false;
+
        /* Decide whether we want to dump it */
        selectDumpableType(&tinfo[i]);
 
@@ -3894,7 +3916,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
        else if (g_fout->remoteVersion >= 70100)
        {
            appendPQExpBuffer(query,
-                             "SELECT tgname, tgfoid::pg_catalog.regproc as tgfname, "
+                             "SELECT tgname, tgfoid::regproc as tgfname, "
                              "tgtype, tgnargs, tgargs, tgenabled, "
                              "tgisconstraint, tgconstrname, tgdeferrable, "
                              "tgconstrrelid, tginitdeferred, tableoid, oid, "
@@ -3907,7 +3929,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
        else
        {
            appendPQExpBuffer(query,
-                             "SELECT tgname, tgfoid::pg_catalog.regproc as tgfname, "
+                             "SELECT tgname, tgfoid::regproc as tgfname, "
                              "tgtype, tgnargs, tgargs, tgenabled, "
                              "tgisconstraint, tgconstrname, tgdeferrable, "
                              "tgconstrrelid, tginitdeferred, "
@@ -5473,7 +5495,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
            appendPQExpBufferStr(q, typdefault);
    }
 
-   if (tinfo->isArray)
+   if (OidIsValid(tinfo->typelem))
    {
        char       *elemType;
 
index 8694376b5299c42a29a5d04e3effb472fa2cffe5..9575cd5b19d1429789f0f0a7a3e8f37a59fc6363 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.134 2007/03/19 23:38:30 wieck Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.135 2007/05/11 17:57:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -164,7 +164,7 @@ typedef struct _typeInfo
    Oid         typrelid;
    char        typrelkind;     /* 'r', 'v', 'c', etc */
    char        typtype;        /* 'b', 'c', etc */
-   bool        isArray;        /* true if user-defined array type */
+   bool        isArray;        /* true if auto-generated array type */
    bool        isDefined;      /* true if typisdefined */
    /* If it's a dumpable base type, we create a "shell type" entry for it */
    struct _shellTypeInfo *shellType;   /* shell-type entry, or NULL */
index 69ef260ad3fdf975df9f8733c767c3548013db72..b0d562f842480b380eda92b005bef69105cf40ca 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.405 2007/05/08 18:56:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.406 2007/05/11 17:57:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200705081
+#define CATALOG_VERSION_NO 200705111
 
 #endif
index 5ca45adbade29a0268d88494570dfb04722abb26..8562d468d57a838d68f7907c62051d58981d461b 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.130 2007/01/22 01:35:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.131 2007/05/11 17:57:13 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -232,21 +232,22 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 { 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, {"typinput"},     24, -1,  4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typoutput"},    24, -1,  4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typreceive"},    24, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typsend"},      24, -1,  4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typmodin"},     24, -1,  4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typmodout"},    24, -1,  4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typanalyze"},    24, -1, 4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typalign"},     18, -1,  1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typstorage"},    18, -1, 1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typnotnull"},    16, -1, 1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1247, {"typbasetype"},   26, -1, 4, 21, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typtypmod"},    23, -1,  4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typndims"},     23, -1,  4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typdefaultbin"}, 25, -1, -1, 24, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
-{ 1247, {"typdefault"},    25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, 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 }
 
 DATA(insert ( 1247 typname         19 -1 NAMEDATALEN   1 0 -1 -1 f p i t f f t 0));
 DATA(insert ( 1247 typnamespace        26 -1 4   2 0 -1 -1 t p i t f f t 0));
@@ -258,21 +259,22 @@ 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 typinput            24 -1 4  11 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typoutput       24 -1 4  12 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typreceive      24 -1 4  13 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typsend         24 -1 4  14 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typmodin            24 -1 4  15 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typmodout       24 -1 4  16 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typanalyze      24 -1 4  17 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typalign            18 -1 1  18 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typstorage      18 -1 1  19 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typnotnull      16 -1 1  20 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1247 typbasetype     26 -1 4  21 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typtypmod       23 -1 4  22 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typndims            23 -1 4  23 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typdefaultbin   25 -1 -1 24 0 -1 -1 f x i f f f t 0));
-DATA(insert ( 1247 typdefault      25 -1 -1 25 0 -1 -1 f x i f 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 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 8ac0cb27936845a50d1a564779bf643b3dcf25b0..580588305bd178998d5dd5880a4642c518982971 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.100 2007/01/22 01:35:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.101 2007/05/11 17:57:13 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -132,7 +132,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 25 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 26 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 519be08afc3c8929b94268b7283dbd119781e26d..c663ff4ec7356de575ed3a26132524cd5f10bd99 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.182 2007/04/06 04:21:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.183 2007/05/11 17:57:13 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -97,6 +97,12 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP
     */
    Oid         typelem;
 
+   /*
+    * If there is a "true" array type having this type as element type,
+    * typarray links to it.  Zero if no associated "true" array type.
+    */
+   Oid         typarray;
+
    /*
     * I/O conversion procedures for the datatype.
     */
@@ -214,7 +220,7 @@ typedef FormData_pg_type *Form_pg_type;
  *     compiler constants for pg_type
  * ----------------
  */
-#define Natts_pg_type                  25
+#define Natts_pg_type                  26
 #define Anum_pg_type_typname           1
 #define Anum_pg_type_typnamespace      2
 #define Anum_pg_type_typowner          3
@@ -225,21 +231,22 @@ typedef FormData_pg_type *Form_pg_type;
 #define Anum_pg_type_typdelim          8
 #define Anum_pg_type_typrelid          9
 #define Anum_pg_type_typelem           10
-#define Anum_pg_type_typinput          11
-#define Anum_pg_type_typoutput         12
-#define Anum_pg_type_typreceive            13
-#define Anum_pg_type_typsend           14
-#define Anum_pg_type_typmodin          15
-#define Anum_pg_type_typmodout         16
-#define Anum_pg_type_typanalyze            17
-#define Anum_pg_type_typalign          18
-#define Anum_pg_type_typstorage            19
-#define Anum_pg_type_typnotnull            20
-#define Anum_pg_type_typbasetype       21
-#define Anum_pg_type_typtypmod         22
-#define Anum_pg_type_typndims          23
-#define Anum_pg_type_typdefaultbin     24
-#define Anum_pg_type_typdefault            25
+#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
 
 
 /* ----------------
@@ -255,86 +262,86 @@ typedef FormData_pg_type *Form_pg_type;
 */
 
 /* OIDS 1 - 99 */
-DATA(insert OID = 16 ( bool       PGNSP PGUID  1 t b t \054 0   0 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("boolean, 'true'/'false'");
 #define BOOLOID            16
 
-DATA(insert OID = 17 ( bytea      PGNSP PGUID -1 f b t \054 0  0 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("variable-length string, binary values escaped");
 #define BYTEAOID       17
 
-DATA(insert OID = 18 ( char       PGNSP PGUID  1 t b t \054 0   0 charin charout charrecv charsend - - - c p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("single character");
 #define CHAROID            18
 
-DATA(insert OID = 19 ( name       PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein nameout namerecv namesend - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 19 ( name       PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 namein nameout namerecv namesend - - - i 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 f b t \054 0   0 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 20 ( int8       PGNSP PGUID  8 f b 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 int2in int2out int2recv int2send - - - s p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 int4in int4out int4recv int4send - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("registered procedure");
 #define REGPROCOID     24
 
-DATA(insert OID = 25 ( text       PGNSP PGUID -1 f b t \054 0  0 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("variable-length string, no limit specified");
 #define TEXTOID            25
 
-DATA(insert OID = 26 ( oid        PGNSP PGUID  4 t b t \054 0   0 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("object identifier(oid), maximum 4 billion");
 #define OIDOID         26
 
-DATA(insert OID = 27 ( tid        PGNSP PGUID  6 f b t \054 0   0 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("(Block, offset), physical location of tuple");
 #define TIDOID     27
 
-DATA(insert OID = 28 ( xid        PGNSP PGUID  4 t b t \054 0   0 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("transaction id");
 #define XIDOID 28
 
-DATA(insert OID = 29 ( cid        PGNSP PGUID  4 t b t \054 0   0 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 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 t \054 1247 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 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 t \054 1249 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 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 t \054 1255 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 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 t \054 1259 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 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 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 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 t \054 0 142 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 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 210 (  smgr     PGNSP PGUID 2 t b t \054 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
 DESCR("storage manager");
 
 /* OIDS 300 - 399 */
@@ -344,200 +351,200 @@ DESCR("storage manager");
 /* OIDS 500 - 599 */
 
 /* OIDS 600 - 699 */
-DATA(insert OID = 600 (  point    PGNSP PGUID 16 f b t \054 0 701 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 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 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 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 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 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 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 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 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 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 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 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 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 t \054 0 628 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 f b t \054 0   0 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 700 (  float4    PGNSP PGUID 4 f b 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 f b t \054 0   0 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 701 (  float8    PGNSP PGUID 8 f b 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 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("(abstime,abstime), time interval");
 #define TINTERVALOID   704
-DATA(insert OID = 705 (  unknown   PGNSP PGUID -2 f b t \054 0  0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 705 (  unknown   PGNSP PGUID -2 f b t \054 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 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 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 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 790 (  money    PGNSP PGUID   8 f b t \054 0 0 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 t \054 0  718 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 790 (  money    PGNSP PGUID   8 f b 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 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 t \054 0  790 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 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 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 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 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 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 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 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 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 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 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 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 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 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 t \054 0    16 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 t \054 0    24 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 aclitemin aclitemout - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1022 (  _float8   PGNSP PGUID -1 f b t \054 0 701 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 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 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 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 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_ ));
 DESCR("access control list");
 #define ACLITEMOID     1033
-DATA(insert OID = 1034 (  _aclitem  PGNSP PGUID -1 f b t \054 0 1033 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 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 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 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 1042 ( bpchar         PGNSP PGUID -1 f b t \054 0    0 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1034 (  _aclitem  PGNSP PGUID -1 f b t \054 0 1033 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 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 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 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 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 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 f b t \054 0  0 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 f b 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 f b t \054 0  0 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 f b 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 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 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 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 f b t \054 0  0 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 t \054 0 1114 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 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 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 f b 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 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 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 t \054 0  1184 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_ ));
 DESCR("@ <number> <units>, time interval");
 #define INTERVALOID        1186
-DATA(insert OID = 1187 ( _interval  PGNSP PGUID    -1 f b t \054 0 1186 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 t \054 0 1186 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 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 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 t \054 0    1700 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_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMETZOID      1266
-DATA(insert OID = 1270 ( _timetz    PGNSP PGUID -1 f b t \054 0    1266 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 t \054 0    1266 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 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 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 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 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 t \054 0    1560 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_ ));
 DESCR("variable-length bit string");
 #define VARBITOID    1562
-DATA(insert OID = 1563 ( _varbit    PGNSP PGUID -1 f b t \054 0    1562 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 t \054 0    1562 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 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 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 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
+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_ ));
 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 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 t \054 0 1790 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 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p 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_ ));
 DESCR("registered procedure (with args)");
 #define REGPROCEDUREOID 2202
 
-DATA(insert OID = 2203 ( regoper      PGNSP PGUID  4 t b t \054 0   0 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("registered operator");
 #define REGOPEROID     2203
 
-DATA(insert OID = 2204 ( regoperator   PGNSP PGUID 4 t b t \054 0   0 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("registered operator (with args)");
 #define REGOPERATOROID 2204
 
-DATA(insert OID = 2205 ( regclass     PGNSP PGUID  4 t b t \054 0   0 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("registered class");
 #define REGCLASSOID        2205
 
-DATA(insert OID = 2206 ( regtype      PGNSP PGUID  4 t b t \054 0   0 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 _null_ _null_ ));
+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_ ));
 DESCR("registered type");
 #define REGTYPEOID     2206
 
-DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 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 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 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 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 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 t \054 0 2202 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 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 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 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 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 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 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 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 t \054 0 2950 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 
 /*
  * pseudo-types
@@ -548,27 +555,27 @@ DATA(insert OID = 2951 ( _uuid            PGNSP PGUID -1 f b t \054 0 2950 array_in array
  * argument and result types (if supported by the function's implementation
  * language).
  */
-DATA(insert OID = 2249 ( record            PGNSP PGUID -1 f p t \054 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 t \054 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 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 t \054 0 0 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 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2276 ( any           PGNSP PGUID  4 t p t \054 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 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 t \054 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 void_in void_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2278 ( void          PGNSP PGUID  4 t p t \054 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 trigger_in trigger_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2279 ( trigger       PGNSP PGUID  4 t p t \054 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 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 t \054 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 internal_in internal_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2281 ( internal      PGNSP PGUID  4 t p t \054 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 opaque_in opaque_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2282 ( opaque            PGNSP PGUID  4 t p t \054 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 anyelement_in anyelement_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2283 ( anyelement        PGNSP PGUID  4 t p t \054 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define ANYELEMENTOID  2283
-DATA(insert OID = 3500 ( anyenum       PGNSP PGUID  4 t p t \054 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3500 ( anyenum       PGNSP PGUID  4 t p t \054 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 _null_ _null_ ));
 #define ANYENUMOID     3500
 
 
@@ -592,7 +599,8 @@ DATA(insert OID = 3500 ( anyenum        PGNSP PGUID  4 t p t \054 0 0 anyenum_in anyen
  */
 extern Oid TypeShellMake(const char *typeName, Oid typeNamespace);
 
-extern Oid TypeCreate(const char *typeName,
+extern Oid TypeCreate(Oid newTypeOid,
+          const char *typeName,
           Oid typeNamespace,
           Oid relationOid,
           char relationKind,
@@ -607,6 +615,8 @@ extern Oid TypeCreate(const char *typeName,
           Oid typmodoutProcedure,
           Oid analyzeProcedure,
           Oid elementType,
+          bool isImplicitArray,
+          Oid arrayType,
           Oid baseType,
           const char *defaultTypeValue,
           char *defaultTypeBin,
@@ -630,6 +640,7 @@ extern void GenerateTypeDependencies(Oid typeNamespace,
                         Oid typmodoutProcedure,
                         Oid analyzeProcedure,
                         Oid elementType,
+                        bool isImplicitArray,
                         Oid baseType,
                         Node *defaultExpr,
                         bool rebuild);
@@ -637,6 +648,6 @@ extern void GenerateTypeDependencies(Oid typeNamespace,
 extern void TypeRename(const char *oldTypeName, Oid typeNamespace,
           const char *newTypeName);
 
-extern char *makeArrayTypeName(const char *typeName);
+extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace);
 
 #endif   /* PG_TYPE_H */
index 91e56e12cb0cf0e0eb68a61cb1577b64f998b384..de0c6aea9373672ee19fe0ac27b426ed051144b6 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.18 2007/04/02 03:49:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.19 2007/05/11 17:57:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,9 +36,11 @@ extern void AlterDomainDropConstraint(List *names, const char *constrName,
 extern List *GetDomainConstraints(Oid typeOid);
 
 extern void AlterTypeOwner(List *names, Oid newOwnerId);
-extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId);
+extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId,
+                                  bool hasDependEntry);
 extern void AlterTypeNamespace(List *names, const char *newschema);
 extern void AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
-                          bool errorOnTableType);
+                                      bool isImplicitArray,
+                                      bool errorOnTableType);
 
 #endif   /* TYPECMDS_H */
index 11b8c24c3d60b9e401c1f335e11af5549e4174be..99f0c0b04980a5898e274fde5c6178628cb8c858 100644 (file)
@@ -1456,7 +1456,6 @@ select alter2.plus1(41);
 
 -- clean up
 drop schema alter2 cascade;
-NOTICE:  drop cascades to composite type alter2.ctype
 NOTICE:  drop cascades to type alter2.ctype
 NOTICE:  drop cascades to type alter2.posint
 NOTICE:  drop cascades to function alter2.plus1(integer)
index 5945753a1b3f530cfc9fb6a09d195db461838980..b7ad2b813c1a0d4823140fad65d52da3756478a6 100644 (file)
@@ -409,6 +409,14 @@ WHERE  indrelid != 0 AND
 ------+----------
 (0 rows)
 
+SELECT ctid, lanowner 
+FROM   pg_catalog.pg_language fk 
+WHERE  lanowner != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.lanowner);
+ ctid | lanowner 
+------+----------
+(0 rows)
+
 SELECT ctid, lanvalidator 
 FROM   pg_catalog.pg_language fk 
 WHERE  lanvalidator != 0 AND 
@@ -721,6 +729,14 @@ WHERE  typelem != 0 AND
 ------+---------
 (0 rows)
 
+SELECT ctid, typarray 
+FROM   pg_catalog.pg_type fk 
+WHERE  typarray != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typarray);
+ ctid | typarray 
+------+----------
+(0 rows)
+
 SELECT ctid, typinput 
 FROM   pg_catalog.pg_type fk 
 WHERE  typinput != 0 AND 
index b2db870da4f1fb2108777a9b6f2267e5e9017a48..702cf7eecf1003a9b73c049196ccf963a675f4c0 100644 (file)
@@ -69,6 +69,16 @@ WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
  705 | unknown
 (2 rows)
 
+-- Make sure typarray points to a varlena array type of our own base
+SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, 
+       p2.typelem, p2.typlen
+FROM   pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid)
+WHERE  p1.typarray <> 0 AND
+       (p2.oid IS NULL OR p2.typelem <> p1.oid OR p2.typlen <> -1);
+ oid | basetype | arraytype | typelem | typlen 
+-----+----------+-----------+---------+--------
+(0 rows)
+
 -- Text conversion routines must be provided.
 SELECT p1.oid, p1.typname
 FROM pg_type as p1
index 5eb440f0f541bab854295d7524fc93bb1c25281f..7d2dd3dd1fc43a275183b011f2625a44eb9ed93f 100644 (file)
@@ -205,6 +205,10 @@ SELECT ctid, indrelid
 FROM   pg_catalog.pg_index fk 
 WHERE  indrelid != 0 AND 
    NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.indrelid);
+SELECT ctid, lanowner 
+FROM   pg_catalog.pg_language fk 
+WHERE  lanowner != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.lanowner);
 SELECT ctid, lanvalidator 
 FROM   pg_catalog.pg_language fk 
 WHERE  lanvalidator != 0 AND 
@@ -361,6 +365,10 @@ SELECT ctid, typelem
 FROM   pg_catalog.pg_type fk 
 WHERE  typelem != 0 AND 
    NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typelem);
+SELECT ctid, typarray 
+FROM   pg_catalog.pg_type fk 
+WHERE  typarray != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.typarray);
 SELECT ctid, typinput 
 FROM   pg_catalog.pg_type fk 
 WHERE  typinput != 0 AND 
index b1caa33efbda6d32d56ecc7d396f08a5abae551e..e549fd74892b7ddd9d4868cb5d61dc33fae1af3d 100644 (file)
@@ -59,6 +59,13 @@ WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
      WHERE p2.typname = ('_' || p1.typname)::name AND
            p2.typelem = p1.oid);
 
+-- Make sure typarray points to a varlena array type of our own base
+SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, 
+       p2.typelem, p2.typlen
+FROM   pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid)
+WHERE  p1.typarray <> 0 AND
+       (p2.oid IS NULL OR p2.typelem <> p1.oid OR p2.typlen <> -1);
+
 -- Text conversion routines must be provided.
 
 SELECT p1.oid, p1.typname
index 598aab2bbd1e83f93fd0ffbf9c43d87108696342..be4613eaf38ea4bc0446f371e1f9f0e13e13f1a9 100644 (file)
@@ -1,3 +1,4 @@
+$PostgreSQL: pgsql/src/tools/findoidjoins/README,v 1.4 2007/05/11 17:57:14 tgl Exp $
 
                      findoidjoins
 
@@ -87,6 +88,7 @@ Join pg_catalog.pg_depend.refclassid => pg_catalog.pg_class.oid
 Join pg_catalog.pg_description.classoid => pg_catalog.pg_class.oid
 Join pg_catalog.pg_index.indexrelid => pg_catalog.pg_class.oid
 Join pg_catalog.pg_index.indrelid => pg_catalog.pg_class.oid
+Join pg_catalog.pg_language.lanowner => pg_catalog.pg_authid.oid
 Join pg_catalog.pg_language.lanvalidator => pg_catalog.pg_proc.oid
 Join pg_catalog.pg_namespace.nspowner => pg_catalog.pg_authid.oid
 Join pg_catalog.pg_opclass.opcmethod => pg_catalog.pg_am.oid
@@ -126,6 +128,7 @@ Join pg_catalog.pg_type.typnamespace => pg_catalog.pg_namespace.oid
 Join pg_catalog.pg_type.typowner => pg_catalog.pg_authid.oid
 Join pg_catalog.pg_type.typrelid => pg_catalog.pg_class.oid
 Join pg_catalog.pg_type.typelem => pg_catalog.pg_type.oid
+Join pg_catalog.pg_type.typarray => pg_catalog.pg_type.oid
 Join pg_catalog.pg_type.typinput => pg_catalog.pg_proc.oid
 Join pg_catalog.pg_type.typoutput => pg_catalog.pg_proc.oid
 Join pg_catalog.pg_type.typreceive => pg_catalog.pg_proc.oid