diff -cpr --exclude=CVS head/doc/src/sgml/ref/create_table.sgml work/doc/src/sgml/ref/create_table.sgml
*** head/doc/src/sgml/ref/create_table.sgml	2009-07-30 05:56:17.000000000 +0900
--- work/doc/src/sgml/ref/create_table.sgml	2009-09-06 17:17:39.768335000 +0900
*************** PostgreSQL documentation
*** 24,30 ****
  CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
    { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
      | <replaceable>table_constraint</replaceable>
!     | LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }
      [, ... ]
  ] )
  [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
--- 24,30 ----
  CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
    { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
      | <replaceable>table_constraint</replaceable>
!     | LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGES | COMMENTS } ] ... }
      [, ... ]
  ] )
  [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
*************** and <replaceable class="PARAMETER">table
*** 230,235 ****
--- 230,239 ----
        will always be chosen for it.
       </para>
  
+      <para>
+       Column storage parameters are also copied from parent tables.
+      </para>
+ 
  <!--
       <para>
        <productname>PostgreSQL</> automatically allows the
*************** and <replaceable class="PARAMETER">table
*** 247,253 ****
     </varlistentry>
  
     <varlistentry>
!     <term><literal>LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ]</literal></term>
      <listitem>
       <para>
        The <literal>LIKE</literal> clause specifies a table from which
--- 251,257 ----
     </varlistentry>
  
     <varlistentry>
!     <term><literal>LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGES | COMMENTS } ]</literal></term>
      <listitem>
       <para>
        The <literal>LIKE</literal> clause specifies a table from which
*************** and <replaceable class="PARAMETER">table
*** 281,286 ****
--- 285,302 ----
        specified.
       </para>
       <para>
+       Storage parameters for the copied column definitions will only be
+       copied if <literal>INCLUDING STORAGES</literal> is specified.  The
+       default behavior is to exclude storage paramters, resulting in the
+       copied columns in the new table having type-specific default parameters.
+      </para>
+      <para>
+       Comments for the copied column definitions will only be
+       copied if <literal>INCLUDING COMMENTS</literal> is specified.  The
+       default behavior is to exclude comments, resulting in the
+       copied columns in the new table having no comments.
+      </para>
+      <para>
        Note also that unlike <literal>INHERITS</literal>, copied columns and
        constraints are not merged with similarly named columns and constraints.
        If the same name is specified explicitly or in another
diff -cpr --exclude=CVS head/src/backend/access/common/tupdesc.c work/src/backend/access/common/tupdesc.c
*** head/src/backend/access/common/tupdesc.c	2009-08-03 07:14:51.000000000 +0900
--- work/src/backend/access/common/tupdesc.c	2009-09-06 14:47:00.698569582 +0900
*************** BuildDescForRelation(List *schema)
*** 558,563 ****
--- 558,565 ----
  		has_not_null |= entry->is_not_null;
  		desc->attrs[attnum - 1]->attislocal = entry->is_local;
  		desc->attrs[attnum - 1]->attinhcount = entry->inhcount;
+ 		if (entry->storage)
+ 			desc->attrs[attnum - 1]->attstorage = entry->storage;
  	}
  
  	if (has_not_null)
