| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * rewriteRemove.c |
| 4 | * routines for removing rewrite rules |
| 5 | * |
| 6 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 7 | * Portions Copyright (c) 1994, Regents of the University of California |
| 8 | * |
| 9 | * |
| 10 | * IDENTIFICATION |
| 11 | * src/backend/rewrite/rewriteRemove.c |
| 12 | * |
| 13 | *------------------------------------------------------------------------- |
| 14 | */ |
| 15 | #include "postgres.h" |
| 16 | |
| 17 | #include "access/genam.h" |
| 18 | #include "access/htup_details.h" |
| 19 | #include "access/sysattr.h" |
| 20 | #include "access/table.h" |
| 21 | #include "catalog/dependency.h" |
| 22 | #include "catalog/indexing.h" |
| 23 | #include "catalog/namespace.h" |
| 24 | #include "catalog/pg_rewrite.h" |
| 25 | #include "miscadmin.h" |
| 26 | #include "rewrite/rewriteRemove.h" |
| 27 | #include "utils/acl.h" |
| 28 | #include "utils/fmgroids.h" |
| 29 | #include "utils/inval.h" |
| 30 | #include "utils/lsyscache.h" |
| 31 | #include "utils/syscache.h" |
| 32 | |
| 33 | /* |
| 34 | * Guts of rule deletion. |
| 35 | */ |
| 36 | void |
| 37 | RemoveRewriteRuleById(Oid ruleOid) |
| 38 | { |
| 39 | Relation RewriteRelation; |
| 40 | ScanKeyData skey[1]; |
| 41 | SysScanDesc rcscan; |
| 42 | Relation event_relation; |
| 43 | HeapTuple tuple; |
| 44 | Oid eventRelationOid; |
| 45 | |
| 46 | /* |
| 47 | * Open the pg_rewrite relation. |
| 48 | */ |
| 49 | RewriteRelation = table_open(RewriteRelationId, RowExclusiveLock); |
| 50 | |
| 51 | /* |
| 52 | * Find the tuple for the target rule. |
| 53 | */ |
| 54 | ScanKeyInit(&skey[0], |
| 55 | Anum_pg_rewrite_oid, |
| 56 | BTEqualStrategyNumber, F_OIDEQ, |
| 57 | ObjectIdGetDatum(ruleOid)); |
| 58 | |
| 59 | rcscan = systable_beginscan(RewriteRelation, RewriteOidIndexId, true, |
| 60 | NULL, 1, skey); |
| 61 | |
| 62 | tuple = systable_getnext(rcscan); |
| 63 | |
| 64 | if (!HeapTupleIsValid(tuple)) |
| 65 | elog(ERROR, "could not find tuple for rule %u" , ruleOid); |
| 66 | |
| 67 | /* |
| 68 | * We had better grab AccessExclusiveLock to ensure that no queries are |
| 69 | * going on that might depend on this rule. (Note: a weaker lock would |
| 70 | * suffice if it's not an ON SELECT rule.) |
| 71 | */ |
| 72 | eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; |
| 73 | event_relation = table_open(eventRelationOid, AccessExclusiveLock); |
| 74 | |
| 75 | /* |
| 76 | * Now delete the pg_rewrite tuple for the rule |
| 77 | */ |
| 78 | CatalogTupleDelete(RewriteRelation, &tuple->t_self); |
| 79 | |
| 80 | systable_endscan(rcscan); |
| 81 | |
| 82 | table_close(RewriteRelation, RowExclusiveLock); |
| 83 | |
| 84 | /* |
| 85 | * Issue shared-inval notice to force all backends (including me!) to |
| 86 | * update relcache entries with the new rule set. |
| 87 | */ |
| 88 | CacheInvalidateRelcache(event_relation); |
| 89 | |
| 90 | /* Close rel, but keep lock till commit... */ |
| 91 | table_close(event_relation, NoLock); |
| 92 | } |
| 93 | |