Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8f2f180

Browse files
committed
Code review for LIKE INCLUDING CONSTRAINTS patch --- improve comments,
don't cheat on the raw-vs-cooked status of a constraint.
1 parent3f16647 commit8f2f180

File tree

3 files changed

+142
-106
lines changed

3 files changed

+142
-106
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 114 additions & 83 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.204 2006/10/06 17:13:59 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.205 2006/10/11 16:42:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -163,6 +163,8 @@ static List *MergeAttributes(List *schema, List *supers, bool istemp,
163163
List**supOids,List**supconstr,int*supOidCount);
164164
staticvoidMergeConstraintsIntoExisting(Relationchild_rel,Relationparent_rel);
165165
staticvoidMergeAttributesIntoExisting(Relationchild_rel,Relationparent_rel);
166+
staticvoidadd_nonduplicate_constraint(Constraint*cdef,
167+
ConstrCheck*check,int*ncheck);
166168
staticboolchange_varattnos_walker(Node*node,constAttrNumber*newattno);
167169
staticvoidStoreCatalogInheritance(OidrelationId,List*supers);
168170
staticvoidStoreCatalogInheritance1(OidrelationId,OidparentOid,
@@ -285,7 +287,6 @@ DefineRelation(CreateStmt *stmt, char relkind)
285287
List*rawDefaults;
286288
Datumreloptions;
287289
ListCell*listptr;
288-
inti;
289290
AttrNumberattnum;
290291

291292
/*
@@ -378,49 +379,35 @@ DefineRelation(CreateStmt *stmt, char relkind)
378379
localHasOids=interpretOidsOption(stmt->options);
379380
descriptor->tdhasoid= (localHasOids||parentOidCount>0);
380381

381-
if (old_constraints!=NIL)
382+
if (old_constraints||stmt->constraints)
382383
{
383-
ConstrCheck*check= (ConstrCheck*)
384-
palloc0(list_length(old_constraints)*sizeof(ConstrCheck));
384+
ConstrCheck*check;
385385
intncheck=0;
386386

387+
/* make array that's certainly big enough */
388+
check= (ConstrCheck*)
389+
palloc((list_length(old_constraints)+
390+
list_length(stmt->constraints))*sizeof(ConstrCheck));
391+
/* deal with constraints from MergeAttributes */
387392
foreach(listptr,old_constraints)
388393
{
389394
Constraint*cdef= (Constraint*)lfirst(listptr);
390-
booldup= false;
391395

392-
if (cdef->contype!=CONSTR_CHECK)
393-
continue;
394-
Assert(cdef->name!=NULL);
395-
Assert(cdef->raw_expr==NULL&&cdef->cooked_expr!=NULL);
396+
if (cdef->contype==CONSTR_CHECK)
397+
add_nonduplicate_constraint(cdef,check,&ncheck);
398+
}
399+
/*
400+
* analyze.c might have passed some precooked constraints too,
401+
* due to LIKE tab INCLUDING CONSTRAINTS
402+
*/
403+
foreach(listptr,stmt->constraints)
404+
{
405+
Constraint*cdef= (Constraint*)lfirst(listptr);
396406

397-
/*
398-
* In multiple-inheritance situations, it's possible to inherit
399-
* the same grandparent constraint through multiple parents.
400-
* Hence, discard inherited constraints that match as to both name
401-
* and expression.Otherwise, gripe if the names conflict.
402-
*/
403-
for (i=0;i<ncheck;i++)
404-
{
405-
if (strcmp(check[i].ccname,cdef->name)!=0)
406-
continue;
407-
if (strcmp(check[i].ccbin,cdef->cooked_expr)==0)
408-
{
409-
dup= true;
410-
break;
411-
}
412-
ereport(ERROR,
413-
(errcode(ERRCODE_DUPLICATE_OBJECT),
414-
errmsg("duplicate check constraint name \"%s\"",
415-
cdef->name)));
416-
}
417-
if (!dup)
418-
{
419-
check[ncheck].ccname=cdef->name;
420-
check[ncheck].ccbin=pstrdup(cdef->cooked_expr);
421-
ncheck++;
422-
}
407+
if (cdef->contype==CONSTR_CHECK&&cdef->cooked_expr!=NULL)
408+
add_nonduplicate_constraint(cdef,check,&ncheck);
423409
}
410+
/* if we found any, insert 'em into the descriptor */
424411
if (ncheck>0)
425412
{
426413
if (descriptor->constr==NULL)
@@ -1118,66 +1105,57 @@ MergeAttributes(List *schema, List *supers, bool istemp,
11181105
returnschema;
11191106
}
11201107

1108+
11211109
/*
1122-
* Varattnos of pg_constraint.conbin must be rewritten when subclasses inherit
1123-
* constraints from parent classes, since the inherited attributes could
1124-
* be given different column numbers in multiple-inheritance cases.
1125-
*
1126-
* Note that the passed node tree is modified in place!
1127-
*
1128-
* This function is used elsewhere such as in analyze.c
1129-
*
1110+
* In multiple-inheritance situations, it's possible to inherit
1111+
* the same grandparent constraint through multiple parents.
1112+
* Hence, we want to discard inherited constraints that match as to
1113+
* both name and expression. Otherwise, gripe if there are conflicting
1114+
* names. Nonconflicting constraints are added to the array check[]
1115+
* of length *ncheck ... caller must ensure there is room!
11301116
*/
1131-
1132-
void
1133-
change_varattnos_of_a_node(Node*node,constAttrNumber*newattno)
1117+
staticvoid
1118+
add_nonduplicate_constraint(Constraint*cdef,ConstrCheck*check,int*ncheck)
11341119
{
1135-
change_varattnos_walker(node,newattno);
1136-
}
1137-
1138-
/* Generate a map for change_varattnos_of_a_node from two tupledesc's. */
1120+
inti;
11391121

1140-
AttrNumber*
1141-
varattnos_map(TupleDescold,TupleDescnew)
1142-
{
1143-
inti,
1144-
j;
1145-
AttrNumber*attmap=palloc0(sizeof(AttrNumber)*old->natts);
1122+
/* Should only see precooked constraints here */
1123+
Assert(cdef->contype==CONSTR_CHECK);
1124+
Assert(cdef->name!=NULL);
1125+
Assert(cdef->raw_expr==NULL&&cdef->cooked_expr!=NULL);
11461126

1147-
for (i=1;i <=old->natts;i++)
1127+
for (i=0;i<*ncheck;i++)
11481128
{
1149-
if (old->attrs[i-1]->attisdropped)
1150-
{
1151-
attmap[i-1]=0;
1129+
if (strcmp(check[i].ccname,cdef->name)!=0)
11521130
continue;
1153-
}
1154-
for (j=1;j <=new->natts;j++)
1155-
if (!strcmp(NameStr(old->attrs[i-1]->attname),NameStr(new->attrs[j-1]->attname)))
1156-
attmap[i-1]=j;
1131+
if (strcmp(check[i].ccbin,cdef->cooked_expr)==0)
1132+
return;/* duplicate constraint, so ignore it */
1133+
ereport(ERROR,
1134+
(errcode(ERRCODE_DUPLICATE_OBJECT),
1135+
errmsg("duplicate check constraint name \"%s\"",
1136+
cdef->name)));
11571137
}
1158-
returnattmap;
1138+
/* No match on name, so add it to array */
1139+
check[*ncheck].ccname=cdef->name;
1140+
check[*ncheck].ccbin=pstrdup(cdef->cooked_expr);
1141+
(*ncheck)++;
11591142
}
11601143

1144+
11611145
/*
1162-
* Generate a map for change_varattnos_of_a_node from a tupledesc and a list of
1163-
* ColumnDefs
1146+
* Replace varattno values in an expression tree according to the given
1147+
* map array, that is, varattno N is replaced by newattno[N-1]. It is
1148+
* caller's responsibility to ensure that the array is long enough to
1149+
* define values for all user varattnos present in the tree. System column
1150+
* attnos remain unchanged.
1151+
*
1152+
* Note that the passed node tree is modified in-place!
11641153
*/
1165-
AttrNumber*
1166-
varattnos_map_schema(TupleDescold,List*schema)
1154+
void
1155+
change_varattnos_of_a_node(Node*node,constAttrNumber*newattno)
11671156
{
1168-
inti;
1169-
AttrNumber*attmap=palloc0(sizeof(AttrNumber)*old->natts);
1170-
1171-
for (i=1;i <=old->natts;i++)
1172-
{
1173-
if (old->attrs[i-1]->attisdropped)
1174-
{
1175-
attmap[i-1]=0;
1176-
continue;
1177-
}
1178-
attmap[i-1]=findAttrByName(NameStr(old->attrs[i-1]->attname),schema);
1179-
}
1180-
returnattmap;
1157+
/* no setup needed, so away we go */
1158+
(void)change_varattnos_walker(node,newattno);
11811159
}
11821160

11831161
staticbool
@@ -1206,6 +1184,59 @@ change_varattnos_walker(Node *node, const AttrNumber *newattno)
12061184
(void*)newattno);
12071185
}
12081186

1187+
/*
1188+
* Generate a map for change_varattnos_of_a_node from old and new TupleDesc's,
1189+
* matching according to column name.
1190+
*/
1191+
AttrNumber*
1192+
varattnos_map(TupleDescold,TupleDescnew)
1193+
{
1194+
AttrNumber*attmap;
1195+
inti,
1196+
j;
1197+
1198+
attmap= (AttrNumber*)palloc0(sizeof(AttrNumber)*old->natts);
1199+
for (i=1;i <=old->natts;i++)
1200+
{
1201+
if (old->attrs[i-1]->attisdropped)
1202+
continue;/* leave the entry as zero */
1203+
1204+
for (j=1;j <=new->natts;j++)
1205+
{
1206+
if (strcmp(NameStr(old->attrs[i-1]->attname),
1207+
NameStr(new->attrs[j-1]->attname))==0)
1208+
{
1209+
attmap[i-1]=j;
1210+
break;
1211+
}
1212+
}
1213+
}
1214+
returnattmap;
1215+
}
1216+
1217+
/*
1218+
* Generate a map for change_varattnos_of_a_node from a TupleDesc and a list
1219+
* of ColumnDefs
1220+
*/
1221+
AttrNumber*
1222+
varattnos_map_schema(TupleDescold,List*schema)
1223+
{
1224+
AttrNumber*attmap;
1225+
inti;
1226+
1227+
attmap= (AttrNumber*)palloc0(sizeof(AttrNumber)*old->natts);
1228+
for (i=1;i <=old->natts;i++)
1229+
{
1230+
if (old->attrs[i-1]->attisdropped)
1231+
continue;/* leave the entry as zero */
1232+
1233+
attmap[i-1]=findAttrByName(NameStr(old->attrs[i-1]->attname),
1234+
schema);
1235+
}
1236+
returnattmap;
1237+
}
1238+
1239+
12091240
/*
12101241
* StoreCatalogInheritance
12111242
*Updates the system catalogs with proper inheritance information.

‎src/backend/parser/analyze.c

Lines changed: 16 additions & 11 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.352 2006/10/04 00:29:55 momjian Exp $
9+
*$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.353 2006/10/11 16:42:59 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -1286,12 +1286,10 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
12861286
InhRelation*inhRelation)
12871287
{
12881288
AttrNumberparent_attno;
1289-
12901289
Relationrelation;
12911290
TupleDesctupleDesc;
12921291
TupleConstr*constr;
12931292
AclResultaclresult;
1294-
12951293
boolincluding_defaults= false;
12961294
boolincluding_constraints= false;
12971295
boolincluding_indexes= false;
@@ -1342,15 +1340,18 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
13421340
including_indexes= false;
13431341
break;
13441342
default:
1345-
elog(ERROR,"unrecognized CREATE TABLE LIKE option: %d",option);
1343+
elog(ERROR,"unrecognized CREATE TABLE LIKE option: %d",
1344+
option);
13461345
}
13471346
}
13481347

13491348
if (including_indexes)
1350-
elog(ERROR,"TODO");
1349+
ereport(ERROR,
1350+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1351+
errmsg("LIKE INCLUDING INDEXES is not implemented")));
13511352

13521353
/*
1353-
* Insert theinherited attributes into the cxt for the new table
1354+
* Insert thecopied attributes into the cxt for the new table
13541355
* definition.
13551356
*/
13561357
for (parent_attno=1;parent_attno <=tupleDesc->natts;
@@ -1367,7 +1368,7 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
13671368
continue;
13681369

13691370
/*
1370-
* Create a newinheritedcolumn.
1371+
* Create a new column, which is marked as NOT inherited.
13711372
*
13721373
* For constraints, ONLY the NOT NULL constraint is inherited by the
13731374
* new column definition per SQL99.
@@ -1389,7 +1390,7 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
13891390
cxt->columns=lappend(cxt->columns,def);
13901391

13911392
/*
1392-
* Copy default ifany, and the default has been requested
1393+
* Copy default, ifpresent and the default has been requested
13931394
*/
13941395
if (attribute->atthasdef&&including_defaults)
13951396
{
@@ -1419,10 +1420,14 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
14191420
}
14201421
}
14211422

1423+
/*
1424+
* Copy CHECK constraints if requested, being careful to adjust
1425+
* attribute numbers
1426+
*/
14221427
if (including_constraints&&tupleDesc->constr)
14231428
{
1424-
intccnum;
14251429
AttrNumber*attmap=varattnos_map_schema(tupleDesc,cxt->columns);
1430+
intccnum;
14261431

14271432
for (ccnum=0;ccnum<tupleDesc->constr->num_check;ccnum++)
14281433
{
@@ -1435,8 +1440,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
14351440

14361441
n->contype=CONSTR_CHECK;
14371442
n->name=pstrdup(ccname);
1438-
n->raw_expr=ccbin_node;
1439-
n->cooked_expr=NULL;
1443+
n->raw_expr=NULL;
1444+
n->cooked_expr=nodeToString(ccbin_node);
14401445
n->indexspace=NULL;
14411446
cxt->ckconstraints=lappend(cxt->ckconstraints, (Node*)n);
14421447
}

‎src/include/nodes/parsenodes.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.331 2006/10/04 00:30:09 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.332 2006/10/11 16:42:59 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -414,9 +414,19 @@ typedef struct InhRelation
414414
{
415415
NodeTagtype;
416416
RangeVar*relation;
417-
List*options;
417+
List*options;/* integer List of CreateStmtLikeOption */
418418
}InhRelation;
419419

420+
typedefenumCreateStmtLikeOption
421+
{
422+
CREATE_TABLE_LIKE_INCLUDING_DEFAULTS,
423+
CREATE_TABLE_LIKE_EXCLUDING_DEFAULTS,
424+
CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS,
425+
CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS,
426+
CREATE_TABLE_LIKE_INCLUDING_INDEXES,
427+
CREATE_TABLE_LIKE_EXCLUDING_INDEXES
428+
}CreateStmtLikeOption;
429+
420430
/*
421431
* IndexElem - index parameters (used in CREATE INDEX)
422432
*
@@ -1055,16 +1065,6 @@ typedef struct CreateStmt
10551065
char*tablespacename;/* table space to use, or NULL */
10561066
}CreateStmt;
10571067

1058-
typedefenumCreateStmtLikeOption
1059-
{
1060-
CREATE_TABLE_LIKE_INCLUDING_DEFAULTS,
1061-
CREATE_TABLE_LIKE_EXCLUDING_DEFAULTS,
1062-
CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS,
1063-
CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS,
1064-
CREATE_TABLE_LIKE_INCLUDING_INDEXES,
1065-
CREATE_TABLE_LIKE_EXCLUDING_INDEXES
1066-
}CreateStmtLikeOption;
1067-
10681068
/* ----------
10691069
* Definitions for plain (non-FOREIGN KEY) constraints in CreateStmt
10701070
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp