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

Commitb2f266f

Browse files
committed
Fix event triggers for partitioned tables
Index DDL cascading on partitioned tables introduced a way for ALTERTABLE to be called reentrantly. This caused an an important deficiencyin event trigger support to be exposed: on exiting the reentrant call,the alter table state object was clobbered, causing a crash when theouter alter table tries to finalize its processing. Fix the crash bycreating a stack of event trigger state objects. There are still waysto cause things to misbehave (and probably other crashers) with moreelaborate tricks, but at least it now doesn't crash in the obviousscenario.Backpatch to 9.5, where DDL deparsing of event triggers was introduced.Reported-by: Marco SlotAuthors: Michaël Paquier, Álvaro HerreraDiscussion:https://postgr.es/m/CANNhMLCpi+HQ7M36uPfGbJZEQLyTy7XvX=5EFkpR-b1bo0uJew@mail.gmail.com
1 parentbdc2e7a commitb2f266f

File tree

7 files changed

+26
-10
lines changed

7 files changed

+26
-10
lines changed

‎src/backend/catalog/index.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include"catalog/pg_type.h"
4949
#include"catalog/storage.h"
5050
#include"commands/tablecmds.h"
51+
#include"commands/event_trigger.h"
5152
#include"commands/trigger.h"
5253
#include"executor/executor.h"
5354
#include"miscadmin.h"
@@ -191,7 +192,8 @@ relationHasPrimaryKey(Relation rel)
191192
void
192193
index_check_primary_key(RelationheapRel,
193194
IndexInfo*indexInfo,
194-
boolis_alter_table)
195+
boolis_alter_table,
196+
IndexStmt*stmt)
195197
{
196198
List*cmds;
197199
inti;
@@ -263,7 +265,11 @@ index_check_primary_key(Relation heapRel,
263265
* unduly.
264266
*/
265267
if (cmds)
268+
{
269+
EventTriggerAlterTableStart((Node*)stmt);
266270
AlterTableInternal(RelationGetRelid(heapRel),cmds, false);
271+
EventTriggerAlterTableEnd();
272+
}
267273
}
268274

269275
/*

‎src/backend/commands/event_trigger.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,11 +1699,6 @@ EventTriggerCollectSimpleCommand(ObjectAddress address,
16991699
* Note we don't collect the command immediately; instead we keep it in
17001700
* currentCommand, and only when we're done processing the subcommands we will
17011701
* add it to the command list.
1702-
*
1703-
* XXX -- this API isn't considering the possibility of an ALTER TABLE command
1704-
* being called reentrantly by an event trigger function. Do we need stackable
1705-
* commands at this level?Perhaps at least we should detect the condition and
1706-
* raise an error.
17071702
*/
17081703
void
17091704
EventTriggerAlterTableStart(Node*parsetree)
@@ -1728,6 +1723,7 @@ EventTriggerAlterTableStart(Node *parsetree)
17281723
command->d.alterTable.subcmds=NIL;
17291724
command->parsetree=copyObject(parsetree);
17301725

1726+
command->parent=currentEventTriggerState->currentCommand;
17311727
currentEventTriggerState->currentCommand=command;
17321728

17331729
MemoryContextSwitchTo(oldcxt);
@@ -1768,6 +1764,7 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address)
17681764
return;
17691765

17701766
Assert(IsA(subcmd,AlterTableCmd));
1767+
Assert(OidIsValid(currentEventTriggerState->currentCommand));
17711768
Assert(OidIsValid(currentEventTriggerState->currentCommand->d.alterTable.objectId));
17721769

17731770
oldcxt=MemoryContextSwitchTo(currentEventTriggerState->cxt);
@@ -1793,11 +1790,15 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address)
17931790
void
17941791
EventTriggerAlterTableEnd(void)
17951792
{
1793+
CollectedCommand*parent;
1794+
17961795
/* ignore if event trigger context not set, or collection disabled */
17971796
if (!currentEventTriggerState||
17981797
currentEventTriggerState->commandCollectionInhibited)
17991798
return;
18001799

1800+
parent=currentEventTriggerState->currentCommand->parent;
1801+
18011802
/* If no subcommands, don't collect */
18021803
if (list_length(currentEventTriggerState->currentCommand->d.alterTable.subcmds)!=0)
18031804
{
@@ -1808,7 +1809,7 @@ EventTriggerAlterTableEnd(void)
18081809
else
18091810
pfree(currentEventTriggerState->currentCommand);
18101811

1811-
currentEventTriggerState->currentCommand=NULL;
1812+
currentEventTriggerState->currentCommand=parent;
18121813
}
18131814

18141815
/*

‎src/backend/commands/indexcmds.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include"commands/comment.h"
3232
#include"commands/dbcommands.h"
3333
#include"commands/defrem.h"
34+
#include"commands/event_trigger.h"
3435
#include"commands/tablecmds.h"
3536
#include"commands/tablespace.h"
3637
#include"mb/pg_wchar.h"
@@ -575,7 +576,7 @@ DefineIndex(Oid relationId,
575576
* Extra checks when creating a PRIMARY KEY index.
576577
*/
577578
if (stmt->primary)
578-
index_check_primary_key(rel,indexInfo,is_alter_table);
579+
index_check_primary_key(rel,indexInfo,is_alter_table,stmt);
579580

580581
/*
581582
* We disallow indexes on system columns other than OID. They would not

‎src/backend/commands/tablecmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6007,7 +6007,7 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
60076007

60086008
/* Extra checks needed if making primary key */
60096009
if (stmt->primary)
6010-
index_check_primary_key(rel,indexInfo, true);
6010+
index_check_primary_key(rel,indexInfo, true,stmt);
60116011

60126012
/* Note we currently don't support EXCLUSION constraints here */
60136013
if (stmt->primary)

‎src/backend/commands/view.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ validateWithCheckOption(char *value)
6161
*
6262
* Create a view relation and use the rules system to store the query
6363
* for the view.
64+
*
65+
* EventTriggerAlterTableStart must have been called already.
6466
*---------------------------------------------------------------------
6567
*/
6668
staticObjectAddress
@@ -186,6 +188,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
186188
atcmds=lappend(atcmds,atcmd);
187189
}
188190

191+
/* EventTriggerAlterTableStart called by ProcessUtilitySlow */
189192
AlterTableInternal(viewOid,atcmds, true);
190193

191194
/* Make the new view columns visible */
@@ -217,6 +220,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
217220
atcmd->def= (Node*)options;
218221
atcmds=list_make1(atcmd);
219222

223+
/* EventTriggerAlterTableStart called by ProcessUtilitySlow */
220224
AlterTableInternal(viewOid,atcmds, true);
221225

222226
ObjectAddressSet(address,RelationRelationId,viewOid);

‎src/include/catalog/index.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ typedef enum
4040

4141
externvoidindex_check_primary_key(RelationheapRel,
4242
IndexInfo*indexInfo,
43-
boolis_alter_table);
43+
boolis_alter_table,
44+
IndexStmt*stmt);
4445

4546
externOidindex_create(RelationheapRelation,
4647
constchar*indexRelationName,

‎src/include/tcop/deparse_utility.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef struct CollectedATSubcmd
4444
typedefstructCollectedCommand
4545
{
4646
CollectedCommandTypetype;
47+
4748
boolin_extension;
4849
Node*parsetree;
4950

@@ -100,6 +101,8 @@ typedef struct CollectedCommand
100101
GrantObjectTypeobjtype;
101102
}defprivs;
102103
}d;
104+
105+
structCollectedCommand*parent;/* when nested */
103106
}CollectedCommand;
104107

105108
#endif/* DEPARSE_UTILITY_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp