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

Commitf2a4278

Browse files
committed
Propagate ALTER TYPE operations to typed tables
This adds RESTRICT/CASCADE flags to ALTER TYPE ... ADD/DROP/ALTER/RENAME ATTRIBUTE to control whether to alter typed tables as well.
1 parentfc946c3 commitf2a4278

File tree

10 files changed

+258
-68
lines changed

10 files changed

+258
-68
lines changed

‎doc/src/sgml/ref/alter_type.sgml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ PostgreSQL documentation
2626
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> <replaceable class="PARAMETER">action</replaceable> [, ... ]
2727
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
2828
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> TO <replaceable class="PARAMETER">new_attribute_name</replaceable>
29-
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
29+
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable> [ CASCADE | RESTRICT ]
3030
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable>
3131
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> ADD VALUE <replaceable class="PARAMETER">new_enum_value</replaceable> [ { BEFORE | AFTER } <replaceable class="PARAMETER">existing_enum_value</replaceable> ]
3232

3333
<phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase>
3434

35-
ADD ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable>
36-
DROP ATTRIBUTE [ IF EXISTS ] <replaceable class="PARAMETER">attribute_name</replaceable>
37-
ALTER ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> [ SET DATA ] TYPE <replaceable class="PARAMETER">data_type</replaceable>
35+
ADD ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ CASCADE | RESTRICT ]
36+
DROP ATTRIBUTE [ IF EXISTS ] <replaceable class="PARAMETER">attribute_name</replaceable> [ CASCADE | RESTRICT ]
37+
ALTER ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> [ SET DATA ] TYPE <replaceable class="PARAMETER">data_type</replaceable> [ CASCADE | RESTRICT ]
3838
</synopsis>
3939
</refsynopsisdiv>
4040

@@ -116,6 +116,26 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> ADD VALUE <replacea
116116
</para>
117117
</listitem>
118118
</varlistentry>
119+
120+
<varlistentry>
121+
<term><literal>CASCADE</literal></term>
122+
<listitem>
123+
<para>
124+
Automatically propagate the operation to typed tables of the
125+
type being altered.
126+
</para>
127+
</listitem>
128+
</varlistentry>
129+
130+
<varlistentry>
131+
<term><literal>RESTRICT</literal></term>
132+
<listitem>
133+
<para>
134+
Refuse the operation if the type being altered is the type of a
135+
typed table. This is the default.
136+
</para>
137+
</listitem>
138+
</varlistentry>
119139
</variablelist>
120140
</para>
121141

