|
26 | 26 | #include "catalog/indexing.h" |
27 | 27 | #include "catalog/namespace.h" |
28 | 28 | #include "catalog/pg_namespace.h" |
| 29 | +#include "catalog/pg_proc.h" |
29 | 30 | #include "catalog/pg_trigger.h" |
30 | 31 |
|
31 | 32 | #include "commands/event_trigger.h" |
@@ -401,6 +402,8 @@ bdr_create_truncate_trigger(char *schemaname, char *relname, Oid relid) |
401 | 402 | RangeVar *relrv = makeRangeVar(schemaname, relname, -1); |
402 | 403 | Relation rel; |
403 | 404 | List *funcname; |
| 405 | + ObjectAddress tgaddr, procaddr; |
| 406 | + int nfound; |
404 | 407 |
|
405 | 408 | if (OidIsValid(relid)) |
406 | 409 | rel = heap_open(relid, AccessExclusiveLock); |
@@ -450,8 +453,44 @@ bdr_create_truncate_trigger(char *schemaname, char *relname, Oid relid) |
450 | 453 | tgstmt->initdeferred = false; |
451 | 454 | tgstmt->constrrel = NULL; |
452 | 455 |
|
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); |
455 | 494 |
|
456 | 495 | heap_close(rel, AccessExclusiveLock); |
457 | 496 |
|
|
0 commit comments