aboutsummaryrefslogtreecommitdiff
path: root/src/backend/rewrite
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite')
-rw-r--r--src/backend/rewrite/rewriteDefine.c70
-rw-r--r--src/backend/rewrite/rewriteHandler.c27
2 files changed, 95 insertions, 2 deletions
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 64a2a96f0e9..864b00f1e73 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.118 2007/03/13 00:33:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.119 2007/03/19 23:38:29 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,6 +30,7 @@
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
+#include "utils/inval.h"
static void checkRuleResultList(List *targetList, TupleDesc resultDesc,
@@ -79,6 +80,7 @@ InsertRule(char *rulname,
values[i++] = ObjectIdGetDatum(eventrel_oid); /* ev_class */
values[i++] = Int16GetDatum(evslot_index); /* ev_attr */
values[i++] = CharGetDatum(evtype + '0'); /* ev_type */
+ values[i++] = CharGetDatum(RULE_FIRES_ON_ORIGIN); /* ev_enabled */
values[i++] = BoolGetDatum(evinstead); /* is_instead */
values[i++] = DirectFunctionCall1(textin, CStringGetDatum(evqual)); /* ev_qual */
values[i++] = DirectFunctionCall1(textin, CStringGetDatum(actiontree)); /* ev_action */
@@ -629,6 +631,72 @@ setRuleCheckAsUser_Query(Query *qry, Oid userid)
/*
+ * Change the firing semantics of an existing rule.
+ *
+ */
+void
+EnableDisableRule(Relation rel, const char *rulename,
+ char fires_when)
+{
+ Relation pg_rewrite_desc;
+ Oid owningRel = RelationGetRelid(rel);
+ Oid eventRelationOid;
+ HeapTuple ruletup;
+ bool changed = false;
+
+ /*
+ * Find the rule tuple to change.
+ */
+ pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock);
+ ruletup = SearchSysCacheCopy(RULERELNAME,
+ ObjectIdGetDatum(owningRel),
+ PointerGetDatum(rulename),
+ 0, 0);
+ if (!HeapTupleIsValid(ruletup))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("rule \"%s\" for relation \"%s\" does not exist",
+ rulename, get_rel_name(owningRel))));
+
+ /*
+ * Verify that the user has appropriate permissions.
+ */
+ eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_class;
+ Assert(eventRelationOid == owningRel);
+ if (!pg_class_ownercheck(eventRelationOid, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
+ get_rel_name(eventRelationOid));
+
+ /*
+ * Change ev_enabled if it is different from the desired new state.
+ */
+ if (DatumGetChar(((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_enabled) !=
+ fires_when)
+ {
+ ((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_enabled =
+ CharGetDatum(fires_when);
+ simple_heap_update(pg_rewrite_desc, &ruletup->t_self, ruletup);
+
+ /* keep system catalog indexes current */
+ CatalogUpdateIndexes(pg_rewrite_desc, ruletup);
+
+ changed = true;
+ }
+
+ heap_freetuple(ruletup);
+ heap_close(pg_rewrite_desc, RowExclusiveLock);
+
+ /*
+ * If we changed anything, broadcast a SI inval message to force each
+ * backend (including our own!) to rebuild relation's relcache entry.
+ * Otherwise they will fail to apply the change promptly.
+ */
+ if (changed)
+ CacheInvalidateRelcache(rel);
+}
+
+
+/*
* Rename an existing rewrite rule.
*
* This is unused code at the moment.
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index e5a1d4c7472..cd1cb54e9af 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.172 2007/03/17 00:11:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.173 2007/03/19 23:38:29 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,10 +21,12 @@
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parsetree.h"
+#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteHandler.h"
#include "rewrite/rewriteManip.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
+#include "commands/trigger.h"
/* We use a list of these to detect recursion in RewriteQuery */
@@ -1035,6 +1037,29 @@ matchLocks(CmdType event,
{
RewriteRule *oneLock = rulelocks->rules[i];
+ /*
+ * Suppress ON INSERT/UPDATE/DELETE rules that are disabled
+ * or configured to not fire during the current sessions
+ * replication role. ON SELECT rules will always be applied
+ * in order to keep views working even in LOCAL or REPLICA
+ * role.
+ */
+ if (oneLock->event != CMD_SELECT)
+ {
+ if (SessionReplicationRole == SESSION_REPLICATION_ROLE_REPLICA)
+ {
+ if (oneLock->enabled == RULE_FIRES_ON_ORIGIN ||
+ oneLock->enabled == RULE_DISABLED)
+ continue;
+ }
+ else /* ORIGIN or LOCAL ROLE */
+ {
+ if (oneLock->enabled == RULE_FIRES_ON_REPLICA ||
+ oneLock->enabled == RULE_DISABLED)
+ continue;
+ }
+ }
+
if (oneLock->event == event)
{
if (parsetree->commandType != CMD_SELECT ||