diff options
-rw-r--r-- | src/backend/catalog/index.c | 8 | ||||
-rw-r--r-- | src/backend/commands/event_trigger.c | 13 | ||||
-rw-r--r-- | src/backend/commands/indexcmds.c | 3 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 2 | ||||
-rw-r--r-- | src/backend/commands/view.c | 4 | ||||
-rw-r--r-- | src/include/catalog/index.h | 3 | ||||
-rw-r--r-- | src/include/tcop/deparse_utility.h | 3 |
7 files changed, 26 insertions, 10 deletions
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 18f5ca246e1..b8c1daf09a4 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -45,6 +45,7 @@ #include "catalog/pg_type.h" #include "catalog/storage.h" #include "commands/tablecmds.h" +#include "commands/event_trigger.h" #include "commands/trigger.h" #include "executor/executor.h" #include "miscadmin.h" @@ -186,7 +187,8 @@ relationHasPrimaryKey(Relation rel) void index_check_primary_key(Relation heapRel, IndexInfo *indexInfo, - bool is_alter_table) + bool is_alter_table, + IndexStmt *stmt) { List *cmds; int i; @@ -258,7 +260,11 @@ index_check_primary_key(Relation heapRel, * unduly. */ if (cmds) + { + EventTriggerAlterTableStart((Node *) stmt); AlterTableInternal(RelationGetRelid(heapRel), cmds, false); + EventTriggerAlterTableEnd(); + } } /* diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 6c3aad58d74..4a61044858a 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -1700,11 +1700,6 @@ EventTriggerCollectSimpleCommand(ObjectAddress address, * Note we don't collect the command immediately; instead we keep it in * currentCommand, and only when we're done processing the subcommands we will * add it to the command list. - * - * XXX -- this API isn't considering the possibility of an ALTER TABLE command - * being called reentrantly by an event trigger function. Do we need stackable - * commands at this level? Perhaps at least we should detect the condition and - * raise an error. */ void EventTriggerAlterTableStart(Node *parsetree) @@ -1729,6 +1724,7 @@ EventTriggerAlterTableStart(Node *parsetree) command->d.alterTable.subcmds = NIL; command->parsetree = copyObject(parsetree); + command->parent = currentEventTriggerState->currentCommand; currentEventTriggerState->currentCommand = command; MemoryContextSwitchTo(oldcxt); @@ -1769,6 +1765,7 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address) return; Assert(IsA(subcmd, AlterTableCmd)); + Assert(OidIsValid(currentEventTriggerState->currentCommand)); Assert(OidIsValid(currentEventTriggerState->currentCommand->d.alterTable.objectId)); oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt); @@ -1794,11 +1791,15 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address) void EventTriggerAlterTableEnd(void) { + CollectedCommand *parent; + /* ignore if event trigger context not set, or collection disabled */ if (!currentEventTriggerState || currentEventTriggerState->commandCollectionInhibited) return; + parent = currentEventTriggerState->currentCommand->parent; + /* If no subcommands, don't collect */ if (list_length(currentEventTriggerState->currentCommand->d.alterTable.subcmds) != 0) { @@ -1809,7 +1810,7 @@ EventTriggerAlterTableEnd(void) else pfree(currentEventTriggerState->currentCommand); - currentEventTriggerState->currentCommand = NULL; + currentEventTriggerState->currentCommand = parent; } /* diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 6355dcfbf15..f4fd3c128e4 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -28,6 +28,7 @@ #include "commands/comment.h" #include "commands/dbcommands.h" #include "commands/defrem.h" +#include "commands/event_trigger.h" #include "commands/tablecmds.h" #include "commands/tablespace.h" #include "mb/pg_wchar.h" @@ -565,7 +566,7 @@ DefineIndex(Oid relationId, * Extra checks when creating a PRIMARY KEY index. */ if (stmt->primary) - index_check_primary_key(rel, indexInfo, is_alter_table); + index_check_primary_key(rel, indexInfo, is_alter_table, stmt); /* * Report index creation if appropriate (delay this till after most of the diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index a36458bf024..bc64794b66a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5977,7 +5977,7 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, /* Extra checks needed if making primary key */ if (stmt->primary) - index_check_primary_key(rel, indexInfo, true); + index_check_primary_key(rel, indexInfo, true, stmt); /* Note we currently don't support EXCLUSION constraints here */ if (stmt->primary) diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 0caa39b7466..ae73e2d934b 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -61,6 +61,8 @@ validateWithCheckOption(char *value) * * Create a view relation and use the rules system to store the query * for the view. + * + * EventTriggerAlterTableStart must have been called already. *--------------------------------------------------------------------- */ static ObjectAddress @@ -186,6 +188,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, atcmds = lappend(atcmds, atcmd); } + /* EventTriggerAlterTableStart called by ProcessUtilitySlow */ AlterTableInternal(viewOid, atcmds, true); /* Make the new view columns visible */ @@ -217,6 +220,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, atcmd->def = (Node *) options; atcmds = list_make1(atcmd); + /* EventTriggerAlterTableStart called by ProcessUtilitySlow */ AlterTableInternal(viewOid, atcmds, true); ObjectAddressSet(address, RelationRelationId, viewOid); diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index a29174b6905..f982489168e 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -40,7 +40,8 @@ typedef enum extern void index_check_primary_key(Relation heapRel, IndexInfo *indexInfo, - bool is_alter_table); + bool is_alter_table, + IndexStmt *stmt); extern Oid index_create(Relation heapRelation, const char *indexRelationName, diff --git a/src/include/tcop/deparse_utility.h b/src/include/tcop/deparse_utility.h index d276eeb2287..8dd7bd61983 100644 --- a/src/include/tcop/deparse_utility.h +++ b/src/include/tcop/deparse_utility.h @@ -44,6 +44,7 @@ typedef struct CollectedATSubcmd typedef struct CollectedCommand { CollectedCommandType type; + bool in_extension; Node *parsetree; @@ -100,6 +101,8 @@ typedef struct CollectedCommand GrantObjectType objtype; } defprivs; } d; + + struct CollectedCommand *parent; /* when nested */ } CollectedCommand; #endif /* DEPARSE_UTILITY_H */ |