Move the HTSU_Result enum definition into snapshot.h, to avoid including
[PostgreSQL.git] / src / backend / rewrite / rewriteRemove.c
blobb99c3dc2e087c997bf470e3bd3da8dbbb61486d2
1 /*-------------------------------------------------------------------------
3 * rewriteRemove.c
4 * routines for removing rewrite rules
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * $PostgreSQL$
13 *-------------------------------------------------------------------------
15 #include "postgres.h"
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "catalog/dependency.h"
20 #include "catalog/indexing.h"
21 #include "catalog/pg_rewrite.h"
22 #include "miscadmin.h"
23 #include "rewrite/rewriteRemove.h"
24 #include "rewrite/rewriteSupport.h"
25 #include "utils/acl.h"
26 #include "utils/fmgroids.h"
27 #include "utils/lsyscache.h"
28 #include "utils/syscache.h"
29 #include "utils/tqual.h"
33 * RemoveRewriteRule
35 * Delete a rule given its name.
37 void
38 RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior,
39 bool missing_ok)
41 HeapTuple tuple;
42 Oid eventRelationOid;
43 ObjectAddress object;
46 * Find the tuple for the target rule.
48 tuple = SearchSysCache(RULERELNAME,
49 ObjectIdGetDatum(owningRel),
50 PointerGetDatum(ruleName),
51 0, 0);
54 * complain if no rule with such name exists
56 if (!HeapTupleIsValid(tuple))
58 if (!missing_ok)
59 ereport(ERROR,
60 (errcode(ERRCODE_UNDEFINED_OBJECT),
61 errmsg("rule \"%s\" for relation \"%s\" does not exist",
62 ruleName, get_rel_name(owningRel))));
63 else
64 ereport(NOTICE,
65 (errmsg("rule \"%s\" for relation \"%s\" does not exist, skipping",
66 ruleName, get_rel_name(owningRel))));
67 return;
71 * Verify user has appropriate permissions.
73 eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
74 Assert(eventRelationOid == owningRel);
75 if (!pg_class_ownercheck(eventRelationOid, GetUserId()))
76 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
77 get_rel_name(eventRelationOid));
80 * Do the deletion
82 object.classId = RewriteRelationId;
83 object.objectId = HeapTupleGetOid(tuple);
84 object.objectSubId = 0;
86 ReleaseSysCache(tuple);
88 performDeletion(&object, behavior);
93 * Guts of rule deletion.
95 void
96 RemoveRewriteRuleById(Oid ruleOid)
98 Relation RewriteRelation;
99 ScanKeyData skey[1];
100 SysScanDesc rcscan;
101 Relation event_relation;
102 HeapTuple tuple;
103 Oid eventRelationOid;
104 bool hasMoreRules;
107 * Open the pg_rewrite relation.
109 RewriteRelation = heap_open(RewriteRelationId, RowExclusiveLock);
112 * Find the tuple for the target rule.
114 ScanKeyInit(&skey[0],
115 ObjectIdAttributeNumber,
116 BTEqualStrategyNumber, F_OIDEQ,
117 ObjectIdGetDatum(ruleOid));
119 rcscan = systable_beginscan(RewriteRelation, RewriteOidIndexId, true,
120 SnapshotNow, 1, skey);
122 tuple = systable_getnext(rcscan);
124 if (!HeapTupleIsValid(tuple))
125 elog(ERROR, "could not find tuple for rule %u", ruleOid);
128 * We had better grab AccessExclusiveLock so that we know no other rule
129 * additions/deletions are going on for this relation. Else we cannot set
130 * relhasrules correctly. Besides, we don't want to be changing the
131 * ruleset while queries are executing on the rel.
133 eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
134 event_relation = heap_open(eventRelationOid, AccessExclusiveLock);
136 hasMoreRules = event_relation->rd_rules != NULL &&
137 event_relation->rd_rules->numLocks > 1;
140 * Now delete the pg_rewrite tuple for the rule
142 simple_heap_delete(RewriteRelation, &tuple->t_self);
144 systable_endscan(rcscan);
146 heap_close(RewriteRelation, RowExclusiveLock);
149 * Set pg_class 'relhasrules' field correctly for event relation.
151 * Important side effect: an SI notice is broadcast to force all backends
152 * (including me!) to update relcache entries with the new rule set.
153 * Therefore, must do this even if relhasrules is still true!
155 SetRelationRuleStatus(eventRelationOid, hasMoreRules, false);
157 /* Close rel, but keep lock till commit... */
158 heap_close(event_relation, NoLock);