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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy