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

Commitf43ca3c

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 parentefa81e3 commitf43ca3c

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -323,13 +323,15 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
323323
IndexStmt*stmt,boolis_rebuild,LOCKMODElockmode);
324324
staticvoidATExecAddConstraint(List**wqueue,
325325
AlteredTableInfo*tab,Relationrel,
326-
Constraint*newConstraint,boolrecurse,LOCKMODElockmode);
326+
Constraint*newConstraint,boolrecurse,boolis_readd,
327+
LOCKMODElockmode);
327328
staticvoidATExecAddIndexConstraint(AlteredTableInfo*tab,Relationrel,
328329
IndexStmt*stmt,LOCKMODElockmode);
329330
staticvoidATAddCheckConstraint(List**wqueue,
330331
AlteredTableInfo*tab,Relationrel,
331332
Constraint*constr,
332-
boolrecurse,boolrecursing,LOCKMODElockmode);
333+
boolrecurse,boolrecursing,boolis_readd,
334+
LOCKMODElockmode);
333335
staticvoidATAddForeignKeyConstraint(AlteredTableInfo*tab,Relationrel,
334336
Constraint*fkconstraint,LOCKMODElockmode);
335337
staticvoidATExecDropConstraint(Relationrel,constchar*constrName,
@@ -2560,6 +2562,7 @@ AlterTableGetLockLevel(List *cmds)
25602562
caseAT_ColumnDefault:
25612563
caseAT_ProcessedConstraint:/* becomes AT_AddConstraint */
25622564
caseAT_AddConstraintRecurse:/* becomes AT_AddConstraint */
2565+
caseAT_ReAddConstraint:/* becomes AT_AddConstraint */
25632566
caseAT_EnableTrig:
25642567
caseAT_EnableAlwaysTrig:
25652568
caseAT_EnableReplicaTrig:
@@ -3036,11 +3039,15 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
30363039
break;
30373040
caseAT_AddConstraint:/* ADD CONSTRAINT */
30383041
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
3039-
false,lockmode);
3042+
false,false,lockmode);
30403043
break;
30413044
caseAT_AddConstraintRecurse:/* ADD CONSTRAINT with recursion */
30423045
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
3043-
true,lockmode);
3046+
true, false,lockmode);
3047+
break;
3048+
caseAT_ReAddConstraint:/* Re-add pre-existing check constraint */
3049+
ATExecAddConstraint(wqueue,tab,rel, (Constraint*)cmd->def,
3050+
false, true,lockmode);
30443051
break;
30453052
caseAT_AddIndexConstraint:/* ADD CONSTRAINT USING INDEX */
30463053
ATExecAddIndexConstraint(tab,rel, (IndexStmt*)cmd->def,lockmode);
@@ -5235,7 +5242,8 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
52355242
*/
52365243
staticvoid
52375244
ATExecAddConstraint(List**wqueue,AlteredTableInfo*tab,Relationrel,
5238-
Constraint*newConstraint,boolrecurse,LOCKMODElockmode)
5245+
Constraint*newConstraint,boolrecurse,boolis_readd,
5246+
LOCKMODElockmode)
52395247
{
52405248
Assert(IsA(newConstraint,Constraint));
52415249

@@ -5248,7 +5256,8 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
52485256
{
52495257
caseCONSTR_CHECK:
52505258
ATAddCheckConstraint(wqueue,tab,rel,
5251-
newConstraint,recurse, false,lockmode);
5259+
newConstraint,recurse, false,is_readd,
5260+
lockmode);
52525261
break;
52535262

52545263
caseCONSTR_FOREIGN:
@@ -5300,11 +5309,18 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
53005309
* AddRelationNewConstraints would normally assign different names to the
53015310
* child constraints. To fix that, we must capture the name assigned at
53025311
* the parent table and pass that down.
5312+
*
5313+
* When re-adding a previously existing constraint (during ALTER COLUMN TYPE),
5314+
* we don't need to recurse here, because recursion will be carried out at a
5315+
* higher level; the constraint name issue doesn't apply because the names
5316+
* have already been assigned and are just being re-used. We need a separate
5317+
* "is_readd" flag for that; just setting recurse=false would result in an
5318+
* error if there are child tables.
53035319
*/
53045320
staticvoid
53055321
ATAddCheckConstraint(List**wqueue,AlteredTableInfo*tab,Relationrel,
53065322
Constraint*constr,boolrecurse,boolrecursing,
5307-
LOCKMODElockmode)
5323+
boolis_readd,LOCKMODElockmode)
53085324
{
53095325
List*newcons;
53105326
ListCell*lcon;
@@ -5363,6 +5379,13 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
53635379
if (newcons==NIL)
53645380
return;
53655381

5382+
/*
5383+
* Also, in a re-add operation, we don't need to recurse (that will be
5384+
* handled at higher levels).
5385+
*/
5386+
if (is_readd)
5387+
return;
5388+
53665389
/*
53675390
* Propagate to children as appropriate. Unlike most other ALTER
53685391
* routines, we have to do this one level of recursion at a time; we can't
@@ -5394,7 +5417,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
53945417

53955418
/* Recurse to child */
53965419
ATAddCheckConstraint(wqueue,childtab,childrel,
5397-
constr,recurse, true,lockmode);
5420+
constr,recurse, true,is_readd,lockmode);
53985421

53995422
heap_close(childrel,NoLock);
54005423
}
@@ -7220,6 +7243,10 @@ ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
72207243
/*
72217244
* Attach each generated command to the proper place in the work queue.
72227245
* Note this could result in creation of entirely new work-queue entries.
7246+
*
7247+
* Also note that we have to tweak the command subtypes, because it turns
7248+
* out that re-creation of indexes and constraints has to act a bit
7249+
* differently from initial creation.
72237250
*/
72247251
foreach(list_item,querytree_list)
72257252
{
@@ -7263,6 +7290,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
72637290
lappend(tab->subcmds[AT_PASS_OLD_INDEX],cmd);
72647291
break;
72657292
caseAT_AddConstraint:
7293+
cmd->subtype=AT_ReAddConstraint;
72667294
tab->subcmds[AT_PASS_OLD_CONSTR]=
72677295
lappend(tab->subcmds[AT_PASS_OLD_CONSTR],cmd);
72687296
break;

‎src/include/nodes/parsenodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,9 @@ typedef enum AlterTableType
12211221
AT_DropInherit,/* NO INHERIT parent */
12221222
AT_AddOf,/* OF <type_name> */
12231223
AT_DropOf,/* NOT OF */
1224-
AT_GenericOptions/* OPTIONS (...) */
1224+
AT_GenericOptions,/* OPTIONS (...) */
1225+
/* this will be in a more natural position in 9.3: */
1226+
AT_ReAddConstraint/* internal to commands/tablecmds.c */
12251227
}AlterTableType;
12261228

12271229
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
@@ -1538,6 +1538,28 @@ where oid = 'test_storage'::regclass;
15381538
t
15391539
(1 row)
15401540

1541+
-- ALTER TYPE with a check constraint and a child table (bug before Nov 2012)
1542+
CREATE TABLE test_inh_check (a float check (a > 10.2));
1543+
CREATE TABLE test_inh_check_child() INHERITS(test_inh_check);
1544+
ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric;
1545+
\d test_inh_check
1546+
Table "public.test_inh_check"
1547+
Column | Type | Modifiers
1548+
--------+---------+-----------
1549+
a | numeric |
1550+
Check constraints:
1551+
"test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
1552+
Number of child tables: 1 (Use \d+ to list them.)
1553+
1554+
\d test_inh_check_child
1555+
Table "public.test_inh_check_child"
1556+
Column | Type | Modifiers
1557+
--------+---------+-----------
1558+
a | numeric |
1559+
Check constraints:
1560+
"test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
1561+
Inherits: test_inh_check
1562+
15411563
--
15421564
-- lock levels
15431565
--

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

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

1148+
-- ALTER TYPE with a check constraint and a child table (bug before Nov 2012)
1149+
CREATETABLEtest_inh_check (a floatcheck (a>10.2));
1150+
CREATETABLEtest_inh_check_child() INHERITS(test_inh_check);
1151+
ALTERTABLE test_inh_check ALTER COLUMN a TYPEnumeric;
1152+
\d test_inh_check
1153+
\d test_inh_check_child
1154+
11481155
--
11491156
-- lock levels
11501157
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp