1 /*-------------------------------------------------------------------------
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
13 *-------------------------------------------------------------------------
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "access/sysattr.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 "utils/acl.h"
26 #include "utils/fmgroids.h"
27 #include "utils/inval.h"
28 #include "utils/lsyscache.h"
29 #include "utils/rel.h"
30 #include "utils/syscache.h"
31 #include "utils/tqual.h"
37 * Delete a rule given its name.
40 RemoveRewriteRule(Oid owningRel
, const char *ruleName
, DropBehavior behavior
,
48 * Find the tuple for the target rule.
50 tuple
= SearchSysCache(RULERELNAME
,
51 ObjectIdGetDatum(owningRel
),
52 PointerGetDatum(ruleName
),
56 * complain if no rule with such name exists
58 if (!HeapTupleIsValid(tuple
))
62 (errcode(ERRCODE_UNDEFINED_OBJECT
),
63 errmsg("rule \"%s\" for relation \"%s\" does not exist",
64 ruleName
, get_rel_name(owningRel
))));
67 (errmsg("rule \"%s\" for relation \"%s\" does not exist, skipping",
68 ruleName
, get_rel_name(owningRel
))));
73 * Verify user has appropriate permissions.
75 eventRelationOid
= ((Form_pg_rewrite
) GETSTRUCT(tuple
))->ev_class
;
76 Assert(eventRelationOid
== owningRel
);
77 if (!pg_class_ownercheck(eventRelationOid
, GetUserId()))
78 aclcheck_error(ACLCHECK_NOT_OWNER
, ACL_KIND_CLASS
,
79 get_rel_name(eventRelationOid
));
84 object
.classId
= RewriteRelationId
;
85 object
.objectId
= HeapTupleGetOid(tuple
);
86 object
.objectSubId
= 0;
88 ReleaseSysCache(tuple
);
90 performDeletion(&object
, behavior
);
95 * Guts of rule deletion.
98 RemoveRewriteRuleById(Oid ruleOid
)
100 Relation RewriteRelation
;
103 Relation event_relation
;
105 Oid eventRelationOid
;
108 * Open the pg_rewrite relation.
110 RewriteRelation
= heap_open(RewriteRelationId
, RowExclusiveLock
);
113 * Find the tuple for the target rule.
115 ScanKeyInit(&skey
[0],
116 ObjectIdAttributeNumber
,
117 BTEqualStrategyNumber
, F_OIDEQ
,
118 ObjectIdGetDatum(ruleOid
));
120 rcscan
= systable_beginscan(RewriteRelation
, RewriteOidIndexId
, true,
121 SnapshotNow
, 1, skey
);
123 tuple
= systable_getnext(rcscan
);
125 if (!HeapTupleIsValid(tuple
))
126 elog(ERROR
, "could not find tuple for rule %u", ruleOid
);
129 * We had better grab AccessExclusiveLock to ensure that no queries
130 * are going on that might depend on this rule. (Note: a weaker lock
131 * would suffice if it's not an ON SELECT rule.)
133 eventRelationOid
= ((Form_pg_rewrite
) GETSTRUCT(tuple
))->ev_class
;
134 event_relation
= heap_open(eventRelationOid
, AccessExclusiveLock
);
137 * Now delete the pg_rewrite tuple for the rule
139 simple_heap_delete(RewriteRelation
, &tuple
->t_self
);
141 systable_endscan(rcscan
);
143 heap_close(RewriteRelation
, RowExclusiveLock
);
146 * Issue shared-inval notice to force all backends (including me!) to
147 * update relcache entries with the new rule set.
149 CacheInvalidateRelcache(event_relation
);
151 /* Close rel, but keep lock till commit... */
152 heap_close(event_relation
, NoLock
);