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

Reply via email to