summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2007-05-11 17:57:14 +0000
committerTom Lane2007-05-11 17:57:14 +0000
commite60a0aa4e5d43344897304a4dc47c245fd4d75e5 (patch)
tree67755624c9ffaa80478b6ffcceb190a9be981508
parent4e2fbf4a19f4eb4522fdb041d7e393f5c07b3ecc (diff)
Support arrays of composite types, including the rowtypes of regular tables
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
-rw-r--r--doc/src/sgml/array.sgml5
-rw-r--r--doc/src/sgml/catalogs.sgml18
-rw-r--r--doc/src/sgml/ref/create_type.sgml36
-rw-r--r--doc/src/sgml/syntax.sgml4
-rw-r--r--src/backend/catalog/README6
-rw-r--r--src/backend/catalog/heap.c139
-rw-r--r--src/backend/catalog/pg_shdepend.c2
-rw-r--r--src/backend/catalog/pg_type.c100
-rw-r--r--src/backend/commands/tablecmds.c31
-rw-r--r--src/backend/commands/typecmds.c216
-rw-r--r--src/backend/parser/parse_type.c8
-rw-r--r--src/backend/utils/cache/lsyscache.c34
-rw-r--r--src/bin/pg_dump/pg_dump.c62
-rw-r--r--src/bin/pg_dump/pg_dump.h2
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_attribute.h62
-rw-r--r--src/include/catalog/pg_class.h2
-rw-r--r--src/include/catalog/pg_type.h285
-rw-r--r--src/include/commands/typecmds.h6
-rw-r--r--src/test/regress/expected/alter_table.out1
-rw-r--r--src/test/regress/expected/oidjoins.out16
-rw-r--r--src/test/regress/expected/type_sanity.out10
-rw-r--r--src/test/regress/sql/oidjoins.sql8
-rw-r--r--src/test/regress/sql/type_sanity.sql7
-rw-r--r--src/tools/findoidjoins/README3
25 files changed, 678 insertions, 387 deletions
diff --git a/doc/src/sgml/array.sgml b/doc/src/sgml/array.sgml
index 22266e0610..80b4a41412 100644
--- a/doc/src/sgml/array.sgml
+++ b/doc/src/sgml/array.sgml
@@ -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>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 32889a467d..51bc966f10 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -4525,6 +4525,17 @@
</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><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
@@ -4686,9 +4697,10 @@
<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>
diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
index f8682506ac..f874754b26 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -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>
diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml
index 2a8bf2728c..2ca2af6885 100644
--- a/doc/src/sgml/syntax.sgml
+++ b/doc/src/sgml/syntax.sgml
@@ -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>
diff --git a/src/backend/catalog/README b/src/backend/catalog/README
index c84c2d9431..f66c6b9d50 100644
--- a/src/backend/catalog/README
+++ b/src/backend/catalog/README
@@ -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
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 693a7bfe55..6750a85842 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -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);
}
/*
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index f728c7ae22..a506245e62 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -1254,7 +1254,7 @@ shdepReassignOwned(List *roleids, Oid newrole)
break;
case TypeRelationId:
- AlterTypeOwnerInternal(sdepForm->objid, newrole);
+ AlterTypeOwnerInternal(sdepForm->objid, newrole, true);
break;
case OperatorRelationId:
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index c412a1c432..d10abe2ff3 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -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;
}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 7296baa604..d86c78ad18 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -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);
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index c70a784c21..e987493bca 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -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);
@@ -133,16 +136,6 @@ DefineType(List *names, List *parameters)
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
* that the OID is known for use in the I/O function definitions.
@@ -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);
/*
@@ -608,19 +617,6 @@ DefineDomain(CreateDomainStmt *stmt)
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.
*/
typeTup = typenameType(NULL, stmt->typename);
@@ -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);
}
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 86e89c7d89..cbe5d1044c 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -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;
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 5c6f6d3920..da51341732 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -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;
}
/*
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 65658fcc0e..7a64ea6562 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -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;
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 449754e087..1e549c33bf 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -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 */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index f4ec3e34a8..cd1f43d06c 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200705081
+#define CATALOG_VERSION_NO 200705111
#endif
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 437f2320bf..26fa482ec4 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -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));
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 86a0aa6e77..357acc5b70 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -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("");
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 7667e2a1cc..fa1a3d844b 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -98,6 +98,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.
*/
regproc typinput; /* text format (required) */
@@ -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 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 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 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 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 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
/* OIDS 200 - 299 */
-DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
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 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DESCR("");
/* OIDS 700 - 799 */
-DATA(insert OID = 700 ( float4 PGNSP PGUID 4 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 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 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 790 ( money PGNSP PGUID 8 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 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
/* OIDS 800 - 899 */
-DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 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 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
#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 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b t \054 0 20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b t \073 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
#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 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b t \054 0 0 1034 aclitemin aclitemout - - - - - i p f 0 -1 0 _null_ _null_ ));
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 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b t \054 0 829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b t \054 0 869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b t \054 0 650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 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 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 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 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b t \054 0 0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ ));
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 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 _null_ _null_ ));
/* OIDS 1200 - 1299 */
-DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 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 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b t \054 0 0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ ));
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 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 _null_ _null_ ));
/* OIDS 1500 - 1599 */
-DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 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 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b t \054 0 0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
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 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
/* OIDS 1600 - 1699 */
/* OIDS 1700 - 1799 */
-DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 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 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
-DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 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 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
#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 0 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 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 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 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 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 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 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 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 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 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 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 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 */
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index 1467f9d5fb..04d7053ec6 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -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 */
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 11b8c24c3d..99f0c0b049 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -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)
diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out
index 5945753a1b..b7ad2b813c 100644
--- a/src/test/regress/expected/oidjoins.out
+++ b/src/test/regress/expected/oidjoins.out
@@ -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
diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out
index b2db870da4..702cf7eecf 100644
--- a/src/test/regress/expected/type_sanity.out
+++ b/src/test/regress/expected/type_sanity.out
@@ -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
diff --git a/src/test/regress/sql/oidjoins.sql b/src/test/regress/sql/oidjoins.sql
index 5eb440f0f5..7d2dd3dd1f 100644
--- a/src/test/regress/sql/oidjoins.sql
+++ b/src/test/regress/sql/oidjoins.sql
@@ -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
diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql
index b1caa33efb..e549fd7489 100644
--- a/src/test/regress/sql/type_sanity.sql
+++ b/src/test/regress/sql/type_sanity.sql
@@ -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
diff --git a/src/tools/findoidjoins/README b/src/tools/findoidjoins/README
index 598aab2bbd..5d966d7cc5 100644
--- a/src/tools/findoidjoins/README
+++ b/src/tools/findoidjoins/README
@@ -1,3 +1,4 @@
+$PostgreSQL$
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