Skip to content

Commit 88491a4

Browse files
committed
Update trigger dependencies so BDR triggers get dropped when BDR ext is
1 parent cf8f84c commit 88491a4

1 file changed

Lines changed: 41 additions & 2 deletions

File tree

bdr_executor.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "catalog/indexing.h"
2727
#include "catalog/namespace.h"
2828
#include "catalog/pg_namespace.h"
29+
#include "catalog/pg_proc.h"
2930
#include "catalog/pg_trigger.h"
3031

3132
#include "commands/event_trigger.h"
@@ -401,6 +402,8 @@ bdr_create_truncate_trigger(char *schemaname, char *relname, Oid relid)
401402
RangeVar *relrv = makeRangeVar(schemaname, relname, -1);
402403
Relation rel;
403404
List *funcname;
405+
ObjectAddress tgaddr, procaddr;
406+
int nfound;
404407

405408
if (OidIsValid(relid))
406409
rel = heap_open(relid, AccessExclusiveLock);
@@ -450,8 +453,44 @@ bdr_create_truncate_trigger(char *schemaname, char *relname, Oid relid)
450453
tgstmt->initdeferred = false;
451454
tgstmt->constrrel = NULL;
452455

453-
(void) CreateTrigger(tgstmt, NULL, rel->rd_id, InvalidOid,
454-
InvalidOid, InvalidOid, true /* tgisinternal */);
456+
tgaddr.objectId = CreateTrigger(tgstmt, NULL, rel->rd_id, InvalidOid,
457+
InvalidOid, InvalidOid,
458+
true /* tgisinternal */);
459+
460+
tgaddr.classId = TriggerRelationId;
461+
tgaddr.objectSubId = 0;
462+
463+
/*
464+
* The trigger was created with a 'n'ormal dependency on
465+
* bdr.queue_truncate(), which will cause DROP EXTENSION bdr to fail with
466+
* something like:
467+
*
468+
* trigger truncate_trigger_26908 on table sometable depends on function bdr.queue_truncate()
469+
*
470+
* We want the trigger to bdr dropped if EITHER the BDR extension is dropped
471+
* (thus so is bdr.queue_truncate()) OR if the table the trigger is attached
472+
* to is dropped, so we want an automatic dependency on the target table.
473+
* CreateTrigger doesn't offer this directly and we'd rather not cause an
474+
* API break by adding a param, so just twiddle the created dependency.
475+
*/
476+
477+
procaddr.classId = ProcedureRelationId;
478+
procaddr.objectId = LookupFuncName(list_make2(makeString("bdr"), makeString("queue_truncate")), 0, NULL, false);
479+
procaddr.objectSubId = 0;
480+
481+
/* We need to be able to see the pg_depend entry to delete it */
482+
CommandCounterIncrement();
483+
484+
if ((nfound = deleteDependencyRecordsForClass(tgaddr.classId, tgaddr.objectId, ProcedureRelationId, 'n')) != 1)
485+
{
486+
ereport(ERROR,
487+
(errmsg_internal("expected exectly one 'n'ormal dependency from a newly created trigger to a pg_proc entry, got %u", nfound)));
488+
}
489+
490+
recordDependencyOn(&tgaddr, &procaddr, DEPENDENCY_AUTO);
491+
492+
/* We should also record that the trigger is part of the extension */
493+
recordDependencyOnCurrentExtension(&tgaddr, false);
455494

456495
heap_close(rel, AccessExclusiveLock);
457496

0 commit comments

Comments
 (0)