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

Commit5ed6546

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 parent4bb106e commit5ed6546

File tree

4 files changed

+63
-10
lines changed

4 files changed

+63
-10
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,15 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
335335
IndexStmt*stmt,boolis_rebuild,LOCKMODElockmode);
336336
staticvoidATExecAddConstraint(List**wqueue,
337337
AlteredTableInfo*tab,Relationrel,
338-
Constraint*newConstraint,boolrecurse,LOCKMODElockmode);
338+
Constraint*newConstraint,boolrecurse,boolis_readd,
339+
LOCKMODElockmode);
339340
staticvoidATExecAddIndexConstraint(AlteredTableInfo*tab,Relationrel,
340341
IndexStmt*stmt,LOCKMODElockmode);
341342
staticvoidATAddCheckConstraint(List**wqueue,
342343
AlteredTableInfo*tab,Relationrel,
343344
Constraint*constr,
344-
boolrecurse,boolrecursing,LOCKMODElockmode);
345+
boolrecurse,boolrecursing,boolis_readd,
346+
LOCKMODElockmode);
345347
staticvoidATAddForeignKeyConstraint(AlteredTableInfo*tab,Relationrel,
346348
Constraint*fkconstraint,LOCKMODElockmode);
347349
staticvoidATExecDropConstraint(Relationrel,constchar*constrName,
@@ -2758,6 +2760,7 @@ AlterTableGetLockLevel(List *cmds)
27582760
caseAT_ColumnDefault:
27592761
caseAT_ProcessedConstraint:/* becomes AT_AddConstraint */
27602762
caseAT_AddConstraintRecurse:/* becomes AT_AddConstraint */
2763+
caseAT_ReAddConstraint:/* becomes AT_AddConstraint */
27612764
caseAT_EnableTrig:
27622765
caseAT_EnableAlwaysTrig:
27632766
caseAT_EnableReplicaTrig:
@@ -3249,11 +3252,15 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
32493252
break;
32503253
caseAT_AddConstraint:/* ADD CONSTRAINT */
32513254
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
3252-
false,lockmode);
3255+
false,false,lockmode);
32533256
break;
32543257
caseAT_AddConstraintRecurse:/* ADD CONSTRAINT with recursion */
32553258
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
3256-
true,lockmode);
3259+
true, false,lockmode);
3260+
break;
3261+
caseAT_ReAddConstraint:/* Re-add pre-existing check constraint */
3262+
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
3263+
false, true,lockmode);
32573264
break;
32583265
caseAT_AddIndexConstraint:/* ADD CONSTRAINT USING INDEX */
32593266
ATExecAddIndexConstraint(tab,rel, (IndexStmt*)cmd->def,lockmode);
@@ -5500,7 +5507,8 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
55005507
*/
55015508
staticvoid
55025509
ATExecAddConstraint(List**wqueue,AlteredTableInfo*tab,Relationrel,
5503-
Constraint*newConstraint,boolrecurse,LOCKMODElockmode)
5510+
Constraint*newConstraint,boolrecurse,boolis_readd,
5511+
LOCKMODElockmode)
55045512
{
55055513
Assert(IsA(newConstraint,Constraint));
55065514

@@ -5513,7 +5521,8 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
55135521
{
55145522
caseCONSTR_CHECK:
55155523
ATAddCheckConstraint(wqueue,tab,rel,
5516-
newConstraint,recurse, false,lockmode);
5524+
newConstraint,recurse, false,is_readd,
5525+
lockmode);
55175526
break;
55185527

55195528
caseCONSTR_FOREIGN:
@@ -5565,11 +5574,18 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
55655574
* AddRelationNewConstraints would normally assign different names to the
55665575
* child constraints. To fix that, we must capture the name assigned at
55675576
* the parent table and pass that down.
5577+
*
5578+
* When re-adding a previously existing constraint (during ALTER COLUMN TYPE),
5579+
* we don't need to recurse here, because recursion will be carried out at a
5580+
* higher level; the constraint name issue doesn't apply because the names
5581+
* have already been assigned and are just being re-used. We need a separate
5582+
* "is_readd" flag for that; just setting recurse=false would result in an
5583+
* error if there are child tables.
55685584
*/
55695585
staticvoid
55705586
ATAddCheckConstraint(List**wqueue,AlteredTableInfo*tab,Relationrel,
55715587
Constraint*constr,boolrecurse,boolrecursing,
5572-
LOCKMODElockmode)
5588+
boolis_readd,LOCKMODElockmode)
55735589
{
55745590
List*newcons;
55755591
ListCell*lcon;
@@ -5634,9 +5650,11 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
56345650
return;
56355651

56365652
/*
5637-
* Adding a NO INHERIT constraint? No need to find our children
5653+
* If adding a NO INHERIT constraint, no need to find our children.
5654+
* Likewise, in a re-add operation, we don't need to recurse (that will be
5655+
* handled at higher levels).
56385656
*/
5639-
if (constr->is_no_inherit)
5657+
if (constr->is_no_inherit||is_readd)
56405658
return;
56415659

56425660
/*
@@ -5671,7 +5689,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
56715689

56725690
/* Recurse to child */
56735691
ATAddCheckConstraint(wqueue,childtab,childrel,
5674-
constr,recurse, true,lockmode);
5692+
constr,recurse, true,is_readd,lockmode);
56755693

56765694
heap_close(childrel,NoLock);
56775695
}
@@ -7862,6 +7880,10 @@ ATPostAlterTypeParse(Oid oldId, char *cmd,
78627880
/*
78637881
* Attach each generated command to the proper place in the work queue.
78647882
* Note this could result in creation of entirely new work-queue entries.
7883+
*
7884+
* Also note that we have to tweak the command subtypes, because it turns
7885+
* out that re-creation of indexes and constraints has to act a bit
7886+
* differently from initial creation.
78657887
*/
78667888
foreach(list_item,querytree_list)
78677889
{
@@ -7919,6 +7941,7 @@ ATPostAlterTypeParse(Oid oldId, char *cmd,
79197941
if (con->contype==CONSTR_FOREIGN&&
79207942
!rewrite&& !tab->rewrite)
79217943
TryReuseForeignKey(oldId,con);
7944+
cmd->subtype=AT_ReAddConstraint;
79227945
tab->subcmds[AT_PASS_OLD_CONSTR]=
79237946
lappend(tab->subcmds[AT_PASS_OLD_CONSTR],cmd);
79247947
break;

‎src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,7 @@ typedef enum AlterTableType
11971197
AT_ReAddIndex,/* internal to commands/tablecmds.c */
11981198
AT_AddConstraint,/* add constraint */
11991199
AT_AddConstraintRecurse,/* internal to commands/tablecmds.c */
1200+
AT_ReAddConstraint,/* internal to commands/tablecmds.c */
12001201
AT_ValidateConstraint,/* validate constraint */
12011202
AT_ValidateConstraintRecurse,/* internal to commands/tablecmds.c */
12021203
AT_ProcessedConstraint,/* pre-processed add constraint (local in

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,28 @@ where oid = 'test_storage'::regclass;
17801780
t
17811781
(1 row)
17821782

1783+
-- ALTER TYPE with a check constraint and a child table (bug before Nov 2012)
1784+
CREATE TABLE test_inh_check (a float check (a > 10.2));
1785+
CREATE TABLE test_inh_check_child() INHERITS(test_inh_check);
1786+
ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric;
1787+
\d test_inh_check
1788+
Table "public.test_inh_check"
1789+
Column | Type | Modifiers
1790+
--------+---------+-----------
1791+
a | numeric |
1792+
Check constraints:
1793+
"test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
1794+
Number of child tables: 1 (Use \d+ to list them.)
1795+
1796+
\d test_inh_check_child
1797+
Table "public.test_inh_check_child"
1798+
Column | Type | Modifiers
1799+
--------+---------+-----------
1800+
a | numeric |
1801+
Check constraints:
1802+
"test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
1803+
Inherits: test_inh_check
1804+
17831805
--
17841806
-- lock levels
17851807
--

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,13 @@ select reltoastrelid <> 0 as has_toast_table
12391239
from pg_class
12401240
whereoid='test_storage'::regclass;
12411241

1242+
-- ALTER TYPE with a check constraint and a child table (bug before Nov 2012)
1243+
CREATETABLEtest_inh_check (a floatcheck (a>10.2));
1244+
CREATETABLEtest_inh_check_child() INHERITS(test_inh_check);
1245+
ALTERTABLE test_inh_check ALTER COLUMN a TYPEnumeric;
1246+
\d test_inh_check
1247+
\d test_inh_check_child
1248+
12421249
--
12431250
-- lock levels
12441251
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp