Skip to content

Commit dc2c25f

Browse files
committed
Add INCLUDING CONSTRAINTS to CREATE TABLE LIKE.
Greg Stark
1 parent 62f2693 commit dc2c25f

File tree

12 files changed

+206
-39
lines changed

12 files changed

+206
-39
lines changed

doc/src/sgml/ref/create_table.sgml

Lines changed: 17 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.100 2006/02/19 00:04:26 neilc Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.101 2006/06/27 03:43:19 momjian Exp $
33
PostgreSQL documentation
44
-->
55

@@ -23,7 +23,7 @@ PostgreSQL documentation
2323
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
2424
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
2525
| <replaceable>table_constraint</replaceable>
26-
| LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } DEFAULTS ] }
26+
| LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS } ] ... }
2727
[, ... ]
2828
] )
2929
[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
@@ -232,7 +232,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
232232
</varlistentry>
233233

234234
<varlistentry>
235-
<term><literal>LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } DEFAULTS ]</literal></term>
235+
<term><literal>LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS } ]</literal></term>
236236
<listitem>
237237
<para>
238238
The <literal>LIKE</literal> clause specifies a table from which
@@ -252,6 +252,20 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
252252
default behavior is to exclude default expressions, resulting in
253253
all columns of the new table having null defaults.
254254
</para>
255+
<para>
256+
Likewise constraints for the copied column definitions will only be
257+
copied if <literal>INCLUDING CONSTRAINTS</literal> is specified. Note
258+
that currently even when <literal>INCLUDING CONSTRAINTS</literal> is specified
259+
only CHECK constraints are copied. Also, no distinction is made between
260+
column constraints and table constraints -- when constraints are
261+
requested all check constraints are copied.
262+
</para>
263+
<para>
264+
Note also that unlike <literal>INHERITS<literal> copied columns and
265+
constraints are not merged with similarly named columns and constraints.
266+
If the same name is specified explicitly or in another
267+
<literal>LIKE</literal> clause an error is signalled.
268+
</para>
255269
</listitem>
256270
</varlistentry>
257271

src/backend/commands/tablecmds.c

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.186 2006/06/27 03:21:54 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.187 2006/06/27 03:43:19 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -159,7 +159,7 @@ typedef struct NewColumnValue
159159
static void truncate_check_rel(Relation rel);
160160
static List *MergeAttributes(List *schema, List *supers, bool istemp,
161161
List **supOids, List **supconstr, int *supOidCount);
162-
static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
162+
static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
163163
static void StoreCatalogInheritance(Oid relationId, List *supers);
164164
static int findAttrByName(const char *attributeName, List *schema);
165165
static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
@@ -1106,14 +1106,59 @@ MergeAttributes(List *schema, List *supers, bool istemp,
11061106
}
11071107

11081108
/*
1109-
* complementary static functions for MergeAttributes().
1110-
*
11111109
* Varattnos of pg_constraint.conbin must be rewritten when subclasses inherit
11121110
* constraints from parent classes, since the inherited attributes could
11131111
* be given different column numbers in multiple-inheritance cases.
11141112
*
11151113
* Note that the passed node tree is modified in place!
1114+
*
1115+
* This function is used elsewhere such as in analyze.c
1116+
*
11161117
*/
1118+
1119+
void
1120+
change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
1121+
{
1122+
change_varattnos_walker(node, newattno);
1123+
}
1124+
1125+
/* Generate a map for change_varattnos_of_a_node from two tupledesc's. */
1126+
1127+
AttrNumber *
1128+
varattnos_map(TupleDesc old, TupleDesc new)
1129+
{
1130+
int i,j;
1131+
AttrNumber *attmap = palloc0(sizeof(AttrNumber)*old->natts);
1132+
for (i=1; i <= old->natts; i++) {
1133+
if (old->attrs[i-1]->attisdropped) {
1134+
attmap[i-1] = 0;
1135+
continue;
1136+
}
1137+
for (j=1; j<= new->natts; j++)
1138+
if (!strcmp(NameStr(old->attrs[i-1]->attname), NameStr(new->attrs[j-1]->attname)))
1139+
attmap[i-1] = j;
1140+
}
1141+
return attmap;
1142+
}
1143+
1144+
/* Generate a map for change_varattnos_of_a_node from a tupledesc and a list of
1145+
* ColumnDefs */
1146+
1147+
AttrNumber *
1148+
varattnos_map_schema(TupleDesc old, List *schema)
1149+
{
1150+
int i;
1151+
AttrNumber *attmap = palloc0(sizeof(AttrNumber)*old->natts);
1152+
for (i=1; i <= old->natts; i++) {
1153+
if (old->attrs[i-1]->attisdropped) {
1154+
attmap[i-1] = 0;
1155+
continue;
1156+
}
1157+
attmap[i-1] = findAttrByName(NameStr(old->attrs[i-1]->attname), schema);
1158+
}
1159+
return attmap;
1160+
}
1161+
11171162
static bool
11181163
change_varattnos_walker(Node *node, const AttrNumber *newattno)
11191164
{
@@ -1140,12 +1185,6 @@ change_varattnos_walker(Node *node, const AttrNumber *newattno)
11401185
(void *) newattno);
11411186
}
11421187

1143-
static bool
1144-
change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
1145-
{
1146-
return change_varattnos_walker(node, newattno);
1147-
}
1148-
11491188
/*
11501189
* StoreCatalogInheritance
11511190
* Updates the system catalogs with proper inheritance information.

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.336 2006/06/16 20:23:44 adunstan Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.337 2006/06/27 03:43:19 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1940,7 +1940,7 @@ _copyInhRelation(InhRelation *from)
19401940
InhRelation *newnode = makeNode(InhRelation);
19411941

19421942
COPY_NODE_FIELD(relation);
1943-
COPY_SCALAR_FIELD(including_defaults);
1943+
COPY_NODE_FIELD(options);
19441944

19451945
return newnode;
19461946
}

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.272 2006/06/16 20:23:44 adunstan Exp $
21+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.273 2006/06/27 03:43:20 momjian Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -884,7 +884,7 @@ static bool
884884
_equalInhRelation(InhRelation *a, InhRelation *b)
885885
{
886886
COMPARE_NODE_FIELD(relation);
887-
COMPARE_SCALAR_FIELD(including_defaults);
887+
COMPARE_NODE_FIELD(options);
888888

889889
return true;
890890
}

src/backend/parser/analyze.c

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.335 2006/06/21 18:30:11 tgl Exp $
9+
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.336 2006/06/27 03:43:20 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -21,6 +21,7 @@
2121
#include "catalog/pg_type.h"
2222
#include "commands/defrem.h"
2323
#include "commands/prepare.h"
24+
#include "commands/tablecmds.h"
2425
#include "miscadmin.h"
2526
#include "nodes/makefuncs.h"
2627
#include "optimizer/clauses.h"
@@ -1075,6 +1076,11 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
10751076
TupleConstr *constr;
10761077
AclResult aclresult;
10771078

1079+
bool including_defaults = false;
1080+
bool including_constraints = false;
1081+
bool including_indexes = false;
1082+
ListCell *elem;
1083+
10781084
relation = heap_openrv(inhRelation->relation, AccessShareLock);
10791085

10801086
if (relation->rd_rel->relkind != RELKIND_RELATION)
@@ -1095,6 +1101,37 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
10951101
tupleDesc = RelationGetDescr(relation);
10961102
constr = tupleDesc->constr;
10971103

1104+
foreach(elem, inhRelation->options)
1105+
{
1106+
int option = lfirst_int(elem);
1107+
switch (option)
1108+
{
1109+
case CREATE_TABLE_LIKE_INCLUDING_DEFAULTS:
1110+
including_defaults = true;
1111+
break;
1112+
case CREATE_TABLE_LIKE_EXCLUDING_DEFAULTS:
1113+
including_defaults = false;
1114+
break;
1115+
case CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS:
1116+
including_constraints = true;
1117+
break;
1118+
case CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS:
1119+
including_constraints = false;
1120+
break;
1121+
case CREATE_TABLE_LIKE_INCLUDING_INDEXES:
1122+
including_indexes = true;
1123+
break;
1124+
case CREATE_TABLE_LIKE_EXCLUDING_INDEXES:
1125+
including_indexes = false;
1126+
break;
1127+
default:
1128+
elog(ERROR, "unrecognized CREATE TABLE LIKE option: %d", option);
1129+
}
1130+
}
1131+
1132+
if (including_indexes)
1133+
elog(ERROR, "TODO");
1134+
10981135
/*
10991136
* Insert the inherited attributes into the cxt for the new table
11001137
* definition.
@@ -1123,7 +1160,7 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
11231160
def->typename = makeTypeNameFromOid(attribute->atttypid,
11241161
attribute->atttypmod);
11251162
def->inhcount = 0;
1126-
def->is_local = false;
1163+
def->is_local = true;
11271164
def->is_not_null = attribute->attnotnull;
11281165
def->raw_default = NULL;
11291166
def->cooked_default = NULL;
@@ -1138,7 +1175,7 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
11381175
/*
11391176
* Copy default if any, and the default has been requested
11401177
*/
1141-
if (attribute->atthasdef && inhRelation->including_defaults)
1178+
if (attribute->atthasdef && including_defaults)
11421179
{
11431180
char *this_default = NULL;
11441181
AttrDefault *attrdef;
@@ -1165,6 +1202,27 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
11651202
def->cooked_default = pstrdup(this_default);
11661203
}
11671204
}
1205+
1206+
if (including_constraints && tupleDesc->constr) {
1207+
int ccnum;
1208+
AttrNumber *attmap = varattnos_map_schema(tupleDesc, cxt->columns);
1209+
1210+
for(ccnum = 0; ccnum < tupleDesc->constr->num_check; ccnum++) {
1211+
char *ccname = tupleDesc->constr->check[ccnum].ccname;
1212+
char *ccbin = tupleDesc->constr->check[ccnum].ccbin;
1213+
Node *ccbin_node = stringToNode(ccbin);
1214+
Constraint *n = makeNode(Constraint);
1215+
1216+
change_varattnos_of_a_node(ccbin_node, attmap);
1217+
1218+
n->contype = CONSTR_CHECK;
1219+
n->name = pstrdup(ccname);
1220+
n->raw_expr = ccbin_node;
1221+
n->cooked_expr = NULL;
1222+
n->indexspace = NULL;
1223+
cxt->ckconstraints = lappend(cxt->ckconstraints, (Node*)n);
1224+
}
1225+
}
11681226

11691227
/*
11701228
* Close the parent rel, but keep our AccessShareLock on it until xact

src/backend/parser/gram.y

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.547 2006/06/16 23:50:48 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.548 2006/06/27 03:43:20 momjian Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -193,8 +193,6 @@ static void doNegateFloat(Value *v);
193193
opt_grant_grant_option opt_grant_admin_option
194194
opt_nowait opt_if_exists
195195

196-
%type <boolean> like_including_defaults
197-
198196
%type <list> OptRoleList
199197
%type <defelt> OptRoleElem
200198

@@ -335,7 +333,9 @@ static void doNegateFloat(Value *v);
335333
%type <keyword> unreserved_keyword func_name_keyword
336334
%type <keyword> col_name_keyword reserved_keyword
337335

338-
%type <node> TableConstraint TableLikeClause
336+
%type <node> TableConstraint TableLikeClause
337+
%type <list> TableLikeOptionList
338+
%type <ival> TableLikeOption
339339
%type <list> ColQualList
340340
%type <node> ColConstraint ColConstraintElem ConstraintAttr
341341
%type <ival> key_actions key_delete key_match key_update key_action
@@ -385,7 +385,7 @@ static void doNegateFloat(Value *v);
385385
HANDLER HAVING HEADER_P HOLD HOUR_P
386386

387387
IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
388-
INDEX INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
388+
INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
389389
INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
390390
INTERVAL INTO INVOKER IS ISNULL ISOLATION
391391

@@ -1994,20 +1994,27 @@ ConstraintAttr:
19941994
* which is a part of SQL 200N
19951995
*/
19961996
TableLikeClause:
1997-
LIKE qualified_name like_including_defaults
1997+
LIKE qualified_name TableLikeOptionList
19981998
{
19991999
InhRelation *n = makeNode(InhRelation);
20002000
n->relation = $2;
2001-
n->including_defaults = $3;
2002-
2001+
n->options = $3;
20032002
$$ = (Node *)n;
20042003
}
20052004
;
20062005

2007-
like_including_defaults:
2008-
INCLUDING DEFAULTS { $$ = true; }
2009-
| EXCLUDING DEFAULTS { $$ = false; }
2010-
| /* EMPTY */ { $$ = false; }
2006+
TableLikeOptionList:
2007+
TableLikeOptionList TableLikeOption { $$ = lappend_int($1, $2); }
2008+
| /* EMPTY */ { $$ = NIL; }
2009+
;
2010+
2011+
TableLikeOption:
2012+
INCLUDING DEFAULTS { $$ = CREATE_TABLE_LIKE_INCLUDING_DEFAULTS; }
2013+
| EXCLUDING DEFAULTS { $$ = CREATE_TABLE_LIKE_EXCLUDING_DEFAULTS; }
2014+
| INCLUDING CONSTRAINTS { $$ = CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS; }
2015+
| EXCLUDING CONSTRAINTS { $$ = CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS; }
2016+
| INCLUDING INDEXES { $$ = CREATE_TABLE_LIKE_INCLUDING_INDEXES; }
2017+
| EXCLUDING INDEXES { $$ = CREATE_TABLE_LIKE_EXCLUDING_INDEXES; }
20112018
;
20122019

20132020

@@ -8507,6 +8514,7 @@ unreserved_keyword:
85078514
| INCLUDING
85088515
| INCREMENT
85098516
| INDEX
8517+
| INDEXES
85108518
| INHERIT
85118519
| INHERITS
85128520
| INPUT_P

src/backend/parser/keywords.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.171 2006/03/05 15:58:32 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.172 2006/06/27 03:43:20 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -169,6 +169,7 @@ static const ScanKeyword ScanKeywords[] = {
169169
{"including", INCLUDING},
170170
{"increment", INCREMENT},
171171
{"index", INDEX},
172+
{"indexes", INDEXES},
172173
{"inherit", INHERIT},
173174
{"inherits", INHERITS},
174175
{"initially", INITIALLY},

0 commit comments

Comments
 (0)