‎src/backend/commands/alter.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,7 @@ ExecRenameStmt(RenameStmt *stmt)
125125
}
126126
caseOBJECT_COLUMN:
127127
caseOBJECT_ATTRIBUTE:
128-
renameatt(relid,
129-
stmt->subname,/* old att name */
130-
stmt->newname,/* new att name */
131-
interpretInhOption(stmt->relation->inhOpt),/* recursive? */
132-
0);/* expected inhcount */
128+
renameatt(relid,stmt);
133129
break;
134130
caseOBJECT_TRIGGER:
135131
renametrig(relid,

‎src/backend/commands/tablecmds.c

Lines changed: 109 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,11 @@ static void ATSimpleRecursion(List **wqueue, Relation rel,
269269
AlterTableCmd*cmd,boolrecurse,LOCKMODElockmode);
270270
staticvoidATOneLevelRecursion(List**wqueue,Relationrel,
271271
AlterTableCmd*cmd,LOCKMODElockmode);
272-
staticvoidfind_typed_table_dependencies(OidtypeOid,constchar*typeName);
273-
staticvoidATPrepAddColumn(List**wqueue,Relationrel,boolrecurse,
272+
staticvoidATTypedTableRecursion(List**wqueue,Relationrel,AlterTableCmd*cmd,
273+
LOCKMODElockmode);
274+
staticList*find_typed_table_dependencies(OidtypeOid,constchar*typeName,
275+
DropBehaviorbehavior);
276+
staticvoidATPrepAddColumn(List**wqueue,Relationrel,boolrecurse,boolrecursing,
274277
AlterTableCmd*cmd,LOCKMODElockmode);
275278
staticvoidATExecAddColumn(AlteredTableInfo*tab,Relationrel,
276279
ColumnDef*colDef,boolisOid,LOCKMODElockmode);
@@ -290,7 +293,8 @@ static void ATExecSetOptions(Relation rel, const char *colName,
290293
Node*options,boolisReset,LOCKMODElockmode);
291294
staticvoidATExecSetStorage(Relationrel,constchar*colName,
292295
Node*newValue,LOCKMODElockmode);
293-
staticvoidATPrepDropColumn(Relationrel,boolrecurse,AlterTableCmd*cmd);
296+
staticvoidATPrepDropColumn(List**wqueue,Relationrel,boolrecurse,boolrecursing,
297+
AlterTableCmd*cmd,LOCKMODElockmode);
294298
staticvoidATExecDropColumn(List**wqueue,Relationrel,constchar*colName,
295299
DropBehaviorbehavior,
296300
boolrecurse,boolrecursing,
@@ -1942,14 +1946,16 @@ setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
19421946

19431947

19441948
/*
1945-
*renameatt-changes the name of a attribute in a relation
1949+
*renameatt_internal-workhorse for renameatt
19461950
*/
1947-
void
1948-
renameatt(Oidmyrelid,
1949-
constchar*oldattname,
1950-
constchar*newattname,
1951-
boolrecurse,
1952-
intexpected_parents)
1951+
staticvoid
1952+
renameatt_internal(Oidmyrelid,
1953+
constchar*oldattname,
1954+
constchar*newattname,
1955+
boolrecurse,
1956+
boolrecursing,
1957+
intexpected_parents,
1958+
DropBehaviorbehavior)
19531959
{
19541960
Relationtargetrelation;
19551961
Relationattrelation;
@@ -1964,15 +1970,11 @@ renameatt(Oid myrelid,
19641970
*/
19651971
targetrelation=relation_open(myrelid,AccessExclusiveLock);
19661972

1967-
if (targetrelation->rd_rel->reloftype)
1973+
if (targetrelation->rd_rel->reloftype&& !recursing)
19681974
ereport(ERROR,
19691975
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
19701976
errmsg("cannot rename column of typed table")));
19711977

1972-
if (targetrelation->rd_rel->relkind==RELKIND_COMPOSITE_TYPE)
1973-
find_typed_table_dependencies(targetrelation->rd_rel->reltype,
1974-
RelationGetRelationName(targetrelation));
1975-
19761978
/*
19771979
* Renaming the columns of sequences or toast tables doesn't actually
19781980
* break anything from the system's point of view, since internal
@@ -2038,7 +2040,7 @@ renameatt(Oid myrelid,
20382040
if (childrelid==myrelid)
20392041
continue;
20402042
/* note we need not recurse again */
2041-
renameatt(childrelid,oldattname,newattname, false,numparents);
2043+
renameatt_internal(childrelid,oldattname,newattname, false,true,numparents,behavior);
20422044
}
20432045
}
20442046
else
@@ -2057,6 +2059,20 @@ renameatt(Oid myrelid,
20572059
oldattname)));
20582060
}
20592061

2062+
/* rename attributes in typed tables of composite type */
2063+
if (targetrelation->rd_rel->relkind==RELKIND_COMPOSITE_TYPE)
2064+
{
2065+
List*child_oids;
2066+
ListCell*lo;
2067+
2068+
child_oids=find_typed_table_dependencies(targetrelation->rd_rel->reltype,
2069+
RelationGetRelationName(targetrelation),
2070+
behavior);
2071+
2072+
foreach(lo,child_oids)
2073+
renameatt_internal(lfirst_oid(lo),oldattname,newattname, true, true,0,behavior);
2074+
}
2075+
20602076
attrelation=heap_open(AttributeRelationId,RowExclusiveLock);
20612077

20622078
atttup=SearchSysCacheCopyAttName(myrelid,oldattname);
@@ -2116,6 +2132,22 @@ renameatt(Oid myrelid,
21162132
}
21172133

21182134

2135+
/*
2136+
*renameatt- changes the name of a attribute in a relation
2137+
*/
2138+
void
2139+
renameatt(Oidmyrelid,RenameStmt*stmt)
2140+
{
2141+
renameatt_internal(myrelid,
2142+
stmt->subname,/* old att name */
2143+
stmt->newname,/* new att name */
2144+
interpretInhOption(stmt->relation->inhOpt),/* recursive? */
2145+
false,/* recursing? */
2146+
0,/* expected inhcount */
2147+
stmt->behavior);
2148+
}
2149+
2150+
21192151
/*
21202152
* Execute ALTER TABLE/INDEX/SEQUENCE/VIEW RENAME
21212153
*
@@ -2649,14 +2681,14 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
26492681
caseAT_AddColumn:/* ADD COLUMN */
26502682
ATSimplePermissions(rel, false, true);
26512683
/* Performs own recursion */
2652-
ATPrepAddColumn(wqueue,rel,recurse,cmd,lockmode);
2684+
ATPrepAddColumn(wqueue,rel,recurse,recursing,cmd,lockmode);
26532685
pass=AT_PASS_ADD_COL;
26542686
break;
26552687
caseAT_AddColumnToView:/* add column via CREATE OR REPLACE
26562688
* VIEW */
26572689
ATSimplePermissions(rel, true, false);
26582690
/* Performs own recursion */
2659-
ATPrepAddColumn(wqueue,rel,recurse,cmd,lockmode);
2691+
ATPrepAddColumn(wqueue,rel,recurse,recursing,cmd,lockmode);
26602692
pass=AT_PASS_ADD_COL;
26612693
break;
26622694
caseAT_ColumnDefault:/* ALTER COLUMN DEFAULT */
@@ -2704,7 +2736,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
27042736
break;
27052737
caseAT_DropColumn:/* DROP COLUMN */
27062738
ATSimplePermissions(rel, false, true);
2707-
ATPrepDropColumn(rel,recurse,cmd);
2739+
ATPrepDropColumn(wqueue,rel,recurse,recursing,cmd,lockmode);
27082740
/* Recursion occurs during execution phase */
27092741
pass=AT_PASS_DROP;
27102742
break;
@@ -3671,6 +3703,37 @@ ATOneLevelRecursion(List **wqueue, Relation rel,
36713703
}
36723704
}
36733705

3706+
/*
3707+
* ATTypedTableRecursion
3708+
*
3709+
* Propagate ALTER TYPE operations to the typed tables of that type.
3710+
* Also check the RESTRICT/CASCADE behavior.
3711+
*/
3712+
staticvoid
3713+
ATTypedTableRecursion(List**wqueue,Relationrel,AlterTableCmd*cmd,
3714+
LOCKMODElockmode)
3715+
{
3716+
ListCell*child;
3717+
List*children;
3718+
3719+
Assert(rel->rd_rel->relkind==RELKIND_COMPOSITE_TYPE);
3720+
3721+
children=find_typed_table_dependencies(rel->rd_rel->reltype,
3722+
RelationGetRelationName(rel),
3723+
cmd->behavior);
3724+
3725+
foreach(child,children)
3726+
{
3727+
Oidchildrelid=lfirst_oid(child);
3728+
Relationchildrel;
3729+
3730+
childrel=relation_open(childrelid,lockmode);
3731+
CheckTableNotInUse(childrel,"ALTER TABLE");
3732+
ATPrepCmd(wqueue,childrel,cmd, false, true,lockmode);
3733+
relation_close(childrel,NoLock);
3734+
}
3735+
}
3736+
36743737

36753738
/*
36763739
* find_composite_type_dependencies
@@ -3778,17 +3841,17 @@ find_composite_type_dependencies(Oid typeOid,
37783841
* find_typed_table_dependencies
37793842
*
37803843
* Check to see if a composite type is being used as the type of a
3781-
* typed table. Eventually, we'd like to propagate the alter
3782-
* operation into such tables, but for now, just error out if we find
3783-
* any.
3844+
* typed table. Abort if any are found and behavior is RESTRICT.
3845+
* Else return the list of tables.
37843846
*/
3785-
staticvoid
3786-
find_typed_table_dependencies(OidtypeOid,constchar*typeName)
3847+
staticList*
3848+
find_typed_table_dependencies(OidtypeOid,constchar*typeName,DropBehaviorbehavior)
37873849
{
37883850
RelationclassRel;
37893851
ScanKeyDatakey[1];
37903852
HeapScanDescscan;
37913853
HeapTupletuple;
3854+
List*result=NIL;
37923855

37933856
classRel=heap_open(RelationRelationId,AccessShareLock);
37943857

@@ -3801,14 +3864,20 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName)
38013864

38023865
if (HeapTupleIsValid(tuple=heap_getnext(scan,ForwardScanDirection)))
38033866
{
3804-
ereport(ERROR,
3805-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3806-
errmsg("cannot alter type \"%s\" because it is the type of a typed table",
3807-
typeName)));
3867+
if (behavior==DROP_RESTRICT)
3868+
ereport(ERROR,
3869+
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
3870+
errmsg("cannot alter type \"%s\" because it is the type of a typed table",
3871+
typeName),
3872+
errhint("Use ALTER ... CASCADE to alter the typed tables too.")));
3873+
else
3874+
result=lappend_oid(result,HeapTupleGetOid(tuple));
38083875
}
38093876

38103877
heap_endscan(scan);
38113878
heap_close(classRel,AccessShareLock);
3879+
3880+
returnresult;
38123881
}
38133882

38143883

@@ -3821,10 +3890,10 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName)
38213890
* AlterTableCmd's.
38223891
*/
38233892
staticvoid
3824-
ATPrepAddColumn(List**wqueue,Relationrel,boolrecurse,
3893+
ATPrepAddColumn(List**wqueue,Relationrel,boolrecurse,boolrecursing,
38253894
AlterTableCmd*cmd,LOCKMODElockmode)
38263895
{
3827-
if (rel->rd_rel->reloftype)
3896+
if (rel->rd_rel->reloftype&& !recursing)
38283897
ereport(ERROR,
38293898
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
38303899
errmsg("cannot add column to typed table")));
@@ -3860,8 +3929,7 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
38603929
}
38613930

38623931
if (rel->rd_rel->relkind==RELKIND_COMPOSITE_TYPE)
3863-
find_typed_table_dependencies(rel->rd_rel->reltype,
3864-
RelationGetRelationName(rel));
3932+
ATTypedTableRecursion(wqueue,rel,cmd,lockmode);
38653933
}
38663934

38673935
staticvoid
@@ -4162,7 +4230,7 @@ ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOC
41624230
cdef->storage=0;
41634231
cmd->def= (Node*)cdef;
41644232
}
4165-
ATPrepAddColumn(wqueue,rel,recurse,cmd,lockmode);
4233+
ATPrepAddColumn(wqueue,rel,recurse,false,cmd,lockmode);
41664234
}
41674235

41684236
/*
@@ -4586,18 +4654,17 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
45864654
* correctly.)
45874655
*/
45884656
staticvoid
4589-
ATPrepDropColumn(Relationrel,boolrecurse,AlterTableCmd*cmd)
4657+
ATPrepDropColumn(List**wqueue,Relationrel,boolrecurse,boolrecursing,
4658+
AlterTableCmd*cmd,LOCKMODElockmode)
45904659
{
4591-
if (rel->rd_rel->reloftype)
4660+
if (rel->rd_rel->reloftype&& !recursing)
45924661
ereport(ERROR,
45934662
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
45944663
errmsg("cannot drop column from typed table")));
45954664

45964665
if (rel->rd_rel->relkind==RELKIND_COMPOSITE_TYPE)
4597-
find_typed_table_dependencies(rel->rd_rel->reltype,
4598-
RelationGetRelationName(rel));
4666+
ATTypedTableRecursion(wqueue,rel,cmd,lockmode);
45994667

4600-
/* No command-specific prep needed except saving recurse flag */
46014668
if (recurse)
46024669
cmd->subtype=AT_DropColumnRecurse;
46034670
}
@@ -6060,7 +6127,7 @@ ATPrepAlterColumnType(List **wqueue,
60606127
NewColumnValue*newval;
60616128
ParseState*pstate=make_parsestate(NULL);
60626129

6063-
if (rel->rd_rel->reloftype)
6130+
if (rel->rd_rel->reloftype&& !recursing)
60646131
ereport(ERROR,
60656132
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
60666133
errmsg("cannot alter column type of typed table")));
@@ -6178,9 +6245,6 @@ ATPrepAlterColumnType(List **wqueue,
61786245
find_composite_type_dependencies(rel->rd_rel->reltype,
61796246
NULL,
61806247
RelationGetRelationName(rel));
6181-
6182-
find_typed_table_dependencies(rel->rd_rel->reltype,
6183-
RelationGetRelationName(rel));
61846248
}
61856249

61866250
ReleaseSysCache(tuple);
@@ -6198,6 +6262,9 @@ ATPrepAlterColumnType(List **wqueue,
61986262
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
61996263
errmsg("type of inherited column \"%s\" must be changed in child tables too",
62006264
colName)));
6265+
6266+
if (tab->relkind==RELKIND_COMPOSITE_TYPE)
6267+
ATTypedTableRecursion(wqueue,rel,cmd,lockmode);
62016268
}
62026269

62036270
staticvoid

‎src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,6 +2803,7 @@ _copyRenameStmt(RenameStmt *from)
28032803
COPY_NODE_FIELD(objarg);
28042804
COPY_STRING_FIELD(subname);
28052805
COPY_STRING_FIELD(newname);
2806+
COPY_SCALAR_FIELD(behavior);
28062807

28072808
returnnewnode;
28082809
}

‎src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,7 @@ _equalRenameStmt(RenameStmt *a, RenameStmt *b)
13061306
COMPARE_NODE_FIELD(objarg);
13071307
COMPARE_STRING_FIELD(subname);
13081308
COMPARE_STRING_FIELD(newname);
1309+
COMPARE_SCALAR_FIELD(behavior);
13091310

13101311
return true;
13111312
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp