1
/*-------------------------------------------------------------------------
4
* routines for removing rewrite rules
6
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.61 2004-12-31 22:00:46 pgsql Exp $
13
*-------------------------------------------------------------------------
17
#include "access/genam.h"
18
#include "access/heapam.h"
19
#include "catalog/catname.h"
20
#include "catalog/dependency.h"
21
#include "catalog/indexing.h"
22
#include "catalog/pg_rewrite.h"
23
#include "miscadmin.h"
24
#include "rewrite/rewriteRemove.h"
25
#include "rewrite/rewriteSupport.h"
26
#include "utils/acl.h"
27
#include "utils/fmgroids.h"
28
#include "utils/lsyscache.h"
29
#include "utils/syscache.h"
35
* Delete a rule given its name.
38
RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior)
46
* Find the tuple for the target rule.
48
tuple = SearchSysCache(RULERELNAME,
49
ObjectIdGetDatum(owningRel),
50
PointerGetDatum(ruleName),
54
* complain if no rule with such name exists
56
if (!HeapTupleIsValid(tuple))
58
(errcode(ERRCODE_UNDEFINED_OBJECT),
59
errmsg("rule \"%s\" for relation \"%s\" does not exist",
60
ruleName, get_rel_name(owningRel))));
63
* Verify user has appropriate permissions.
65
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
66
Assert(eventRelationOid == owningRel);
67
aclresult = pg_class_aclcheck(eventRelationOid, GetUserId(), ACL_RULE);
68
if (aclresult != ACLCHECK_OK)
69
aclcheck_error(aclresult, ACL_KIND_CLASS,
70
get_rel_name(eventRelationOid));
75
object.classId = get_system_catalog_relid(RewriteRelationName);
76
object.objectId = HeapTupleGetOid(tuple);
77
object.objectSubId = 0;
79
ReleaseSysCache(tuple);
81
performDeletion(&object, behavior);
86
* Guts of rule deletion.
89
RemoveRewriteRuleById(Oid ruleOid)
91
Relation RewriteRelation;
94
Relation event_relation;
100
* Open the pg_rewrite relation.
102
RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
105
* Find the tuple for the target rule.
107
ScanKeyInit(&skey[0],
108
ObjectIdAttributeNumber,
109
BTEqualStrategyNumber, F_OIDEQ,
110
ObjectIdGetDatum(ruleOid));
112
rcscan = systable_beginscan(RewriteRelation, RewriteOidIndex, true,
113
SnapshotNow, 1, skey);
115
tuple = systable_getnext(rcscan);
117
if (!HeapTupleIsValid(tuple))
118
elog(ERROR, "could not find tuple for rule %u", ruleOid);
121
* We had better grab AccessExclusiveLock so that we know no other
122
* rule additions/deletions are going on for this relation. Else we
123
* cannot set relhasrules correctly. Besides, we don't want to be
124
* changing the ruleset while queries are executing on the rel.
126
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
127
event_relation = heap_open(eventRelationOid, AccessExclusiveLock);
129
hasMoreRules = event_relation->rd_rules != NULL &&
130
event_relation->rd_rules->numLocks > 1;
133
* Now delete the pg_rewrite tuple for the rule
135
simple_heap_delete(RewriteRelation, &tuple->t_self);
137
systable_endscan(rcscan);
139
heap_close(RewriteRelation, RowExclusiveLock);
142
* Set pg_class 'relhasrules' field correctly for event relation.
144
* Important side effect: an SI notice is broadcast to force all backends
145
* (including me!) to update relcache entries with the new rule set.
146
* Therefore, must do this even if relhasrules is still true!
148
SetRelationRuleStatus(eventRelationOid, hasMoreRules, false);
150
/* Close rel, but keep lock till commit... */
151
heap_close(event_relation, NoLock);