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

Commit909efc4

Browse files
committed
Disallow changing an inherited column's type if not all parents changed.
If a table inherits from multiple unrelated parents, we must disallowchanging the type of a column inherited from multiple such parents, elseit would be out of step with the other parents. However, it's possiblefor the column to ultimately be inherited from just one common ancestor,in which case a change starting from that ancestor should still beallowed. (I would not be excited about preserving that option, wereit not that we have regression test cases exercising it already ...)It's slightly annoying that this patch looks different from the logicwith the same end goal in renameatt(), and more annoying that itrequires an extra syscache lookup to make the test. However, therecursion logic is quite different in the two functions, and aback-patched bug fix is no place to be trying to unify them.Per report from Manuel Rigger. Back-patch to 9.5. The bug exists in9.4 too (and doubtless much further back); but the way the recursionis done in 9.4 is a good bit different, so that substantial refactoringwould be needed to fix it in 9.4. I'm disinclined to do that, or riskintroducing new bugs, for a bug that has escaped notice for this long.Discussion:https://postgr.es/m/CA+u7OA4qogDv9rz1HAb-ADxttXYPqQdUdPY_yd4kCzywNxRQXA@mail.gmail.com
1 parentaed967d commit909efc4

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9578,7 +9578,11 @@ ATPrepAlterColumnType(List **wqueue,
95789578
errmsg("cannot alter system column \"%s\"",
95799579
colName)));
95809580

9581-
/* Don't alter inherited columns */
9581+
/*
9582+
* Don't alter inherited columns. At outer level, there had better not be
9583+
* any inherited definition; when recursing, we assume this was checked at
9584+
* the parent level (see below).
9585+
*/
95829586
if (attTup->attinhcount>0&& !recursing)
95839587
ereport(ERROR,
95849588
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
@@ -9704,20 +9708,26 @@ ATPrepAlterColumnType(List **wqueue,
97049708
if (recurse)
97059709
{
97069710
Oidrelid=RelationGetRelid(rel);
9707-
ListCell*child;
9708-
List*children;
9711+
List*child_oids,
9712+
*child_numparents;
9713+
ListCell*lo,
9714+
*li;
97099715

9710-
children=find_all_inheritors(relid,lockmode,NULL);
9716+
child_oids=find_all_inheritors(relid,lockmode,
9717+
&child_numparents);
97119718

97129719
/*
97139720
* find_all_inheritors does the recursive search of the inheritance
97149721
* hierarchy, so all we have to do is process all of the relids in the
97159722
* list that it returns.
97169723
*/
9717-
foreach(child,children)
9724+
forboth(lo,child_oids,li,child_numparents)
97189725
{
9719-
Oidchildrelid=lfirst_oid(child);
9726+
Oidchildrelid=lfirst_oid(lo);
9727+
intnumparents=lfirst_int(li);
97209728
Relationchildrel;
9729+
HeapTuplechildtuple;
9730+
Form_pg_attributechildattTup;
97219731

97229732
if (childrelid==relid)
97239733
continue;
@@ -9726,6 +9736,29 @@ ATPrepAlterColumnType(List **wqueue,
97269736
childrel=relation_open(childrelid,NoLock);
97279737
CheckTableNotInUse(childrel,"ALTER TABLE");
97289738

9739+
/*
9740+
* Verify that the child doesn't have any inherited definitions of
9741+
* this column that came from outside this inheritance hierarchy.
9742+
* (renameatt makes a similar test, though in a different way
9743+
* because of its different recursion mechanism.)
9744+
*/
9745+
childtuple=SearchSysCacheAttName(RelationGetRelid(childrel),
9746+
colName);
9747+
if (!HeapTupleIsValid(childtuple))
9748+
ereport(ERROR,
9749+
(errcode(ERRCODE_UNDEFINED_COLUMN),
9750+
errmsg("column \"%s\" of relation \"%s\" does not exist",
9751+
colName,RelationGetRelationName(childrel))));
9752+
childattTup= (Form_pg_attribute)GETSTRUCT(childtuple);
9753+
9754+
if (childattTup->attinhcount>numparents)
9755+
ereport(ERROR,
9756+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
9757+
errmsg("cannot alter inherited column \"%s\" of relation \"%s\"",
9758+
colName,RelationGetRelationName(childrel))));
9759+
9760+
ReleaseSysCache(childtuple);
9761+
97299762
/*
97309763
* Remap the attribute numbers. If no USING expression was
97319764
* specified, there is no need for this step.

‎src/test/regress/expected/inherit.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,16 @@ select * from d;
723723
32 | one | two | three
724724
(1 row)
725725

726+
-- The above verified that we can change the type of a multiply-inherited
727+
-- column; but we should reject that if any definition was inherited from
728+
-- an unrelated parent.
729+
create temp table parent1(f1 int, f2 int);
730+
create temp table parent2(f1 int, f3 bigint);
731+
create temp table childtab(f4 int) inherits(parent1, parent2);
732+
NOTICE: merging multiple inherited definitions of column "f1"
733+
alter table parent1 alter column f1 type bigint; -- fail, conflict w/parent2
734+
ERROR: cannot alter inherited column "f1" of relation "childtab"
735+
alter table parent1 alter column f2 type bigint; -- ok
726736
-- check that oid column is handled properly during alter table inherit
727737
create table oid_parent (a int) with oids;
728738
create table oid_child () inherits (oid_parent);

‎src/test/regress/sql/inherit.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ insert into d values('test','one','two','three');
208208
altertable a alter column aa typeinteger using bit_length(aa);
209209
select*from d;
210210

211+
-- The above verified that we can change the type of a multiply-inherited
212+
-- column; but we should reject that if any definition was inherited from
213+
-- an unrelated parent.
214+
create temp table parent1(f1int, f2int);
215+
create temp table parent2(f1int, f3bigint);
216+
create temp table childtab(f4int) inherits(parent1, parent2);
217+
altertable parent1 alter column f1 typebigint;-- fail, conflict w/parent2
218+
altertable parent1 alter column f2 typebigint;-- ok
219+
211220
-- check that oid column is handled properly during alter table inherit
212221
createtableoid_parent (aint) with oids;
213222

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp