On Fri, Mar 30, 2007 at 05:08:42PM -0400, Tom Lane wrote:
> David Fetter <[EMAIL PROTECTED]> writes:
> > After several rounds of patches, it appears that it might be easier to
> > create a new typtype entry, which I'll tentatively call 'a' because it
> > seems a little fragile and a lot inelegant and hard to maintain to
> > have typtype='c' and typrelid=InvalidOid mean, "this is an array of
> > complex types."
>
> Uh, wouldn't it be typtype = 'c' and typelem != 0 ?
Right. The attached patch passes the current regression tests and at
least to a "smoke test" level does what it's supposed to do. I'd
really like to help refactor the whole array system to use 'a', tho.
Cheers,
D
--
David Fetter <[EMAIL PROTECTED]> http://fetter.org/
phone: +1 415 235 3778 AIM: dfetter666
Skype: davidfetter
Remember to vote!
Consider donating to PostgreSQL: http://www.postgresql.org/about/donate
Index: src/backend/catalog/heap.c
===================================================================
RCS file: /projects/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 2 Apr 2007 20:09:16 -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"
***************
*** 763,768 ****
--- 764,770 ----
Relation pg_class_desc;
Relation new_rel_desc;
Oid new_type_oid;
+ char *relarrayname;
pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
***************
*** 815,820 ****
--- 817,856 ----
relnamespace,
relid,
relkind);
+ /*
+ * Add in the corresponding array types if appropriate.
+ */
+ if (relkind == RELKIND_RELATION ||
+ relkind == RELKIND_VIEW ||
+ relkind == RELKIND_COMPOSITE_TYPE)
+ {
+ relarrayname = makeArrayTypeName(relname);
+ TypeCreate(relarrayname, /* Array type name */
+ relnamespace, /* Same
namespace as parent */
+ InvalidOid, /* relation's
type oid, set here to InvalidOid to make dependency work right */
+ 0, /*
relkind, also N/A here */
+ -1, /*
Internal size, unlimited */
+ 'c', /* It's
a complex type */
+ 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
alignment. Should this be something else? */
+ 'x', /*
Always TOASTable */
+ -1, /* No
typMod for regular composite 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: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.218
diff -c -r1.218 tablecmds.c
*** src/backend/commands/tablecmds.c 19 Mar 2007 23:38:29 -0000 1.218
--- src/backend/commands/tablecmds.c 2 Apr 2007 20:09:17 -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
***************
*** 6488,6495 ****
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)
--- 6499,6507 ----
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: /projects/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 2 Apr 2007 20:09:17 -0000
***************
*** 2367,2372 ****
--- 2367,2375 ----
/* 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",
--- 2434,2445 ----
/* 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;
--- 2460,2466 ----
* 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",
--- 2493,2499 ----
* 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: /projects/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 2 Apr 2007 20:09:19 -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: /projects/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 2 Apr 2007 20:09:19 -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: /projects/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 2 Apr 2007 20:09:19 -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.
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly