Thread: updated WIP: arrays of composites
Attached is my rework of David Fetter's array of composites patch. It has all the agreed modifications and checks, except altering the name mangling. If people prefer I can apply this as it stands and then get working on the name mangling piece. Or I can hold off. I'm still wondering if we can get away without a catalog change on that - e.g. could we look up an array type by looking for a pg_type entry containing the base type's oid in the typelem field? Or would that be too slow? cheers andrew Index: doc/src/sgml/array.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/array.sgml,v retrieving revision 1.60 diff -c -r1.60 array.sgml *** doc/src/sgml/array.sgml 6 Apr 2007 19:22:38 -0000 1.60 --- doc/src/sgml/array.sgml 7 May 2007 17:17:29 -0000 *************** *** 11,17 **** <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.) </para> <sect2> --- 11,18 ---- <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 are now supported. Arrays of domains are ! not yet supported. </para> <sect2> Index: src/backend/catalog/heap.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/heap.c,v retrieving revision 1.318 diff -c -r1.318 heap.c *** src/backend/catalog/heap.c 2 Apr 2007 03:49:37 -0000 1.318 --- src/backend/catalog/heap.c 7 May 2007 17:17:31 -0000 *************** *** 45,50 **** --- 45,51 ---- #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" *************** *** 402,417 **** 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) 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 */ --- 403,442 ---- char att_typtype = get_typtype(atttypid); /* ! * For a composite type, recurse into its attributes. Otherwise, * ! * a) warn user, but don't fail, if column to be created has UNKNOWN type ! * (usually as a result of a 'retrieve into' - jolly) ! * ! * b) Refuse any attempt to create a pseudo-type column, except for ! * pg_statistic hack. */ ! if (att_typtype == TYPTYPE_COMPOSITE) ! { ! Relation relation; ! TupleDesc tupdesc; ! int i; ! ! relation = RelationIdGetRelation(get_typ_typrelid(atttypid)); ! ! tupdesc = RelationGetDescr(relation); ! ! for (i = 0; i < tupdesc->natts; i++) ! { ! if (tupdesc->attrs[i]->attisdropped) ! continue; ! CheckAttributeType(attname, tupdesc->attrs[i]->atttypid); ! } ! ! RelationClose(relation); ! } ! else if (atttypid == UNKNOWNOID) ! { 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 */ *************** *** 763,768 **** --- 788,794 ---- Relation pg_class_desc; Relation new_rel_desc; Oid new_type_oid; + char *relarrayname; pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock); *************** *** 815,820 **** --- 841,880 ---- relnamespace, relid, relkind); + /* + * Add in the corresponding array types if appropriate. + */ + if (IsUnderPostmaster && (relkind == RELKIND_RELATION || + relkind == RELKIND_VIEW || + relkind == RELKIND_COMPOSITE_TYPE)) + { + relarrayname = makeArrayTypeName(relname); + TypeCreate(relarrayname, /* Array type name */ + relnamespace, /* Same namespace as parent */ + InvalidOid, /* Not composite, so no relationOid */ + 0, /* relkind, also N/A here */ + -1, /* Internal size, unlimited */ + TYPTYPE_BASE, /* Not a complex type - typelem is */ + DEFAULT_TYPDELIM, /* Use the default */ + F_ARRAY_IN, /* Macro for array input procedure */ + F_ARRAY_OUT, /* Macro for array output procedure */ + F_ARRAY_RECV, /* Macro for array receive (binary input) procedure */ + F_ARRAY_SEND, /* Macro for array send (binary output) procedure */ + InvalidOid, /* No input typmod */ + InvalidOid, /* No output typmod */ + InvalidOid, /* Default ANALYZE procedure */ + new_type_oid, /* The OID just created */ + InvalidOid, /* No base type--this isn't a DOMAIN */ + NULL, /* No default type value */ + NULL, /* Don't send binary */ + false, /* Never passed by value */ + 'd', /* Type align. Largest for safety */ + 'x', /* Always TOASTable */ + -1, /* No typMod for non-domain types. */ + 0, /* Array diminsions of typbasetype */ + false); /* Type NOT NULL */ + pfree(relarrayname); /* Seems like the right thing to do here. */ + } /* * now create an entry in pg_class for the relation. Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.219 diff -c -r1.219 tablecmds.c *** src/backend/commands/tablecmds.c 8 Apr 2007 01:26:32 -0000 1.219 --- src/backend/commands/tablecmds.c 7 May 2007 17:17:36 -0000 *************** *** 287,298 **** Datum reloptions; ListCell *listptr; AttrNumber attnum; /* ! * Truncate relname to appropriate length (probably a waste of time, as ! * parser should have done this already). */ ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); /* * Check consistency of arguments --- 287,309 ---- Datum reloptions; ListCell *listptr; AttrNumber attnum; + char *relarrayname; /* ! * Truncate relname to appropriate length (probably a waste of time, as * ! * parser should have done this already). Because tables and views now get ! * an array type, this depends on the relkind. */ ! if (relkind == RELKIND_RELATION || ! relkind == RELKIND_VIEW || ! relkind == RELKIND_COMPOSITE_TYPE) ! { ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN-2); ! } ! else ! { ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); ! } /* * Check consistency of arguments *************** *** 6461,6468 **** AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's rowtype too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) --- 6472,6480 ---- AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's types too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); + AlterTypeNamespaceInternal(get_array_type(rel->rd_rel->reltype), nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) Index: src/backend/commands/typecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.101 diff -c -r1.101 typecmds.c *** src/backend/commands/typecmds.c 2 Apr 2007 03:49:38 -0000 1.101 --- src/backend/commands/typecmds.c 7 May 2007 17:17:37 -0000 *************** *** 474,479 **** --- 474,480 ---- Oid typeoid; HeapTuple tup; ObjectAddress object; + Form_pg_type typ; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); *************** *** 505,513 **** if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typeoid); /* Permission check: must own type or its namespace */ if (!pg_type_ownercheck(typeoid, GetUserId()) && ! !pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, TypeNameToString(typename)); --- 506,524 ---- if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typeoid); + typ = (Form_pg_type) GETSTRUCT(tup); + + /* don't alow direct deletion of array types */ + if (typ->typelem != 0 && typ->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot delete array type \"%s\" ", + TypeNameToString(typename)))); + + /* Permission check: must own type or its namespace */ if (!pg_type_ownercheck(typeoid, GetUserId()) && ! !pg_namespace_ownercheck(typ->typnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, TypeNameToString(typename)); *************** *** 2249,2254 **** --- 2260,2273 ---- elog(ERROR, "cache lookup failed for type %u", typeOid); typTup = (Form_pg_type) GETSTRUCT(tup); + /* don't allow direct alteration of array types */ + if (typTup->typelem != 0 && typTup->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot alter array type \"%s\" ", + TypeNameToString(typename)))); + + /* * 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 *************** *** 2352,2357 **** --- 2371,2379 ---- TypeName *typename; Oid typeOid; Oid nspOid; + Relation rel; + HeapTuple tup; + Form_pg_type typ; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); *************** *** 2365,2372 **** --- 2387,2420 ---- /* get schema OID and check its permissions */ nspOid = LookupCreationNamespace(newschema); + /* don't allow direct alteration of array types */ + + rel = heap_open(TypeRelationId, RowExclusiveLock); + + tup = SearchSysCacheCopy(TYPEOID, + ObjectIdGetDatum(typeOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", typeOid); + + typ = (Form_pg_type) GETSTRUCT(tup); + + if (typ->typelem != 0 && typ->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot alter array type \"%s\" ", + TypeNameToString(typename)))); + + + heap_freetuple(tup); + + heap_close(rel, RowExclusiveLock); + /* and do the work */ AlterTypeNamespaceInternal(typeOid, nspOid, true); + typeOid = get_array_type(typeOid); + if (typeOid != InvalidOid) + AlterTypeNamespaceInternal(typeOid, nspOid, true); } /* *************** *** 2431,2442 **** /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", --- 2479,2490 ---- /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && typform->typrelid != InvalidOid && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! typform->typrelid != InvalidOid && errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", *************** *** 2457,2463 **** * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType) { Relation classRel; --- 2505,2511 ---- * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType && typform->typrelid != InvalidOid) { Relation classRel; *************** *** 2490,2496 **** * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", --- 2538,2544 ---- * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE || typform->typrelid == InvalidOid) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", Index: src/test/regress/expected/alter_table.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/alter_table.out,v retrieving revision 1.101 diff -c -r1.101 alter_table.out *** src/test/regress/expected/alter_table.out 14 Feb 2007 01:58:58 -0000 1.101 --- src/test/regress/expected/alter_table.out 7 May 2007 17:17:41 -0000 *************** *** 1456,1468 **** --- 1456,1471 ---- -- clean up drop schema alter2 cascade; + NOTICE: drop cascades to type alter2.ctype[] 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) + NOTICE: drop cascades to type alter2.v1[] NOTICE: drop cascades to view alter2.v1 NOTICE: drop cascades to rule _RETURN on view alter2.v1 NOTICE: drop cascades to sequence alter2.t1_f1_seq NOTICE: drop cascades to default for table alter2.t1 column f1 + NOTICE: drop cascades to type alter2.t1[] NOTICE: drop cascades to table alter2.t1 NOTICE: drop cascades to constraint t1_f2_check on table alter2.t1 Index: src/test/regress/expected/type_sanity.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/type_sanity.out,v retrieving revision 1.29 diff -c -r1.29 type_sanity.out *** src/test/regress/expected/type_sanity.out 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/expected/type_sanity.out 7 May 2007 17:17:41 -0000 *************** *** 49,55 **** -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- --- 49,55 ---- -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- Index: src/test/regress/sql/type_sanity.sql =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/sql/type_sanity.sql,v retrieving revision 1.29 diff -c -r1.29 type_sanity.sql *** src/test/regress/sql/type_sanity.sql 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/sql/type_sanity.sql 7 May 2007 17:17:41 -0000 *************** *** 46,52 **** SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type. --- 46,52 ---- SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type.
Andrew Dunstan <andrew@dunslane.net> writes: > I'm still wondering if we can get away without a catalog change on that > - e.g. could we look up an array type by looking for a pg_type entry > containing the base type's oid in the typelem field? Or would that be > too slow? (a) too slow, (b) not unique. regards, tom lane
I wrote: > > Attached is my rework of David Fetter's array of composites patch. It > has all the agreed modifications and checks, except altering the name > mangling. > > Here is the latest with the name mangling piece done - it's got quite large with the catalog rewrite :-) It could do with some extra eyeballs - especially the error codes. I'm not sure if we need to adjust the test in pg_dump.c - maybe we should look at using the same test as the backend (typlen == -1) to disambiguate real arrays from subscriptable base types. cheers andrew Index: doc/src/sgml/array.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/array.sgml,v retrieving revision 1.60 diff -c -r1.60 array.sgml *** doc/src/sgml/array.sgml 6 Apr 2007 19:22:38 -0000 1.60 --- doc/src/sgml/array.sgml 9 May 2007 00:38:12 -0000 *************** *** 11,17 **** <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.) </para> <sect2> --- 11,18 ---- <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 are now supported. Arrays of domains are ! not yet supported. </para> <sect2> Index: src/backend/catalog/heap.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/heap.c,v retrieving revision 1.318 diff -c -r1.318 heap.c *** src/backend/catalog/heap.c 2 Apr 2007 03:49:37 -0000 1.318 --- src/backend/catalog/heap.c 9 May 2007 00:38:13 -0000 *************** *** 45,50 **** --- 45,51 ---- #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,75 **** static Oid AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! char new_rel_kind); static void RelationRemoveInheritance(Oid relid); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreConstraints(Relation rel, TupleDesc tupdesc); --- 70,78 ---- static Oid AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! 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); *************** *** 402,417 **** 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) 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 */ --- 405,444 ---- char att_typtype = get_typtype(atttypid); /* ! * For a composite type, recurse into its attributes. Otherwise, * ! * a) warn user, but don't fail, if column to be created has UNKNOWN type ! * (usually as a result of a 'retrieve into' - jolly) ! * ! * b) Refuse any attempt to create a pseudo-type column, except for ! * pg_statistic hack. */ ! if (att_typtype == TYPTYPE_COMPOSITE) ! { ! Relation relation; ! TupleDesc tupdesc; ! int i; ! ! relation = RelationIdGetRelation(get_typ_typrelid(atttypid)); ! ! tupdesc = RelationGetDescr(relation); ! ! for (i = 0; i < tupdesc->natts; i++) ! { ! if (tupdesc->attrs[i]->attisdropped) ! continue; ! CheckAttributeType(attname, tupdesc->attrs[i]->atttypid); ! } ! ! RelationClose(relation); ! } ! else if (atttypid == UNKNOWNOID) ! { 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 */ *************** *** 710,716 **** AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! char new_rel_kind) { return TypeCreate(typeName, /* type name */ --- 737,744 ---- AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! char new_rel_kind, ! Oid new_array_type) { return TypeCreate(typeName, /* type name */ *************** *** 736,742 **** 'x', /* fully TOASTable */ -1, /* typmod */ 0, /* array dimensions for typBaseType */ ! false); /* Type NOT NULL */ } /* -------------------------------- --- 764,773 ---- 'x', /* fully TOASTable */ -1, /* typmod */ 0, /* array dimensions for typBaseType */ ! false, /* Type NOT NULL */ ! new_array_type, /* oid of type we are about to make */ ! false /* no this is not an array type */ ! ); } /* -------------------------------- *************** *** 763,768 **** --- 794,801 ---- Relation pg_class_desc; Relation new_rel_desc; Oid new_type_oid; + Oid new_array_oid = InvalidOid; + pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock); *************** *** 804,809 **** --- 837,853 ---- Assert(relid == RelationGetRelid(new_rel_desc)); + /* Get an oid for the array type of necessary */ + if (IsUnderPostmaster && (relkind == RELKIND_RELATION || + relkind == RELKIND_VIEW || + relkind == RELKIND_COMPOSITE_TYPE)) + { + Relation pg_type = heap_open(TypeRelationId, RowExclusiveLock); + new_array_oid = GetNewOid(pg_type); + heap_close(pg_type, RowExclusiveLock); + } + + /* * since defining a relation also defines a complex type, we add a new * system type corresponding to the new relation. *************** *** 814,820 **** new_type_oid = AddNewRelationType(relname, relnamespace, relid, ! relkind); /* * now create an entry in pg_class for the relation. --- 858,906 ---- new_type_oid = AddNewRelationType(relname, relnamespace, relid, ! relkind, ! new_array_oid); ! /* ! * Add in the corresponding array types if appropriate. ! */ ! if (IsUnderPostmaster && (relkind == RELKIND_RELATION || ! relkind == RELKIND_VIEW || ! relkind == RELKIND_COMPOSITE_TYPE)) ! { ! char *relarrayname; ! ! relarrayname = makeArrayTypeName(relname, relnamespace); ! ! TypeCreate(relarrayname, /* Array type name */ ! relnamespace, /* Same namespace as parent */ ! InvalidOid, /* Not composite, no relationOid */ ! 0, /* relkind, also N/A here */ ! -1, /* Internal size, unlimited */ ! TYPTYPE_BASE, /* Not composite - typelem is */ ! DEFAULT_TYPDELIM, /* Use the default */ ! 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, /* No input typmod */ ! InvalidOid, /* No output typmod */ ! InvalidOid, /* Default ANALYZE procedure */ ! new_type_oid, /* The OID just created */ ! InvalidOid, /* No base type--not a DOMAIN */ ! NULL, /* No default type value */ ! NULL, /* Don't send binary */ ! false, /* Never passed by value */ ! 'd', /* Type align. Max for safety */ ! 'x', /* Always TOASTable */ ! -1, /* No typMod for non-domain */ ! 0, /* Array dims of typbasetype */ ! false, /* Type NOT NULL */ ! new_array_oid, /* oid of this type entry */ ! true /* yes, this is an array type */ ! ); ! ! pfree(relarrayname); ! } /* * now create an entry in pg_class for the relation. *************** *** 887,893 **** */ heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(pg_class_desc, RowExclusiveLock); ! return relid; } --- 973,979 ---- */ heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(pg_class_desc, RowExclusiveLock); ! return relid; } Index: src/backend/catalog/pg_type.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v retrieving revision 1.111 diff -c -r1.111 pg_type.c *** src/backend/catalog/pg_type.c 2 Apr 2007 03:49:37 -0000 1.111 --- src/backend/catalog/pg_type.c 9 May 2007 00:38:14 -0000 *************** *** 90,95 **** --- 90,96 ---- 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 */ *************** *** 180,186 **** char storage, int32 typeMod, int32 typNDims, /* Array dimensions for baseType */ ! bool typeNotNull) { Relation pg_type_desc; Oid typeObjectId; --- 181,190 ---- char storage, int32 typeMod, int32 typNDims, /* Array dimensions for baseType */ ! bool typeNotNull, ! Oid arrayType, ! bool is_array_type ! ) { Relation pg_type_desc; Oid typeObjectId; *************** *** 246,251 **** --- 250,257 ---- values[i++] = ObjectIdGetDatum(typeType == TYPTYPE_COMPOSITE ? relationOid : InvalidOid); /* typrelid */ values[i++] = ObjectIdGetDatum(elementType); /* typelem */ + values[i++] = ObjectIdGetDatum(is_array_type ? + InvalidOid : arrayType); /* typarray */ values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */ values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */ values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */ *************** *** 331,336 **** --- 337,347 ---- values, nulls); + /* should only happen if it's not a shell type */ + if (is_array_type) + HeapTupleSetOid(tup, arrayType); + + typeObjectId = simple_heap_insert(pg_type_desc, tup); } *************** *** 571,590 **** } /* * makeArrayTypeName(typeName); * - given a base type name, make an array of type name out of it * * the caller is responsible for pfreeing the result */ char * ! makeArrayTypeName(const char *typeName) { char *arr; if (!typeName) return NULL; arr = palloc(NAMEDATALEN); ! snprintf(arr, NAMEDATALEN, ! "_%.*s", NAMEDATALEN - 2, typeName); return arr; } --- 582,660 ---- } /* + * find the mb-safe substring length that is not greater than max + */ + static int + mb_substr_len(char * str, int max) + { + int result = 0; + char * crsr = str; + int len = strlen(str); + + if (max > len) + max = len; + + if (pg_database_encoding_max_length() == 1) + return max; + if (crsr == NULL) + return 0; + while (*crsr) + { + len = pg_mblen(crsr); + if (result + len > max) + break; + result += len; + crsr += len; + } + return result; + } + + + + /* * makeArrayTypeName(typeName); * - given a base type name, make an array of type name out of it * * the caller is responsible for pfreeing the result */ char * ! makeArrayTypeName(const char *typeName, Oid typeNamespace) { char *arr; + int i, safelen; + bool found = false; + Relation pg_type_desc; + + pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); + if (!typeName) return NULL; + arr = palloc(NAMEDATALEN); ! ! for (i = 1; i < NAMEDATALEN / 2; i++) ! { ! arr[i - 1] = '_'; ! safelen = mb_substr_len(typeName, NAMEDATALEN - (i + 1)); ! snprintf(arr+i, NAMEDATALEN - 1, "%.*s", safelen, typeName); ! if (SearchSysCacheExists(TYPENAMENSP, ! CStringGetDatum(arr), ! ObjectIdGetDatum(typeNamespace), ! 0, 0)) ! continue; ! found = true; ! break; ! } ! ! heap_close(pg_type_desc, RowExclusiveLock); ! ! if (! found) ! ereport(ERROR, ! (errcode(ERRCODE_DUPLICATE_OBJECT), ! errmsg("could not form array type name for type \"%s\"", ! typeName))); ! ! return arr; } Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.219 diff -c -r1.219 tablecmds.c *** src/backend/commands/tablecmds.c 8 Apr 2007 01:26:32 -0000 1.219 --- src/backend/commands/tablecmds.c 9 May 2007 00:38:18 -0000 *************** *** 287,298 **** Datum reloptions; ListCell *listptr; AttrNumber attnum; /* ! * Truncate relname to appropriate length (probably a waste of time, as ! * parser should have done this already). */ ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); /* * Check consistency of arguments --- 287,309 ---- Datum reloptions; ListCell *listptr; AttrNumber attnum; + char *relarrayname; /* ! * Truncate relname to appropriate length (probably a waste of time, as * ! * parser should have done this already). Because tables and views now get ! * an array type, this depends on the relkind. */ ! if (relkind == RELKIND_RELATION || ! relkind == RELKIND_VIEW || ! relkind == RELKIND_COMPOSITE_TYPE) ! { ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN-2); ! } ! else ! { ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); ! } /* * Check consistency of arguments *************** *** 6461,6468 **** AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's rowtype too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) --- 6472,6480 ---- AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's types too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); + AlterTypeNamespaceInternal(get_array_type(rel->rd_rel->reltype), nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) Index: src/backend/commands/typecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.101 diff -c -r1.101 typecmds.c *** src/backend/commands/typecmds.c 2 Apr 2007 03:49:38 -0000 1.101 --- src/backend/commands/typecmds.c 9 May 2007 00:38:20 -0000 *************** *** 34,39 **** --- 34,40 ---- #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" *************** *** 119,127 **** --- 120,130 ---- Oid typmodoutOid = InvalidOid; Oid analyzeOid = InvalidOid; char *shadow_type; + Oid shadow_oid; ListCell *pl; Oid typoid; Oid resulttype; + Relation pg_type; /* Convert list of names to a name and namespace */ typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName); *************** *** 396,401 **** --- 399,408 ---- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(analyzeName)); + pg_type = heap_open(TypeRelationId, RowExclusiveLock); + shadow_oid = GetNewOid(pg_type); + heap_close(pg_type, RowExclusiveLock); + /* * now have TypeCreate do all the real work. */ *************** *** 423,465 **** storage, /* TOAST strategy */ -1, /* typMod (Domains only) */ 0, /* Array Dimensions of typbasetype */ ! 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. */ ! shadow_type = makeArrayTypeName(typeName); /* alignment must be 'i' or 'd' for arrays */ alignment = (alignment == 'd') ? 'd' : 'i'; ! TypeCreate(shadow_type, /* type name */ ! typeNamespace, /* namespace */ ! InvalidOid, /* relation oid (n/a here) */ ! 0, /* relation kind (ditto) */ ! -1, /* internal size */ ! TYPTYPE_BASE, /* type-type (base type) */ ! DEFAULT_TYPDELIM, /* array element delimiter */ ! F_ARRAY_IN, /* input procedure */ ! F_ARRAY_OUT, /* output procedure */ ! F_ARRAY_RECV, /* receive procedure */ ! F_ARRAY_SEND, /* send procedure */ ! typmodinOid, /* typmodin procedure */ ! typmodoutOid, /* typmodout procedure */ ! InvalidOid, /* analyze procedure - default */ ! typoid, /* element type ID */ ! InvalidOid, /* base type ID */ ! NULL, /* never a default type value */ ! NULL, /* binary default isn't sent either */ ! false, /* never passed by value */ ! alignment, /* see above */ ! 'x', /* ARRAY is always toastable */ ! -1, /* typMod (Domains only) */ ! 0, /* Array dimensions of typbasetype */ ! false); /* Type NOT NULL */ pfree(shadow_type); } --- 430,479 ---- storage, /* TOAST strategy */ -1, /* typMod (Domains only) */ 0, /* Array Dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! shadow_oid, /* array type we are about to create */ ! false /* this is not an array type */ ! ); /* * 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. */ ! shadow_type = makeArrayTypeName(typeName, typeNamespace); /* alignment must be 'i' or 'd' for arrays */ alignment = (alignment == 'd') ? 'd' : 'i'; ! TypeCreate(shadow_type, /* type name */ ! typeNamespace, /* namespace */ ! InvalidOid, /* relation oid (n/a here) */ ! 0, /* relation kind (ditto) */ ! -1, /* internal size */ ! TYPTYPE_BASE, /* type-type (base type) */ ! DEFAULT_TYPDELIM, /* array element delimiter */ ! F_ARRAY_IN, /* input procedure */ ! F_ARRAY_OUT, /* output procedure */ ! F_ARRAY_RECV, /* receive procedure */ ! F_ARRAY_SEND, /* send procedure */ ! typmodinOid, /* typmodin procedure */ ! typmodoutOid, /* typmodout procedure */ ! InvalidOid, /* analyze procedure - default */ ! typoid, /* element type ID */ ! InvalidOid, /* base type ID */ ! NULL, /* never a default type value */ ! NULL, /* binary default isn't sent either */ ! false, /* never passed by value */ ! alignment, /* see above */ ! 'x', /* ARRAY is always toastable */ ! -1, /* typMod (Domains only) */ ! 0, /* Array dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! shadow_oid, /* oid for this entry */ ! true /* yes this is an array type */ ! ); pfree(shadow_type); + } *************** *** 474,479 **** --- 488,494 ---- Oid typeoid; HeapTuple tup; ObjectAddress object; + Form_pg_type typ; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); *************** *** 505,513 **** if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typeoid); /* Permission check: must own type or its namespace */ if (!pg_type_ownercheck(typeoid, GetUserId()) && ! !pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, TypeNameToString(typename)); --- 520,538 ---- if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typeoid); + typ = (Form_pg_type) GETSTRUCT(tup); + + /* don't alow direct deletion of array types */ + if (typ->typelem != 0 && typ->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot delete array type \"%s\" ", + TypeNameToString(typename)))); + + /* Permission check: must own type or its namespace */ if (!pg_type_ownercheck(typeoid, GetUserId()) && ! !pg_namespace_ownercheck(typ->typnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, TypeNameToString(typename)); *************** *** 545,551 **** simple_heap_delete(relation, &tup->t_self); /* ! * If it is an enum, delete the pg_enum entries too; we don't bother * with making dependency entries for those, so it has to be done * "by hand" here. */ --- 570,576 ---- simple_heap_delete(relation, &tup->t_self); /* ! * If it is an enum delete the pg_enum entries too; we don't bother * with making dependency entries for those, so it has to be done * "by hand" here. */ *************** *** 828,835 **** storage, /* TOAST strategy */ basetypeMod, /* typeMod value */ typNDims, /* Array dimensions for base type */ ! typNotNull); /* Type NOT NULL */ ! /* * Process constraints which refer to the domain ID returned by TypeCreate */ --- 853,862 ---- storage, /* TOAST strategy */ basetypeMod, /* typeMod value */ typNDims, /* Array dimensions for base type */ ! typNotNull, /* Type NOT NULL */ ! InvalidOid, /* no arrays for domains */ ! false /* this isn't an array */ ! ); /* * Process constraints which refer to the domain ID returned by TypeCreate */ *************** *** 949,954 **** --- 976,983 ---- Oid enumNamespace; Oid enumTypeOid; AclResult aclresult; + Oid enumArrayOid; + Relation pg_type; /* Convert list of names to a name and namespace */ enumNamespace = QualifiedNameGetCreationNamespace(stmt->typename, *************** *** 970,975 **** --- 999,1009 ---- errmsg("type names must be %d characters or less", NAMEDATALEN - 2))); + + pg_type = heap_open(TypeRelationId, RowExclusiveLock); + enumArrayOid = GetNewOid(pg_type); + heap_close(pg_type, RowExclusiveLock); + /* Create the pg_type entry */ enumTypeOid = TypeCreate(enumName, /* type name */ *************** *** 995,1007 **** 'p', /* TOAST strategy always plain */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false); /* Type NOT NULL */ /* Enter the enum's values into pg_enum */ EnumValuesCreate(enumTypeOid, stmt->vals); /* Create array type for enum */ ! enumArrayName = makeArrayTypeName(enumName); TypeCreate(enumArrayName, /* type name */ enumNamespace, /* namespace */ --- 1029,1044 ---- 'p', /* TOAST strategy always plain */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! enumArrayOid, /* oid of entry we are about to create */ ! false /* this is not an array */ ! ); /* Enter the enum's values into pg_enum */ EnumValuesCreate(enumTypeOid, stmt->vals); /* Create array type for enum */ ! enumArrayName = makeArrayTypeName(enumName, enumNamespace); TypeCreate(enumArrayName, /* type name */ enumNamespace, /* namespace */ *************** *** 1026,1032 **** 'x', /* ARRAY is always toastable */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false); /* Type NOT NULL */ pfree(enumArrayName); } --- 1063,1072 ---- 'x', /* ARRAY is always toastable */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! enumArrayOid, /* oid to use for this entry */ ! true /* this is an array */ ! ); pfree(enumArrayName); } *************** *** 2249,2254 **** --- 2289,2302 ---- elog(ERROR, "cache lookup failed for type %u", typeOid); typTup = (Form_pg_type) GETSTRUCT(tup); + /* don't allow direct alteration of array types */ + if (typTup->typelem != 0 && typTup->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot alter array type \"%s\" ", + TypeNameToString(typename)))); + + /* * 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 *************** *** 2352,2357 **** --- 2400,2408 ---- TypeName *typename; Oid typeOid; Oid nspOid; + Relation rel; + HeapTuple tup; + Form_pg_type typ; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); *************** *** 2365,2372 **** --- 2416,2449 ---- /* get schema OID and check its permissions */ nspOid = LookupCreationNamespace(newschema); + /* don't allow direct alteration of array types */ + + rel = heap_open(TypeRelationId, RowExclusiveLock); + + tup = SearchSysCacheCopy(TYPEOID, + ObjectIdGetDatum(typeOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", typeOid); + + typ = (Form_pg_type) GETSTRUCT(tup); + + if (typ->typelem != 0 && typ->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot alter array type \"%s\" ", + TypeNameToString(typename)))); + + + heap_freetuple(tup); + + heap_close(rel, RowExclusiveLock); + /* and do the work */ AlterTypeNamespaceInternal(typeOid, nspOid, true); + typeOid = get_array_type(typeOid); + if (typeOid != InvalidOid) + AlterTypeNamespaceInternal(typeOid, nspOid, true); } /* *************** *** 2431,2442 **** /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", --- 2508,2519 ---- /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && typform->typrelid != InvalidOid && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! typform->typrelid != InvalidOid && errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", *************** *** 2457,2463 **** * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType) { Relation classRel; --- 2534,2540 ---- * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType && typform->typrelid != InvalidOid) { Relation classRel; *************** *** 2490,2496 **** * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", --- 2567,2573 ---- * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE || typform->typrelid == InvalidOid) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", Index: src/backend/parser/parse_type.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/parser/parse_type.c,v retrieving revision 1.89 diff -c -r1.89 parse_type.c *** src/backend/parser/parse_type.c 27 Apr 2007 22:05:48 -0000 1.89 --- src/backend/parser/parse_type.c 9 May 2007 00:38:20 -0000 *************** *** 116,125 **** /* 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 */ --- 116,121 ---- *************** *** 136,141 **** --- 132,142 ---- /* Unqualified type name, so search the search path */ restype = TypenameGetTypid(typname); } + + /* If an array reference, return the array type instead */ + if (typename->arrayBounds != NIL) + restype = get_array_type(restype); + } return restype; Index: src/backend/utils/cache/lsyscache.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v retrieving revision 1.151 diff -c -r1.151 lsyscache.c *** src/backend/utils/cache/lsyscache.c 2 Apr 2007 03:49:39 -0000 1.151 --- src/backend/utils/cache/lsyscache.c 9 May 2007 00:38:23 -0000 *************** *** 2206,2252 **** * Given the type OID, get the corresponding 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; 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; 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; } /* --- 2206,2227 ---- * Given the type OID, get the corresponding array type. * Returns InvalidOid if no array type can be found. * */ Oid get_array_type(Oid typid) { HeapTuple tp; + Oid result = InvalidOid; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { ! result = ((Form_pg_type) GETSTRUCT(tp))->typarray; ReleaseSysCache(tp); } ! return result; } /* Index: src/include/catalog/catversion.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/catversion.h,v retrieving revision 1.404 diff -c -r1.404 catversion.h *** src/include/catalog/catversion.h 15 Apr 2007 10:56:27 -0000 1.404 --- src/include/catalog/catversion.h 9 May 2007 00:38:23 -0000 *************** *** 53,58 **** */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200704151 #endif --- 53,58 ---- */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200705061 #endif Index: src/include/catalog/pg_attribute.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_attribute.h,v retrieving revision 1.130 diff -c -r1.130 pg_attribute.h *** src/include/catalog/pg_attribute.h 22 Jan 2007 01:35:21 -0000 1.130 --- src/include/catalog/pg_attribute.h 9 May 2007 00:38:23 -0000 *************** *** 232,252 **** { 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 } 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)); --- 232,253 ---- { 1247, {"typdelim"}, 18, -1, 1, 8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1247, {"typrelid"}, 26, -1, 4, 9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typelem"}, 26, -1, 4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typarray"}, 26, -1, 4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typinput"}, 24, -1, 4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typoutput"}, 24, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typreceive"}, 24, -1, 4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typsend"}, 24, -1, 4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typmodin"}, 24, -1, 4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typmodout"}, 24, -1, 4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typanalyze"}, 24, -1, 4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typalign"}, 18, -1, 1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ ! { 1247, {"typstorage"}, 18, -1, 1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ ! { 1247, {"typnotnull"}, 16, -1, 1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ ! { 1247, {"typbasetype"}, 26, -1, 4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typtypmod"}, 23, -1, 4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typndims"}, 23, -1, 4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typdefaultbin"}, 25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \ ! { 1247, {"typdefault"}, 25, -1, -1, 26, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 } 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,278 **** 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 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)); --- 259,280 ---- DATA(insert ( 1247 typdelim 18 -1 1 8 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1247 typrelid 26 -1 4 9 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typelem 26 -1 4 10 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typarray 26 -1 4 11 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typinput 24 -1 4 12 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typoutput 24 -1 4 13 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typreceive 24 -1 4 14 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typsend 24 -1 4 15 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typmodin 24 -1 4 16 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typmodout 24 -1 4 17 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typanalyze 24 -1 4 18 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typalign 18 -1 1 19 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1247 typstorage 18 -1 1 20 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1247 typnotnull 16 -1 1 21 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1247 typbasetype 26 -1 4 22 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typtypmod 23 -1 4 23 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typndims 23 -1 4 24 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typdefaultbin 25 -1 -1 25 0 -1 -1 f x i f f f t 0)); ! DATA(insert ( 1247 typdefault 25 -1 -1 26 0 -1 -1 f x i f f f t 0)); DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0)); DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0)); Index: src/include/catalog/pg_class.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_class.h,v retrieving revision 1.100 diff -c -r1.100 pg_class.h *** src/include/catalog/pg_class.h 22 Jan 2007 01:35:22 -0000 1.100 --- src/include/catalog/pg_class.h 9 May 2007 00:38:24 -0000 *************** *** 132,138 **** */ /* 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_ )); 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(""); --- 132,138 ---- */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ ! DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 26 0 0 0 0 0 t f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ )); DESCR(""); Index: src/include/catalog/pg_type.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_type.h,v retrieving revision 1.182 diff -c -r1.182 pg_type.h *** src/include/catalog/pg_type.h 6 Apr 2007 04:21:43 -0000 1.182 --- src/include/catalog/pg_type.h 9 May 2007 00:38:24 -0000 *************** *** 97,102 **** --- 97,105 ---- */ Oid typelem; + /* Oid of array type, or 0 if it does not exist */ + Oid typarray; + /* * I/O conversion procedures for the datatype. */ *************** *** 214,220 **** * compiler constants for pg_type * ---------------- */ ! #define Natts_pg_type 25 #define Anum_pg_type_typname 1 #define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typowner 3 --- 217,223 ---- * compiler constants for pg_type * ---------------- */ ! #define Natts_pg_type 26 #define Anum_pg_type_typname 1 #define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typowner 3 *************** *** 225,245 **** #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 /* ---------------- --- 228,249 ---- #define Anum_pg_type_typdelim 8 #define Anum_pg_type_typrelid 9 #define Anum_pg_type_typelem 10 ! #define Anum_pg_type_typarray 11 ! #define Anum_pg_type_typinput 12 ! #define Anum_pg_type_typoutput 13 ! #define Anum_pg_type_typreceive 14 ! #define Anum_pg_type_typsend 15 ! #define Anum_pg_type_typmodin 16 ! #define Anum_pg_type_typmodout 17 ! #define Anum_pg_type_typanalyze 18 ! #define Anum_pg_type_typalign 19 ! #define Anum_pg_type_typstorage 20 ! #define Anum_pg_type_typnotnull 21 ! #define Anum_pg_type_typbasetype 22 ! #define Anum_pg_type_typtypmod 23 ! #define Anum_pg_type_typndims 24 ! #define Anum_pg_type_typdefaultbin 25 ! #define Anum_pg_type_typdefault 26 /* ---------------- *************** *** 255,340 **** */ /* 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_ )); 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 f0 -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_ )); 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 pf 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_ )); 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_ )); 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_ )); 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_ )); 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_ )); 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 -10 _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_ )); 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_ )); 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_ )); 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_ )); 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_ )); 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_ )); #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_ )); #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_ )); #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_ )); #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_ )); 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 f0 -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_ )); DESCR("storage manager"); /* OIDS 300 - 399 */ --- 259,344 ---- */ /* OIDS 1 - 99 */ ! DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 1000 boolin boolout boolrecv boolsend - - - cp f 0 -1 0 _null_ _null_ )); DESCR("boolean, 'true'/'false'"); #define BOOLOID 16 ! DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 1001 byteain byteaout bytearecv byteasend - - -i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length string, binary values escaped"); #define BYTEAOID 17 ! DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 1002 charin charout charrecv charsend - - - cp f 0 -1 0 _null_ _null_ )); DESCR("single character"); #define CHAROID 18 ! DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 namein nameout namerecv namesend - -- 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 1016 int8in int8out int8recv int8send - - - dp f 0 -1 0 _null_ _null_ )); DESCR("~18 digit integer, 8-byte storage"); #define INT8OID 20 ! DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 1005 int2in int2out int2recv int2send - - - sp f 0 -1 0 _null_ _null_ )); DESCR("-32 thousand to 32 thousand, 2-byte storage"); #define INT2OID 21 ! DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b t \054 0 21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("array of int2, used in system tables"); #define INT2VECTOROID 22 ! DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 1007 int4in int4out int4recv int4send - - - ip f 0 -1 0 _null_ _null_ )); DESCR("-2 billion to 2 billion integer, 4-byte storage"); #define INT4OID 23 ! DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 1008 regprocin regprocout regprocrecv regprocsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered procedure"); #define REGPROCOID 24 ! DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 1009 textin textout textrecv textsend - - - i x f0 -1 0 _null_ _null_ )); DESCR("variable-length string, no limit specified"); #define TEXTOID 25 ! DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 1028 oidin oidout oidrecv oidsend - - - i pf 0 -1 0 _null_ _null_ )); DESCR("object identifier(oid), maximum 4 billion"); #define OIDOID 26 ! DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b t \054 0 0 1010 tidin tidout tidrecv tidsend - - - s pf 0 -1 0 _null_ _null_ )); DESCR("(Block, offset), physical location of tuple"); #define TIDOID 27 ! DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b t \054 0 0 1011 xidin xidout xidrecv xidsend - - - i pf 0 -1 0 _null_ _null_ )); DESCR("transaction id"); #define XIDOID 28 ! DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 1012 cidin cidout cidrecv cidsend - - - i pf 0 -1 0 _null_ _null_ )); DESCR("command identifier type, sequence in transaction id"); #define CIDOID 29 ! DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b t \054 0 26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("array of oids, used in system tables"); #define OIDVECTOROID 30 /* hand-built rowtype entries for bootstrapped catalogs: */ ! DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c t \054 1247 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_TYPE_RELTYPE_OID 71 ! DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c t \054 1249 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_ATTRIBUTE_RELTYPE_OID 75 ! DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c t \054 1255 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_PROC_RELTYPE_OID 81 ! DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c t \054 1259 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_CLASS_RELTYPE_OID 83 /* OIDS 100 - 199 */ ! DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0-1 0 _null_ _null_ )); DESCR("XML content"); #define XMLOID 142 ! DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b t \054 0 142 0 array_in array_out array_recv array_send - - - i xf 0 -1 0 _null_ _null_ )); /* OIDS 200 - 299 */ ! DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_)); DESCR("storage manager"); /* OIDS 300 - 399 */ *************** *** 344,543 **** /* 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 pf 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_ )); 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 -10 _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_ )); 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_ )); 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_ )); 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_ )); DESCR(""); /* OIDS 700 - 799 */ ! DATA(insert OID = 700 ( float4 PGNSP PGUID 4 f b t \054 0 0 float4in float4out float4recv float4send - - - ip 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 - - - dp 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_ )); 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_ )); 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_ )); 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_ )); 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_ )); 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 - - - dx 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 f0 -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 - - - dx 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_ )); 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_ )); 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_ )); 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 - - - ix f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); #define INT4ARRAYOID 1007 ! DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 array_in array_out array_recv array_send - - - ix 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 bpchartypmodinbpchartypmodout - 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 varchartypmodinvarchartypmodout - 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 xf 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 - - - dx 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 - - - ix 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 - - - dx 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 - - - ix 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 - - - ix 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 xf 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 - - - dx 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_ )); 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 - - - ix 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 - - - ix f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b t \054 0 0 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodinbpchartypmodout - 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 varchartypmodinvarchartypmodout - 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 pf 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 timetypmodintimetypmodout - 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_sendtimestamptypmodin 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 timestamptypmodintimestamptypmodout - 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 timetypmodintimetypmodout - 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_recvtimestamptz_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 timestamptztypmodintimestamptztypmodout - 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_sendintervaltypmodin 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 intervaltypmodinintervaltypmodout - 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 numerictypmodinnumerictypmodout - 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 timetztypmodintimetztypmodout - 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 timetztypmodintimetztypmodout - 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_ )); 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 bittypmodinbittypmodout - 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 varbittypmodinvarbittypmodout - 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 varbittypmodinvarbittypmodout - 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_sendnumerictypmodin 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 f0 -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 = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 regprocedurein regprocedureout regprocedurerecvregproceduresend - - - 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_ )); DESCR("registered operator"); #define REGOPEROID 2203 ! DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 regoperatorin regoperatorout regoperatorrecvregoperatorsend - - - 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_ )); 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_ )); 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_ )); #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 f0 -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_ )); /* * pseudo-types --- 348,547 ---- /* OIDS 500 - 599 */ /* OIDS 600 - 699 */ ! DATA(insert OID = 600 ( point PGNSP PGUID 16 f b t \054 0 701 1017 point_in point_out point_recv point_send - -- d p f 0 -1 0 _null_ _null_ )); DESCR("geometric point '(x, y)'"); #define POINTOID 600 ! DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d pf 0 -1 0 _null_ _null_ )); DESCR("geometric line segment '(pt1,pt2)'"); #define LSEGOID 601 ! DATA(insert OID = 602 ( path PGNSP PGUID -1 f b t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f0 -1 0 _null_ _null_ )); DESCR("geometric path '(pt1,...)'"); #define PATHOID 602 ! DATA(insert OID = 603 ( box PGNSP PGUID 32 f b t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0-1 0 _null_ _null_ )); DESCR("geometric box '(lower left,upper right)'"); #define BOXOID 603 ! DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b t \054 0 0 1027 poly_in poly_out poly_recv poly_send - - - dx f 0 -1 0 _null_ _null_ )); DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 ! DATA(insert OID = 628 ( line PGNSP PGUID 32 f b t \054 0 701 629 line_in line_out line_recv line_send - - - d pf 0 -1 0 _null_ _null_ )); DESCR("geometric line (not implemented)'"); #define LINEOID 628 ! DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b t \054 0 628 0 array_in array_out array_recv array_send - -- d x f 0 -1 0 _null_ _null_ )); DESCR(""); /* OIDS 700 - 799 */ ! 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 1022 float8in float8out float8recv float8send -- - d p f 0 -1 0 _null_ _null_ )); DESCR("double-precision floating point number, 8-byte storage"); #define FLOAT8OID 701 ! DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b t \054 0 0 1023 abstimein abstimeout abstimerecv abstimesend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("absolute, limited-range date and time (Unix system time)"); #define ABSTIMEOID 702 ! DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b t \054 0 0 1024 reltimein reltimeout reltimerecv reltimesend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("relative, limited-range time interval (Unix delta time)"); #define RELTIMEOID 703 ! DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 1025 tintervalin tintervalout tintervalrecv tintervalsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("(abstime,abstime), time interval"); #define TINTERVALOID 704 ! DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b t \054 0 0 0 unknownin unknownout unknownrecv unknownsend - -- c p f 0 -1 0 _null_ _null_ )); DESCR(""); #define UNKNOWNOID 705 ! DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b t \054 0 0 719 circle_in circle_out circle_recv circle_send -- - d p f 0 -1 0 _null_ _null_ )); DESCR("geometric circle '(center,radius)'"); #define CIRCLEOID 718 ! DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b t \054 0 718 0 array_in array_out array_recv array_send - - -d x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 790 ( money PGNSP PGUID 8 f b t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - dp f 0 -1 0 _null_ _null_ )); DESCR("monetary amounts, $d,ddd.cc"); #define CASHOID 790 ! DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b t \054 0 790 0 array_in array_out array_recv array_send - - -d x f 0 -1 0 _null_ _null_ )); /* OIDS 800 - 899 */ ! DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send- - - i p f 0 -1 0 _null_ _null_ )); DESCR("XX:XX:XX:XX:XX:XX, MAC address"); #define MACADDROID 829 ! DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i mf 0 -1 0 _null_ _null_ )); DESCR("IP address/netmask, host address, netmask optional"); #define INETOID 869 ! DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i mf 0 -1 0 _null_ _null_ )); DESCR("network IP address/netmask, network address"); #define CIDROID 650 /* OIDS 900 - 999 */ /* OIDS 1000 - 1099 */ ! DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b t \054 0 16 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 0 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); #define INT4ARRAYOID 1007 ! DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 0 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodinbpchartypmodout - 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 varchartypmodinvarchartypmodout - 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 - - - dx 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 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 - - - ix 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 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 bpcharsendbpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("char(length), blank-padded string, fixed storage length"); #define BPCHAROID 1042 ! DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b t \054 0 0 1015 varcharin varcharout varcharrecv varcharsendvarchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("varchar(length), non-blank-padded string, variable storage length"); #define VARCHAROID 1043 ! DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b t \054 0 0 1182 date_in date_out date_recv date_send - -- i p f 0 -1 0 _null_ _null_ )); DESCR("ANSI SQL date"); #define DATEOID 1082 ! DATA(insert OID = 1083 ( time PGNSP PGUID 8 f b t \054 0 0 1183 time_in time_out time_recv time_send timetypmodintimetypmodout - 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 1115 timestamp_in timestamp_out timestamp_recvtimestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("date and time"); #define TIMESTAMPOID 1114 ! DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodintimestamptypmodout - 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 timetypmodintimetypmodout - 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_recvtimestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("date and time with time zone"); #define TIMESTAMPTZOID 1184 ! DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0 1184 0 array_in array_out array_recv array_send timestamptztypmodintimestamptztypmodout - 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_sendintervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("@ <number> <units>, time interval"); #define INTERVALOID 1186 ! DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodinintervaltypmodout - d x f 0 -1 0 _null_ _null_ )); /* OIDS 1200 - 1299 */ ! DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 0 array_in array_out array_recv array_send numerictypmodinnumerictypmodout - 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_sendtimetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("hh:mm:ss, ANSI SQL time"); #define TIMETZOID 1266 ! DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b t \054 0 1266 0 array_in array_out array_recv array_send timetztypmodintimetztypmodout - d x f 0 -1 0 _null_ _null_ )); /* OIDS 1500 - 1599 */ ! DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 1561 bit_in bit_out bit_recv bit_send bittypmodinbittypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("fixed-length bit string"); #define BITOID 1560 ! DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b t \054 0 1560 0 array_in array_out array_recv array_send bittypmodinbittypmodout - 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_sendvarbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length bit string"); #define VARBITOID 1562 ! DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b t \054 0 1562 0 array_in array_out array_recv array_send varbittypmodinvarbittypmodout - i x f 0 -1 0 _null_ _null_ )); /* OIDS 1600 - 1699 */ /* OIDS 1700 - 1799 */ ! DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 1231 numeric_in numeric_out numeric_recv numeric_sendnumerictypmodin numerictypmodout - i m f 0 -1 0 _null_ _null_ )); DESCR("numeric(precision, decimal), arbitrary precision number"); #define NUMERICOID 1700 ! DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 2201 textin textout textrecv textsend - - - ix f 0 -1 0 _null_ _null_ )); DESCR("reference cursor (portal name)"); #define REFCURSOROID 1790 /* OIDS 2200 - 2299 */ ! DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b t \054 0 1790 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 2207 regprocedurein regprocedureout regprocedurerecvregproceduresend - - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered procedure (with args)"); #define REGPROCEDUREOID 2202 ! DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b t \054 0 0 2208 regoperin regoperout regoperrecv regopersend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered operator"); #define REGOPEROID 2203 ! DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 2209 regoperatorin regoperatorout regoperatorrecvregoperatorsend - - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered operator (with args)"); #define REGOPERATOROID 2204 ! DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b t \054 0 0 2210 regclassin regclassout regclassrecv regclasssend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered class"); #define REGCLASSOID 2205 ! DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b t \054 0 0 2211 regtypein regtypeout regtyperecv regtypesend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered type"); #define REGTYPEOID 2206 ! DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); #define REGTYPEARRAYOID 2211 /* uuid */ ! DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - -c p f 0 -1 0 _null_ _null_ )); DESCR("UUID datatype"); ! DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b t \054 0 2950 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); /* * pseudo-types *************** *** 548,574 **** * 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_ )); #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_ )); #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_)); #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_ )); #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_)); #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_ )); #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_ )); #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_ )); #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_ )); #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_ )); #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_ )); #define ANYENUMOID 3500 --- 552,578 ---- * 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 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 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 0 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_)); #define ANYOID 2276 ! DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send- - - d x f 0 -1 0 _null_ _null_ )); #define ANYARRAYOID 2277 ! DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p t \054 0 0 0 void_in void_out - - - - - i p f 0 -1 0 _null__null_ )); #define VOIDOID 2278 ! DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 _null__null_ )); #define TRIGGEROID 2279 ! DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p t \054 0 0 0 language_handler_in language_handler_out -- - - - i p f 0 -1 0 _null_ _null_ )); #define LANGUAGE_HANDLEROID 2280 ! DATA(insert OID = 2281 ( internal PGNSP PGUID 4 t p t \054 0 0 0 internal_in internal_out - - - - - i p f 0 -10 _null_ _null_ )); #define INTERNALOID 2281 ! DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0_null_ _null_ )); #define OPAQUEOID 2282 ! DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f0 -1 0 _null_ _null_ )); #define ANYELEMENTOID 2283 ! 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,621 **** */ extern Oid TypeShellMake(const char *typeName, Oid typeNamespace); ! extern Oid TypeCreate(const char *typeName, ! Oid typeNamespace, ! Oid relationOid, ! char relationKind, ! int16 internalSize, ! char typeType, ! char typDelim, ! Oid inputProcedure, ! Oid outputProcedure, ! Oid receiveProcedure, ! Oid sendProcedure, ! Oid typmodinProcedure, ! Oid typmodoutProcedure, ! Oid analyzeProcedure, ! Oid elementType, ! Oid baseType, ! const char *defaultTypeValue, ! char *defaultTypeBin, ! bool passedByValue, ! char alignment, ! char storage, ! int32 typeMod, ! int32 typNDims, ! bool typeNotNull); extern void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, --- 596,629 ---- */ extern Oid TypeShellMake(const char *typeName, Oid typeNamespace); ! extern Oid TypeCreate( ! const char *typeName, ! Oid typeNamespace, ! Oid relationOid, ! char relationKind, ! int16 internalSize, ! char typeType, ! char typDelim, ! Oid inputProcedure, ! Oid outputProcedure, ! Oid receiveProcedure, ! Oid sendProcedure, ! Oid typmodinProcedure, ! Oid typmodoutProcedure, ! Oid analyzeProcedure, ! Oid elementType, ! Oid baseType, ! const char *defaultTypeValue, ! char *defaultTypeBin, ! bool passedByValue, ! char alignment, ! char storage, ! int32 typeMod, ! int32 typNDims, ! bool typeNotNull, ! Oid arrayType, ! bool is_array_type ! ); extern void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, *************** *** 637,642 **** extern void TypeRename(const char *oldTypeName, Oid typeNamespace, const char *newTypeName); ! extern char *makeArrayTypeName(const char *typeName); #endif /* PG_TYPE_H */ --- 645,650 ---- extern void TypeRename(const char *oldTypeName, Oid typeNamespace, const char *newTypeName); ! extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace); #endif /* PG_TYPE_H */ Index: src/test/regress/expected/alter_table.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/alter_table.out,v retrieving revision 1.101 diff -c -r1.101 alter_table.out *** src/test/regress/expected/alter_table.out 14 Feb 2007 01:58:58 -0000 1.101 --- src/test/regress/expected/alter_table.out 9 May 2007 00:38:27 -0000 *************** *** 1456,1468 **** --- 1456,1471 ---- -- clean up drop schema alter2 cascade; + NOTICE: drop cascades to type alter2.ctype[] 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) + NOTICE: drop cascades to type alter2.v1[] NOTICE: drop cascades to view alter2.v1 NOTICE: drop cascades to rule _RETURN on view alter2.v1 NOTICE: drop cascades to sequence alter2.t1_f1_seq NOTICE: drop cascades to default for table alter2.t1 column f1 + NOTICE: drop cascades to type alter2.t1[] NOTICE: drop cascades to table alter2.t1 NOTICE: drop cascades to constraint t1_f2_check on table alter2.t1 Index: src/test/regress/expected/type_sanity.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/type_sanity.out,v retrieving revision 1.29 diff -c -r1.29 type_sanity.out *** src/test/regress/expected/type_sanity.out 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/expected/type_sanity.out 9 May 2007 00:38:28 -0000 *************** *** 49,55 **** -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- --- 49,55 ---- -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- *************** *** 69,74 **** --- 69,84 ---- 705 | unknown (2 rows) + -- Make sure typarray points to a varlena array type of our own base + SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, + p2.typelem, p2.typlen + FROM pg_type p1 left join pg_type p2 on (p1.typarray = p2.oid) + WHERE p1.typarray <> 0 AND + (p2.oid IS NULL OR p2.typelem <> p1.oid OR p2.typlen <> -1); + oid | basetype | arraytype | typelem | typlen + -----+----------+-----------+---------+-------- + (0 rows) + -- Text conversion routines must be provided. SELECT p1.oid, p1.typname FROM pg_type as p1 Index: src/test/regress/sql/type_sanity.sql =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/sql/type_sanity.sql,v retrieving revision 1.29 diff -c -r1.29 type_sanity.sql *** src/test/regress/sql/type_sanity.sql 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/sql/type_sanity.sql 9 May 2007 00:38:28 -0000 *************** *** 46,52 **** SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type. --- 46,52 ---- SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type. *************** *** 59,64 **** --- 59,71 ---- 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
>> >> Attached is my rework of David Fetter's array of composites patch. It >> has all the agreed modifications and checks, except altering the name >> mangling. >> >> > > Here is the latest with the name mangling piece done - it's got quite > large with the catalog rewrite :-) > > It could do with some extra eyeballs - especially the error codes. > > I'm not sure if we need to adjust the test in pg_dump.c - maybe we > should look at using the same test as the backend (typlen == -1) to > disambiguate real arrays from subscriptable base types. > The attached version removes all the places we had NAMEDATALEN - 2 restrictions on object names. If there's no objection I will commit this shortly, as I think it now does all the previously agreed things. cheers andrew Index: doc/src/sgml/array.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/array.sgml,v retrieving revision 1.60 diff -c -r1.60 array.sgml *** doc/src/sgml/array.sgml 6 Apr 2007 19:22:38 -0000 1.60 --- doc/src/sgml/array.sgml 9 May 2007 22:56:01 -0000 *************** *** 11,17 **** <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.) </para> <sect2> --- 11,18 ---- <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 are now supported. Arrays of domains are ! not yet supported. </para> <sect2> Index: src/backend/catalog/heap.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/heap.c,v retrieving revision 1.318 diff -c -r1.318 heap.c *** src/backend/catalog/heap.c 2 Apr 2007 03:49:37 -0000 1.318 --- src/backend/catalog/heap.c 9 May 2007 22:56:03 -0000 *************** *** 45,50 **** --- 45,51 ---- #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,75 **** static Oid AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! char new_rel_kind); static void RelationRemoveInheritance(Oid relid); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreConstraints(Relation rel, TupleDesc tupdesc); --- 70,78 ---- static Oid AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! 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); *************** *** 402,417 **** 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) 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 */ --- 405,444 ---- char att_typtype = get_typtype(atttypid); /* ! * For a composite type, recurse into its attributes. Otherwise, * ! * a) warn user, but don't fail, if column to be created has UNKNOWN type ! * (usually as a result of a 'retrieve into' - jolly) ! * ! * b) Refuse any attempt to create a pseudo-type column, except for ! * pg_statistic hack. */ ! if (att_typtype == TYPTYPE_COMPOSITE) ! { ! Relation relation; ! TupleDesc tupdesc; ! int i; ! ! relation = RelationIdGetRelation(get_typ_typrelid(atttypid)); ! ! tupdesc = RelationGetDescr(relation); ! ! for (i = 0; i < tupdesc->natts; i++) ! { ! if (tupdesc->attrs[i]->attisdropped) ! continue; ! CheckAttributeType(attname, tupdesc->attrs[i]->atttypid); ! } ! ! RelationClose(relation); ! } ! else if (atttypid == UNKNOWNOID) ! { 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 */ *************** *** 710,716 **** AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! char new_rel_kind) { return TypeCreate(typeName, /* type name */ --- 737,744 ---- AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, ! char new_rel_kind, ! Oid new_array_type) { return TypeCreate(typeName, /* type name */ *************** *** 736,742 **** 'x', /* fully TOASTable */ -1, /* typmod */ 0, /* array dimensions for typBaseType */ ! false); /* Type NOT NULL */ } /* -------------------------------- --- 764,773 ---- 'x', /* fully TOASTable */ -1, /* typmod */ 0, /* array dimensions for typBaseType */ ! false, /* Type NOT NULL */ ! new_array_type, /* oid of type we are about to make */ ! false /* no this is not an array type */ ! ); } /* -------------------------------- *************** *** 763,768 **** --- 794,801 ---- Relation pg_class_desc; Relation new_rel_desc; Oid new_type_oid; + Oid new_array_oid = InvalidOid; + pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock); *************** *** 804,809 **** --- 837,853 ---- Assert(relid == RelationGetRelid(new_rel_desc)); + /* Get an oid for the array type of necessary */ + if (IsUnderPostmaster && (relkind == RELKIND_RELATION || + relkind == RELKIND_VIEW || + relkind == RELKIND_COMPOSITE_TYPE)) + { + Relation pg_type = heap_open(TypeRelationId, RowExclusiveLock); + new_array_oid = GetNewOid(pg_type); + heap_close(pg_type, RowExclusiveLock); + } + + /* * since defining a relation also defines a complex type, we add a new * system type corresponding to the new relation. *************** *** 814,820 **** new_type_oid = AddNewRelationType(relname, relnamespace, relid, ! relkind); /* * now create an entry in pg_class for the relation. --- 858,906 ---- new_type_oid = AddNewRelationType(relname, relnamespace, relid, ! relkind, ! new_array_oid); ! /* ! * Add in the corresponding array types if appropriate. ! */ ! if (IsUnderPostmaster && (relkind == RELKIND_RELATION || ! relkind == RELKIND_VIEW || ! relkind == RELKIND_COMPOSITE_TYPE)) ! { ! char *relarrayname; ! ! relarrayname = makeArrayTypeName(relname, relnamespace); ! ! TypeCreate(relarrayname, /* Array type name */ ! relnamespace, /* Same namespace as parent */ ! InvalidOid, /* Not composite, no relationOid */ ! 0, /* relkind, also N/A here */ ! -1, /* Internal size, unlimited */ ! TYPTYPE_BASE, /* Not composite - typelem is */ ! DEFAULT_TYPDELIM, /* Use the default */ ! 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, /* No input typmod */ ! InvalidOid, /* No output typmod */ ! InvalidOid, /* Default ANALYZE procedure */ ! new_type_oid, /* The OID just created */ ! InvalidOid, /* No base type--not a DOMAIN */ ! NULL, /* No default type value */ ! NULL, /* Don't send binary */ ! false, /* Never passed by value */ ! 'd', /* Type align. Max for safety */ ! 'x', /* Always TOASTable */ ! -1, /* No typMod for non-domain */ ! 0, /* Array dims of typbasetype */ ! false, /* Type NOT NULL */ ! new_array_oid, /* oid of this type entry */ ! true /* yes, this is an array type */ ! ); ! ! pfree(relarrayname); ! } /* * now create an entry in pg_class for the relation. *************** *** 887,893 **** */ heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(pg_class_desc, RowExclusiveLock); ! return relid; } --- 973,979 ---- */ heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(pg_class_desc, RowExclusiveLock); ! return relid; } Index: src/backend/catalog/pg_type.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v retrieving revision 1.111 diff -c -r1.111 pg_type.c *** src/backend/catalog/pg_type.c 2 Apr 2007 03:49:37 -0000 1.111 --- src/backend/catalog/pg_type.c 9 May 2007 22:56:03 -0000 *************** *** 90,95 **** --- 90,96 ---- 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 */ *************** *** 180,186 **** char storage, int32 typeMod, int32 typNDims, /* Array dimensions for baseType */ ! bool typeNotNull) { Relation pg_type_desc; Oid typeObjectId; --- 181,190 ---- char storage, int32 typeMod, int32 typNDims, /* Array dimensions for baseType */ ! bool typeNotNull, ! Oid arrayType, ! bool is_array_type ! ) { Relation pg_type_desc; Oid typeObjectId; *************** *** 246,251 **** --- 250,257 ---- values[i++] = ObjectIdGetDatum(typeType == TYPTYPE_COMPOSITE ? relationOid : InvalidOid); /* typrelid */ values[i++] = ObjectIdGetDatum(elementType); /* typelem */ + values[i++] = ObjectIdGetDatum(is_array_type ? + InvalidOid : arrayType); /* typarray */ values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */ values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */ values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */ *************** *** 331,336 **** --- 337,347 ---- values, nulls); + /* should only happen if it's not a shell type */ + if (is_array_type) + HeapTupleSetOid(tup, arrayType); + + typeObjectId = simple_heap_insert(pg_type_desc, tup); } *************** *** 571,590 **** } /* * makeArrayTypeName(typeName); * - given a base type name, make an array of type name out of it * * the caller is responsible for pfreeing the result */ char * ! makeArrayTypeName(const char *typeName) { char *arr; if (!typeName) return NULL; arr = palloc(NAMEDATALEN); ! snprintf(arr, NAMEDATALEN, ! "_%.*s", NAMEDATALEN - 2, typeName); return arr; } --- 582,660 ---- } /* + * find the mb-safe substring length that is not greater than max + */ + static int + mb_substr_len(char * str, int max) + { + int result = 0; + char * crsr = str; + int len = strlen(str); + + if (max > len) + max = len; + + if (pg_database_encoding_max_length() == 1) + return max; + if (crsr == NULL) + return 0; + while (*crsr) + { + len = pg_mblen(crsr); + if (result + len > max) + break; + result += len; + crsr += len; + } + return result; + } + + + + /* * makeArrayTypeName(typeName); * - given a base type name, make an array of type name out of it * * the caller is responsible for pfreeing the result */ char * ! makeArrayTypeName(const char *typeName, Oid typeNamespace) { char *arr; + int i, safelen; + bool found = false; + Relation pg_type_desc; + + pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); + if (!typeName) return NULL; + arr = palloc(NAMEDATALEN); ! ! for (i = 1; i < NAMEDATALEN / 2; i++) ! { ! arr[i - 1] = '_'; ! safelen = mb_substr_len(typeName, NAMEDATALEN - (i + 1)); ! snprintf(arr+i, NAMEDATALEN - 1, "%.*s", safelen, typeName); ! if (SearchSysCacheExists(TYPENAMENSP, ! CStringGetDatum(arr), ! ObjectIdGetDatum(typeNamespace), ! 0, 0)) ! continue; ! found = true; ! break; ! } ! ! heap_close(pg_type_desc, RowExclusiveLock); ! ! if (! found) ! ereport(ERROR, ! (errcode(ERRCODE_DUPLICATE_OBJECT), ! errmsg("could not form array type name for type \"%s\"", ! typeName))); ! ! return arr; } Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.219 diff -c -r1.219 tablecmds.c *** src/backend/commands/tablecmds.c 8 Apr 2007 01:26:32 -0000 1.219 --- src/backend/commands/tablecmds.c 9 May 2007 22:56:08 -0000 *************** *** 287,296 **** Datum reloptions; ListCell *listptr; AttrNumber attnum; /* ! * Truncate relname to appropriate length (probably a waste of time, as ! * parser should have done this already). */ StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); --- 287,297 ---- Datum reloptions; ListCell *listptr; AttrNumber attnum; + char *relarrayname; /* ! * Truncate relname to appropriate length (probably a waste of time, as * ! * parser should have done this already). */ StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); *************** *** 6461,6468 **** AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's rowtype too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) --- 6462,6470 ---- AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's types too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); + AlterTypeNamespaceInternal(get_array_type(rel->rd_rel->reltype), nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) Index: src/backend/commands/typecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.101 diff -c -r1.101 typecmds.c *** src/backend/commands/typecmds.c 2 Apr 2007 03:49:38 -0000 1.101 --- src/backend/commands/typecmds.c 9 May 2007 22:56:09 -0000 *************** *** 34,39 **** --- 34,40 ---- #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" *************** *** 119,127 **** --- 120,130 ---- Oid typmodoutOid = InvalidOid; Oid analyzeOid = InvalidOid; char *shadow_type; + Oid shadow_oid; ListCell *pl; Oid typoid; Oid resulttype; + Relation pg_type; /* Convert list of names to a name and namespace */ typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName); *************** *** 133,148 **** 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. --- 136,141 ---- *************** *** 396,401 **** --- 389,398 ---- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(analyzeName)); + pg_type = heap_open(TypeRelationId, RowExclusiveLock); + shadow_oid = GetNewOid(pg_type); + heap_close(pg_type, RowExclusiveLock); + /* * now have TypeCreate do all the real work. */ *************** *** 423,465 **** storage, /* TOAST strategy */ -1, /* typMod (Domains only) */ 0, /* Array Dimensions of typbasetype */ ! 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. */ ! shadow_type = makeArrayTypeName(typeName); /* alignment must be 'i' or 'd' for arrays */ alignment = (alignment == 'd') ? 'd' : 'i'; ! TypeCreate(shadow_type, /* type name */ ! typeNamespace, /* namespace */ ! InvalidOid, /* relation oid (n/a here) */ ! 0, /* relation kind (ditto) */ ! -1, /* internal size */ ! TYPTYPE_BASE, /* type-type (base type) */ ! DEFAULT_TYPDELIM, /* array element delimiter */ ! F_ARRAY_IN, /* input procedure */ ! F_ARRAY_OUT, /* output procedure */ ! F_ARRAY_RECV, /* receive procedure */ ! F_ARRAY_SEND, /* send procedure */ ! typmodinOid, /* typmodin procedure */ ! typmodoutOid, /* typmodout procedure */ ! InvalidOid, /* analyze procedure - default */ ! typoid, /* element type ID */ ! InvalidOid, /* base type ID */ ! NULL, /* never a default type value */ ! NULL, /* binary default isn't sent either */ ! false, /* never passed by value */ ! alignment, /* see above */ ! 'x', /* ARRAY is always toastable */ ! -1, /* typMod (Domains only) */ ! 0, /* Array dimensions of typbasetype */ ! false); /* Type NOT NULL */ pfree(shadow_type); } --- 420,469 ---- storage, /* TOAST strategy */ -1, /* typMod (Domains only) */ 0, /* Array Dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! shadow_oid, /* array type we are about to create */ ! false /* this is not an array type */ ! ); /* * 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. */ ! shadow_type = makeArrayTypeName(typeName, typeNamespace); /* alignment must be 'i' or 'd' for arrays */ alignment = (alignment == 'd') ? 'd' : 'i'; ! TypeCreate(shadow_type, /* type name */ ! typeNamespace, /* namespace */ ! InvalidOid, /* relation oid (n/a here) */ ! 0, /* relation kind (ditto) */ ! -1, /* internal size */ ! TYPTYPE_BASE, /* type-type (base type) */ ! DEFAULT_TYPDELIM, /* array element delimiter */ ! F_ARRAY_IN, /* input procedure */ ! F_ARRAY_OUT, /* output procedure */ ! F_ARRAY_RECV, /* receive procedure */ ! F_ARRAY_SEND, /* send procedure */ ! typmodinOid, /* typmodin procedure */ ! typmodoutOid, /* typmodout procedure */ ! InvalidOid, /* analyze procedure - default */ ! typoid, /* element type ID */ ! InvalidOid, /* base type ID */ ! NULL, /* never a default type value */ ! NULL, /* binary default isn't sent either */ ! false, /* never passed by value */ ! alignment, /* see above */ ! 'x', /* ARRAY is always toastable */ ! -1, /* typMod (Domains only) */ ! 0, /* Array dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! shadow_oid, /* oid for this entry */ ! true /* yes this is an array type */ ! ); pfree(shadow_type); + } *************** *** 474,479 **** --- 478,484 ---- Oid typeoid; HeapTuple tup; ObjectAddress object; + Form_pg_type typ; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); *************** *** 505,513 **** if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typeoid); /* Permission check: must own type or its namespace */ if (!pg_type_ownercheck(typeoid, GetUserId()) && ! !pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, TypeNameToString(typename)); --- 510,528 ---- if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typeoid); + typ = (Form_pg_type) GETSTRUCT(tup); + + /* don't alow direct deletion of array types */ + if (typ->typelem != 0 && typ->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot delete array type \"%s\" ", + TypeNameToString(typename)))); + + /* Permission check: must own type or its namespace */ if (!pg_type_ownercheck(typeoid, GetUserId()) && ! !pg_namespace_ownercheck(typ->typnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, TypeNameToString(typename)); *************** *** 545,551 **** simple_heap_delete(relation, &tup->t_self); /* ! * If it is an enum, delete the pg_enum entries too; we don't bother * with making dependency entries for those, so it has to be done * "by hand" here. */ --- 560,566 ---- simple_heap_delete(relation, &tup->t_self); /* ! * If it is an enum delete the pg_enum entries too; we don't bother * with making dependency entries for those, so it has to be done * "by hand" here. */ *************** *** 608,626 **** 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); --- 623,628 ---- *************** *** 828,835 **** storage, /* TOAST strategy */ basetypeMod, /* typeMod value */ typNDims, /* Array dimensions for base type */ ! typNotNull); /* Type NOT NULL */ ! /* * Process constraints which refer to the domain ID returned by TypeCreate */ --- 830,839 ---- storage, /* TOAST strategy */ basetypeMod, /* typeMod value */ typNDims, /* Array dimensions for base type */ ! typNotNull, /* Type NOT NULL */ ! InvalidOid, /* no arrays for domains */ ! false /* this isn't an array */ ! ); /* * Process constraints which refer to the domain ID returned by TypeCreate */ *************** *** 949,954 **** --- 953,960 ---- 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,974 **** 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))); /* Create the pg_type entry */ enumTypeOid = --- 966,974 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(enumNamespace)); ! pg_type = heap_open(TypeRelationId, RowExclusiveLock); ! enumArrayOid = GetNewOid(pg_type); ! heap_close(pg_type, RowExclusiveLock); /* Create the pg_type entry */ enumTypeOid = *************** *** 995,1007 **** 'p', /* TOAST strategy always plain */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false); /* Type NOT NULL */ /* Enter the enum's values into pg_enum */ EnumValuesCreate(enumTypeOid, stmt->vals); /* Create array type for enum */ ! enumArrayName = makeArrayTypeName(enumName); TypeCreate(enumArrayName, /* type name */ enumNamespace, /* namespace */ --- 995,1010 ---- 'p', /* TOAST strategy always plain */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! enumArrayOid, /* oid of entry we are about to create */ ! false /* this is not an array */ ! ); /* Enter the enum's values into pg_enum */ EnumValuesCreate(enumTypeOid, stmt->vals); /* Create array type for enum */ ! enumArrayName = makeArrayTypeName(enumName, enumNamespace); TypeCreate(enumArrayName, /* type name */ enumNamespace, /* namespace */ *************** *** 1026,1032 **** 'x', /* ARRAY is always toastable */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false); /* Type NOT NULL */ pfree(enumArrayName); } --- 1029,1038 ---- 'x', /* ARRAY is always toastable */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ ! false, /* Type NOT NULL */ ! enumArrayOid, /* oid to use for this entry */ ! true /* this is an array */ ! ); pfree(enumArrayName); } *************** *** 2249,2254 **** --- 2255,2268 ---- elog(ERROR, "cache lookup failed for type %u", typeOid); typTup = (Form_pg_type) GETSTRUCT(tup); + /* don't allow direct alteration of array types */ + if (typTup->typelem != 0 && typTup->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot alter array type \"%s\" ", + TypeNameToString(typename)))); + + /* * 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 *************** *** 2352,2357 **** --- 2366,2374 ---- TypeName *typename; Oid typeOid; Oid nspOid; + Relation rel; + HeapTuple tup; + Form_pg_type typ; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); *************** *** 2365,2372 **** --- 2382,2415 ---- /* get schema OID and check its permissions */ nspOid = LookupCreationNamespace(newschema); + /* don't allow direct alteration of array types */ + + rel = heap_open(TypeRelationId, RowExclusiveLock); + + tup = SearchSysCacheCopy(TYPEOID, + ObjectIdGetDatum(typeOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", typeOid); + + typ = (Form_pg_type) GETSTRUCT(tup); + + if (typ->typelem != 0 && typ->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot alter array type \"%s\" ", + TypeNameToString(typename)))); + + + heap_freetuple(tup); + + heap_close(rel, RowExclusiveLock); + /* and do the work */ AlterTypeNamespaceInternal(typeOid, nspOid, true); + typeOid = get_array_type(typeOid); + if (typeOid != InvalidOid) + AlterTypeNamespaceInternal(typeOid, nspOid, true); } /* *************** *** 2431,2442 **** /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", --- 2474,2485 ---- /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && typform->typrelid != InvalidOid && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! typform->typrelid != InvalidOid && errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", *************** *** 2457,2463 **** * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType) { Relation classRel; --- 2500,2506 ---- * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType && typform->typrelid != InvalidOid) { Relation classRel; *************** *** 2490,2496 **** * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", --- 2533,2539 ---- * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE || typform->typrelid == InvalidOid) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", Index: src/backend/parser/parse_type.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/parser/parse_type.c,v retrieving revision 1.89 diff -c -r1.89 parse_type.c *** src/backend/parser/parse_type.c 27 Apr 2007 22:05:48 -0000 1.89 --- src/backend/parser/parse_type.c 9 May 2007 22:56:10 -0000 *************** *** 116,125 **** /* 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 */ --- 116,121 ---- *************** *** 136,141 **** --- 132,142 ---- /* Unqualified type name, so search the search path */ restype = TypenameGetTypid(typname); } + + /* If an array reference, return the array type instead */ + if (typename->arrayBounds != NIL) + restype = get_array_type(restype); + } return restype; Index: src/backend/utils/cache/lsyscache.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v retrieving revision 1.151 diff -c -r1.151 lsyscache.c *** src/backend/utils/cache/lsyscache.c 2 Apr 2007 03:49:39 -0000 1.151 --- src/backend/utils/cache/lsyscache.c 9 May 2007 22:56:12 -0000 *************** *** 2206,2252 **** * Given the type OID, get the corresponding 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; 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; 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; } /* --- 2206,2227 ---- * Given the type OID, get the corresponding array type. * Returns InvalidOid if no array type can be found. * */ Oid get_array_type(Oid typid) { HeapTuple tp; + Oid result = InvalidOid; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { ! result = ((Form_pg_type) GETSTRUCT(tp))->typarray; ReleaseSysCache(tp); } ! return result; } /* Index: src/include/catalog/catversion.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/catversion.h,v retrieving revision 1.404 diff -c -r1.404 catversion.h *** src/include/catalog/catversion.h 15 Apr 2007 10:56:27 -0000 1.404 --- src/include/catalog/catversion.h 9 May 2007 22:56:13 -0000 *************** *** 53,58 **** */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200704151 #endif --- 53,58 ---- */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200705061 #endif Index: src/include/catalog/pg_attribute.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_attribute.h,v retrieving revision 1.130 diff -c -r1.130 pg_attribute.h *** src/include/catalog/pg_attribute.h 22 Jan 2007 01:35:21 -0000 1.130 --- src/include/catalog/pg_attribute.h 9 May 2007 22:56:13 -0000 *************** *** 232,252 **** { 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 } 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)); --- 232,253 ---- { 1247, {"typdelim"}, 18, -1, 1, 8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1247, {"typrelid"}, 26, -1, 4, 9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typelem"}, 26, -1, 4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typarray"}, 26, -1, 4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typinput"}, 24, -1, 4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typoutput"}, 24, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typreceive"}, 24, -1, 4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typsend"}, 24, -1, 4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typmodin"}, 24, -1, 4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typmodout"}, 24, -1, 4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typanalyze"}, 24, -1, 4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typalign"}, 18, -1, 1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ ! { 1247, {"typstorage"}, 18, -1, 1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ ! { 1247, {"typnotnull"}, 16, -1, 1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ ! { 1247, {"typbasetype"}, 26, -1, 4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typtypmod"}, 23, -1, 4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typndims"}, 23, -1, 4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ ! { 1247, {"typdefaultbin"}, 25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \ ! { 1247, {"typdefault"}, 25, -1, -1, 26, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 } 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,278 **** 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 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)); --- 259,280 ---- DATA(insert ( 1247 typdelim 18 -1 1 8 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1247 typrelid 26 -1 4 9 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typelem 26 -1 4 10 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typarray 26 -1 4 11 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typinput 24 -1 4 12 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typoutput 24 -1 4 13 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typreceive 24 -1 4 14 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typsend 24 -1 4 15 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typmodin 24 -1 4 16 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typmodout 24 -1 4 17 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typanalyze 24 -1 4 18 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typalign 18 -1 1 19 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1247 typstorage 18 -1 1 20 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1247 typnotnull 16 -1 1 21 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1247 typbasetype 26 -1 4 22 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typtypmod 23 -1 4 23 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typndims 23 -1 4 24 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1247 typdefaultbin 25 -1 -1 25 0 -1 -1 f x i f f f t 0)); ! DATA(insert ( 1247 typdefault 25 -1 -1 26 0 -1 -1 f x i f f f t 0)); DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0)); DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0)); Index: src/include/catalog/pg_class.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_class.h,v retrieving revision 1.100 diff -c -r1.100 pg_class.h *** src/include/catalog/pg_class.h 22 Jan 2007 01:35:22 -0000 1.100 --- src/include/catalog/pg_class.h 9 May 2007 22:56:13 -0000 *************** *** 132,138 **** */ /* 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_ )); 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(""); --- 132,138 ---- */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ ! DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 26 0 0 0 0 0 t f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ )); DESCR(""); Index: src/include/catalog/pg_type.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_type.h,v retrieving revision 1.182 diff -c -r1.182 pg_type.h *** src/include/catalog/pg_type.h 6 Apr 2007 04:21:43 -0000 1.182 --- src/include/catalog/pg_type.h 9 May 2007 22:56:14 -0000 *************** *** 97,102 **** --- 97,105 ---- */ Oid typelem; + /* Oid of array type, or 0 if it does not exist */ + Oid typarray; + /* * I/O conversion procedures for the datatype. */ *************** *** 214,220 **** * compiler constants for pg_type * ---------------- */ ! #define Natts_pg_type 25 #define Anum_pg_type_typname 1 #define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typowner 3 --- 217,223 ---- * compiler constants for pg_type * ---------------- */ ! #define Natts_pg_type 26 #define Anum_pg_type_typname 1 #define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typowner 3 *************** *** 225,245 **** #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 /* ---------------- --- 228,249 ---- #define Anum_pg_type_typdelim 8 #define Anum_pg_type_typrelid 9 #define Anum_pg_type_typelem 10 ! #define Anum_pg_type_typarray 11 ! #define Anum_pg_type_typinput 12 ! #define Anum_pg_type_typoutput 13 ! #define Anum_pg_type_typreceive 14 ! #define Anum_pg_type_typsend 15 ! #define Anum_pg_type_typmodin 16 ! #define Anum_pg_type_typmodout 17 ! #define Anum_pg_type_typanalyze 18 ! #define Anum_pg_type_typalign 19 ! #define Anum_pg_type_typstorage 20 ! #define Anum_pg_type_typnotnull 21 ! #define Anum_pg_type_typbasetype 22 ! #define Anum_pg_type_typtypmod 23 ! #define Anum_pg_type_typndims 24 ! #define Anum_pg_type_typdefaultbin 25 ! #define Anum_pg_type_typdefault 26 /* ---------------- *************** *** 255,340 **** */ /* 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_ )); 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 f0 -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_ )); 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 pf 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_ )); 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_ )); 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_ )); 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_ )); 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_ )); 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 -10 _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_ )); 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_ )); 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_ )); 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_ )); 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_ )); 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_ )); #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_ )); #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_ )); #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_ )); #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_ )); 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 f0 -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_ )); DESCR("storage manager"); /* OIDS 300 - 399 */ --- 259,344 ---- */ /* OIDS 1 - 99 */ ! DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 1000 boolin boolout boolrecv boolsend - - - cp f 0 -1 0 _null_ _null_ )); DESCR("boolean, 'true'/'false'"); #define BOOLOID 16 ! DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 1001 byteain byteaout bytearecv byteasend - - -i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length string, binary values escaped"); #define BYTEAOID 17 ! DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 1002 charin charout charrecv charsend - - - cp f 0 -1 0 _null_ _null_ )); DESCR("single character"); #define CHAROID 18 ! DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 1003 namein nameout namerecv namesend - -- 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 1016 int8in int8out int8recv int8send - - - dp f 0 -1 0 _null_ _null_ )); DESCR("~18 digit integer, 8-byte storage"); #define INT8OID 20 ! DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 1005 int2in int2out int2recv int2send - - - sp f 0 -1 0 _null_ _null_ )); DESCR("-32 thousand to 32 thousand, 2-byte storage"); #define INT2OID 21 ! DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b t \054 0 21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("array of int2, used in system tables"); #define INT2VECTOROID 22 ! DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 1007 int4in int4out int4recv int4send - - - ip f 0 -1 0 _null_ _null_ )); DESCR("-2 billion to 2 billion integer, 4-byte storage"); #define INT4OID 23 ! DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 1008 regprocin regprocout regprocrecv regprocsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered procedure"); #define REGPROCOID 24 ! DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 1009 textin textout textrecv textsend - - - i x f0 -1 0 _null_ _null_ )); DESCR("variable-length string, no limit specified"); #define TEXTOID 25 ! DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 1028 oidin oidout oidrecv oidsend - - - i pf 0 -1 0 _null_ _null_ )); DESCR("object identifier(oid), maximum 4 billion"); #define OIDOID 26 ! DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b t \054 0 0 1010 tidin tidout tidrecv tidsend - - - s pf 0 -1 0 _null_ _null_ )); DESCR("(Block, offset), physical location of tuple"); #define TIDOID 27 ! DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b t \054 0 0 1011 xidin xidout xidrecv xidsend - - - i pf 0 -1 0 _null_ _null_ )); DESCR("transaction id"); #define XIDOID 28 ! DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 1012 cidin cidout cidrecv cidsend - - - i pf 0 -1 0 _null_ _null_ )); DESCR("command identifier type, sequence in transaction id"); #define CIDOID 29 ! DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b t \054 0 26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("array of oids, used in system tables"); #define OIDVECTOROID 30 /* hand-built rowtype entries for bootstrapped catalogs: */ ! DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c t \054 1247 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_TYPE_RELTYPE_OID 71 ! DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c t \054 1249 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_ATTRIBUTE_RELTYPE_OID 75 ! DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c t \054 1255 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_PROC_RELTYPE_OID 81 ! DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c t \054 1259 0 0 record_in record_out record_recv record_send- - - d x f 0 -1 0 _null_ _null_ )); #define PG_CLASS_RELTYPE_OID 83 /* OIDS 100 - 199 */ ! DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0-1 0 _null_ _null_ )); DESCR("XML content"); #define XMLOID 142 ! DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b t \054 0 142 0 array_in array_out array_recv array_send - - - i xf 0 -1 0 _null_ _null_ )); /* OIDS 200 - 299 */ ! DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_)); DESCR("storage manager"); /* OIDS 300 - 399 */ *************** *** 344,543 **** /* 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 pf 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_ )); 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 -10 _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_ )); 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_ )); 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_ )); 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_ )); DESCR(""); /* OIDS 700 - 799 */ ! DATA(insert OID = 700 ( float4 PGNSP PGUID 4 f b t \054 0 0 float4in float4out float4recv float4send - - - ip 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 - - - dp 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_ )); 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_ )); 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_ )); 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_ )); 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_ )); 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 - - - dx 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 f0 -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 - - - dx 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_ )); 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_ )); 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_ )); 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 - - - ix f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); #define INT4ARRAYOID 1007 ! DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 array_in array_out array_recv array_send - - - ix 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 bpchartypmodinbpchartypmodout - 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 varchartypmodinvarchartypmodout - 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 xf 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 - - - dx 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 - - - ix 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 - - - dx 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 - - - ix 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 - - - ix 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 xf 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 - - - dx 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_ )); 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 - - - ix 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 - - - ix f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b t \054 0 0 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodinbpchartypmodout - 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 varchartypmodinvarchartypmodout - 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 pf 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 timetypmodintimetypmodout - 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_sendtimestamptypmodin 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 timestamptypmodintimestamptypmodout - 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 timetypmodintimetypmodout - 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_recvtimestamptz_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 timestamptztypmodintimestamptztypmodout - 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_sendintervaltypmodin 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 intervaltypmodinintervaltypmodout - 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 numerictypmodinnumerictypmodout - 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 timetztypmodintimetztypmodout - 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 timetztypmodintimetztypmodout - 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_ )); 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 bittypmodinbittypmodout - 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 varbittypmodinvarbittypmodout - 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 varbittypmodinvarbittypmodout - 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_sendnumerictypmodin 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 f0 -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 = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 regprocedurein regprocedureout regprocedurerecvregproceduresend - - - 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_ )); DESCR("registered operator"); #define REGOPEROID 2203 ! DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 regoperatorin regoperatorout regoperatorrecvregoperatorsend - - - 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_ )); 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_ )); 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_ )); #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 f0 -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_ )); /* * pseudo-types --- 348,547 ---- /* OIDS 500 - 599 */ /* OIDS 600 - 699 */ ! DATA(insert OID = 600 ( point PGNSP PGUID 16 f b t \054 0 701 1017 point_in point_out point_recv point_send - -- d p f 0 -1 0 _null_ _null_ )); DESCR("geometric point '(x, y)'"); #define POINTOID 600 ! DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d pf 0 -1 0 _null_ _null_ )); DESCR("geometric line segment '(pt1,pt2)'"); #define LSEGOID 601 ! DATA(insert OID = 602 ( path PGNSP PGUID -1 f b t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f0 -1 0 _null_ _null_ )); DESCR("geometric path '(pt1,...)'"); #define PATHOID 602 ! DATA(insert OID = 603 ( box PGNSP PGUID 32 f b t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0-1 0 _null_ _null_ )); DESCR("geometric box '(lower left,upper right)'"); #define BOXOID 603 ! DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b t \054 0 0 1027 poly_in poly_out poly_recv poly_send - - - dx f 0 -1 0 _null_ _null_ )); DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 ! DATA(insert OID = 628 ( line PGNSP PGUID 32 f b t \054 0 701 629 line_in line_out line_recv line_send - - - d pf 0 -1 0 _null_ _null_ )); DESCR("geometric line (not implemented)'"); #define LINEOID 628 ! DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b t \054 0 628 0 array_in array_out array_recv array_send - -- d x f 0 -1 0 _null_ _null_ )); DESCR(""); /* OIDS 700 - 799 */ ! 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 1022 float8in float8out float8recv float8send -- - d p f 0 -1 0 _null_ _null_ )); DESCR("double-precision floating point number, 8-byte storage"); #define FLOAT8OID 701 ! DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b t \054 0 0 1023 abstimein abstimeout abstimerecv abstimesend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("absolute, limited-range date and time (Unix system time)"); #define ABSTIMEOID 702 ! DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b t \054 0 0 1024 reltimein reltimeout reltimerecv reltimesend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("relative, limited-range time interval (Unix delta time)"); #define RELTIMEOID 703 ! DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 1025 tintervalin tintervalout tintervalrecv tintervalsend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("(abstime,abstime), time interval"); #define TINTERVALOID 704 ! DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b t \054 0 0 0 unknownin unknownout unknownrecv unknownsend - -- c p f 0 -1 0 _null_ _null_ )); DESCR(""); #define UNKNOWNOID 705 ! DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b t \054 0 0 719 circle_in circle_out circle_recv circle_send -- - d p f 0 -1 0 _null_ _null_ )); DESCR("geometric circle '(center,radius)'"); #define CIRCLEOID 718 ! DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b t \054 0 718 0 array_in array_out array_recv array_send - - -d x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 790 ( money PGNSP PGUID 8 f b t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - dp f 0 -1 0 _null_ _null_ )); DESCR("monetary amounts, $d,ddd.cc"); #define CASHOID 790 ! DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b t \054 0 790 0 array_in array_out array_recv array_send - - -d x f 0 -1 0 _null_ _null_ )); /* OIDS 800 - 899 */ ! DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send- - - i p f 0 -1 0 _null_ _null_ )); DESCR("XX:XX:XX:XX:XX:XX, MAC address"); #define MACADDROID 829 ! DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i mf 0 -1 0 _null_ _null_ )); DESCR("IP address/netmask, host address, netmask optional"); #define INETOID 869 ! DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i mf 0 -1 0 _null_ _null_ )); DESCR("network IP address/netmask, network address"); #define CIDROID 650 /* OIDS 900 - 999 */ /* OIDS 1000 - 1099 */ ! DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b t \054 0 16 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 0 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); #define INT4ARRAYOID 1007 ! DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 0 array_in array_out array_recv array_send - - -i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodinbpchartypmodout - 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 varchartypmodinvarchartypmodout - 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 - - - dx 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 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 - - - ix 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 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 bpcharsendbpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("char(length), blank-padded string, fixed storage length"); #define BPCHAROID 1042 ! DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b t \054 0 0 1015 varcharin varcharout varcharrecv varcharsendvarchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("varchar(length), non-blank-padded string, variable storage length"); #define VARCHAROID 1043 ! DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b t \054 0 0 1182 date_in date_out date_recv date_send - -- i p f 0 -1 0 _null_ _null_ )); DESCR("ANSI SQL date"); #define DATEOID 1082 ! DATA(insert OID = 1083 ( time PGNSP PGUID 8 f b t \054 0 0 1183 time_in time_out time_recv time_send timetypmodintimetypmodout - 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 1115 timestamp_in timestamp_out timestamp_recvtimestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("date and time"); #define TIMESTAMPOID 1114 ! DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodintimestamptypmodout - 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 timetypmodintimetypmodout - 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_recvtimestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("date and time with time zone"); #define TIMESTAMPTZOID 1184 ! DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0 1184 0 array_in array_out array_recv array_send timestamptztypmodintimestamptztypmodout - 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_sendintervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("@ <number> <units>, time interval"); #define INTERVALOID 1186 ! DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodinintervaltypmodout - d x f 0 -1 0 _null_ _null_ )); /* OIDS 1200 - 1299 */ ! DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 0 array_in array_out array_recv array_send numerictypmodinnumerictypmodout - 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_sendtimetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ )); DESCR("hh:mm:ss, ANSI SQL time"); #define TIMETZOID 1266 ! DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b t \054 0 1266 0 array_in array_out array_recv array_send timetztypmodintimetztypmodout - d x f 0 -1 0 _null_ _null_ )); /* OIDS 1500 - 1599 */ ! DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 1561 bit_in bit_out bit_recv bit_send bittypmodinbittypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("fixed-length bit string"); #define BITOID 1560 ! DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b t \054 0 1560 0 array_in array_out array_recv array_send bittypmodinbittypmodout - 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_sendvarbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length bit string"); #define VARBITOID 1562 ! DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b t \054 0 1562 0 array_in array_out array_recv array_send varbittypmodinvarbittypmodout - i x f 0 -1 0 _null_ _null_ )); /* OIDS 1600 - 1699 */ /* OIDS 1700 - 1799 */ ! DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 1231 numeric_in numeric_out numeric_recv numeric_sendnumerictypmodin numerictypmodout - i m f 0 -1 0 _null_ _null_ )); DESCR("numeric(precision, decimal), arbitrary precision number"); #define NUMERICOID 1700 ! DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 2201 textin textout textrecv textsend - - - ix f 0 -1 0 _null_ _null_ )); DESCR("reference cursor (portal name)"); #define REFCURSOROID 1790 /* OIDS 2200 - 2299 */ ! DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b t \054 0 1790 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 2207 regprocedurein regprocedureout regprocedurerecvregproceduresend - - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered procedure (with args)"); #define REGPROCEDUREOID 2202 ! DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b t \054 0 0 2208 regoperin regoperout regoperrecv regopersend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered operator"); #define REGOPEROID 2203 ! DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 2209 regoperatorin regoperatorout regoperatorrecvregoperatorsend - - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered operator (with args)"); #define REGOPERATOROID 2204 ! DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b t \054 0 0 2210 regclassin regclassout regclassrecv regclasssend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered class"); #define REGCLASSOID 2205 ! DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b t \054 0 0 2211 regtypein regtypeout regtyperecv regtypesend- - - i p f 0 -1 0 _null_ _null_ )); DESCR("registered type"); #define REGTYPEOID 2206 ! DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); ! DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 0 array_in array_out array_recv array_send - -- i x f 0 -1 0 _null_ _null_ )); #define REGTYPEARRAYOID 2211 /* uuid */ ! DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - -c p f 0 -1 0 _null_ _null_ )); DESCR("UUID datatype"); ! DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b t \054 0 2950 0 array_in array_out array_recv array_send -- - i x f 0 -1 0 _null_ _null_ )); /* * pseudo-types *************** *** 548,574 **** * 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_ )); #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_ )); #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_)); #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_ )); #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_)); #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_ )); #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_ )); #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_ )); #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_ )); #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_ )); #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_ )); #define ANYENUMOID 3500 --- 552,578 ---- * 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 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 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 0 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_)); #define ANYOID 2276 ! DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send- - - d x f 0 -1 0 _null_ _null_ )); #define ANYARRAYOID 2277 ! DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p t \054 0 0 0 void_in void_out - - - - - i p f 0 -1 0 _null__null_ )); #define VOIDOID 2278 ! DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 _null__null_ )); #define TRIGGEROID 2279 ! DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p t \054 0 0 0 language_handler_in language_handler_out -- - - - i p f 0 -1 0 _null_ _null_ )); #define LANGUAGE_HANDLEROID 2280 ! DATA(insert OID = 2281 ( internal PGNSP PGUID 4 t p t \054 0 0 0 internal_in internal_out - - - - - i p f 0 -10 _null_ _null_ )); #define INTERNALOID 2281 ! DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0_null_ _null_ )); #define OPAQUEOID 2282 ! DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f0 -1 0 _null_ _null_ )); #define ANYELEMENTOID 2283 ! 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,621 **** */ extern Oid TypeShellMake(const char *typeName, Oid typeNamespace); ! extern Oid TypeCreate(const char *typeName, ! Oid typeNamespace, ! Oid relationOid, ! char relationKind, ! int16 internalSize, ! char typeType, ! char typDelim, ! Oid inputProcedure, ! Oid outputProcedure, ! Oid receiveProcedure, ! Oid sendProcedure, ! Oid typmodinProcedure, ! Oid typmodoutProcedure, ! Oid analyzeProcedure, ! Oid elementType, ! Oid baseType, ! const char *defaultTypeValue, ! char *defaultTypeBin, ! bool passedByValue, ! char alignment, ! char storage, ! int32 typeMod, ! int32 typNDims, ! bool typeNotNull); extern void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, --- 596,629 ---- */ extern Oid TypeShellMake(const char *typeName, Oid typeNamespace); ! extern Oid TypeCreate( ! const char *typeName, ! Oid typeNamespace, ! Oid relationOid, ! char relationKind, ! int16 internalSize, ! char typeType, ! char typDelim, ! Oid inputProcedure, ! Oid outputProcedure, ! Oid receiveProcedure, ! Oid sendProcedure, ! Oid typmodinProcedure, ! Oid typmodoutProcedure, ! Oid analyzeProcedure, ! Oid elementType, ! Oid baseType, ! const char *defaultTypeValue, ! char *defaultTypeBin, ! bool passedByValue, ! char alignment, ! char storage, ! int32 typeMod, ! int32 typNDims, ! bool typeNotNull, ! Oid arrayType, ! bool is_array_type ! ); extern void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, *************** *** 637,642 **** extern void TypeRename(const char *oldTypeName, Oid typeNamespace, const char *newTypeName); ! extern char *makeArrayTypeName(const char *typeName); #endif /* PG_TYPE_H */ --- 645,650 ---- extern void TypeRename(const char *oldTypeName, Oid typeNamespace, const char *newTypeName); ! extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace); #endif /* PG_TYPE_H */ Index: src/test/regress/expected/alter_table.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/alter_table.out,v retrieving revision 1.101 diff -c -r1.101 alter_table.out *** src/test/regress/expected/alter_table.out 14 Feb 2007 01:58:58 -0000 1.101 --- src/test/regress/expected/alter_table.out 9 May 2007 22:56:17 -0000 *************** *** 1456,1468 **** --- 1456,1471 ---- -- clean up drop schema alter2 cascade; + NOTICE: drop cascades to type alter2.ctype[] 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) + NOTICE: drop cascades to type alter2.v1[] NOTICE: drop cascades to view alter2.v1 NOTICE: drop cascades to rule _RETURN on view alter2.v1 NOTICE: drop cascades to sequence alter2.t1_f1_seq NOTICE: drop cascades to default for table alter2.t1 column f1 + NOTICE: drop cascades to type alter2.t1[] NOTICE: drop cascades to table alter2.t1 NOTICE: drop cascades to constraint t1_f2_check on table alter2.t1 Index: src/test/regress/expected/type_sanity.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/type_sanity.out,v retrieving revision 1.29 diff -c -r1.29 type_sanity.out *** src/test/regress/expected/type_sanity.out 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/expected/type_sanity.out 9 May 2007 22:56:17 -0000 *************** *** 49,55 **** -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- --- 49,55 ---- -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- *************** *** 69,74 **** --- 69,84 ---- 705 | unknown (2 rows) + -- Make sure typarray points to a varlena array type of our own base + SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, + p2.typelem, p2.typlen + FROM pg_type p1 left join pg_type p2 on (p1.typarray = p2.oid) + WHERE p1.typarray <> 0 AND + (p2.oid IS NULL OR p2.typelem <> p1.oid OR p2.typlen <> -1); + oid | basetype | arraytype | typelem | typlen + -----+----------+-----------+---------+-------- + (0 rows) + -- Text conversion routines must be provided. SELECT p1.oid, p1.typname FROM pg_type as p1 Index: src/test/regress/sql/type_sanity.sql =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/sql/type_sanity.sql,v retrieving revision 1.29 diff -c -r1.29 type_sanity.sql *** src/test/regress/sql/type_sanity.sql 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/sql/type_sanity.sql 9 May 2007 22:56:17 -0000 *************** *** 46,52 **** SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type. --- 46,52 ---- SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type. *************** *** 59,64 **** --- 59,71 ---- 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
Andrew Dunstan <andrew@dunslane.net> writes: > The attached version removes all the places we had NAMEDATALEN - 2 > restrictions on object names. If there's no objection I will commit this > shortly, as I think it now does all the previously agreed things. It needs some work yet, but I'll go over it and commit it. BTW, just idly looking at this, I'm wondering whether we couldn't now support arrays of domains too. If record_in/record_out work for array elements, why wouldn't domain_in/domain_out? regards, tom lane
Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >> The attached version removes all the places we had NAMEDATALEN - 2 >> restrictions on object names. If there's no objection I will commit this >> shortly, as I think it now does all the previously agreed things. >> > > It needs some work yet, but I'll go over it and commit it. > > BTW, just idly looking at this, I'm wondering whether we couldn't > now support arrays of domains too. If record_in/record_out work for > array elements, why wouldn't domain_in/domain_out? > > > Good question. I'm all in favor of doing that. Presumably we would not in the case of a domain of an array type? cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: >>> Attached is my rework of David Fetter's array of composites patch. It >>> has all the agreed modifications and checks, except altering the name >>> mangling. Applied with revisions. There are some loose ends yet: * I didn't do anything about arrays of domains. Although I think they'd basically work, there's one nasty fly in the ointment, which is ALTER DOMAIN ADD CONSTRAINT. get_rels_with_domain() is not smart enough to detect arrays of domains, and its callers are not nearly smart enough to apply their checks to arrays. So I think this had better wait for 8.4. BTW, I realized there's an existing bug here as of 8.2: when I enabled domains over domains I didn't do anything with get_rels_with_domain(). Fortunately this is a relatively easy thing to deal with, we can just recurse to find columns of derived domain types, which the callers don't really need to treat any differently than they do now. I'll go fix that part. * The feature leaves something to be desired in terms of usability, because array[row()] doesn't work: regression=# create type foo as (f1 int, f2 int); CREATE TYPE regression=# create table bar (ff1 foo[]); CREATE TABLE regression=# insert into bar values(array[row(1,2),row(3,4)]); ERROR: could not find array type for data type record regression=# You can only get it to work if you plaster ::foo onto *each* row() construct. Ugh. This didn't seem trivial to improve. * I'm a bit concerned about dump order. If a user wants to create types named "foo" and "_foo", he can, but it will only work if he makes "_foo" first --- else the derived type for foo is in the way. Since pg_dump has no clue about that constraint, it might easily dump "foo" first leading to an unrestorable dump. The most usable solution would be to auto-rename previously created array types, but I dunno how implementable that would be. regards, tom lane
"Tom Lane" <tgl@sss.pgh.pa.us> writes: > * I'm a bit concerned about dump order. If a user wants to create > types named "foo" and "_foo", he can, but it will only work if he > makes "_foo" first --- else the derived type for foo is in the way. > Since pg_dump has no clue about that constraint, it might easily > dump "foo" first leading to an unrestorable dump. The most usable > solution would be to auto-rename previously created array types, > but I dunno how implementable that would be. BTW, why exactly do we need array types to have names at all? The only user-visible way to refer to these types is always by foo[] isn't it? -- Gregory Stark EnterpriseDB http://www.enterprisedb.com
Andrew Dunstan <andrew@dunslane.net> writes: > Tom Lane wrote: >> That's not really the most preferable solution, I think, seeing that it >> still leaves the user with the problem of having to create the types in >> the right order to start with. > I'm not sure we can keep the _foo convention and avoid that. Auto-rename. I'm working on a patch now, and it doesn't look like it'll be too awful. Will post it for comments when it's working. > ... I'd vote to revert the new name > mangling piece (but keep the typarray mapping column), deprecate the use > of the _foo convention, and abandon it next release. I came across a comment in the source that says PG has been using _foo for arrays since 3.1 (!). I don't think we can get away with changing it, certainly not with only one release cycle's notice. The current code is OK from a compatibility point of view, since it only changes _foo to something else in situations where the old way would've failed outright. I think we need to preserve that property ... regards, tom lane
Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >> Tom Lane wrote: >> >>> That's not really the most preferable solution, I think, seeing that it >>> still leaves the user with the problem of having to create the types in >>> the right order to start with. >>> > > >> I'm not sure we can keep the _foo convention and avoid that. >> > > Auto-rename. I'm working on a patch now, and it doesn't look like it'll > be too awful. Will post it for comments when it's working. > Ok, cool. I look forward to it. cheers andrew
Tom Lane wrote: > > There is *tons* of legacy code that uses _foo, mainly because there was > a time when we didn't support the [] notation in a lot of places where > types can be named. There still are some places, in fact: > > regression=# alter type widget[] set schema public; > ERROR: syntax error at or near "[" > LINE 1: alter type widget[] set schema public; > ^ > regression=# alter type _widget set schema public; > ERROR: cannot alter array type widget[] > HINT: You can alter type widget, which will alter the array type as well. > regression=# > > That particular one may not need fixed (anymore) but the real problem is > the torches-and-pitchforks session that will ensue if we break legacy > code for no reason beyond cosmetics. > > IIRC some of the contrib modules still have instances of _foo in > their SQL scripts. > Then I think we need to work out a way to make pg_dump smart enough to dump things in the right order. Can we perhaps explicitly deprecate using the type name to refer to array types? cheers andrew
Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >> Then I think we need to work out a way to make pg_dump smart enough to >> dump things in the right order. >> > > That's not really the most preferable solution, I think, seeing that it > still leaves the user with the problem of having to create the types in > the right order to start with. > > > I'm not sure we can keep the _foo convention and avoid that. If we can't find something sensible pretty quickly, I'd vote to revert the new name mangling piece (but keep the typarray mapping column), deprecate the use of the _foo convention, and abandon it next release. It would be a pity though. cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > Then I think we need to work out a way to make pg_dump smart enough to > dump things in the right order. That's not really the most preferable solution, I think, seeing that it still leaves the user with the problem of having to create the types in the right order to start with. regards, tom lane
Andrew Dunstan <andrew@dunslane.net> writes: > Tom Lane wrote: >> Auto-rename. I'm working on a patch now, and it doesn't look like it'll >> be too awful. Will post it for comments when it's working. > Ok, cool. I look forward to it. Here's a bare-bones patch (no doc or regression tests). Seems to work. Anyone think this is too ugly a way to proceed? regards, tom lane Index: src/backend/catalog/heap.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/heap.c,v retrieving revision 1.319 diff -c -r1.319 heap.c *** src/backend/catalog/heap.c 11 May 2007 17:57:11 -0000 1.319 --- src/backend/catalog/heap.c 11 May 2007 23:18:51 -0000 *************** *** 797,802 **** --- 797,803 ---- { Relation pg_class_desc; Relation new_rel_desc; + Oid old_type_oid; Oid new_type_oid; Oid new_array_oid = InvalidOid; *************** *** 815,820 **** --- 816,842 ---- errmsg("relation \"%s\" already exists", relname))); /* + * Since we are going to create a rowtype as well, also check for + * collision with an existing type name. If there is one and it's + * an autogenerated array, we can rename it out of the way; otherwise + * we can at least give a good error message. + */ + old_type_oid = GetSysCacheOid(TYPENAMENSP, + CStringGetDatum(relname), + ObjectIdGetDatum(relnamespace), + 0, 0); + if (OidIsValid(old_type_oid)) + { + if (!moveArrayTypeName(old_type_oid, relname, relnamespace)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("type \"%s\" already exists", relname), + errhint("A relation has an associated type of the same name, " + "so you must use a name that doesn't conflict " + "with any existing type."))); + } + + /* * Allocate an OID for the relation, unless we were told what to use. * * The OID will be the relfilenode as well, so make sure it doesn't *************** *** 861,868 **** * 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 ! * has already been used for a type. */ new_type_oid = AddNewRelationType(relname, relnamespace, --- 883,891 ---- * 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 someone else is ! * creating the same type name in parallel but hadn't committed yet ! * when we checked for a duplicate name above. */ new_type_oid = AddNewRelationType(relname, relnamespace, Index: src/backend/catalog/pg_type.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v retrieving revision 1.112 diff -c -r1.112 pg_type.c *** src/backend/catalog/pg_type.c 11 May 2007 17:57:12 -0000 1.112 --- src/backend/catalog/pg_type.c 11 May 2007 23:18:51 -0000 *************** *** 15,20 **** --- 15,21 ---- #include "postgres.h" #include "access/heapam.h" + #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_namespace.h" *************** *** 26,31 **** --- 27,33 ---- #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" + #include "utils/lsyscache.h" #include "utils/syscache.h" *************** *** 551,580 **** /* * TypeRename ! * This renames a type * ! * Note: any associated array type is *not* renamed; caller must make ! * another call to handle that case. Currently this is only used for ! * renaming types associated with tables, for which there are no arrays. */ void ! TypeRename(const char *oldTypeName, Oid typeNamespace, ! const char *newTypeName) { Relation pg_type_desc; HeapTuple tuple; pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); ! tuple = SearchSysCacheCopy(TYPENAMENSP, ! CStringGetDatum(oldTypeName), ! ObjectIdGetDatum(typeNamespace), ! 0, 0); if (!HeapTupleIsValid(tuple)) ! ereport(ERROR, ! (errcode(ERRCODE_UNDEFINED_OBJECT), ! errmsg("type \"%s\" does not exist", oldTypeName))); if (SearchSysCacheExists(TYPENAMENSP, CStringGetDatum(newTypeName), ObjectIdGetDatum(typeNamespace), --- 553,587 ---- /* * TypeRename ! * This renames a type, as well as any associated array type. * ! * Note: this isn't intended to be a user-exposed function; it doesn't check ! * permissions etc. (Perhaps TypeRenameInternal would be a better name.) ! * Currently this is only used for renaming table rowtypes. */ void ! TypeRename(Oid typeOid, const char *newTypeName, Oid typeNamespace) { Relation pg_type_desc; HeapTuple tuple; + Form_pg_type typ; + Oid arrayOid; pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); ! tuple = SearchSysCacheCopy(TYPEOID, ! ObjectIdGetDatum(typeOid), ! 0, 0, 0); if (!HeapTupleIsValid(tuple)) ! elog(ERROR, "cache lookup failed for type %u", typeOid); ! typ = (Form_pg_type) GETSTRUCT(tuple); ! ! /* We are not supposed to be changing schemas here */ ! Assert(typeNamespace == typ->typnamespace); + arrayOid = typ->typarray; + + /* Just to give a more friendly error than unique-index violation */ if (SearchSysCacheExists(TYPENAMENSP, CStringGetDatum(newTypeName), ObjectIdGetDatum(typeNamespace), *************** *** 583,589 **** (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("type \"%s\" already exists", newTypeName))); ! namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), newTypeName); simple_heap_update(pg_type_desc, &tuple->t_self, tuple); --- 590,597 ---- (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("type \"%s\" already exists", newTypeName))); ! /* OK, do the rename --- tuple is a copy, so OK to scribble on it */ ! namestrcpy(&(typ->typname), newTypeName); simple_heap_update(pg_type_desc, &tuple->t_self, tuple); *************** *** 592,602 **** heap_freetuple(tuple); heap_close(pg_type_desc, RowExclusiveLock); } /* ! * makeArrayTypeName(typeName) * - given a base type name, make an array type name for it * * the caller is responsible for pfreeing the result --- 600,619 ---- heap_freetuple(tuple); heap_close(pg_type_desc, RowExclusiveLock); + + /* If the type has an array type, recurse to handle that */ + if (OidIsValid(arrayOid)) + { + char *arrname = makeArrayTypeName(newTypeName, typeNamespace); + + TypeRename(arrayOid, arrname, typeNamespace); + pfree(arrname); + } } /* ! * makeArrayTypeName * - given a base type name, make an array type name for it * * the caller is responsible for pfreeing the result *************** *** 638,640 **** --- 655,712 ---- return arr; } + + + /* + * moveArrayTypeName + * - try to reassign an array type name that the user wants to use. + * + * The given type name has been discovered to already exist (with the given + * OID). If it is an autogenerated array type, change the array type's name + * to not conflict. This allows the user to create type "foo" followed by + * type "_foo" without problems. (Of course, there are race conditions if + * two backends try to create similarly-named types concurrently, but the + * worst that can happen is an unnecessary failure --- anything we do here + * will be rolled back if the type creation fails due to conflicting names.) + * + * Note that this must be called *before* calling makeArrayTypeName to + * determine the new type's own array type name; else the latter will + * certainly pick the same name. + * + * Returns TRUE if successfully moved the type, FALSE if not. + */ + bool + moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace) + { + Oid elemOid; + char *newname; + + /* + * Can't change it if it's not an autogenerated array type. + */ + elemOid = get_element_type(typeOid); + if (!OidIsValid(elemOid) || + get_array_type(elemOid) != typeOid) + return false; + + /* + * OK, use makeArrayTypeName to pick an unused modification of the + * name. Note that since makeArrayTypeName is an iterative process, + * this will produce a name that it might have produced the first time, + * had the conflicting type we are about to create already existed. + */ + newname = makeArrayTypeName(typeName, typeNamespace); + + /* Apply the rename */ + TypeRename(typeOid, newname, typeNamespace); + + /* + * We must bump the command counter so that any subsequent use of + * makeArrayTypeName sees what we just did and doesn't pick the same name. + */ + CommandCounterIncrement(); + + pfree(newname); + + return true; + } Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.221 diff -c -r1.221 tablecmds.c *** src/backend/commands/tablecmds.c 11 May 2007 20:16:36 -0000 1.221 --- src/backend/commands/tablecmds.c 11 May 2007 23:18:52 -0000 *************** *** 1626,1631 **** --- 1626,1632 ---- Relation targetrelation; Relation relrelation; /* for RELATION relation */ HeapTuple reltup; + Form_pg_class relform; Oid namespaceId; char *oldrelname; char relkind; *************** *** 1655,1664 **** relrelation = heap_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy(RELOID, ! PointerGetDatum(myrelid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) /* shouldn't happen */ elog(ERROR, "cache lookup failed for relation %u", myrelid); if (get_relname_relid(newrelname, namespaceId) != InvalidOid) ereport(ERROR, --- 1656,1666 ---- relrelation = heap_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy(RELOID, ! ObjectIdGetDatum(myrelid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) /* shouldn't happen */ elog(ERROR, "cache lookup failed for relation %u", myrelid); + relform = (Form_pg_class) GETSTRUCT(reltup); if (get_relname_relid(newrelname, namespaceId) != InvalidOid) ereport(ERROR, *************** *** 1670,1676 **** * Update pg_class tuple with new relname. (Scribbling on reltup is OK * because it's a copy...) */ ! namestrcpy(&(((Form_pg_class) GETSTRUCT(reltup))->relname), newrelname); simple_heap_update(relrelation, &reltup->t_self, reltup); --- 1672,1678 ---- * Update pg_class tuple with new relname. (Scribbling on reltup is OK * because it's a copy...) */ ! namestrcpy(&(relform->relname), newrelname); simple_heap_update(relrelation, &reltup->t_self, reltup); *************** *** 1683,1690 **** /* * Also rename the associated type, if any. */ ! if (relkind != RELKIND_INDEX) ! TypeRename(oldrelname, namespaceId, newrelname); /* * Close rel, but keep exclusive lock! --- 1685,1692 ---- /* * Also rename the associated type, if any. */ ! if (OidIsValid(targetrelation->rd_rel->reltype)) ! TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId); /* * Close rel, but keep exclusive lock! Index: src/backend/commands/typecmds.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.103 diff -c -r1.103 typecmds.c *** src/backend/commands/typecmds.c 11 May 2007 20:16:54 -0000 1.103 --- src/backend/commands/typecmds.c 11 May 2007 23:18:52 -0000 *************** *** 137,149 **** /* * 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. */ typoid = GetSysCacheOid(TYPENAMENSP, CStringGetDatum(typeName), ObjectIdGetDatum(typeNamespace), 0, 0); if (!OidIsValid(typoid)) { typoid = TypeShellMake(typeName, typeNamespace); --- 137,163 ---- /* * Look to see if type already exists (presumably as a shell; if not, ! * TypeCreate will complain). */ typoid = GetSysCacheOid(TYPENAMENSP, CStringGetDatum(typeName), ObjectIdGetDatum(typeNamespace), 0, 0); + + /* + * If it's not a shell, see if it's an autogenerated array type, + * and if so rename it out of the way. + */ + if (OidIsValid(typoid) && get_typisdefined(typoid)) + { + if (moveArrayTypeName(typoid, typeName, typeNamespace)) + typoid = InvalidOid; + } + + /* + * If it doesn't exist, create it as a shell, so that the OID is known + * for use in the I/O function definitions. + */ if (!OidIsValid(typoid)) { typoid = TypeShellMake(typeName, typeNamespace); *************** *** 602,607 **** --- 616,622 ---- ListCell *listptr; Oid basetypeoid; Oid domainoid; + Oid old_type_oid; Form_pg_type baseType; int32 basetypeMod; *************** *** 617,622 **** --- 632,653 ---- get_namespace_name(domainNamespace)); /* + * Check for collision with an existing type name. If there is one and + * it's an autogenerated array, we can rename it out of the way. + */ + old_type_oid = GetSysCacheOid(TYPENAMENSP, + CStringGetDatum(domainName), + ObjectIdGetDatum(domainNamespace), + 0, 0); + if (OidIsValid(old_type_oid)) + { + if (!moveArrayTypeName(old_type_oid, domainName, domainNamespace)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("type \"%s\" already exists", domainName))); + } + + /* * Look up the base type. */ typeTup = typenameType(NULL, stmt->typename); *************** *** 948,953 **** --- 979,985 ---- Oid enumNamespace; Oid enumTypeOid; AclResult aclresult; + Oid old_type_oid; Oid enumArrayOid; Relation pg_type; *************** *** 961,966 **** --- 993,1014 ---- aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(enumNamespace)); + /* + * Check for collision with an existing type name. If there is one and + * it's an autogenerated array, we can rename it out of the way. + */ + old_type_oid = GetSysCacheOid(TYPENAMENSP, + CStringGetDatum(enumName), + ObjectIdGetDatum(enumNamespace), + 0, 0); + if (OidIsValid(old_type_oid)) + { + if (!moveArrayTypeName(old_type_oid, enumName, enumNamespace)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("type \"%s\" already exists", enumName))); + } + /* Preassign array type OID so we can insert it in pg_type.typarray */ pg_type = heap_open(TypeRelationId, AccessShareLock); enumArrayOid = GetNewOid(pg_type); Index: src/include/catalog/pg_type.h =================================================================== RCS file: /cvsroot/pgsql/src/include/catalog/pg_type.h,v retrieving revision 1.183 diff -c -r1.183 pg_type.h *** src/include/catalog/pg_type.h 11 May 2007 17:57:13 -0000 1.183 --- src/include/catalog/pg_type.h 11 May 2007 23:18:52 -0000 *************** *** 645,653 **** Node *defaultExpr, bool rebuild); ! extern void TypeRename(const char *oldTypeName, Oid typeNamespace, ! const char *newTypeName); extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace); #endif /* PG_TYPE_H */ --- 645,656 ---- Node *defaultExpr, bool rebuild); ! extern void TypeRename(Oid typeOid, const char *newTypeName, ! Oid typeNamespace); extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace); + extern bool moveArrayTypeName(Oid typeOid, const char *typeName, + Oid typeNamespace); + #endif /* PG_TYPE_H */
Gregory Stark wrote: > "Tom Lane" <tgl@sss.pgh.pa.us> writes: > > >> * I'm a bit concerned about dump order. If a user wants to create >> types named "foo" and "_foo", he can, but it will only work if he >> makes "_foo" first --- else the derived type for foo is in the way. >> Since pg_dump has no clue about that constraint, it might easily >> dump "foo" first leading to an unrestorable dump. The most usable >> solution would be to auto-rename previously created array types, >> but I dunno how implementable that would be. >> > > BTW, why exactly do we need array types to have names at all? The only > user-visible way to refer to these types is always by foo[] isn't it? > > I think you can use the _foo name, but it would certainly be an odd thing to do. I'd be happy to get rid of the name, or at least make it something very unlikely indeed, but Tom didn't want to move too far from our present naming convention. I am now wondering if we shouldn't at lest append _arr or some such to the array type name, similarly to what we do for generated sequence and index names. cheers andrew
Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >> Tom Lane wrote: >> >>> Auto-rename. I'm working on a patch now, and it doesn't look like it'll >>> be too awful. Will post it for comments when it's working. >>> > > >> Ok, cool. I look forward to it. >> > > Here's a bare-bones patch (no doc or regression tests). Seems to work. > Anyone think this is too ugly a way to proceed? > > > Summarising the behaviour as I understand it: . if you never name a type/table with a name beginning with underscore, behaviour is as expected - type foo gets array type _foo . if you create a type foo and then create a type _foo, the array type for foo will first be renamed to __foo, and the new array type for _foo will be ___foo . if you create type _foo and then create type foo, the corresponding array types will be __foo and ___foo as per my patch, with no renaming required. I think I like it. Certainly seems to get round the ordering problem nicely. cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > Summarising the behaviour as I understand it: > . if you never name a type/table with a name beginning with underscore, > behaviour is as expected - type foo gets array type _foo > . if you create a type foo and then create a type _foo, the array type > for foo will first be renamed to __foo, and the new array type for _foo > will be ___foo > . if you create type _foo and then create type foo, the corresponding > array types will be __foo and ___foo as per my patch, with no renaming > required. > I think I like it. Certainly seems to get round the ordering problem nicely. At least as far as the user's names are concerned. There's some ordering dependency for the names that the array types end up with, but we had that problem already; and AFAIK it shouldn't create any big issue for dump/restore. BTW, I forgot to mention that this patch also fixes an oversight in the original patch: we all missed the fact that ALTER TABLE RENAME didn't rename the rowtype's array type. regards, tom lane
Tom Lane wrote: > >> I think I like it. Certainly seems to get round the ordering problem nicely. >> > > At least as far as the user's names are concerned. There's some > ordering dependency for the names that the array types end up with, > but we had that problem already; and AFAIK it shouldn't create any > big issue for dump/restore. > There will only be an issue if you use table/type names beginning with underscore, right? And I don't think it will matter because nobody has been relying on that to date as we haven't had array types for those. We should probably document that relying on the array name is both fragile and unnecessary. > BTW, I forgot to mention that this patch also fixes an oversight in the > original patch: we all missed the fact that ALTER TABLE RENAME didn't > rename the rowtype's array type. > > Oh, good catch. Sorry about that. cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > Gregory Stark wrote: >> BTW, why exactly do we need array types to have names at all? Because typname is part of the primary key for pg_type ... >> The only >> user-visible way to refer to these types is always by foo[] isn't it? > I think you can use the _foo name, but it would certainly be an odd > thing to do. There is *tons* of legacy code that uses _foo, mainly because there was a time when we didn't support the [] notation in a lot of places where types can be named. There still are some places, in fact: regression=# alter type widget[] set schema public; ERROR: syntax error at or near "[" LINE 1: alter type widget[] set schema public; ^ regression=# alter type _widget set schema public; ERROR: cannot alter array type widget[] HINT: You can alter type widget, which will alter the array type as well. regression=# That particular one may not need fixed (anymore) but the real problem is the torches-and-pitchforks session that will ensue if we break legacy code for no reason beyond cosmetics. IIRC some of the contrib modules still have instances of _foo in their SQL scripts. regards, tom lane
Andrew Dunstan <andrew@dunslane.net> writes: > There will only be an issue if you use table/type names beginning with > underscore, right? And I don't think it will matter because nobody has > been relying on that to date as we haven't had array types for those. We > should probably document that relying on the array name is both fragile > and unnecessary. I added this to the CREATE TYPE reference page, which AFAIR is the only place that mentions the naming convention at all: <para> Before <productname>PostgreSQL</productname> version 8.3, the name of a generated array type was always exactly the element type's name with one underscore character (<literal>_</literal>) prepended. (Type names were therefore restricted in length to one less character than other names.) While this is still usually the case, the array type name may vary from this in case of maximum-length names or collisions with user type names that begin with underscore. Writing code that depends on this convention is therefore deprecated. Instead, use <structname>pg_type</>.<structfield>typarray</> to locate the array type associated with a given type. </para> <para> It may be advisable to avoid using type and table names that begin with underscore. While the server will change generated array type names to avoid collisions with user-given names, there is still risk of confusion, particularly with old client software that may assume that type names beginning with underscores always represent arrays. </para> regards, tom lane
TODO marked as done: o -Add support for arrays of complex types I assume this is _not_ done, as stated below: o Add support for arrays of domains I will add a URL for this item: http://archives.postgresql.org/pgsql-patches/2007-05/msg00114.php --------------------------------------------------------------------------- Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >>> Attached is my rework of David Fetter's array of composites patch. It > >>> has all the agreed modifications and checks, except altering the name > >>> mangling. > > Applied with revisions. There are some loose ends yet: > > * I didn't do anything about arrays of domains. Although I think they'd > basically work, there's one nasty fly in the ointment, which is ALTER > DOMAIN ADD CONSTRAINT. get_rels_with_domain() is not smart enough to > detect arrays of domains, and its callers are not nearly smart enough to > apply their checks to arrays. So I think this had better wait for 8.4. > > BTW, I realized there's an existing bug here as of 8.2: when I enabled > domains over domains I didn't do anything with get_rels_with_domain(). > Fortunately this is a relatively easy thing to deal with, we can just > recurse to find columns of derived domain types, which the callers don't > really need to treat any differently than they do now. I'll go fix > that part. > > * The feature leaves something to be desired in terms of usability, > because array[row()] doesn't work: > > regression=# create type foo as (f1 int, f2 int); > CREATE TYPE > regression=# create table bar (ff1 foo[]); > CREATE TABLE > regression=# insert into bar values(array[row(1,2),row(3,4)]); > ERROR: could not find array type for data type record > regression=# > > You can only get it to work if you plaster ::foo onto *each* row() > construct. Ugh. This didn't seem trivial to improve. > > * I'm a bit concerned about dump order. If a user wants to create > types named "foo" and "_foo", he can, but it will only work if he > makes "_foo" first --- else the derived type for foo is in the way. > Since pg_dump has no clue about that constraint, it might easily > dump "foo" first leading to an unrestorable dump. The most usable > solution would be to auto-rename previously created array types, > but I dunno how implementable that would be. > > regards, tom lane > > ---------------------------(end of broadcast)--------------------------- > TIP 2: Don't 'kill -9' the postmaster -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. +