/* * Guts of rule deletion. */ void RemoveRewriteRuleById(Oid ruleOid) { cqContext *pcqCtx; Relation event_relation; HeapTuple tuple; Oid eventRelationOid; bool hasMoreRules; /* * Find the tuple for the target rule. */ pcqCtx = caql_beginscan( NULL, cql("SELECT * FROM pg_rewrite " " WHERE oid = :1 " " FOR UPDATE ", ObjectIdGetDatum(ruleOid))); tuple = caql_getnext(pcqCtx); if (!HeapTupleIsValid(tuple)) elog(ERROR, "could not find tuple for rule %u", ruleOid); /* * We had better grab AccessExclusiveLock so that we know no other rule * additions/deletions are going on for this relation. Else we cannot set * relhasrules correctly. Besides, we don't want to be changing the * ruleset while queries are executing on the rel. */ eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; event_relation = heap_open(eventRelationOid, AccessExclusiveLock); hasMoreRules = event_relation->rd_rules != NULL && event_relation->rd_rules->numLocks > 1; /* * Now delete the pg_rewrite tuple for the rule */ caql_delete_current(pcqCtx); caql_endscan(pcqCtx); /* * Set pg_class 'relhasrules' field correctly for event relation. * * Important side effect: an SI notice is broadcast to force all backends * (including me!) to update relcache entries with the new rule set. * Therefore, must do this even if relhasrules is still true! */ SetRelationRuleStatus(eventRelationOid, hasMoreRules, false); /* Close rel, but keep lock till commit... */ heap_close(event_relation, NoLock); }
/* * Guts of rule deletion. */ void RemoveRewriteRuleById(Oid ruleOid) { Relation RewriteRelation; ScanKeyData skey[1]; SysScanDesc rcscan; Relation event_relation; HeapTuple tuple; Oid eventRelationOid; bool hasMoreRules; /* * Open the pg_rewrite relation. */ RewriteRelation = heap_open(RewriteRelationId, RowExclusiveLock); /* * Find the tuple for the target rule. */ ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ruleOid)); rcscan = systable_beginscan(RewriteRelation, RewriteOidIndexId, true, SnapshotNow, 1, skey); tuple = systable_getnext(rcscan); if (!HeapTupleIsValid(tuple)) elog(ERROR, "could not find tuple for rule %u", ruleOid); /* * We had better grab AccessExclusiveLock so that we know no other rule * additions/deletions are going on for this relation. Else we cannot set * relhasrules correctly. Besides, we don't want to be changing the * ruleset while queries are executing on the rel. */ eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; event_relation = heap_open(eventRelationOid, AccessExclusiveLock); hasMoreRules = event_relation->rd_rules != NULL && event_relation->rd_rules->numLocks > 1; /* * Now delete the pg_rewrite tuple for the rule */ simple_heap_delete(RewriteRelation, &tuple->t_self); systable_endscan(rcscan); heap_close(RewriteRelation, RowExclusiveLock); /* * Set pg_class 'relhasrules' field correctly for event relation. * * Important side effect: an SI notice is broadcast to force all backends * (including me!) to update relcache entries with the new rule set. * Therefore, must do this even if relhasrules is still true! */ SetRelationRuleStatus(eventRelationOid, hasMoreRules, false); /* Close rel, but keep lock till commit... */ heap_close(event_relation, NoLock); }