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

Commit8e344ea

Browse files
committed
Fix handling of inherited check constraints in ALTER COLUMN TYPE.
This case got broken in 8.4 by the addition of an error check thatcomplains if ALTER TABLE ONLY is used on a table that has children.We do use ONLY for this situation, but it's okay because the necessaryrecursion occurs at a higher level. So we need to have a separateflag to suppress recursion without making the error check.Reported and patched by Pavan Deolasee, with some editorial adjustments byme. Back-patch to 8.4, since this is a regression of functionality thatworked in earlier branches.
1 parentd997bd2 commit8e344ea

File tree

4 files changed

+64
-9
lines changed

4 files changed

+64
-9
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,11 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
297297
IndexStmt*stmt,boolis_rebuild);
298298
staticvoidATExecAddConstraint(List**wqueue,
299299
AlteredTableInfo*tab,Relationrel,
300-
Constraint*newConstraint,boolrecurse);
300+
Constraint*newConstraint,boolrecurse,boolis_readd);
301301
staticvoidATAddCheckConstraint(List**wqueue,
302302
AlteredTableInfo*tab,Relationrel,
303303
Constraint*constr,
304-
boolrecurse,boolrecursing);
304+
boolrecurse,boolrecursing,boolis_readd);
305305
staticvoidATAddForeignKeyConstraint(AlteredTableInfo*tab,Relationrel,
306306
Constraint*fkconstraint);
307307
staticvoidATExecDropConstraint(Relationrel,constchar*constrName,
@@ -2663,11 +2663,15 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
26632663
break;
26642664
caseAT_AddConstraint:/* ADD CONSTRAINT */
26652665
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
2666-
false);
2666+
false, false);
26672667
break;
26682668
caseAT_AddConstraintRecurse:/* ADD CONSTRAINT with recursion */
26692669
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
2670-
true);
2670+
true, false);
2671+
break;
2672+
caseAT_ReAddConstraint:/* Re-add pre-existing check constraint */
2673+
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
2674+
false, true);
26712675
break;
26722676
caseAT_DropConstraint:/* DROP CONSTRAINT */
26732677
ATExecDropConstraint(rel,cmd->name,cmd->behavior,
@@ -4516,7 +4520,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
45164520
*/
45174521
staticvoid
45184522
ATExecAddConstraint(List**wqueue,AlteredTableInfo*tab,Relationrel,
4519-
Constraint*newConstraint,boolrecurse)
4523+
Constraint*newConstraint,boolrecurse,boolis_readd)
45204524
{
45214525
Assert(IsA(newConstraint,Constraint));
45224526

@@ -4529,7 +4533,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
45294533
{
45304534
caseCONSTR_CHECK:
45314535
ATAddCheckConstraint(wqueue,tab,rel,
4532-
newConstraint,recurse, false);
4536+
newConstraint,recurse, false,is_readd);
45334537
break;
45344538

45354539
caseCONSTR_FOREIGN:
@@ -4581,10 +4585,18 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
45814585
* AddRelationNewConstraints would normally assign different names to the
45824586
* child constraints. To fix that, we must capture the name assigned at
45834587
* the parent table and pass that down.
4588+
*
4589+
* When re-adding a previously existing constraint (during ALTER COLUMN TYPE),
4590+
* we don't need to recurse here, because recursion will be carried out at a
4591+
* higher level; the constraint name issue doesn't apply because the names
4592+
* have already been assigned and are just being re-used. We need a separate
4593+
* "is_readd" flag for that; just setting recurse=false would result in an
4594+
* error if there are child tables.
45844595
*/
45854596
staticvoid
45864597
ATAddCheckConstraint(List**wqueue,AlteredTableInfo*tab,Relationrel,
4587-
Constraint*constr,boolrecurse,boolrecursing)
4598+
Constraint*constr,boolrecurse,boolrecursing,
4599+
boolis_readd)
45884600
{
45894601
List*newcons;
45904602
ListCell*lcon;
@@ -4643,6 +4655,13 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
46434655
if (newcons==NIL)
46444656
return;
46454657

4658+
/*
4659+
* Also, in a re-add operation, we don't need to recurse (that will be
4660+
* handled at higher levels).
4661+
*/
4662+
if (is_readd)
4663+
return;
4664+
46464665
/*
46474666
* Propagate to children as appropriate. Unlike most other ALTER
46484667
* routines, we have to do this one level of recursion at a time; we can't
@@ -4675,7 +4694,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
46754694

46764695
/* Recurse to child */
46774696
ATAddCheckConstraint(wqueue,childtab,childrel,
4678-
constr,recurse, true);
4697+
constr,recurse, true,is_readd);
46794698

