diff options
Diffstat (limited to 'src/backend/tcop/utility.c')
-rw-r--r-- | src/backend/tcop/utility.c | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index a1c03f1f763..77b4e5368e7 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -346,12 +346,13 @@ ProcessUtility(Node *parsetree, do { \ if (isCompleteQuery) \ { \ - EventTriggerDDLCommandStart(parsetree); \ + EventTriggerDDLCommandStart(parsetree); \ } \ fncall; \ if (isCompleteQuery) \ { \ - EventTriggerDDLCommandEnd(parsetree); \ + EventTriggerSQLDrop(parsetree); \ + EventTriggerDDLCommandEnd(parsetree); \ } \ } while (0) @@ -366,10 +367,48 @@ ProcessUtility(Node *parsetree, fncall; \ if (_supported) \ { \ + EventTriggerSQLDrop(parsetree); \ EventTriggerDDLCommandEnd(parsetree); \ } \ } while (0) +/* + * UTILITY_BEGIN_QUERY and UTILITY_END_QUERY are a pair of macros to enclose + * execution of a single DDL command, to ensure the event trigger environment + * is appropriately set up before starting, and tore down after completion or + * error. + */ +#define UTILITY_BEGIN_QUERY(isComplete) \ + do { \ + bool _needCleanup = false; \ + \ + if (isComplete) \ + { \ + _needCleanup = EventTriggerBeginCompleteQuery(); \ + } \ + \ + PG_TRY(); \ + { \ + /* avoid empty statement when followed by a semicolon */ \ + (void) 0 + +#define UTILITY_END_QUERY() \ + } \ + PG_CATCH(); \ + { \ + if (_needCleanup) \ + { \ + EventTriggerEndCompleteQuery(); \ + } \ + PG_RE_THROW(); \ + } \ + PG_END_TRY(); \ + if (_needCleanup) \ + { \ + EventTriggerEndCompleteQuery(); \ + } \ + } while (0) + void standard_ProcessUtility(Node *parsetree, const char *queryString, @@ -386,6 +425,8 @@ standard_ProcessUtility(Node *parsetree, if (completionTag) completionTag[0] = '\0'; + UTILITY_BEGIN_QUERY(isCompleteQuery); + switch (nodeTag(parsetree)) { /* @@ -615,7 +656,10 @@ standard_ProcessUtility(Node *parsetree, } if (isCompleteQuery) + { + EventTriggerSQLDrop(parsetree); EventTriggerDDLCommandEnd(parsetree); + } } break; @@ -726,7 +770,10 @@ standard_ProcessUtility(Node *parsetree, if (isCompleteQuery && EventTriggerSupportsObjectType(stmt->removeType)) + { + EventTriggerSQLDrop(parsetree); EventTriggerDDLCommandEnd(parsetree); + } break; } @@ -856,6 +903,12 @@ standard_ProcessUtility(Node *parsetree, ereport(NOTICE, (errmsg("relation \"%s\" does not exist, skipping", atstmt->relation->relname))); + + if (isCompleteQuery) + { + EventTriggerSQLDrop(parsetree); + EventTriggerDDLCommandEnd(parsetree); + } } break; @@ -1248,8 +1301,9 @@ standard_ProcessUtility(Node *parsetree, break; case T_DropOwnedStmt: - /* no event triggers for global objects */ - DropOwnedObjects((DropOwnedStmt *) parsetree); + InvokeDDLCommandEventTriggers( + parsetree, + DropOwnedObjects((DropOwnedStmt *) parsetree)); break; case T_ReassignOwnedStmt: @@ -1372,6 +1426,8 @@ standard_ProcessUtility(Node *parsetree, (int) nodeTag(parsetree)); break; } + + UTILITY_END_QUERY(); } /* |