diff -cpr --exclude=CVS head/src/backend/commands/comment.c work/src/backend/commands/comment.c
*** head/src/backend/commands/comment.c	2009-06-11 23:48:55.000000000 +0900
--- work/src/backend/commands/comment.c	2009-09-06 13:17:56.294992259 +0900
*************** DeleteSharedComments(Oid oid, Oid classo
*** 463,468 ****
--- 463,523 ----
  }
  
  /*
+  * GetComment -- get the comment for a object, or null if not found.
+  */
+ char *
+ GetComment(Oid oid, Oid classoid, int32 subid)
+ {
+ 	Relation	description;
+ 	ScanKeyData skey[3];
+ 	SysScanDesc sd;
+ 	TupleDesc	tupdesc;
+ 	HeapTuple	tuple;
+ 	char	   *comment;
+ 
+ 	/* Use the index to search for a matching old tuple */
+ 
+ 	ScanKeyInit(&skey[0],
+ 				Anum_pg_description_objoid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(oid));
+ 	ScanKeyInit(&skey[1],
+ 				Anum_pg_description_classoid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(classoid));
+ 	ScanKeyInit(&skey[2],
+ 				Anum_pg_description_objsubid,
+ 				BTEqualStrategyNumber, F_INT4EQ,
+ 				Int32GetDatum(subid));
+ 
+ 	description = heap_open(DescriptionRelationId, AccessShareLock);
+ 	tupdesc = RelationGetDescr(description);
+ 
+ 	sd = systable_beginscan(description, DescriptionObjIndexId, true,
+ 							SnapshotNow, 3, skey);
+ 
+ 	comment  = NULL;
+ 	while ((tuple = systable_getnext(sd)) != NULL)
+ 	{
+ 		Datum	value;
+ 		bool	isnull;
+ 
+ 		/* Found the tuple, get description field */
+ 		value = heap_getattr(tuple, Anum_pg_description_description, tupdesc, &isnull);
+ 		if (!isnull)
+ 			comment = TextDatumGetCString(value);
+ 		break;					/* Assume there can be only one match */
+ 	}
+ 
+ 	systable_endscan(sd);
+ 
+ 	/* Done */
+ 	heap_close(description, AccessShareLock);
+ 
+ 	return comment;
+ }
+ 
+ /*
   * CommentRelation --
   *
   * This routine is used to add/drop a comment from a relation, where
diff -cpr --exclude=CVS head/src/backend/commands/tablecmds.c work/src/backend/commands/tablecmds.c
*** head/src/backend/commands/tablecmds.c	2009-08-24 04:23:41.000000000 +0900
--- work/src/backend/commands/tablecmds.c	2009-09-06 16:25:45.324561796 +0900
***************
*** 39,44 ****
--- 39,45 ----
  #include "catalog/storage.h"
  #include "catalog/toasting.h"
  #include "commands/cluster.h"
+ #include "commands/comment.h"
  #include "commands/defrem.h"
  #include "commands/sequence.h"
  #include "commands/tablecmds.h"
*************** truncate_check_rel(Relation rel)
*** 1098,1103 ****
--- 1099,1117 ----
  	CheckTableNotInUse(rel, "TRUNCATE");
  }
  
+ static const char *
+ storage_name(char c)
+ {
+ 	switch (c)
+ 	{
+ 		case 'p': return "PLAIN";
+ 		case 'm': return "MAIN";
+ 		case 'x': return "EXTENDED";
+ 		case 'e': return "EXTERNAL";
+ 		default: return "???";
+ 	}
+ }
+ 
  /*----------
   * MergeAttributes
   *		Returns new schema given initial schema and superclasses.
*************** MergeAttributes(List *schema, List *supe
*** 1166,1171 ****
--- 1180,1186 ----
  	List	   *constraints = NIL;
  	int			parentsWithOids = 0;
  	bool		have_bogus_defaults = false;
+ 	bool		have_bogus_comments = false;
  	char	   *bogus_marker = "Bogus!";		/* marks conflicting defaults */
  	int			child_attno;
  
*************** MergeAttributes(List *schema, List *supe
*** 1321,1326 ****
--- 1336,1353 ----
  							 errdetail("%s versus %s",
  									   TypeNameToString(def->typeName),
  									   format_type_be(attribute->atttypid))));
+ 
+ 				/* Copy storage parameter */
+ 				if (def->storage == 0)
+ 					def->storage = attribute->attstorage;
+ 				else if (def->storage != attribute->attstorage)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_DATATYPE_MISMATCH),
+ 						errmsg("inherited column \"%s\" has a storage parameter conflict",
+ 							   attributeName),
+ 							   errdetail("%s versus %s", storage_name(def->storage),
+ 										 storage_name(attribute->attstorage))));
+ 
  				def->inhcount++;
  				/* Merge of NOT NULL constraints = OR 'em together */
  				def->is_not_null |= attribute->attnotnull;
*************** MergeAttributes(List *schema, List *supe
*** 1342,1347 ****
--- 1369,1375 ----
  				def->raw_default = NULL;
  				def->cooked_default = NULL;
  				def->constraints = NIL;
+ 				def->storage = attribute->attstorage;
  				inhSchema = lappend(inhSchema, def);
  				newattno[parent_attno - 1] = ++child_attno;
  			}
*************** MergeAttributes(List *schema, List *supe
*** 1479,1484 ****
--- 1507,1524 ----
  							 errdetail("%s versus %s",
  									   TypeNameToString(def->typeName),
  									   TypeNameToString(newdef->typeName))));
+ 
+ 				/* Copy storage parameter */
+ 				if (def->storage == 0)
+ 					def->storage = newdef->storage;
+ 				else if (newdef->storage != 0 && def->storage != newdef->storage)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_DATATYPE_MISMATCH),
+ 						errmsg("column \"%s\" has a storage parameter conflict",
+ 							   attributeName),
+ 							   errdetail("%s versus %s", storage_name(def->storage),
+ 										 storage_name(newdef->storage))));
+ 
  				/* Mark the column as locally defined */
  				def->is_local = true;
  				/* Merge of NOT NULL constraints = OR 'em together */
*************** MergeAttributes(List *schema, List *supe
*** 1531,1536 ****
--- 1571,1590 ----
  		}
  	}
  
+ 	/* error is conflicting comments */
+ 	if (have_bogus_comments)
+ 	{
+ 		foreach(entry, schema)
+ 		{
+ 			ColumnDef  *def = lfirst(entry);
+ 
+ 			if (def->cooked_default == bogus_marker)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
+ 				  errmsg("column \"%s\" inherits conflicting comments", def->colname)));
+ 		}
+ 	}
+ 
  	*supOids = parentOids;
  	*supconstr = constraints;
  	*supOidCount = parentsWithOids;
diff -cpr --exclude=CVS head/src/backend/parser/gram.y work/src/backend/parser/gram.y
*** head/src/backend/parser/gram.y	2009-08-19 08:40:20.000000000 +0900
--- work/src/backend/parser/gram.y	2009-09-06 15:56:07.469540714 +0900
*************** static TypeName *TableFuncTypeName(List 
*** 455,461 ****
  
  	CACHE CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! 	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
  	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
  	CREATEROLE CREATEUSER CROSS CSV CURRENT_P
--- 455,461 ----
  
  	CACHE CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! 	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMENTS COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
  	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
  	CREATEROLE CREATEUSER CROSS CSV CURRENT_P
*************** static TypeName *TableFuncTypeName(List 
*** 511,517 ****
  	SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
  	SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SHARE
  	SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
! 	STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
  	SYMMETRIC SYSID SYSTEM_P
  
  	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
--- 511,517 ----
  	SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
  	SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SHARE
  	SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
! 	STATISTICS STDIN STDOUT STORAGE STORAGES STRICT_P STRIP_P SUBSTRING SUPERUSER_P
  	SYMMETRIC SYSID SYSTEM_P
  
  	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
*************** TableLikeOption:
*** 2350,2355 ****
--- 2350,2359 ----
  				| EXCLUDING CONSTRAINTS				{ $$ = 	CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS; }
  				| INCLUDING INDEXES					{ $$ = 	CREATE_TABLE_LIKE_INCLUDING_INDEXES; }
  				| EXCLUDING INDEXES					{ $$ = 	CREATE_TABLE_LIKE_EXCLUDING_INDEXES; }
+ 				| INCLUDING STORAGES				{ $$ = 	CREATE_TABLE_LIKE_INCLUDING_STORAGES; }
+ 				| EXCLUDING STORAGES				{ $$ = 	CREATE_TABLE_LIKE_EXCLUDING_STORAGES; }
+ 				| INCLUDING COMMENTS				{ $$ = 	CREATE_TABLE_LIKE_INCLUDING_COMMENTS; }
+ 				| EXCLUDING COMMENTS				{ $$ = 	CREATE_TABLE_LIKE_EXCLUDING_COMMENTS; }
  		;
  
  
*************** unreserved_keyword:
*** 10239,10244 ****
--- 10243,10249 ----
  			| CLOSE
  			| CLUSTER
  			| COMMENT
+ 			| COMMENTS
  			| COMMIT
  			| COMMITTED
  			| CONCURRENTLY
*************** unreserved_keyword:
*** 10416,10421 ****
--- 10421,10427 ----
  			| STDIN
  			| STDOUT
  			| STORAGE
+ 			| STORAGES
  			| STRICT_P
  			| STRIP_P
  			| SUPERUSER_P
diff -cpr --exclude=CVS head/src/backend/parser/parse_utilcmd.c work/src/backend/parser/parse_utilcmd.c
*** head/src/backend/parser/parse_utilcmd.c	2009-07-30 11:45:37.000000000 +0900
--- work/src/backend/parser/parse_utilcmd.c	2009-09-06 16:58:33.718541820 +0900
***************
*** 36,41 ****
--- 36,42 ----
  #include "catalog/pg_constraint.h"
  #include "catalog/pg_opclass.h"
  #include "catalog/pg_type.h"
+ #include "commands/comment.h"
  #include "commands/defrem.h"
  #include "commands/tablecmds.h"
  #include "commands/tablespace.h"
*************** transformInhRelation(ParseState *pstate,
*** 549,554 ****
--- 550,557 ----
  	bool		including_defaults = false;
  	bool		including_constraints = false;
  	bool		including_indexes = false;
+ 	bool		including_storages = false;
+ 	bool		including_comments = false;
  	ListCell   *elem;
  
  	relation = parserOpenTable(pstate, inhRelation->relation, AccessShareLock);
*************** transformInhRelation(ParseState *pstate,
*** 595,600 ****
--- 598,615 ----
  			case CREATE_TABLE_LIKE_EXCLUDING_INDEXES:
  				including_indexes = false;
  				break;
+ 			case CREATE_TABLE_LIKE_INCLUDING_STORAGES:
+ 				including_storages = true;
+ 				break;
+ 			case CREATE_TABLE_LIKE_EXCLUDING_STORAGES:
+ 				including_storages = false;
+ 				break;
+ 			case CREATE_TABLE_LIKE_INCLUDING_COMMENTS:
+ 				including_comments = true;
+ 				break;
+ 			case CREATE_TABLE_LIKE_EXCLUDING_COMMENTS:
+ 				including_comments = false;
+ 				break;
  			default:
  				elog(ERROR, "unrecognized CREATE TABLE LIKE option: %d",
  					 option);
*************** transformInhRelation(ParseState *pstate,
*** 668,673 ****
--- 683,712 ----
  
  			def->cooked_default = pstrdup(this_default);
  		}
+ 
+ 		/* Likewise, copy storage if requested */
+ 		if (including_storages)
+ 			def->storage = attribute->attstorage;
+ 
+ 		/* Likewise, copy comment if requested */
+ 		if (including_comments)
+ 		{
+ 			char	   *comment;
+ 
+ 			if ((comment = GetComment(attribute->attrelid, RelationRelationId, attribute->attnum)) != NULL)
+ 			{
+ 				CommentStmt *stmt = makeNode(CommentStmt);
+ 
+ 				stmt->objtype = OBJECT_COLUMN;
+ 				stmt->objname = list_make3(makeString(cxt->relation->schemaname),
+ 										   makeString(cxt->relation->relname),
+ 										   makeString(def->colname));
+ 				stmt->objargs = NIL;
+ 				stmt->comment = comment;
+ 
+ 				cxt->alist = lappend(cxt->alist, stmt);
+ 			}
+ 		}
  	}
  
  	/*
diff -cpr --exclude=CVS head/src/include/commands/comment.h work/src/include/commands/comment.h
*** head/src/include/commands/comment.h	2009-06-11 23:49:11.000000000 +0900
--- work/src/include/commands/comment.h	2009-09-06 13:15:24.482240402 +0900
*************** extern void DeleteSharedComments(Oid oid
*** 39,42 ****
--- 39,44 ----
  
  extern void CreateSharedComments(Oid oid, Oid classoid, char *comment);
  
+ extern char *GetComment(Oid oid, Oid classoid, int32 subid);
+ 
  #endif   /* COMMENT_H */
diff -cpr --exclude=CVS head/src/include/nodes/parsenodes.h work/src/include/nodes/parsenodes.h
*** head/src/include/nodes/parsenodes.h	2009-08-03 07:14:53.000000000 +0900
--- work/src/include/nodes/parsenodes.h	2009-09-06 16:40:59.379534872 +0900
*************** typedef struct ColumnDef
*** 461,466 ****
--- 461,467 ----
  	int			inhcount;		/* number of times column is inherited */
  	bool		is_local;		/* column has local (non-inherited) def'n */
  	bool		is_not_null;	/* NOT NULL constraint specified? */
+ 	char		storage;		/* storage parameter of column */
  	Node	   *raw_default;	/* default value (untransformed parse tree) */
  	char	   *cooked_default; /* nodeToString representation */
  	List	   *constraints;	/* other constraints on column */
*************** typedef enum CreateStmtLikeOption
*** 483,489 ****
  	CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS,
  	CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS,
  	CREATE_TABLE_LIKE_INCLUDING_INDEXES,
! 	CREATE_TABLE_LIKE_EXCLUDING_INDEXES
  } CreateStmtLikeOption;
  
  /*
--- 484,494 ----
  	CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS,
  	CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS,
  	CREATE_TABLE_LIKE_INCLUDING_INDEXES,
! 	CREATE_TABLE_LIKE_EXCLUDING_INDEXES,
! 	CREATE_TABLE_LIKE_INCLUDING_STORAGES,
! 	CREATE_TABLE_LIKE_EXCLUDING_STORAGES,
! 	CREATE_TABLE_LIKE_INCLUDING_COMMENTS,
! 	CREATE_TABLE_LIKE_EXCLUDING_COMMENTS
  } CreateStmtLikeOption;
  
  /*
diff -cpr --exclude=CVS head/src/include/parser/kwlist.h work/src/include/parser/kwlist.h
*** head/src/include/parser/kwlist.h	2009-04-06 17:42:53.000000000 +0900
--- work/src/include/parser/kwlist.h	2009-09-06 15:13:57.966535522 +0900
*************** PG_KEYWORD("coalesce", COALESCE, COL_NAM
*** 80,85 ****
--- 80,86 ----
  PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD)
  PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD)
  PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD)
+ PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD)
  PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD)
  PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD)
  PG_KEYWORD("concurrently", CONCURRENTLY, UNRESERVED_KEYWORD)
*************** PG_KEYWORD("statistics", STATISTICS, UNR
*** 348,353 ****
--- 349,355 ----
  PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD)
  PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD)
  PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD)
+ PG_KEYWORD("storages", STORAGES, UNRESERVED_KEYWORD)
  PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD)
  PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD)
  PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD)
diff -cpr --exclude=CVS head/src/test/regress/expected/inherit.out work/src/test/regress/expected/inherit.out
*** head/src/test/regress/expected/inherit.out	2009-08-02 04:59:41.000000000 +0900
--- work/src/test/regress/expected/inherit.out	2009-09-06 16:29:56.346467000 +0900
*************** drop table pp1 cascade;
*** 906,908 ****
--- 906,989 ----
  NOTICE:  drop cascades to 2 other objects
  DETAIL:  drop cascades to table cc1
  drop cascades to table cc2
+ -- including storages and comments
+ CREATE TABLE t1 (a text, b text);
+ COMMENT ON COLUMN t1.a IS 'A';
+ COMMENT ON COLUMN t1.b IS 'B';
+ ALTER TABLE t1 ALTER COLUMN a SET STORAGE MAIN;
+ CREATE TABLE t2 (c text);
+ ALTER TABLE t2 ALTER COLUMN c SET STORAGE EXTERNAL;
+ COMMENT ON COLUMN t2.c IS 'C';
+ CREATE TABLE t3 (a text, c text);
+ ALTER TABLE t3 ALTER COLUMN c SET STORAGE EXTERNAL;
+ ALTER TABLE t3 ALTER COLUMN a SET STORAGE MAIN;
+ COMMENT ON COLUMN t3.a IS 'A3';
+ COMMENT ON COLUMN t3.c IS 'C';
+ CREATE TABLE t4 (a text, c text);
+ ALTER TABLE t4 ALTER COLUMN c SET STORAGE EXTERNAL;
+ CREATE TABLE t12_storages (LIKE t1 INCLUDING STORAGES, LIKE t2 INCLUDING STORAGES);
+ \d+ t12_storages
+             Table "public.t12_storages"
+  Column | Type | Modifiers | Storage  | Description 
+ --------+------+-----------+----------+-------------
+  a      | text |           | main     | 
+  b      | text |           | extended | 
+  c      | text |           | external | 
+ Has OIDs: no
+ 
+ CREATE TABLE t12_comments (LIKE t1 INCLUDING COMMENTS, LIKE t2 INCLUDING COMMENTS);
+ \d+ t12_comments
+             Table "public.t12_comments"
+  Column | Type | Modifiers | Storage  | Description 
+ --------+------+-----------+----------+-------------
+  a      | text |           | extended | A
+  b      | text |           | extended | B
+  c      | text |           | extended | C
+ Has OIDs: no
+ 
+ CREATE TABLE t1_inh (LIKE t1 INCLUDING COMMENTS) INHERITS (t1);
+ NOTICE:  merging column "a" with inherited definition
+ NOTICE:  merging column "b" with inherited definition
+ \d+ t1_inh
+                Table "public.t1_inh"
+  Column | Type | Modifiers | Storage  | Description 
+ --------+------+-----------+----------+-------------
+  a      | text |           | main     | A
+  b      | text |           | extended | B
+ Inherits: t1
+ Has OIDs: no
+ 
+ CREATE TABLE t13_inh () INHERITS (t1, t3);
+ NOTICE:  merging multiple inherited definitions of column "a"
+ \d+ t13_inh
+                Table "public.t13_inh"
+  Column | Type | Modifiers | Storage  | Description 
+ --------+------+-----------+----------+-------------
+  a      | text |           | main     | 
+  b      | text |           | extended | 
+  c      | text |           | external | 
+ Inherits: t1,
+           t3
+ Has OIDs: no
+ 
+ CREATE TABLE t13_like (LIKE t3 INCLUDING COMMENTS INCLUDING STORAGES) INHERITS (t1);
+ NOTICE:  merging column "a" with inherited definition
+ \d+ t13_like
+               Table "public.t13_like"
+  Column | Type | Modifiers | Storage  | Description 
+ --------+------+-----------+----------+-------------
+  a      | text |           | main     | A3
+  b      | text |           | extended | 
+  c      | text |           | external | C
+ Inherits: t1
+ Has OIDs: no
+ 
+ CREATE TABLE inh_error1 () INHERITS (t1, t4);
+ NOTICE:  merging multiple inherited definitions of column "a"
+ ERROR:  inherited column "a" has a storage parameter conflict
+ DETAIL:  MAIN versus EXTENDED
+ CREATE TABLE inh_error2 (LIKE t4 INCLUDING STORAGES) INHERITS (t1);
+ NOTICE:  merging column "a" with inherited definition
+ ERROR:  column "a" has a storage parameter conflict
+ DETAIL:  MAIN versus EXTENDED
+ DROP TABLE t1, t2, t3, t4, t12_storages, t12_comments, t1_inh, t13_inh, t13_like;
diff -cpr --exclude=CVS head/src/test/regress/sql/inherit.sql work/src/test/regress/sql/inherit.sql
*** head/src/test/regress/sql/inherit.sql	2008-05-10 08:32:05.000000000 +0900
--- work/src/test/regress/sql/inherit.sql	2009-09-06 16:29:22.903535459 +0900
*************** create table cc2(f4 float) inherits(pp1,
*** 276,278 ****
--- 276,312 ----
  alter table pp1 add column a2 int check (a2 > 0);
  \d cc2
  drop table pp1 cascade;
+ 
+ -- including storages and comments
+ CREATE TABLE t1 (a text, b text);
+ COMMENT ON COLUMN t1.a IS 'A';
+ COMMENT ON COLUMN t1.b IS 'B';
+ ALTER TABLE t1 ALTER COLUMN a SET STORAGE MAIN;
+ 
+ CREATE TABLE t2 (c text);
+ ALTER TABLE t2 ALTER COLUMN c SET STORAGE EXTERNAL;
+ COMMENT ON COLUMN t2.c IS 'C';
+ 
+ CREATE TABLE t3 (a text, c text);
+ ALTER TABLE t3 ALTER COLUMN c SET STORAGE EXTERNAL;
+ ALTER TABLE t3 ALTER COLUMN a SET STORAGE MAIN;
+ COMMENT ON COLUMN t3.a IS 'A3';
+ COMMENT ON COLUMN t3.c IS 'C';
+ 
+ CREATE TABLE t4 (a text, c text);
+ ALTER TABLE t4 ALTER COLUMN c SET STORAGE EXTERNAL;
+ 
+ CREATE TABLE t12_storages (LIKE t1 INCLUDING STORAGES, LIKE t2 INCLUDING STORAGES);
+ \d+ t12_storages
+ CREATE TABLE t12_comments (LIKE t1 INCLUDING COMMENTS, LIKE t2 INCLUDING COMMENTS);
+ \d+ t12_comments
+ CREATE TABLE t1_inh (LIKE t1 INCLUDING COMMENTS) INHERITS (t1);
+ \d+ t1_inh
+ CREATE TABLE t13_inh () INHERITS (t1, t3);
+ \d+ t13_inh
+ CREATE TABLE t13_like (LIKE t3 INCLUDING COMMENTS INCLUDING STORAGES) INHERITS (t1);
+ \d+ t13_like
+ CREATE TABLE inh_error1 () INHERITS (t1, t4);
+ CREATE TABLE inh_error2 (LIKE t4 INCLUDING STORAGES) INHERITS (t1);
+ 
+ DROP TABLE t1, t2, t3, t4, t12_storages, t12_comments, t1_inh, t13_inh, t13_like;