Skip to content

Commit faa1afc

Browse files
committed
CREATE LIKE INCLUDING COMMENTS and STORAGE, and INCLUDING ALL shortcut. Itagaki Takahiro.
1 parent 0adaf4c commit faa1afc

File tree

15 files changed

+564
-117
lines changed

15 files changed

+564
-117
lines changed

doc/src/sgml/ref/create_table.sgml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.116 2009/09/18 05:00:41 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.117 2009/10/12 19:49:24 adunstan Exp $
33
PostgreSQL documentation
44
-->
55

@@ -24,7 +24,7 @@ PostgreSQL documentation
2424
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
2525
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
2626
| <replaceable>table_constraint</replaceable>
27-
| LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }
27+
| LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | ALL } ] ... }
2828
[, ... ]
2929
] )
3030
[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
@@ -230,6 +230,10 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
230230
will always be chosen for it.
231231
</para>
232232

233+
<para>
234+
Column storage parameters are also copied from parent tables.
235+
</para>
236+
233237
<!--
234238
<para>
235239
<productname>PostgreSQL</> automatically allows the
@@ -247,7 +251,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
247251
</varlistentry>
248252

249253
<varlistentry>
250-
<term><literal>LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ]</literal></term>
254+
<term><literal>LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | ALL } ]</literal></term>
251255
<listitem>
252256
<para>
253257
The <literal>LIKE</literal> clause specifies a table from which
@@ -280,6 +284,23 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
280284
table, unless the <literal>INCLUDING INDEXES</literal> clause is
281285
specified.
282286
</para>
287+
<para>
288+
Storage parameters for the copied column definitions will only be copied
289+
if <literal>INCLUDING STORAGE</literal> is specified. The default
290+
behavior is to exclude storage parameters, resulting in the copied
291+
columns in the new table having type-specific default parameters. For
292+
more on storage parameters, see <xref linkend="storage-toast">.
293+
</para>
294+
<para>
295+
Comments for the copied column, constraint, index and columns of index
296+
definitions will only be copied if <literal>INCLUDING COMMENTS</literal>
297+
is specified. The default behavior is to exclude comments, resulting in
298+
the copied columns and constraints in the new table having no comments.
299+
</para>
300+
<para>
301+
<literal>INCLUDING ALL</literal> is an abbreviated form of
302+
<literal>INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS</literal>.
303+
</para>
283304
<para>
284305
Note also that unlike <literal>INHERITS</literal>, copied columns and
285306
constraints are not merged with similarly named columns and constraints.

src/backend/access/common/tupdesc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.128 2009/08/02 22:14:51 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.129 2009/10/12 19:49:24 adunstan Exp $
1212
*
1313
* NOTES
1414
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -558,6 +558,8 @@ BuildDescForRelation(List *schema)
558558
has_not_null |= entry->is_not_null;
559559
desc->attrs[attnum - 1]->attislocal = entry->is_local;
560560
desc->attrs[attnum - 1]->attinhcount = entry->inhcount;
561+
if (entry->storage)
562+
desc->attrs[attnum - 1]->attstorage = entry->storage;
561563
}
562564

563565
if (has_not_null)

src/backend/catalog/pg_constraint.c

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.47 2009/07/28 02:56:29 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.48 2009/10/12 19:49:24 adunstan Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -702,3 +702,65 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
702702

703703
heap_close(conRel, RowExclusiveLock);
704704
}
705+
706+
/*
707+
* GetConstraintByName
708+
* Find a constraint with the specified name.
709+
*/
710+
Oid
711+
GetConstraintByName(Oid relid, const char *conname)
712+
{
713+
Relation pg_constraint;
714+
HeapTuple tuple;
715+
SysScanDesc scan;
716+
ScanKeyData skey[1];
717+
Oid conOid = InvalidOid;
718+
719+
/*
720+
* Fetch the constraint tuple from pg_constraint. There may be more than
721+
* one match, because constraints are not required to have unique names;
722+
* if so, error out.
723+
*/
724+
pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
725+
726+
ScanKeyInit(&skey[0],
727+
Anum_pg_constraint_conrelid,
728+
BTEqualStrategyNumber, F_OIDEQ, relid);
729+
730+
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
731+
SnapshotNow, 1, skey);
732+
733+
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
734+
{
735+
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
736+
737+
if (strcmp(NameStr(con->conname), conname) == 0)
738+
{
739+
if (OidIsValid(conOid))
740+
{
741+
char *relname = get_rel_name(relid);
742+
ereport(ERROR,
743+
(errcode(ERRCODE_DUPLICATE_OBJECT),
744+
errmsg("table \"%s\" has multiple constraints named \"%s\"",
745+
(relname ? relname : "(unknown)"), conname)));
746+
}
747+
conOid = HeapTupleGetOid(tuple);
748+
}
749+
}
750+
751+
systable_endscan(scan);
752+
753+
/* If no constraint exists for the relation specified, notify user */
754+
if (!OidIsValid(conOid))
755+
{
756+
char *relname = get_rel_name(relid);
757+
ereport(ERROR,
758+
(errcode(ERRCODE_UNDEFINED_OBJECT),
759+
errmsg("constraint \"%s\" for table \"%s\" does not exist",
760+
conname, (relname ? relname : "(unknown)"))));
761+
}
762+
763+
heap_close(pg_constraint, AccessShareLock);
764+
765+
return conOid;
766+
}

src/backend/commands/comment.c

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.107 2009/06/11 14:48:55 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.108 2009/10/12 19:49:24 adunstan Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -462,6 +462,61 @@ DeleteSharedComments(Oid oid, Oid classoid)
462462
heap_close(shdescription, RowExclusiveLock);
463463
}
464464

465+
/*
466+
* GetComment -- get the comment for an object, or null if not found.
467+
*/
468+
char *
469+
GetComment(Oid oid, Oid classoid, int32 subid)
470+
{
471+
Relation description;
472+
ScanKeyData skey[3];
473+
SysScanDesc sd;
474+
TupleDesc tupdesc;
475+
HeapTuple tuple;
476+
char *comment;
477+
478+
/* Use the index to search for a matching old tuple */
479+
480+
ScanKeyInit(&skey[0],
481+
Anum_pg_description_objoid,
482+
BTEqualStrategyNumber, F_OIDEQ,
483+
ObjectIdGetDatum(oid));
484+
ScanKeyInit(&skey[1],
485+
Anum_pg_description_classoid,
486+
BTEqualStrategyNumber, F_OIDEQ,
487+
ObjectIdGetDatum(classoid));
488+
ScanKeyInit(&skey[2],
489+
Anum_pg_description_objsubid,
490+
BTEqualStrategyNumber, F_INT4EQ,
491+
Int32GetDatum(subid));
492+
493+
description = heap_open(DescriptionRelationId, AccessShareLock);
494+
tupdesc = RelationGetDescr(description);
495+
496+
sd = systable_beginscan(description, DescriptionObjIndexId, true,
497+
SnapshotNow, 3, skey);
498+
499+
comment = NULL;
500+
while ((tuple = systable_getnext(sd)) != NULL)
501+
{
502+
Datum value;
503+
bool isnull;
504+
505+
/* Found the tuple, get description field */
506+
value = heap_getattr(tuple, Anum_pg_description_description, tupdesc, &isnull);
507+
if (!isnull)
508+
comment = TextDatumGetCString(value);
509+
break; /* Assume there can be only one match */
510+
}
511+
512+
systable_endscan(sd);
513+
514+
/* Done */
515+
heap_close(description, AccessShareLock);
516+
517+
return comment;
518+
}
519+
465520
/*
466521
* CommentRelation --
467522
*
@@ -1064,12 +1119,8 @@ CommentConstraint(List *qualname, char *comment)
10641119
List *relName;
10651120
char *conName;
10661121
RangeVar *rel;
1067-
Relation pg_constraint,
1068-
relation;
1069-
HeapTuple tuple;
1070-
SysScanDesc scan;
1071-
ScanKeyData skey[1];
1072-
Oid conOid = InvalidOid;
1122+
Relation relation;
1123+
Oid conOid;
10731124

10741125
/* Separate relname and constraint name */
10751126
nnames = list_length(qualname);
@@ -1088,50 +1139,12 @@ CommentConstraint(List *qualname, char *comment)
10881139
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
10891140
RelationGetRelationName(relation));
10901141

1091-
/*
1092-
* Fetch the constraint tuple from pg_constraint. There may be more than
1093-
* one match, because constraints are not required to have unique names;
1094-
* if so, error out.
1095-
*/
1096-
pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
1097-
1098-
ScanKeyInit(&skey[0],
1099-
Anum_pg_constraint_conrelid,
1100-
BTEqualStrategyNumber, F_OIDEQ,
1101-
ObjectIdGetDatum(RelationGetRelid(relation)));
1102-
1103-
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
1104-
SnapshotNow, 1, skey);
1105-
1106-
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1107-
{
1108-
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
1109-
1110-
if (strcmp(NameStr(con->conname), conName) == 0)
1111-
{
1112-
if (OidIsValid(conOid))
1113-
ereport(ERROR,
1114-
(errcode(ERRCODE_DUPLICATE_OBJECT),
1115-
errmsg("table \"%s\" has multiple constraints named \"%s\"",
1116-
RelationGetRelationName(relation), conName)));
1117-
conOid = HeapTupleGetOid(tuple);
1118-
}
1119-
}
1120-
1121-
systable_endscan(scan);
1122-
1123-
/* If no constraint exists for the relation specified, notify user */
1124-
if (!OidIsValid(conOid))
1125-
ereport(ERROR,
1126-
(errcode(ERRCODE_UNDEFINED_OBJECT),
1127-
errmsg("constraint \"%s\" for table \"%s\" does not exist",
1128-
conName, RelationGetRelationName(relation))));
1142+
conOid = GetConstraintByName(RelationGetRelid(relation), conName);
11291143

11301144
/* Call CreateComments() to create/drop the comments */
11311145
CreateComments(conOid, ConstraintRelationId, 0, comment);
11321146

11331147
/* Done, but hold lock on relation */
1134-
heap_close(pg_constraint, AccessShareLock);
11351148
heap_close(relation, NoLock);
11361149
}
11371150

0 commit comments

Comments
 (0)