46804699
heap_close(childrel,NoLock);
46814700
}
@@ -6330,6 +6349,10 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
63306349
/*
63316350
* Attach each generated command to the proper place in the work queue.
63326351
* Note this could result in creation of entirely new work-queue entries.
6352+
*
6353+
* Also note that we have to tweak the command subtypes, because it turns
6354+
* out that re-creation of indexes and constraints has to act a bit
6355+
* differently from initial creation.
63336356
*/
63346357
foreach(list_item,querytree_list)
63356358
{
@@ -6373,6 +6396,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
63736396
lappend(tab->subcmds[AT_PASS_OLD_INDEX],cmd);
63746397
break;
63756398
caseAT_AddConstraint:
6399+
cmd->subtype=AT_ReAddConstraint;
63766400
tab->subcmds[AT_PASS_OLD_CONSTR]=
63776401
lappend(tab->subcmds[AT_PASS_OLD_CONSTR],cmd);
63786402
break;

‎src/include/nodes/parsenodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,9 @@ typedef enum AlterTableType
11501150
AT_EnableReplicaRule,/* ENABLE REPLICA RULE name */
11511151
AT_DisableRule,/* DISABLE RULE name */
11521152
AT_AddInherit,/* INHERIT parent */
1153-
AT_DropInherit/* NO INHERIT parent */
1153+
AT_DropInherit,/* NO INHERIT parent */
1154+
/* this will be in a more natural position in 9.3: */
1155+
AT_ReAddConstraint/* internal to commands/tablecmds.c */
11541156
}AlterTableType;
11551157

11561158
typedefstructAlterTableCmd/* one subcommand of an ALTER TABLE */

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,28 @@ select * from another;
14761476
(3 rows)
14771477

14781478
drop table another;
1479+
-- ALTER TYPE with a check constraint and a child table (bug before Nov 2012)
1480+
CREATE TABLE test_inh_check (a float check (a > 10.2));
1481+
CREATE TABLE test_inh_check_child() INHERITS(test_inh_check);
1482+
ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric;
1483+
\d test_inh_check
1484+
Table "public.test_inh_check"
1485+
Column | Type | Modifiers
1486+
--------+---------+-----------
1487+
a | numeric |
1488+
Check constraints:
1489+
"test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
1490+
Number of child tables: 1 (Use \d+ to list them.)
1491+
1492+
\d test_inh_check_child
1493+
Table "public.test_inh_check_child"
1494+
Column | Type | Modifiers
1495+
--------+---------+-----------
1496+
a | numeric |
1497+
Check constraints:
1498+
"test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
1499+
Inherits: test_inh_check
1500+
14791501
-- disallow recursive containment of row types
14801502
create temp table recur1 (f1 int);
14811503
alter table recur1 add column f2 recur1; -- fails

‎src/test/regress/sql/alter_table.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,13 @@ select * from another;
10921092

10931093
droptable another;
10941094

1095+
-- ALTER TYPE with a check constraint and a child table (bug before Nov 2012)
1096+
CREATETABLEtest_inh_check (a floatcheck (a>10.2));
1097+
CREATETABLEtest_inh_check_child() INHERITS(test_inh_check);
1098+
ALTERTABLE test_inh_check ALTER COLUMN a TYPEnumeric;
1099+
\d test_inh_check
1100+
\d test_inh_check_child
1101+
10951102
-- disallow recursive containment of row types
10961103
create temp table recur1 (f1int);
10971104
altertable recur1 add column f2 recur1;-- fails

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp