summaryrefslogtreecommitdiff
path: root/src/backend/rewrite
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite')
-rw-r--r--src/backend/rewrite/locks.c173
-rw-r--r--src/backend/rewrite/rewriteDefine.c399
-rw-r--r--src/backend/rewrite/rewriteHandler.c1066
-rw-r--r--src/backend/rewrite/rewriteManip.c707
-rw-r--r--src/backend/rewrite/rewriteRemove.c257
-rw-r--r--src/backend/rewrite/rewriteSupport.c428
6 files changed, 1586 insertions, 1444 deletions
diff --git a/src/backend/rewrite/locks.c b/src/backend/rewrite/locks.c
index 3171d2c845..213fae9b32 100644
--- a/src/backend/rewrite/locks.c
+++ b/src/backend/rewrite/locks.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.2 1996/11/10 03:01:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.3 1997/09/07 04:48:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,7 +14,7 @@
#include "utils/elog.h" /* for elog */
#include "nodes/pg_list.h" /* lisp support package */
#include "nodes/parsenodes.h"
-#include "nodes/primnodes.h" /* Var node def */
+#include "nodes/primnodes.h" /* Var node def */
#include "utils/syscache.h" /* for SearchSysCache */
#include "rewrite/locks.h" /* for rewrite specific lock defns */
@@ -26,106 +26,115 @@
* if we find at least one such match, we return true
* otherwise, we return false
*/
-static bool
-nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
+static bool
+nodeThisLockWasTriggered(Node * node, int varno, AttrNumber attnum)
{
- if (node==NULL)
- return FALSE;
- switch(nodeTag(node)) {
- case T_Var:
+ if (node == NULL)
+ return FALSE;
+ switch (nodeTag(node))
{
- Var *var = (Var *)node;
- if (varno == var->varno &&
- (attnum == var->varattno || attnum == -1))
- return TRUE;
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- return
- nodeThisLockWasTriggered((Node*)expr->args, varno, attnum);
- }
- break;
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- return
- nodeThisLockWasTriggered(tle->expr, varno, attnum);
- }
- break;
- case T_List:
- {
- List *l;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+
+ if (varno == var->varno &&
+ (attnum == var->varattno || attnum == -1))
+ return TRUE;
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ return
+ nodeThisLockWasTriggered((Node *) expr->args, varno, attnum);
+ }
+ break;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ return
+ nodeThisLockWasTriggered(tle->expr, varno, attnum);
+ }
+ break;
+ case T_List:
+ {
+ List *l;
- foreach(l, (List*)node) {
- if (nodeThisLockWasTriggered(lfirst(l), varno, attnum))
- return TRUE;
- }
- return FALSE;
+ foreach(l, (List *) node)
+ {
+ if (nodeThisLockWasTriggered(lfirst(l), varno, attnum))
+ return TRUE;
+ }
+ return FALSE;
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
- return (FALSE);
+ return (FALSE);
}
/*
* thisLockWasTriggered -
- * walk the tree, if there we find a varnode, we check the varattno
- * against the attnum if we find at least one such match, we return true
- * otherwise, we return false
+ * walk the tree, if there we find a varnode, we check the varattno
+ * against the attnum if we find at least one such match, we return true
+ * otherwise, we return false
*/
-static bool
+static bool
thisLockWasTriggered(int varno,
- AttrNumber attnum,
- Query *parsetree)
+ AttrNumber attnum,
+ Query * parsetree)
{
- return
+ return
(nodeThisLockWasTriggered(parsetree->qual, varno, attnum) ||
- nodeThisLockWasTriggered((Node*)parsetree->targetList,
- varno, attnum));
+ nodeThisLockWasTriggered((Node *) parsetree->targetList,
+ varno, attnum));
}
/*
* matchLocks -
- * match the list of locks and returns the matching rules
+ * match the list of locks and returns the matching rules
*/
-List *
+List *
matchLocks(CmdType event,
- RuleLock *rulelocks,
- int varno,
- Query *parsetree)
+ RuleLock * rulelocks,
+ int varno,
+ Query * parsetree)
{
- List *real_locks = NIL;
- int nlocks;
- int i;
-
- Assert(rulelocks != NULL); /* we get called iff there is some lock */
- Assert(parsetree != NULL);
-
- if (parsetree->commandType != CMD_SELECT) {
- if (parsetree->resultRelation != varno) {
- return ( NULL );
+ List *real_locks = NIL;
+ int nlocks;
+ int i;
+
+ Assert(rulelocks != NULL); /* we get called iff there is some lock */
+ Assert(parsetree != NULL);
+
+ if (parsetree->commandType != CMD_SELECT)
+ {
+ if (parsetree->resultRelation != varno)
+ {
+ return (NULL);
+ }
}
- }
-
- nlocks = rulelocks->numLocks;
-
- for (i = 0; i < nlocks; i++) {
- RewriteRule *oneLock = rulelocks->rules[i];
- if (oneLock->event == event) {
- if (parsetree->commandType != CMD_SELECT ||
- thisLockWasTriggered(varno,
- oneLock->attrno,
- parsetree)) {
- real_locks = lappend(real_locks, oneLock);
- }
+ nlocks = rulelocks->numLocks;
+
+ for (i = 0; i < nlocks; i++)
+ {
+ RewriteRule *oneLock = rulelocks->rules[i];
+
+ if (oneLock->event == event)
+ {
+ if (parsetree->commandType != CMD_SELECT ||
+ thisLockWasTriggered(varno,
+ oneLock->attrno,
+ parsetree))
+ {
+ real_locks = lappend(real_locks, oneLock);
+ }
+ }
}
- }
-
- return (real_locks);
-}
+ return (real_locks);
+}
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index a9383fe53d..01b05c4cd0 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rewriteDefine.c--
- * routines for defining a rewrite rule
+ * routines for defining a rewrite rule
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.3 1997/07/24 20:13:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.4 1997/09/07 04:48:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,235 +20,252 @@
#include "utils/builtins.h"
#include "utils/elog.h" /* for elog */
#include "utils/palloc.h"
-#include "utils/lsyscache.h" /* for get_typlen */
+#include "utils/lsyscache.h" /* for get_typlen */
#include "nodes/pg_list.h" /* for Lisp support */
#include "nodes/parsenodes.h"
#include "parser/catalog_utils.h"
-#include "rewrite/locks.h"
+#include "rewrite/locks.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
#include "tcop/tcopprot.h"
-Oid LastOidProcessed = InvalidOid;
+Oid LastOidProcessed = InvalidOid;
/*
* This is too small for many rule plans, but it'll have to do for now.
* Rule plans, etc will eventually have to be large objects.
- *
+ *
* should this be smaller?
*/
-#define RULE_PLAN_SIZE 8192
+#define RULE_PLAN_SIZE 8192
static void
strcpyq(char *dest, char *source)
{
- char *current=source,*destp= dest;
-
- for(current=source; *current; current++) {
- if (*current == '\"') {
- *destp = '\\';
- destp++;
+ char *current = source,
+ *destp = dest;
+
+ for (current = source; *current; current++)
+ {
+ if (*current == '\"')
+ {
+ *destp = '\\';
+ destp++;
+ }
+ *destp = *current;
+ destp++;
}
- *destp = *current;
- destp++;
- }
- *destp = '\0';
+ *destp = '\0';
}
/*
* InsertRule -
- * takes the arguments and inserts them as attributes into the system
- * relation "pg_rewrite"
+ * takes the arguments and inserts them as attributes into the system
+ * relation "pg_rewrite"
*
- * MODS : changes the value of LastOidProcessed as a side
- * effect of inserting the rule tuple
+ * MODS : changes the value of LastOidProcessed as a side
+ * effect of inserting the rule tuple
*
- * ARGS : rulname - name of the rule
- * evtype - one of RETRIEVE,REPLACE,DELETE,APPEND
- * evobj - name of relation
- * evslot - comma delimited list of slots
- * if null => multi-attr rule
- * evinstead - is an instead rule
- * actiontree - parsetree(s) of rule action
+ * ARGS : rulname - name of the rule
+ * evtype - one of RETRIEVE,REPLACE,DELETE,APPEND
+ * evobj - name of relation
+ * evslot - comma delimited list of slots
+ * if null => multi-attr rule
+ * evinstead - is an instead rule
+ * actiontree - parsetree(s) of rule action
*/
-static Oid
+static Oid
InsertRule(char *rulname,
- int evtype,
- char *evobj,
- char *evslot,
- char *evqual,
- bool evinstead,
- char *actiontree)
+ int evtype,
+ char *evobj,
+ char *evslot,
+ char *evqual,
+ bool evinstead,
+ char *actiontree)
{
- static char rulebuf[RULE_PLAN_SIZE];
- static char actionbuf[RULE_PLAN_SIZE];
- static char qualbuf[RULE_PLAN_SIZE];
- Oid eventrel_oid = InvalidOid;
- AttrNumber evslot_index = InvalidAttrNumber;
- Relation eventrel = NULL;
- char *is_instead = "f";
- extern void eval_as_new_xact();
- char *template;
-
- eventrel = heap_openr(evobj);
- if (eventrel == NULL) {
- elog(WARN, "rules cannot be defined on relations not in schema");
- }
- eventrel_oid = RelationGetRelationId(eventrel);
-
- /*
- * if the slotname is null, we know that this is a multi-attr
- * rule
- */
- if (evslot == NULL)
- evslot_index = -1;
- else
- evslot_index = varattno(eventrel, (char*)evslot);
- heap_close(eventrel);
-
- if (evinstead)
- is_instead = "t";
-
- if (evqual == NULL)
- evqual = "nil";
-
- if (IsDefinedRewriteRule(rulname))
- elog(WARN, "Attempt to insert rule '%s' failed: already exists",
- rulname);
- strcpyq(actionbuf,actiontree);
- strcpyq(qualbuf, evqual);
-
- template = "INSERT INTO pg_rewrite \
+ static char rulebuf[RULE_PLAN_SIZE];
+ static char actionbuf[RULE_PLAN_SIZE];
+ static char qualbuf[RULE_PLAN_SIZE];
+ Oid eventrel_oid = InvalidOid;
+ AttrNumber evslot_index = InvalidAttrNumber;
+ Relation eventrel = NULL;
+ char *is_instead = "f";
+ extern void eval_as_new_xact();
+ char *template;
+
+ eventrel = heap_openr(evobj);
+ if (eventrel == NULL)
+ {
+ elog(WARN, "rules cannot be defined on relations not in schema");
+ }
+ eventrel_oid = RelationGetRelationId(eventrel);
+
+ /*
+ * if the slotname is null, we know that this is a multi-attr rule
+ */
+ if (evslot == NULL)
+ evslot_index = -1;
+ else
+ evslot_index = varattno(eventrel, (char *) evslot);
+ heap_close(eventrel);
+
+ if (evinstead)
+ is_instead = "t";
+
+ if (evqual == NULL)
+ evqual = "nil";
+
+ if (IsDefinedRewriteRule(rulname))
+ elog(WARN, "Attempt to insert rule '%s' failed: already exists",
+ rulname);
+ strcpyq(actionbuf, actiontree);
+ strcpyq(qualbuf, evqual);
+
+ template = "INSERT INTO pg_rewrite \
(rulename, ev_type, ev_class, ev_attr, action, ev_qual, is_instead) VALUES \
('%s', %d::char, %d::oid, %d::int2, '%s'::text, '%s'::text, \
'%s'::bool);";
- if (strlen(template) + strlen(rulname) + strlen(actionbuf) +
- strlen(qualbuf) + 20 /* fudge fac */ > RULE_PLAN_SIZE) {
- elog(WARN, "DefineQueryRewrite: rule plan string too big.");
- }
- sprintf(rulebuf, template,
- rulname, evtype, eventrel_oid, evslot_index, actionbuf,
- qualbuf, is_instead);
-
- pg_eval(rulebuf, (char **) NULL, (Oid *) NULL, 0);
-
- return (LastOidProcessed);
+ if (strlen(template) + strlen(rulname) + strlen(actionbuf) +
+ strlen(qualbuf) + 20 /* fudge fac */ > RULE_PLAN_SIZE)
+ {
+ elog(WARN, "DefineQueryRewrite: rule plan string too big.");
+ }
+ sprintf(rulebuf, template,
+ rulname, evtype, eventrel_oid, evslot_index, actionbuf,
+ qualbuf, is_instead);
+
+ pg_eval(rulebuf, (char **) NULL, (Oid *) NULL, 0);
+
+ return (LastOidProcessed);
}
/*
- * for now, event_object must be a single attribute
+ * for now, event_object must be a single attribute
*/
static void
ValidateRule(int event_type,
- char *eobj_string,
- char *eslot_string,
- Node *event_qual,
- List **action,
- int is_instead,
- Oid event_attype)
+ char *eobj_string,
+ char *eslot_string,
+ Node * event_qual,
+ List ** action,
+ int is_instead,
+ Oid event_attype)
{
- if (((event_type == CMD_INSERT) || (event_type == CMD_DELETE)) &&
- eslot_string) {
- elog(WARN,
- "rules not allowed for insert or delete events to an attribute");
- }
-
- if (event_qual && !*action && is_instead)
- elog(WARN,
- "event_quals on 'instead nothing' rules not currently supported");
-
-#if 0
- /* on retrieve to class.attribute do instead nothing is converted
- * to 'on retrieve to class.attribute do instead
- * retrieve (attribute = NULL)'
- * --- this is also a terrible hack that works well -- glass*/
- if (is_instead && !*action && eslot_string && event_type == CMD_SELECT) {
- char *temp_buffer = (char *) palloc(strlen(template)+80);
- sprintf(temp_buffer, template, event_attype,
- get_typlen(event_attype), eslot_string,
- event_attype);
-
- *action = (List*) stringToNode(temp_buffer);
-
- pfree(temp_buffer);
- }
-#endif
+ if (((event_type == CMD_INSERT) || (event_type == CMD_DELETE)) &&
+ eslot_string)
+ {
+ elog(WARN,
+ "rules not allowed for insert or delete events to an attribute");
+ }
+
+ if (event_qual && !*action && is_instead)
+ elog(WARN,
+ "event_quals on 'instead nothing' rules not currently supported");
+
+#if 0
+
+ /*
+ * on retrieve to class.attribute do instead nothing is converted to
+ * 'on retrieve to class.attribute do instead retrieve (attribute =
+ * NULL)' --- this is also a terrible hack that works well -- glass
+ */
+ if (is_instead && !*action && eslot_string && event_type == CMD_SELECT)
+ {
+ char *temp_buffer = (char *) palloc(strlen(template) + 80);
+
+ sprintf(temp_buffer, template, event_attype,
+ get_typlen(event_attype), eslot_string,
+ event_attype);
+
+ *action = (List *) stringToNode(temp_buffer);
+
+ pfree(temp_buffer);
+ }
+#endif
}
void
-DefineQueryRewrite(RuleStmt *stmt)
+DefineQueryRewrite(RuleStmt * stmt)
{
- CmdType event_type = stmt->event;
- Attr *event_obj = stmt->object;
- Node *event_qual = stmt->whereClause;
- bool is_instead = stmt->instead;
- List *action = stmt->actions;
- Relation event_relation = NULL ;
- Oid ruleId;
- Oid ev_relid = 0;
- char *eslot_string = NULL;
- int event_attno = 0;
- Oid event_attype = 0;
- char *actionP, *event_qualP;
-
- if (event_obj->attrs)
- eslot_string = strVal(lfirst(event_obj->attrs));
- else
- eslot_string = NULL;
-
- event_relation = heap_openr(event_obj->relname);
- if ( event_relation == NULL ) {
- elog(WARN, "virtual relations not supported yet");
- }
- ev_relid = RelationGetRelationId(event_relation);
-
- if (eslot_string == NULL) {
- event_attno = -1;
- event_attype = -1; /* XXX - don't care */
- } else {
- event_attno = varattno(event_relation, eslot_string);
- event_attype = att_typeid(event_relation,event_attno);
- }
- heap_close(event_relation);
-
- /* fix bug about instead nothing */
- ValidateRule(event_type, event_obj->relname,
- eslot_string, event_qual, &action,
- is_instead,event_attype);
-
- if (action == NULL) {
- if (!is_instead) return; /* doesn't do anything */
-
- event_qualP = nodeToString(event_qual);
-
- ruleId = InsertRule(stmt->rulename,
- event_type,
- event_obj->relname,
- eslot_string,
- event_qualP,
- true,
- "nil");
- prs2_addToRelation(ev_relid, ruleId, event_type, event_attno, TRUE,
- event_qual, NIL);
-
- } else {
- event_qualP = nodeToString(event_qual);
- actionP = nodeToString(action);
-
- ruleId = InsertRule(stmt->rulename,
- event_type,
- event_obj->relname,
- eslot_string,
- event_qualP,
- is_instead,
- actionP);
-
- /* what is the max size of type text? XXX -- glass */
- if (length(action) > 15 )
- elog(WARN,"max # of actions exceeded");
- prs2_addToRelation(ev_relid, ruleId, event_type, event_attno,
- is_instead, event_qual, action);
- }
-}
+ CmdType event_type = stmt->event;
+ Attr *event_obj = stmt->object;
+ Node *event_qual = stmt->whereClause;
+ bool is_instead = stmt->instead;
+ List *action = stmt->actions;
+ Relation event_relation = NULL;
+ Oid ruleId;
+ Oid ev_relid = 0;
+ char *eslot_string = NULL;
+ int event_attno = 0;
+ Oid event_attype = 0;
+ char *actionP,
+ *event_qualP;
+
+ if (event_obj->attrs)
+ eslot_string = strVal(lfirst(event_obj->attrs));
+ else
+ eslot_string = NULL;
+
+ event_relation = heap_openr(event_obj->relname);
+ if (event_relation == NULL)
+ {
+ elog(WARN, "virtual relations not supported yet");
+ }
+ ev_relid = RelationGetRelationId(event_relation);
+
+ if (eslot_string == NULL)
+ {
+ event_attno = -1;
+ event_attype = -1; /* XXX - don't care */
+ }
+ else
+ {
+ event_attno = varattno(event_relation, eslot_string);
+ event_attype = att_typeid(event_relation, event_attno);
+ }
+ heap_close(event_relation);
+ /* fix bug about instead nothing */
+ ValidateRule(event_type, event_obj->relname,
+ eslot_string, event_qual, &action,
+ is_instead, event_attype);
+
+ if (action == NULL)
+ {
+ if (!is_instead)
+ return; /* doesn't do anything */
+
+ event_qualP = nodeToString(event_qual);
+
+ ruleId = InsertRule(stmt->rulename,
+ event_type,
+ event_obj->relname,
+ eslot_string,
+ event_qualP,
+ true,
+ "nil");
+ prs2_addToRelation(ev_relid, ruleId, event_type, event_attno, TRUE,
+ event_qual, NIL);
+
+ }
+ else
+ {
+ event_qualP = nodeToString(event_qual);
+ actionP = nodeToString(action);
+
+ ruleId = InsertRule(stmt->rulename,
+ event_type,
+ event_obj->relname,
+ eslot_string,
+ event_qualP,
+ is_instead,
+ actionP);
+
+ /* what is the max size of type text? XXX -- glass */
+ if (length(action) > 15)
+ elog(WARN, "max # of actions exceeded");
+ prs2_addToRelation(ev_relid, ruleId, event_type, event_attno,
+ is_instead, event_qual, action);
+ }
+}
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 093451655d..980956a480 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.3 1997/08/12 22:53:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.4 1997/09/07 04:48:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,13 +15,13 @@
#include "utils/palloc.h"
#include "utils/elog.h"
#include "utils/rel.h"
-#include "nodes/pg_list.h"
+#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
-#include "parser/parsetree.h" /* for parsetree manipulation */
+#include "parser/parsetree.h" /* for parsetree manipulation */
#include "nodes/parsenodes.h"
-#include "rewrite/rewriteSupport.h"
+#include "rewrite/rewriteSupport.h"
#include "rewrite/rewriteHandler.h"
#include "rewrite/rewriteManip.h"
#include "rewrite/locks.h"
@@ -29,529 +29,580 @@
#include "commands/creatinh.h"
#include "access/heapam.h"
-static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
- int rt_index, int relation_level, int *modified);
-static List *fireRules(Query *parsetree, int rt_index, CmdType event,
- bool *instead_flag, List *locks, List **qual_products);
-static List *deepRewriteQuery(Query *parsetree);
+static void
+ApplyRetrieveRule(Query * parsetree, RewriteRule * rule,
+ int rt_index, int relation_level, int *modified);
+static List *
+fireRules(Query * parsetree, int rt_index, CmdType event,
+ bool * instead_flag, List * locks, List ** qual_products);
+static List *deepRewriteQuery(Query * parsetree);
/*
* gatherRewriteMeta -
- * Gather meta information about parsetree, and rule. Fix rule body
- * and qualifier so that they can be mixed with the parsetree and
- * maintain semantic validity
+ * Gather meta information about parsetree, and rule. Fix rule body
+ * and qualifier so that they can be mixed with the parsetree and
+ * maintain semantic validity
*/
static RewriteInfo *
-gatherRewriteMeta(Query *parsetree,
- Query *rule_action,
- Node *rule_qual,
- int rt_index,
- CmdType event,
- bool *instead_flag)
+gatherRewriteMeta(Query * parsetree,
+ Query * rule_action,
+ Node * rule_qual,
+ int rt_index,
+ CmdType event,
+ bool * instead_flag)
{
- RewriteInfo *info;
- int rt_length;
- int result_reln;
-
- info = (RewriteInfo *) palloc(sizeof(RewriteInfo));
- info->rt_index = rt_index;
- info->event = event;
- info->instead_flag = *instead_flag;
- info->rule_action = (Query*)copyObject(rule_action);
- info->rule_qual = (Node*)copyObject(rule_qual);
- if (info->rule_action == NULL) info->nothing = TRUE;
- else {
- info->nothing = FALSE;
- info->action = info->rule_action->commandType;
- info->current_varno = rt_index;
- info->rt = parsetree->rtable;
- rt_length = length(info->rt);
- info->rt = append(info->rt, info->rule_action->rtable);
-
- info->new_varno = PRS2_NEW_VARNO + rt_length;
- OffsetVarNodes(info->rule_action->qual, rt_length);
- OffsetVarNodes((Node*)info->rule_action->targetList, rt_length);
- OffsetVarNodes(info->rule_qual, rt_length);
- ChangeVarNodes((Node*)info->rule_action->qual,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes((Node*)info->rule_action->targetList,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes(info->rule_qual,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
-
- /*
- * bug here about replace CURRENT -- sort of
- * replace current is deprecated now so this code shouldn't really
- * need to be so clutzy but.....
- */
- if (info->action != CMD_SELECT) { /* i.e update XXXXX */
- int new_result_reln = 0;
- result_reln = info->rule_action->resultRelation;
- switch (result_reln) {
- case PRS2_CURRENT_VARNO: new_result_reln = rt_index;
- break;
- case PRS2_NEW_VARNO: /* XXX */
- default:
- new_result_reln = result_reln + rt_length;
- break;
- }
- info->rule_action->resultRelation = new_result_reln;
- }
- }
- return info;
+ RewriteInfo *info;
+ int rt_length;
+ int result_reln;
+
+ info = (RewriteInfo *) palloc(sizeof(RewriteInfo));
+ info->rt_index = rt_index;
+ info->event = event;
+ info->instead_flag = *instead_flag;
+ info->rule_action = (Query *) copyObject(rule_action);
+ info->rule_qual = (Node *) copyObject(rule_qual);
+ if (info->rule_action == NULL)
+ info->nothing = TRUE;
+ else
+ {
+ info->nothing = FALSE;
+ info->action = info->rule_action->commandType;
+ info->current_varno = rt_index;
+ info->rt = parsetree->rtable;
+ rt_length = length(info->rt);
+ info->rt = append(info->rt, info->rule_action->rtable);
+
+ info->new_varno = PRS2_NEW_VARNO + rt_length;
+ OffsetVarNodes(info->rule_action->qual, rt_length);
+ OffsetVarNodes((Node *) info->rule_action->targetList, rt_length);
+ OffsetVarNodes(info->rule_qual, rt_length);
+ ChangeVarNodes((Node *) info->rule_action->qual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes((Node *) info->rule_action->targetList,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes(info->rule_qual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+
+ /*
+ * bug here about replace CURRENT -- sort of replace current is
+ * deprecated now so this code shouldn't really need to be so
+ * clutzy but.....
+ */
+ if (info->action != CMD_SELECT)
+ { /* i.e update XXXXX */
+ int new_result_reln = 0;
+
+ result_reln = info->rule_action->resultRelation;
+ switch (result_reln)
+ {
+ case PRS2_CURRENT_VARNO:
+ new_result_reln = rt_index;
+ break;
+ case PRS2_NEW_VARNO: /* XXX */
+ default:
+ new_result_reln = result_reln + rt_length;
+ break;
+ }
+ info->rule_action->resultRelation = new_result_reln;
+ }
+ }
+ return info;
}
-static List *
-OptimizeRIRRules(List *locks)
+static List *
+OptimizeRIRRules(List * locks)
{
- List *attr_level = NIL, *i;
- List *relation_level = NIL;
-
- foreach (i, locks) {
- RewriteRule *rule_lock = lfirst(i);
-
- if (rule_lock->attrno == -1)
- relation_level = lappend(relation_level, rule_lock);
- else
- attr_level = lappend(attr_level, rule_lock);
- }
- return nconc(relation_level, attr_level);
+ List *attr_level = NIL,
+ *i;
+ List *relation_level = NIL;
+
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = lfirst(i);
+
+ if (rule_lock->attrno == -1)
+ relation_level = lappend(relation_level, rule_lock);
+ else
+ attr_level = lappend(attr_level, rule_lock);
+ }
+ return nconc(relation_level, attr_level);
}
/*
* idea is to put instead rules before regular rules so that
* excess semantically queasy queries aren't processed
*/
-static List *
-orderRules(List *locks)
+static List *
+orderRules(List * locks)
{
- List *regular = NIL, *i;
- List *instead_rules = NIL;
-
- foreach (i, locks) {
- RewriteRule *rule_lock = (RewriteRule *)lfirst(i);
-
- if (rule_lock->isInstead)
- instead_rules = lappend(instead_rules, rule_lock);
- else
- regular = lappend(regular, rule_lock);
- }
- return nconc(regular, instead_rules);
+ List *regular = NIL,
+ *i;
+ List *instead_rules = NIL;
+
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+
+ if (rule_lock->isInstead)
+ instead_rules = lappend(instead_rules, rule_lock);
+ else
+ regular = lappend(regular, rule_lock);
+ }
+ return nconc(regular, instead_rules);
}
static int
-AllRetrieve(List *actions)
+AllRetrieve(List * actions)
{
- List *n;
-
- foreach(n, actions) {
- Query *pt = lfirst(n);
-
- /*
- * in the old postgres code, we check whether command_type is
- * a consp of '('*'.commandType). but we've never supported transitive
- * closures. Hence removed - ay 10/94.
- */
- if (pt->commandType != CMD_SELECT)
- return false;
- }
- return true;
+ List *n;
+
+ foreach(n, actions)
+ {
+ Query *pt = lfirst(n);
+
+ /*
+ * in the old postgres code, we check whether command_type is a
+ * consp of '('*'.commandType). but we've never supported
+ * transitive closures. Hence removed - ay 10/94.
+ */
+ if (pt->commandType != CMD_SELECT)
+ return false;
+ }
+ return true;
}
-static List *
-FireRetrieveRulesAtQuery(Query *parsetree,
- int rt_index,
- Relation relation,
- bool *instead_flag,
- int rule_flag)
+static List *
+FireRetrieveRulesAtQuery(Query * parsetree,
+ int rt_index,
+ Relation relation,
+ bool * instead_flag,
+ int rule_flag)
{
- List *i, *locks;
- RuleLock *rt_entry_locks = NULL;
- List *work = NIL;
+ List *i,
+ *locks;
+ RuleLock *rt_entry_locks = NULL;
+ List *work = NIL;
- if ((rt_entry_locks = relation->rd_rules) == NULL)
- return NIL;
-
- locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
-
- /* find all retrieve instead */
- foreach (i, locks) {
- RewriteRule *rule_lock = (RewriteRule *)lfirst(i);
-
- if (!rule_lock->isInstead)
- continue;
- work = lappend(work, rule_lock);
- }
- if (work != NIL) {
- work = OptimizeRIRRules(locks);
- foreach (i, work) {
- RewriteRule *rule_lock = lfirst(i);
- int relation_level;
- int modified = FALSE;
-
- relation_level = (rule_lock->attrno == -1);
- if (rule_lock->actions == NIL) {
- *instead_flag = TRUE;
+ if ((rt_entry_locks = relation->rd_rules) == NULL)
return NIL;
- }
- if (!rule_flag &&
- length(rule_lock->actions) >= 2 &&
- AllRetrieve(rule_lock->actions)) {
- *instead_flag = TRUE;
- return rule_lock->actions;
- }
- ApplyRetrieveRule(parsetree, rule_lock, rt_index, relation_level,
- &modified);
- if (modified) {
- *instead_flag = TRUE;
- FixResdomTypes(parsetree->targetList);
- return lcons(parsetree,NIL);
- }
+
+ locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+
+ /* find all retrieve instead */
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+
+ if (!rule_lock->isInstead)
+ continue;
+ work = lappend(work, rule_lock);
+ }
+ if (work != NIL)
+ {
+ work = OptimizeRIRRules(locks);
+ foreach(i, work)
+ {
+ RewriteRule *rule_lock = lfirst(i);
+ int relation_level;
+ int modified = FALSE;
+
+ relation_level = (rule_lock->attrno == -1);
+ if (rule_lock->actions == NIL)
+ {
+ *instead_flag = TRUE;
+ return NIL;
+ }
+ if (!rule_flag &&
+ length(rule_lock->actions) >= 2 &&
+ AllRetrieve(rule_lock->actions))
+ {
+ *instead_flag = TRUE;
+ return rule_lock->actions;
+ }
+ ApplyRetrieveRule(parsetree, rule_lock, rt_index, relation_level,
+ &modified);
+ if (modified)
+ {
+ *instead_flag = TRUE;
+ FixResdomTypes(parsetree->targetList);
+ return lcons(parsetree, NIL);
+ }
+ }
}
- }
- return NIL;
-}
+ return NIL;
+}
/* Idea is like this:
*
* retrieve-instead-retrieve rules have different semantics than update nodes
- * Separate RIR rules from others. Pass others to FireRules.
+ * Separate RIR rules from others. Pass others to FireRules.
* Order RIR rules and process.
*
* side effect: parsetree's rtable field might be changed
*/
static void
-ApplyRetrieveRule(Query *parsetree,
- RewriteRule *rule,
- int rt_index,
- int relation_level,
- int *modified)
+ApplyRetrieveRule(Query * parsetree,
+ RewriteRule * rule,
+ int rt_index,
+ int relation_level,
+ int *modified)
{
- Query *rule_action = NULL;
- Node *rule_qual;
- List *rtable, *rt;
- int nothing, rt_length;
- int badsql= FALSE;
-
- rule_qual = rule->qual;
- if (rule->actions) {
- if (length(rule->actions) > 1) /* ??? because we don't handle rules
- with more than one action? -ay */
- return;
- rule_action = copyObject(lfirst(rule->actions));
- nothing = FALSE;
- } else {
- nothing = TRUE;
- }
-
- rtable = copyObject(parsetree->rtable);
- foreach (rt, rtable) {
- RangeTblEntry *rte = lfirst(rt);
- /*
- * this is to prevent add_missing_vars_to_base_rels() from
- * adding a bogus entry to the new target list.
- */
- rte->inFromCl = false;
- }
- rt_length = length(rtable);
- rtable = nconc(rtable, copyObject(rule_action->rtable));
- parsetree->rtable = rtable;
-
- rule_action->rtable = rtable;
- OffsetVarNodes(rule_action->qual, rt_length);
- OffsetVarNodes((Node*)rule_action->targetList, rt_length);
- OffsetVarNodes(rule_qual, rt_length);
- ChangeVarNodes(rule_action->qual,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes((Node*)rule_action->targetList,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO+rt_length, rt_index);
- if (relation_level) {
- HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
- modified);
- } else {
- HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
- rt_index, rule->attrno, modified, &badsql);
- }
- if (*modified && !badsql)
- AddQual(parsetree, rule_action->qual);
+ Query *rule_action = NULL;
+ Node *rule_qual;
+ List *rtable,
+ *rt;
+ int nothing,
+ rt_length;
+ int badsql = FALSE;
+
+ rule_qual = rule->qual;
+ if (rule->actions)
+ {
+ if (length(rule->actions) > 1) /* ??? because we don't handle
+ * rules with more than one
+ * action? -ay */
+ return;
+ rule_action = copyObject(lfirst(rule->actions));
+ nothing = FALSE;
+ }
+ else
+ {
+ nothing = TRUE;
+ }
+
+ rtable = copyObject(parsetree->rtable);
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rte = lfirst(rt);
+
+ /*
+ * this is to prevent add_missing_vars_to_base_rels() from adding
+ * a bogus entry to the new target list.
+ */
+ rte->inFromCl = false;
+ }
+ rt_length = length(rtable);
+ rtable = nconc(rtable, copyObject(rule_action->rtable));
+ parsetree->rtable = rtable;
+
+ rule_action->rtable = rtable;
+ OffsetVarNodes(rule_action->qual, rt_length);
+ OffsetVarNodes((Node *) rule_action->targetList, rt_length);
+ OffsetVarNodes(rule_qual, rt_length);
+ ChangeVarNodes(rule_action->qual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes((Node *) rule_action->targetList,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index);
+ if (relation_level)
+ {
+ HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
+ modified);
+ }
+ else
+ {
+ HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
+ rt_index, rule->attrno, modified, &badsql);
+ }
+ if (*modified && !badsql)
+ AddQual(parsetree, rule_action->qual);
}
-static List *
-ProcessRetrieveQuery(Query *parsetree,
- List *rtable,
- bool *instead_flag,
- bool rule)
+static List *
+ProcessRetrieveQuery(Query * parsetree,
+ List * rtable,
+ bool * instead_flag,
+ bool rule)
{
- List *rt;
- List *product_queries = NIL;
- int rt_index = 0;
-
- foreach (rt, rtable) {
- RangeTblEntry *rt_entry = lfirst(rt);
- Relation rt_entry_relation = NULL;
- List *result = NIL;
-
- rt_index++;
- rt_entry_relation = heap_openr(rt_entry->relname);
-
- if (rt_entry_relation->rd_rules != NULL) {
- result =
- FireRetrieveRulesAtQuery(parsetree,
- rt_index,
- rt_entry_relation,
- instead_flag,
- rule);
+ List *rt;
+ List *product_queries = NIL;
+ int rt_index = 0;
+
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rt_entry = lfirst(rt);
+ Relation rt_entry_relation = NULL;
+ List *result = NIL;
+
+ rt_index++;
+ rt_entry_relation = heap_openr(rt_entry->relname);
+
+ if (rt_entry_relation->rd_rules != NULL)
+ {
+ result =
+ FireRetrieveRulesAtQuery(parsetree,
+ rt_index,
+ rt_entry_relation,
+ instead_flag,
+ rule);
+ }
+ heap_close(rt_entry_relation);
+ if (*instead_flag)
+ return result;
}
- heap_close(rt_entry_relation);
- if (*instead_flag)
- return result;
- }
- if (rule)
- return NIL;
+ if (rule)
+ return NIL;
- foreach (rt, rtable) {
- RangeTblEntry *rt_entry = lfirst(rt);
- Relation rt_entry_relation = NULL;
- RuleLock *rt_entry_locks = NULL;
- List *result = NIL;
- List *locks = NIL;
- List *dummy_products;
-
- rt_index++;
- rt_entry_relation = heap_openr(rt_entry->relname);
- rt_entry_locks = rt_entry_relation->rd_rules;
- heap_close(rt_entry_relation);
-
- if (rt_entry_locks) {
- locks =
- matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rt_entry = lfirst(rt);
+ Relation rt_entry_relation = NULL;
+ RuleLock *rt_entry_locks = NULL;
+ List *result = NIL;
+ List *locks = NIL;
+ List *dummy_products;
+
+ rt_index++;
+ rt_entry_relation = heap_openr(rt_entry->relname);
+ rt_entry_locks = rt_entry_relation->rd_rules;
+ heap_close(rt_entry_relation);
+
+ if (rt_entry_locks)
+ {
+ locks =
+ matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+ }
+ if (locks != NIL)
+ {
+ result = fireRules(parsetree, rt_index, CMD_SELECT,
+ instead_flag, locks, &dummy_products);
+ if (*instead_flag)
+ return lappend(NIL, result);
+ if (result != NIL)
+ product_queries = nconc(product_queries, result);
+ }
}
- if (locks != NIL) {
- result = fireRules(parsetree, rt_index, CMD_SELECT,
- instead_flag, locks, &dummy_products);
- if (*instead_flag)
- return lappend(NIL, result);
- if (result != NIL)
- product_queries = nconc(product_queries, result);
- }
- }
- return product_queries;
+ return product_queries;
}
-static Query *
-CopyAndAddQual(Query *parsetree,
- List *actions,
- Node *rule_qual,
- int rt_index,
- CmdType event)
+static Query *
+CopyAndAddQual(Query * parsetree,
+ List * actions,
+ Node * rule_qual,
+ int rt_index,
+ CmdType event)
{
- Query *new_tree = (Query *) copyObject(parsetree);
- Node *new_qual = NULL;
- Query *rule_action = NULL;
-
- if (actions)
- rule_action = lfirst(actions);
- if (rule_qual != NULL)
- new_qual = (Node *)copyObject(rule_qual);
- if (rule_action != NULL) {
- List *rtable;
- int rt_length;
-
- rtable = new_tree->rtable;
- rt_length = length(rtable);
- rtable = append(rtable,listCopy(rule_action->rtable));
- new_tree->rtable = rtable;
- OffsetVarNodes(new_qual, rt_length);
- ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO+rt_length, rt_index);
- }
- /* XXX -- where current doesn't work for instead nothing.... yet*/
- AddNotQual(new_tree, new_qual);
-
- return new_tree;
+ Query *new_tree = (Query *) copyObject(parsetree);
+ Node *new_qual = NULL;
+ Query *rule_action = NULL;
+
+ if (actions)
+ rule_action = lfirst(actions);
+ if (rule_qual != NULL)
+ new_qual = (Node *) copyObject(rule_qual);
+ if (rule_action != NULL)
+ {
+ List *rtable;
+ int rt_length;
+
+ rtable = new_tree->rtable;
+ rt_length = length(rtable);
+ rtable = append(rtable, listCopy(rule_action->rtable));
+ new_tree->rtable = rtable;
+ OffsetVarNodes(new_qual, rt_length);
+ ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index);
+ }
+ /* XXX -- where current doesn't work for instead nothing.... yet */
+ AddNotQual(new_tree, new_qual);
+
+ return new_tree;
}
/*
- * fireRules -
- * Iterate through rule locks applying rules. After an instead rule
- * rule has been applied, return just new parsetree and let RewriteQuery
- * start the process all over again. The locks are reordered to maintain
- * sensible semantics. remember: reality is for dead birds -- glass
+ * fireRules -
+ * Iterate through rule locks applying rules. After an instead rule
+ * rule has been applied, return just new parsetree and let RewriteQuery
+ * start the process all over again. The locks are reordered to maintain
+ * sensible semantics. remember: reality is for dead birds -- glass
*
*/
-static List *
-fireRules(Query *parsetree,
- int rt_index,
- CmdType event,
- bool *instead_flag,
- List *locks,
- List **qual_products)
+static List *
+fireRules(Query * parsetree,
+ int rt_index,
+ CmdType event,
+ bool * instead_flag,
+ List * locks,
+ List ** qual_products)
{
- RewriteInfo *info;
- List *results = NIL;
- List *i;
-
- /* choose rule to fire from list of rules */
- if (locks == NIL) {
- ProcessRetrieveQuery(parsetree,
- parsetree->rtable,
- instead_flag, TRUE);
- if (*instead_flag)
- return lappend(NIL, parsetree);
- else
- return NIL;
- }
-
- locks = orderRules(locks); /* instead rules first */
- foreach (i, locks) {
- RewriteRule *rule_lock = (RewriteRule *)lfirst(i);
- Node *qual, *event_qual;
- List *actions;
- List *r;
- bool orig_instead_flag = *instead_flag;
-
- /* multiple rule action time */
- *instead_flag = rule_lock->isInstead;
- event_qual = rule_lock->qual;
- actions = rule_lock->actions;
- if (event_qual != NULL && *instead_flag)
- *qual_products =
- lappend(*qual_products,
- CopyAndAddQual(parsetree, actions, event_qual,
- rt_index, event));
- foreach (r, actions) {
- Query *rule_action = lfirst(r);
- Node *rule_qual = copyObject(event_qual);
-
- /*--------------------------------------------------
- * Step 1:
- * Rewrite current.attribute or current to tuple variable
- * this appears to be done in parser?
- *--------------------------------------------------
- */
- info = gatherRewriteMeta(parsetree, rule_action, rule_qual,
- rt_index,event,instead_flag);
-
- /* handle escapable cases, or those handled by other code */
- if (info->nothing) {
+ RewriteInfo *info;
+ List *results = NIL;
+ List *i;
+
+ /* choose rule to fire from list of rules */
+ if (locks == NIL)
+ {
+ ProcessRetrieveQuery(parsetree,
+ parsetree->rtable,
+ instead_flag, TRUE);
if (*instead_flag)
- return NIL;
+ return lappend(NIL, parsetree);
else
- continue;
- }
-
- if (info->action == info->event &&
- info->event == CMD_SELECT)
- continue;
-
- /*
- * Event Qualification forces copying of parsetree --- XXX
- * and splitting into two queries one w/rule_qual, one
- * w/NOT rule_qual. Also add user query qual onto rule action
- */
- qual = parsetree->qual;
- AddQual(info->rule_action, qual);
-
- if (info->rule_qual != NULL)
- AddQual(info->rule_action, info->rule_qual);
-
- /*--------------------------------------------------
- * Step 2:
- * Rewrite new.attribute w/ right hand side of target-list
- * entry for appropriate field name in insert/update
- *--------------------------------------------------
- */
- if ((info->event == CMD_INSERT) || (info->event == CMD_UPDATE)) {
- FixNew(info, parsetree);
- }
-
- /*--------------------------------------------------
- * Step 3:
- * rewriting due to retrieve rules
- *--------------------------------------------------
- */
- info->rule_action->rtable = info->rt;
- ProcessRetrieveQuery(info->rule_action, info->rt,
- &orig_instead_flag, TRUE);
-
- /*--------------------------------------------------
- * Step 4
- * Simplify? hey, no algorithm for simplification... let
- * the planner do it.
- *--------------------------------------------------
- */
- results = lappend(results, info->rule_action);
-
- pfree(info);
+ return NIL;
}
- if (*instead_flag) break;
- }
- return results;
+
+ locks = orderRules(locks); /* instead rules first */
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+ Node *qual,
+ *event_qual;
+ List *actions;
+ List *r;
+ bool orig_instead_flag = *instead_flag;
+
+ /* multiple rule action time */
+ *instead_flag = rule_lock->isInstead;
+ event_qual = rule_lock->qual;
+ actions = rule_lock->actions;
+ if (event_qual != NULL && *instead_flag)
+ *qual_products =
+ lappend(*qual_products,
+ CopyAndAddQual(parsetree, actions, event_qual,
+ rt_index, event));
+ foreach(r, actions)
+ {
+ Query *rule_action = lfirst(r);
+ Node *rule_qual = copyObject(event_qual);
+
+ /*--------------------------------------------------
+ * Step 1:
+ * Rewrite current.attribute or current to tuple variable
+ * this appears to be done in parser?
+ *--------------------------------------------------
+ */
+ info = gatherRewriteMeta(parsetree, rule_action, rule_qual,
+ rt_index, event, instead_flag);
+
+ /* handle escapable cases, or those handled by other code */
+ if (info->nothing)
+ {
+ if (*instead_flag)
+ return NIL;
+ else
+ continue;
+ }
+
+ if (info->action == info->event &&
+ info->event == CMD_SELECT)
+ continue;
+
+ /*
+ * Event Qualification forces copying of parsetree --- XXX and
+ * splitting into two queries one w/rule_qual, one w/NOT
+ * rule_qual. Also add user query qual onto rule action
+ */
+ qual = parsetree->qual;
+ AddQual(info->rule_action, qual);
+
+ if (info->rule_qual != NULL)
+ AddQual(info->rule_action, info->rule_qual);
+
+ /*--------------------------------------------------
+ * Step 2:
+ * Rewrite new.attribute w/ right hand side of target-list
+ * entry for appropriate field name in insert/update
+ *--------------------------------------------------
+ */
+ if ((info->event == CMD_INSERT) || (info->event == CMD_UPDATE))
+ {
+ FixNew(info, parsetree);
+ }
+
+ /*--------------------------------------------------
+ * Step 3:
+ * rewriting due to retrieve rules
+ *--------------------------------------------------
+ */
+ info->rule_action->rtable = info->rt;
+ ProcessRetrieveQuery(info->rule_action, info->rt,
+ &orig_instead_flag, TRUE);
+
+ /*--------------------------------------------------
+ * Step 4
+ * Simplify? hey, no algorithm for simplification... let
+ * the planner do it.
+ *--------------------------------------------------
+ */
+ results = lappend(results, info->rule_action);
+
+ pfree(info);
+ }
+ if (*instead_flag)
+ break;
+ }
+ return results;
}
-static List *
-RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
+static List *
+RewriteQuery(Query * parsetree, bool * instead_flag, List ** qual_products)
{
- CmdType event;
- List *product_queries = NIL;
- int result_relation = 0;
-
- Assert(parsetree != NULL);
-
- event = parsetree->commandType;
-
- if (event == CMD_UTILITY)
- return NIL;
+ CmdType event;
+ List *product_queries = NIL;
+ int result_relation = 0;
- /*
- * only for a delete may the targetlist be NULL
- */
- if (event != CMD_DELETE) {
- Assert(parsetree->targetList != NULL);
- }
-
- result_relation = parsetree->resultRelation;
+ Assert(parsetree != NULL);
+
+ event = parsetree->commandType;
+
+ if (event == CMD_UTILITY)
+ return NIL;
- if (event != CMD_SELECT) {
/*
- * the statement is an update, insert or delete
+ * only for a delete may the targetlist be NULL
*/
- RangeTblEntry *rt_entry;
- Relation rt_entry_relation = NULL;
- RuleLock *rt_entry_locks = NULL;
-
- rt_entry = rt_fetch(result_relation, parsetree->rtable);
- rt_entry_relation = heap_openr(rt_entry->relname);
- rt_entry_locks = rt_entry_relation->rd_rules;
- heap_close(rt_entry_relation);
-
- if (rt_entry_locks != NULL) {
- List *locks =
- matchLocks(event, rt_entry_locks, result_relation, parsetree);
-
- product_queries =
- fireRules(parsetree,
- result_relation,
- event,
- instead_flag,
- locks,
- qual_products);
+ if (event != CMD_DELETE)
+ {
+ Assert(parsetree->targetList != NULL);
+ }
+
+ result_relation = parsetree->resultRelation;
+
+ if (event != CMD_SELECT)
+ {
+
+ /*
+ * the statement is an update, insert or delete
+ */
+ RangeTblEntry *rt_entry;
+ Relation rt_entry_relation = NULL;
+ RuleLock *rt_entry_locks = NULL;
+
+ rt_entry = rt_fetch(result_relation, parsetree->rtable);
+ rt_entry_relation = heap_openr(rt_entry->relname);
+ rt_entry_locks = rt_entry_relation->rd_rules;
+ heap_close(rt_entry_relation);
+
+ if (rt_entry_locks != NULL)
+ {
+ List *locks =
+ matchLocks(event, rt_entry_locks, result_relation, parsetree);
+
+ product_queries =
+ fireRules(parsetree,
+ result_relation,
+ event,
+ instead_flag,
+ locks,
+ qual_products);
+ }
+ return product_queries;
+ }
+ else
+ {
+
+ /*
+ * the statement is a select
+ */
+ Query *other;
+
+ other = copyObject(parsetree); /* ApplyRetrieveRule changes the
+ * range table */
+ return
+ ProcessRetrieveQuery(other, parsetree->rtable,
+ instead_flag, FALSE);
}
- return product_queries;
- }else {
- /*
- * the statement is a select
- */
- Query *other;
-
- other = copyObject(parsetree); /* ApplyRetrieveRule changes the
- range table */
- return
- ProcessRetrieveQuery(other, parsetree->rtable,
- instead_flag, FALSE);
- }
}
/*
@@ -559,61 +610,62 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
* can be rewritten. Detecting cycles is left for the reader as an excercise.
*/
#ifndef REWRITE_INVOKE_MAX
-#define REWRITE_INVOKE_MAX 10
+#define REWRITE_INVOKE_MAX 10
#endif
-static int numQueryRewriteInvoked = 0;
+static int numQueryRewriteInvoked = 0;
/*
* QueryRewrite -
- * rewrite one query via QueryRewrite system, possibly returning 0, or many
- * queries
- */
-List *
-QueryRewrite(Query *parsetree)
+ * rewrite one query via QueryRewrite system, possibly returning 0, or many
+ * queries
+ */
+List *
+QueryRewrite(Query * parsetree)
{
- numQueryRewriteInvoked = 0;
+ numQueryRewriteInvoked = 0;
- /*
- * take a deep breath and apply all the rewrite rules - ay
- */
- return deepRewriteQuery(parsetree);
+ /*
+ * take a deep breath and apply all the rewrite rules - ay
+ */
+ return deepRewriteQuery(parsetree);
}
/*
* deepRewriteQuery -
- * rewrites the query and apply the rules again on the queries rewritten
+ * rewrites the query and apply the rules again on the queries rewritten
*/
-static List *
-deepRewriteQuery(Query *parsetree)
+static List *
+deepRewriteQuery(Query * parsetree)
{
- List *n;
- List *rewritten = NIL;
- List *result = NIL;
- bool instead;
- List *qual_products = NIL;
-
- if (++numQueryRewriteInvoked > REWRITE_INVOKE_MAX) {
- elog(WARN, "query rewritten %d times, may contain cycles",
- numQueryRewriteInvoked-1);
- }
-
- instead = FALSE;
- result = RewriteQuery(parsetree, &instead, &qual_products);
- if (!instead)
- rewritten = lcons(parsetree, NIL);
-
- foreach(n, result) {
- Query *pt = lfirst(n);
- List *newstuff = NIL;
-
- newstuff = deepRewriteQuery(pt);
- if (newstuff != NIL)
- rewritten = nconc(rewritten, newstuff);
- }
- if (qual_products != NIL)
- rewritten = nconc(rewritten, qual_products);
-
- return rewritten;
-}
+ List *n;
+ List *rewritten = NIL;
+ List *result = NIL;
+ bool instead;
+ List *qual_products = NIL;
+
+ if (++numQueryRewriteInvoked > REWRITE_INVOKE_MAX)
+ {
+ elog(WARN, "query rewritten %d times, may contain cycles",
+ numQueryRewriteInvoked - 1);
+ }
+
+ instead = FALSE;
+ result = RewriteQuery(parsetree, &instead, &qual_products);
+ if (!instead)
+ rewritten = lcons(parsetree, NIL);
+ foreach(n, result)
+ {
+ Query *pt = lfirst(n);
+ List *newstuff = NIL;
+
+ newstuff = deepRewriteQuery(pt);
+ if (newstuff != NIL)
+ rewritten = nconc(rewritten, newstuff);
+ }
+ if (qual_products != NIL)
+ rewritten = nconc(rewritten, qual_products);
+
+ return rewritten;
+}
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 01fad29f77..b8b39b3328 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.4 1996/11/10 03:02:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.5 1997/09/07 04:48:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include "nodes/nodes.h"
#include "nodes/relation.h"
#include "nodes/primnodes.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
#include "utils/lsyscache.h"
#include "utils/builtins.h"
#include "rewrite/rewriteHandler.h"
@@ -28,410 +28,463 @@
#include "nodes/plannodes.h"
#include "optimizer/clauses.h"
-static void ResolveNew(RewriteInfo *info, List *targetlist, Node **node);
+static void ResolveNew(RewriteInfo * info, List * targetlist, Node ** node);
void
-OffsetVarNodes(Node *node, int offset)
+OffsetVarNodes(Node * node, int offset)
{
- if (node==NULL)
- return;
- switch (nodeTag(node)) {
- case T_TargetEntry:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- TargetEntry *tle = (TargetEntry *)node;
- OffsetVarNodes(tle->expr, offset);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- OffsetVarNodes((Node*)expr->args, offset);
- }
- break;
- case T_Var:
- {
- Var *var = (Var*)node;
- var->varno += offset;
- var->varnoold += offset;
- }
- break;
- case T_List:
- {
- List *l;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ OffsetVarNodes(tle->expr, offset);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
- foreach(l, (List*)node) {
- OffsetVarNodes(lfirst(l), offset);
- }
+ OffsetVarNodes((Node *) expr->args, offset);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+
+ var->varno += offset;
+ var->varnoold += offset;
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ OffsetVarNodes(lfirst(l), offset);
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
void
-ChangeVarNodes(Node *node, int old_varno, int new_varno)
+ChangeVarNodes(Node * node, int old_varno, int new_varno)
{
- if (node==NULL)
- return;
- switch (nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- ChangeVarNodes(tle->expr, old_varno, new_varno);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- ChangeVarNodes((Node*)expr->args, old_varno, new_varno);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- Var *var = (Var*)node;
- if (var->varno == old_varno) {
- var->varno = new_varno;
- var->varnoold = new_varno;
- }
- }
- break;
- case T_List:
- {
- List *l;
- foreach (l, (List*)node) {
- ChangeVarNodes(lfirst(l), old_varno, new_varno);
- }
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ ChangeVarNodes(tle->expr, old_varno, new_varno);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ ChangeVarNodes((Node *) expr->args, old_varno, new_varno);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+
+ if (var->varno == old_varno)
+ {
+ var->varno = new_varno;
+ var->varnoold = new_varno;
+ }
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ ChangeVarNodes(lfirst(l), old_varno, new_varno);
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
void
-AddQual(Query *parsetree, Node *qual)
+AddQual(Query * parsetree, Node * qual)
{
- Node *copy, *old;
-
- if (qual == NULL)
- return;
-
- copy = copyObject(qual);
- old = parsetree->qual;
- if (old == NULL)
- parsetree->qual = copy;
- else
- parsetree->qual =
- (Node*)make_andclause(makeList(parsetree->qual, copy, -1));
+ Node *copy,
+ *old;
+
+ if (qual == NULL)
+ return;
+
+ copy = copyObject(qual);
+ old = parsetree->qual;
+ if (old == NULL)
+ parsetree->qual = copy;
+ else
+ parsetree->qual =
+ (Node *) make_andclause(makeList(parsetree->qual, copy, -1));
}
void
-AddNotQual(Query *parsetree, Node *qual)
+AddNotQual(Query * parsetree, Node * qual)
{
- Node *copy;
-
- if (qual == NULL) return;
-
- copy = (Node*)make_notclause(copyObject(qual));
+ Node *copy;
- AddQual(parsetree,copy);
+ if (qual == NULL)
+ return;
+
+ copy = (Node *) make_notclause(copyObject(qual));
+
+ AddQual(parsetree, copy);
}
-static Node *
+static Node *
make_null(Oid type)
{
- Const *c = makeNode(Const);
-
- c->consttype = type;
- c->constlen = get_typlen(type);
- c->constvalue = PointerGetDatum(NULL);
- c->constisnull = true;
- c->constbyval = get_typbyval(type);
- return (Node*)c;
+ Const *c = makeNode(Const);
+
+ c->consttype = type;
+ c->constlen = get_typlen(type);
+ c->constvalue = PointerGetDatum(NULL);
+ c->constisnull = true;
+ c->constbyval = get_typbyval(type);
+ return (Node *) c;
}
void
-FixResdomTypes (List *tlist)
+FixResdomTypes(List * tlist)
{
- List *i;
+ List *i;
- foreach (i, tlist) {
- TargetEntry *tle = lfirst(i);
+ foreach(i, tlist)
+ {
+ TargetEntry *tle = lfirst(i);
- if (nodeTag(tle->expr) == T_Var) {
- Var *var = (Var*)tle->expr;
+ if (nodeTag(tle->expr) == T_Var)
+ {
+ Var *var = (Var *) tle->expr;
- tle->resdom->restype = var->vartype;
- tle->resdom->reslen = get_typlen(var->vartype);
+ tle->resdom->restype = var->vartype;
+ tle->resdom->reslen = get_typlen(var->vartype);
+ }
}
- }
}
-static Node *
-FindMatchingNew(List *tlist, int attno)
+static Node *
+FindMatchingNew(List * tlist, int attno)
{
- List *i;
-
- foreach (i, tlist ) {
- TargetEntry *tle = lfirst(i);
+ List *i;
- if (tle->resdom->resno == attno ) {
- return (tle->expr);
+ foreach(i, tlist)
+ {
+ TargetEntry *tle = lfirst(i);
+
+ if (tle->resdom->resno == attno)
+ {
+ return (tle->expr);
+ }
}
- }
- return NULL;
+ return NULL;
}
-static Node *
-FindMatchingTLEntry(List *tlist, char *e_attname)
+static Node *
+FindMatchingTLEntry(List * tlist, char *e_attname)
{
- List *i;
-
- foreach (i, tlist) {
- TargetEntry *tle = lfirst(i);
- char *resname;
-
- resname = tle->resdom->resname;
- if (!strcmp(e_attname, resname))
- return (tle->expr);
- }
- return NULL;
+ List *i;
+
+ foreach(i, tlist)
+ {
+ TargetEntry *tle = lfirst(i);
+ char *resname;
+
+ resname = tle->resdom->resname;
+ if (!strcmp(e_attname, resname))
+ return (tle->expr);
+ }
+ return NULL;
}
static void
-ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
+ResolveNew(RewriteInfo * info, List * targetlist, Node ** nodePtr)
{
- Node *node = *nodePtr;
-
- if (node == NULL)
- return;
-
- switch(nodeTag(node)) {
- case T_TargetEntry:
- ResolveNew(info, targetlist, &((TargetEntry*)node)->expr);
- break;
- case T_Expr:
- ResolveNew(info, targetlist, (Node**)(&(((Expr*)node)->args)));
- break;
- case T_Var: {
- int this_varno = (int)((Var*)node)->varno;
- Node *n;
-
- if (this_varno == info->new_varno) {
- n = FindMatchingNew(targetlist,
- ((Var*)node)->varattno);
- if (n == NULL) {
- if (info->event == CMD_UPDATE) {
- ((Var*)node)->varno = info->current_varno;
- ((Var*)node)->varnoold = info->current_varno;
- } else {
- *nodePtr = make_null(((Var*)node)->vartype);
+ Node *node = *nodePtr;
+
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
+ {
+ case T_TargetEntry:
+ ResolveNew(info, targetlist, &((TargetEntry *) node)->expr);
+ break;
+ case T_Expr:
+ ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)));
+ break;
+ case T_Var:
+ {
+ int this_varno = (int) ((Var *) node)->varno;
+ Node *n;
+
+ if (this_varno == info->new_varno)
+ {
+ n = FindMatchingNew(targetlist,
+ ((Var *) node)->varattno);
+ if (n == NULL)
+ {
+ if (info->event == CMD_UPDATE)
+ {
+ ((Var *) node)->varno = info->current_varno;
+ ((Var *) node)->varnoold = info->current_varno;
+ }
+ else
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+ }
+ else
+ {
+ *nodePtr = n;
+ }
+ }
+ break;
}
- } else {
- *nodePtr = n;
- }
- }
- break;
- }
- case T_List: {
- List *l;
- foreach(l, (List*)node) {
- ResolveNew(info, targetlist, (Node**)&(lfirst(l)));
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ ResolveNew(info, targetlist, (Node **) & (lfirst(l)));
+ }
+ break;
+ }
+ default:
+ /* ignore the others */
+ break;
}
- break;
- }
- default:
- /* ignore the others */
- break;
- }
}
void
-FixNew(RewriteInfo* info, Query *parsetree)
+FixNew(RewriteInfo * info, Query * parsetree)
{
- ResolveNew(info, parsetree->targetList,
- (Node**)&(info->rule_action->targetList));
- ResolveNew(info, parsetree->targetList, &info->rule_action->qual);
+ ResolveNew(info, parsetree->targetList,
+ (Node **) & (info->rule_action->targetList));
+ ResolveNew(info, parsetree->targetList, &info->rule_action->qual);
}
static void
-nodeHandleRIRAttributeRule(Node **nodePtr,
- List *rtable,
- List *targetlist,
- int rt_index,
- int attr_num,
- int *modified,
- int *badsql)
+nodeHandleRIRAttributeRule(Node ** nodePtr,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int attr_num,
+ int *modified,
+ int *badsql)
{
- Node *node = *nodePtr;
+ Node *node = *nodePtr;
- if (node == NULL)
- return;
- switch (nodeTag(node)) {
- case T_List:
- {
- List *i;
- foreach(i, (List*)node) {
- nodeHandleRIRAttributeRule((Node**)(&(lfirst(i))), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql);
- }
- }
- break;
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
- rt_index, attr_num, modified, badsql);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *)node;
- nodeHandleRIRAttributeRule((Node**)(&(expr->args)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- int this_varno = (int) ((Var*)node)->varno;
- NameData name_to_look_for;
- memset(name_to_look_for.data, 0, NAMEDATALEN);
-
- if (this_varno == rt_index &&
- ((Var*) node)->varattno == attr_num) {
- if (((Var*)node)->vartype == 32) { /* HACK */
- *nodePtr = make_null(((Var*)node)->vartype);
- *modified = TRUE;
- *badsql = TRUE;
- break;
- } else {
- namestrcpy(&name_to_look_for,
- (char *)get_attname(getrelid(this_varno,
- rtable),
- attr_num));
+ case T_List:
+ {
+ List *i;
+
+ foreach(i, (List *) node)
+ {
+ nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
+ targetlist, rt_index, attr_num,
+ modified, badsql);
+ }
}
- }
- if (name_to_look_for.data[0]) {
- Node *n;
-
- n = FindMatchingTLEntry(targetlist, (char *)&name_to_look_for);
- if (n == NULL) {
- *nodePtr = make_null(((Var*) node)->vartype);
- } else {
- *nodePtr = n;
+ break;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
+ rt_index, attr_num, modified, badsql);
}
- *modified = TRUE;
- }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ nodeHandleRIRAttributeRule((Node **) (&(expr->args)), rtable,
+ targetlist, rt_index, attr_num,
+ modified, badsql);
+ }
+ break;
+ case T_Var:
+ {
+ int this_varno = (int) ((Var *) node)->varno;
+ NameData name_to_look_for;
+
+ memset(name_to_look_for.data, 0, NAMEDATALEN);
+
+ if (this_varno == rt_index &&
+ ((Var *) node)->varattno == attr_num)
+ {
+ if (((Var *) node)->vartype == 32)
+ { /* HACK */
+ *nodePtr = make_null(((Var *) node)->vartype);
+ *modified = TRUE;
+ *badsql = TRUE;
+ break;
+ }
+ else
+ {
+ namestrcpy(&name_to_look_for,
+ (char *) get_attname(getrelid(this_varno,
+ rtable),
+ attr_num));
+ }
+ }
+ if (name_to_look_for.data[0])
+ {
+ Node *n;
+
+ n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
+ if (n == NULL)
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+ else
+ {
+ *nodePtr = n;
+ }
+ *modified = TRUE;
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
-/*
+/*
* Handles 'on retrieve to relation.attribute
- * do instead retrieve (attribute = expression) w/qual'
+ * do instead retrieve (attribute = expression) w/qual'
*/
void
-HandleRIRAttributeRule(Query *parsetree,
- List *rtable,
- List *targetlist,
- int rt_index,
- int attr_num,
- int *modified,
- int *badsql)
+HandleRIRAttributeRule(Query * parsetree,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int attr_num,
+ int *modified,
+ int *badsql)
{
- nodeHandleRIRAttributeRule((Node**)(&(parsetree->targetList)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql);
- nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
- rt_index, attr_num, modified, badsql);
+ nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
+ targetlist, rt_index, attr_num,
+ modified, badsql);
+ nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
+ rt_index, attr_num, modified, badsql);
}
static void
-nodeHandleViewRule(Node **nodePtr,
- List *rtable,
- List *targetlist,
- int rt_index,
- int *modified)
+nodeHandleViewRule(Node ** nodePtr,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int *modified)
{
- Node *node = *nodePtr;
-
- if (node == NULL)
- return;
+ Node *node = *nodePtr;
- switch (nodeTag(node)) {
- case T_List:
- {
- List *l;
- foreach (l, (List*)node) {
- nodeHandleViewRule((Node**) (&(lfirst(l))),
- rtable, targetlist,
- rt_index, modified);
- }
- }
- break;
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- nodeHandleViewRule(&(tle->expr), rtable, targetlist,
- rt_index, modified);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- nodeHandleViewRule((Node**)(&(expr->args)),
- rtable, targetlist,
- rt_index, modified);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
{
- Var *var = (Var*)node;
- int this_varno = var->varno;
- Node *n;
-
- if (this_varno == rt_index) {
- n = FindMatchingTLEntry(targetlist,
- get_attname(getrelid(this_varno,
- rtable),
- var->varattno));
- if (n == NULL) {
- *nodePtr = make_null(((Var*) node)->vartype);
- } else {
- *nodePtr = n;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ nodeHandleViewRule((Node **) (&(lfirst(l))),
+ rtable, targetlist,
+ rt_index, modified);
+ }
+ }
+ break;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ nodeHandleViewRule(&(tle->expr), rtable, targetlist,
+ rt_index, modified);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ nodeHandleViewRule((Node **) (&(expr->args)),
+ rtable, targetlist,
+ rt_index, modified);
}
- *modified = TRUE;
- }
- break;
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+ int this_varno = var->varno;
+ Node *n;
+
+ if (this_varno == rt_index)
+ {
+ n = FindMatchingTLEntry(targetlist,
+ get_attname(getrelid(this_varno,
+ rtable),
+ var->varattno));
+ if (n == NULL)
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+ else
+ {
+ *nodePtr = n;
+ }
+ *modified = TRUE;
+ }
+ break;
+ }
+ default:
+ /* ignore the others */
+ break;
}
- default:
- /* ignore the others */
- break;
- }
}
void
-HandleViewRule(Query *parsetree,
- List *rtable,
- List *targetlist,
- int rt_index,
- int *modified)
+HandleViewRule(Query * parsetree,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int *modified)
{
- nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
- modified);
- nodeHandleViewRule((Node**)(&(parsetree->targetList)), rtable, targetlist,
- rt_index, modified);
+ nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
+ modified);
+ nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
+ rt_index, modified);
}
-
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 3052a59a0d..58ccc5865b 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rewriteRemove.c--
- * routines for removing rewrite rules
+ * routines for removing rewrite rules
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.2 1996/11/03 04:51:51 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.3 1997/09/07 04:48:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,37 +18,37 @@
#include "catalog/pg_rewrite.h"
#include "catalog/catname.h" /* for RewriteRelationName */
#include "utils/syscache.h"
-#include "utils/elog.h" /* for elog stuff */
+#include "utils/elog.h" /* for elog stuff */
#include "utils/palloc.h"
-#include "utils/tqual.h" /* 'NowTimeQual' defined here.. */
-#include "access/heapam.h" /* heap AM calls defined here */
-#include "fmgr.h" /* for CHAR_16_EQ */
+#include "utils/tqual.h" /* 'NowTimeQual' defined here.. */
+#include "access/heapam.h" /* heap AM calls defined here */
+#include "fmgr.h" /* for CHAR_16_EQ */
-#include "rewrite/rewriteRemove.h" /* where the decls go */
+#include "rewrite/rewriteRemove.h" /* where the decls go */
#include "rewrite/rewriteSupport.h"
/*-----------------------------------------------------------------------
* RewriteGetRuleEventRel
*-----------------------------------------------------------------------
*/
-char*
+char *
RewriteGetRuleEventRel(char *rulename)
{
- HeapTuple htp;
- Oid eventrel;
-
- htp = SearchSysCacheTuple(REWRITENAME, PointerGetDatum(rulename),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "RewriteGetRuleEventRel: rule \"%s\" not found",
- rulename);
- eventrel = ((Form_pg_rewrite) GETSTRUCT(htp))->ev_class;
- htp = SearchSysCacheTuple(RELOID, PointerGetDatum(eventrel),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "RewriteGetRuleEventRel: class %d not found",
- eventrel);
- return ((Form_pg_class) GETSTRUCT(htp))->relname.data;
+ HeapTuple htp;
+ Oid eventrel;
+
+ htp = SearchSysCacheTuple(REWRITENAME, PointerGetDatum(rulename),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "RewriteGetRuleEventRel: rule \"%s\" not found",
+ rulename);
+ eventrel = ((Form_pg_rewrite) GETSTRUCT(htp))->ev_class;
+ htp = SearchSysCacheTuple(RELOID, PointerGetDatum(eventrel),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "RewriteGetRuleEventRel: class %d not found",
+ eventrel);
+ return ((Form_pg_class) GETSTRUCT(htp))->relname.data;
}
/* ----------------------------------------------------------------
@@ -58,10 +58,10 @@ RewriteGetRuleEventRel(char *rulename)
* Delete a rule given its rulename.
*
* There are three steps.
- * 1) Find the corresponding tuple in 'pg_rewrite' relation.
- * Find the rule Id (i.e. the Oid of the tuple) and finally delete
- * the tuple.
- * 3) Delete the locks from the 'pg_class' relation.
+ * 1) Find the corresponding tuple in 'pg_rewrite' relation.
+ * Find the rule Id (i.e. the Oid of the tuple) and finally delete
+ * the tuple.
+ * 3) Delete the locks from the 'pg_class' relation.
*
*
* ----------------------------------------------------------------
@@ -69,116 +69,119 @@ RewriteGetRuleEventRel(char *rulename)
void
RemoveRewriteRule(char *ruleName)
{
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKeyData;
- HeapTuple tuple = NULL;
- Oid ruleId = (Oid)0;
- Oid eventRelationOid = (Oid)NULL;
- Datum eventRelationOidDatum = (Datum)NULL;
- Buffer buffer = (Buffer)NULL;
- bool isNull = false;
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') until we find a tuple
- */
- ScanKeyEntryInitialize(&scanKeyData, 0, Anum_pg_rewrite_rulename,
- F_CHAR16EQ, NameGetDatum(ruleName));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, NowTimeQual, 1, &scanKeyData);
-
- tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
-
- /*
- * complain if no rule with such name existed
- */
- if (!HeapTupleIsValid(tuple)) {
+ Relation RewriteRelation = NULL;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple = NULL;
+ Oid ruleId = (Oid) 0;
+ Oid eventRelationOid = (Oid) NULL;
+ Datum eventRelationOidDatum = (Datum) NULL;
+ Buffer buffer = (Buffer) NULL;
+ bool isNull = false;
+
+ /*
+ * Open the pg_rewrite relation.
+ */
+ RewriteRelation = heap_openr(RewriteRelationName);
+
+ /*
+ * Scan the RuleRelation ('pg_rewrite') until we find a tuple
+ */
+ ScanKeyEntryInitialize(&scanKeyData, 0, Anum_pg_rewrite_rulename,
+ F_CHAR16EQ, NameGetDatum(ruleName));
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, NowTimeQual, 1, &scanKeyData);
+
+ tuple = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+ /*
+ * complain if no rule with such name existed
+ */
+ if (!HeapTupleIsValid(tuple))
+ {
+ heap_close(RewriteRelation);
+ elog(WARN, "No rule with name = '%s' was found.\n", ruleName);
+ }
+
+ /*
+ * Store the OID of the rule (i.e. the tuple's OID) and the event
+ * relation's OID
+ */
+ ruleId = tuple->t_oid;
+ eventRelationOidDatum =
+ PointerGetDatum(heap_getattr(tuple,
+ buffer,
+ Anum_pg_rewrite_ev_class,
+ RelationGetTupleDescriptor(RewriteRelation),
+ &isNull));
+ if (isNull)
+ {
+ /* XXX strange!!! */
+ elog(WARN, "RemoveRewriteRule: null event target relation!");
+ }
+ eventRelationOid = DatumGetObjectId(eventRelationOidDatum);
+
+ /*
+ * Now delete the relation level locks from the updated relation.
+ * (Make sure we do this before we remove the rule from pg_rewrite.
+ * Otherwise, heap_openr on eventRelationOid which reads pg_rwrite for
+ * the rules will fail.)
+ */
+ prs2_deleteFromRelation(eventRelationOid, ruleId);
+
+ /*
+ * Now delete the tuple...
+ */
+ heap_delete(RewriteRelation, &(tuple->t_ctid));
heap_close(RewriteRelation);
- elog(WARN, "No rule with name = '%s' was found.\n", ruleName);
- }
-
- /*
- * Store the OID of the rule (i.e. the tuple's OID)
- * and the event relation's OID
- */
- ruleId = tuple->t_oid;
- eventRelationOidDatum =
- PointerGetDatum(heap_getattr(tuple,
- buffer,
- Anum_pg_rewrite_ev_class,
- RelationGetTupleDescriptor(RewriteRelation),
- &isNull));
- if (isNull) {
- /* XXX strange!!! */
- elog(WARN, "RemoveRewriteRule: null event target relation!");
- }
- eventRelationOid = DatumGetObjectId(eventRelationOidDatum);
-
- /*
- * Now delete the relation level locks from the updated relation.
- * (Make sure we do this before we remove the rule from pg_rewrite.
- * Otherwise, heap_openr on eventRelationOid which reads pg_rwrite
- * for the rules will fail.)
- */
- prs2_deleteFromRelation(eventRelationOid, ruleId);
-
- /*
- * Now delete the tuple...
- */
- heap_delete(RewriteRelation, &(tuple->t_ctid));
- heap_close(RewriteRelation);
- heap_endscan(scanDesc);
+ heap_endscan(scanDesc);
}
/*
* RelationRemoveRules -
- * removes all rules associated with the relation when the relation is
- * being removed.
+ * removes all rules associated with the relation when the relation is
+ * being removed.
*/
void
RelationRemoveRules(Oid relid)
{
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKeyData;
- HeapTuple tuple = NULL;
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') for all the tuples that
- * has the same ev_class as relid (the relation to be removed).
- */
- ScanKeyEntryInitialize(&scanKeyData,
- 0,
- Anum_pg_rewrite_ev_class,
- F_OIDEQ,
- ObjectIdGetDatum(relid));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, NowTimeQual, 1, &scanKeyData);
-
- for(;;) {
- tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
-
- if (!HeapTupleIsValid(tuple)) {
- break; /* we're done */
- }
-
+ Relation RewriteRelation = NULL;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple = NULL;
+
/*
- * delete the tuple...
+ * Open the pg_rewrite relation.
*/
- heap_delete(RewriteRelation, &(tuple->t_ctid));
- }
+ RewriteRelation = heap_openr(RewriteRelationName);
- heap_endscan(scanDesc);
- heap_close(RewriteRelation);
-}
+ /*
+ * Scan the RuleRelation ('pg_rewrite') for all the tuples that has
+ * the same ev_class as relid (the relation to be removed).
+ */
+ ScanKeyEntryInitialize(&scanKeyData,
+ 0,
+ Anum_pg_rewrite_ev_class,
+ F_OIDEQ,
+ ObjectIdGetDatum(relid));
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, NowTimeQual, 1, &scanKeyData);
+
+ for (;;)
+ {
+ tuple = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ break; /* we're done */
+ }
+ /*
+ * delete the tuple...
+ */
+ heap_delete(RewriteRelation, &(tuple->t_ctid));
+ }
+
+ heap_endscan(scanDesc);
+ heap_close(RewriteRelation);
+}
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index 54a8f0c7f9..8d3beb1c10 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rewriteSupport.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.6 1997/08/12 22:53:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.7 1997/09/07 04:48:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
#include "nodes/parsenodes.h"
#include "utils/builtins.h" /* for textout */
#include "utils/rel.h" /* for Relation, RelationData ... */
-#include "utils/elog.h" /* for elog */
+#include "utils/elog.h" /* for elog */
#include "storage/buf.h" /* for InvalidBuffer */
#include "rewrite/rewriteSupport.h"
#include "access/heapam.h"
@@ -31,242 +31,250 @@
#include "utils/palloc.h"
#include "fmgr.h"
-/*
+/*
* RuleIdGetActionInfo -
- * given a rule oid, look it up and return the rule-event-qual and
- * list of parsetrees for the rule (in parseTrees)
+ * given a rule oid, look it up and return the rule-event-qual and
+ * list of parsetrees for the rule (in parseTrees)
*/
#ifdef NOT_USED
-static Node *
-RuleIdGetActionInfo(Oid ruleoid, bool *instead_flag, Query **parseTrees)
+static Node *
+RuleIdGetActionInfo(Oid ruleoid, bool * instead_flag, Query ** parseTrees)
{
- HeapTuple ruletuple;
- char *ruleaction = NULL;
- bool action_is_null = false;
- bool instead_is_null = false;
- Relation ruleRelation = NULL;
- TupleDesc ruleTupdesc = NULL;
- Query *ruleparse = NULL;
- char *rule_evqual_string = NULL;
- Node *rule_evqual = NULL;
-
- ruleRelation = heap_openr (RewriteRelationName);
- ruleTupdesc = RelationGetTupleDescriptor(ruleRelation);
- ruletuple = SearchSysCacheTuple (RULOID,
- ObjectIdGetDatum(ruleoid),
- 0,0,0);
- if (ruletuple == NULL)
- elog(WARN, "rule %u isn't in rewrite system relation", ruleoid);
-
- ruleaction = heap_getattr(ruletuple,
- InvalidBuffer,
- Anum_pg_rewrite_action,
- ruleTupdesc,
- &action_is_null ) ;
- rule_evqual_string = heap_getattr(ruletuple, InvalidBuffer,
- Anum_pg_rewrite_ev_qual,
- ruleTupdesc, &action_is_null) ;
- *instead_flag = !!heap_getattr(ruletuple, InvalidBuffer,
- Anum_pg_rewrite_is_instead,
- ruleTupdesc, &instead_is_null) ;
-
- if (action_is_null || instead_is_null) {
- elog(WARN, "internal error: rewrite rule not properly set up");
- }
-
- ruleaction = textout((struct varlena *)ruleaction);
- rule_evqual_string = textout((struct varlena *)rule_evqual_string);
-
- ruleparse = (Query*)stringToNode(ruleaction);
- rule_evqual = (Node*)stringToNode(rule_evqual_string);
-
- heap_close(ruleRelation);
-
- *parseTrees = ruleparse;
- return rule_evqual;
+ HeapTuple ruletuple;
+ char *ruleaction = NULL;
+ bool action_is_null = false;
+ bool instead_is_null = false;
+ Relation ruleRelation = NULL;
+ TupleDesc ruleTupdesc = NULL;
+ Query *ruleparse = NULL;
+ char *rule_evqual_string = NULL;
+ Node *rule_evqual = NULL;
+
+ ruleRelation = heap_openr(RewriteRelationName);
+ ruleTupdesc = RelationGetTupleDescriptor(ruleRelation);
+ ruletuple = SearchSysCacheTuple(RULOID,
+ ObjectIdGetDatum(ruleoid),
+ 0, 0, 0);
+ if (ruletuple == NULL)
+ elog(WARN, "rule %u isn't in rewrite system relation", ruleoid);
+
+ ruleaction = heap_getattr(ruletuple,
+ InvalidBuffer,
+ Anum_pg_rewrite_action,
+ ruleTupdesc,
+ &action_is_null);
+ rule_evqual_string = heap_getattr(ruletuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_qual,
+ ruleTupdesc, &action_is_null);
+ *instead_flag = !!heap_getattr(ruletuple, InvalidBuffer,
+ Anum_pg_rewrite_is_instead,
+ ruleTupdesc, &instead_is_null);
+
+ if (action_is_null || instead_is_null)
+ {
+ elog(WARN, "internal error: rewrite rule not properly set up");
+ }
+
+ ruleaction = textout((struct varlena *) ruleaction);
+ rule_evqual_string = textout((struct varlena *) rule_evqual_string);
+
+ ruleparse = (Query *) stringToNode(ruleaction);
+ rule_evqual = (Node *) stringToNode(rule_evqual_string);
+
+ heap_close(ruleRelation);
+
+ *parseTrees = ruleparse;
+ return rule_evqual;
}
+
#endif
int
IsDefinedRewriteRule(char *ruleName)
{
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKey;
- HeapTuple tuple = NULL;
-
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') until we find a tuple
- */
- ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_rewrite_rulename,
- NameEqualRegProcedure, PointerGetDatum(ruleName));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, NowTimeQual, 1, &scanKey);
-
- tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
-
- /*
- * return whether or not the rewrite rule existed
- */
- heap_close(RewriteRelation);
- heap_endscan(scanDesc);
- return (HeapTupleIsValid(tuple));
+ Relation RewriteRelation = NULL;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKey;
+ HeapTuple tuple = NULL;
+
+
+ /*
+ * Open the pg_rewrite relation.
+ */
+ RewriteRelation = heap_openr(RewriteRelationName);
+
+ /*
+ * Scan the RuleRelation ('pg_rewrite') until we find a tuple
+ */
+ ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_rewrite_rulename,
+ NameEqualRegProcedure, PointerGetDatum(ruleName));
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, NowTimeQual, 1, &scanKey);
+
+ tuple = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+ /*
+ * return whether or not the rewrite rule existed
+ */
+ heap_close(RewriteRelation);
+ heap_endscan(scanDesc);
+ return (HeapTupleIsValid(tuple));
}
static void
setRelhasrulesInRelation(Oid relationId, bool relhasrules)
{
- Relation relationRelation;
- HeapTuple tuple;
- HeapTuple newTuple;
- Relation idescs[Num_pg_class_indices];
- Form_pg_class relp;
-
- /*
- * Lock a relation given its Oid.
- * Go to the RelationRelation (i.e. pg_relation), find the
- * appropriate tuple, and add the specified lock to it.
- */
- relationRelation = heap_openr(RelationRelationName);
- tuple = ClassOidIndexScan(relationRelation, relationId);
-
- /*
- * Create a new tuple (i.e. a copy of the old tuple
- * with its rule lock field changed and replace the old
- * tuple in the RelationRelation
- * NOTE: XXX ??? do we really need to make that copy ????
- */
- newTuple = heap_copytuple(tuple);
-
- relp = (Form_pg_class) GETSTRUCT(newTuple);
- relp->relhasrules = relhasrules;
-
- heap_replace(relationRelation, &(tuple->t_ctid), newTuple);
-
- /* keep the catalog indices up to date */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation,
- newTuple);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
-
- /* be tidy */
- pfree(tuple);
- pfree(newTuple);
-
- heap_close(relationRelation);
+ Relation relationRelation;
+ HeapTuple tuple;
+ HeapTuple newTuple;
+ Relation idescs[Num_pg_class_indices];
+ Form_pg_class relp;
+
+ /*
+ * Lock a relation given its Oid. Go to the RelationRelation (i.e.
+ * pg_relation), find the appropriate tuple, and add the specified
+ * lock to it.
+ */
+ relationRelation = heap_openr(RelationRelationName);
+ tuple = ClassOidIndexScan(relationRelation, relationId);
+
+ /*
+ * Create a new tuple (i.e. a copy of the old tuple with its rule lock
+ * field changed and replace the old tuple in the RelationRelation
+ * NOTE: XXX ??? do we really need to make that copy ????
+ */
+ newTuple = heap_copytuple(tuple);
+
+ relp = (Form_pg_class) GETSTRUCT(newTuple);
+ relp->relhasrules = relhasrules;
+
+ heap_replace(relationRelation, &(tuple->t_ctid), newTuple);
+
+ /* keep the catalog indices up to date */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation,
+ newTuple);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
+ /* be tidy */
+ pfree(tuple);
+ pfree(newTuple);
+
+ heap_close(relationRelation);
}
void
prs2_addToRelation(Oid relid,
- Oid ruleId,
- CmdType event_type,
- AttrNumber attno,
- bool isInstead,
- Node *qual,
- List *actions)
+ Oid ruleId,
+ CmdType event_type,
+ AttrNumber attno,
+ bool isInstead,
+ Node * qual,
+ List * actions)
{
- Relation relation;
- RewriteRule *thisRule;
- RuleLock *rulelock;
- MemoryContext oldcxt;
-
- /*
- * create an in memory RewriteRule data structure which is cached by
- * every Relation descriptor. (see utils/cache/relcache.c)
- */
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- thisRule = (RewriteRule *)palloc(sizeof(RewriteRule));
- MemoryContextSwitchTo(oldcxt);
-
- thisRule->ruleId = ruleId;
- thisRule->event = event_type;
- thisRule->attrno = attno;
- thisRule->qual = qual;
- thisRule->actions = actions;
- thisRule->isInstead = isInstead;
-
- relation = heap_open(relid);
-
- /*
- * modify or create a RuleLock cached by Relation
- */
- if (relation->rd_rules == NULL) {
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- rulelock = (RuleLock *)palloc(sizeof(RuleLock));
- rulelock->numLocks = 1;
- rulelock->rules = (RewriteRule **)palloc(sizeof(RewriteRule*));
- rulelock->rules[0] = thisRule;
- relation->rd_rules = rulelock;
- MemoryContextSwitchTo(oldcxt);
+ Relation relation;
+ RewriteRule *thisRule;
+ RuleLock *rulelock;
+ MemoryContext oldcxt;
/*
- * the fact that relation->rd_rules is NULL means the relhasrules
- * attribute of the tuple of this relation in pg_class is false. We
- * need to set it to true.
+ * create an in memory RewriteRule data structure which is cached by
+ * every Relation descriptor. (see utils/cache/relcache.c)
*/
- setRelhasrulesInRelation(relid, TRUE);
- } else {
- int numlock;
-
- rulelock = relation->rd_rules;
- numlock = rulelock->numLocks;
- /* expand, for safety reasons */
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- rulelock->rules =
- (RewriteRule **)repalloc(rulelock->rules,
- sizeof(RewriteRule*)*(numlock+1));
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ thisRule = (RewriteRule *) palloc(sizeof(RewriteRule));
MemoryContextSwitchTo(oldcxt);
- rulelock->rules[numlock] = thisRule;
- rulelock->numLocks++;
- }
- heap_close(relation);
+ thisRule->ruleId = ruleId;
+ thisRule->event = event_type;
+ thisRule->attrno = attno;
+ thisRule->qual = qual;
+ thisRule->actions = actions;
+ thisRule->isInstead = isInstead;
+
+ relation = heap_open(relid);
+
+ /*
+ * modify or create a RuleLock cached by Relation
+ */
+ if (relation->rd_rules == NULL)
+ {
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ rulelock = (RuleLock *) palloc(sizeof(RuleLock));
+ rulelock->numLocks = 1;
+ rulelock->rules = (RewriteRule **) palloc(sizeof(RewriteRule *));
+ rulelock->rules[0] = thisRule;
+ relation->rd_rules = rulelock;
+ MemoryContextSwitchTo(oldcxt);
- return;
+ /*
+ * the fact that relation->rd_rules is NULL means the relhasrules
+ * attribute of the tuple of this relation in pg_class is false.
+ * We need to set it to true.
+ */
+ setRelhasrulesInRelation(relid, TRUE);
+ }
+ else
+ {
+ int numlock;
+
+ rulelock = relation->rd_rules;
+ numlock = rulelock->numLocks;
+ /* expand, for safety reasons */
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ rulelock->rules =
+ (RewriteRule **) repalloc(rulelock->rules,
+ sizeof(RewriteRule *) * (numlock + 1));
+ MemoryContextSwitchTo(oldcxt);
+ rulelock->rules[numlock] = thisRule;
+ rulelock->numLocks++;
+ }
+
+ heap_close(relation);
+
+ return;
}
void
prs2_deleteFromRelation(Oid relid, Oid ruleId)
{
- RuleLock *rulelock;
- Relation relation;
- int numlock;
- int i;
- MemoryContext oldcxt;
-
- relation = heap_open(relid);
- rulelock = relation->rd_rules;
- Assert(rulelock != NULL);
-
- numlock = rulelock->numLocks;
- for(i=0; i < numlock; i++) {
- if (rulelock->rules[i]->ruleId == ruleId)
- break;
- }
- Assert(i<numlock);
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- pfree(rulelock->rules[i]);
- MemoryContextSwitchTo(oldcxt);
- if (numlock==1) {
- relation->rd_rules = NULL;
- /*
- * we don't have rules any more, flag the relhasrules attribute of
- * the tuple of this relation in pg_class false.
- */
- setRelhasrulesInRelation(relid, FALSE);
- } else {
- rulelock->rules[i] = rulelock->rules[numlock-1];
- rulelock->rules[numlock-1] = NULL;
- rulelock->numLocks--;
- }
-
- heap_close(relation);
-}
+ RuleLock *rulelock;
+ Relation relation;
+ int numlock;
+ int i;
+ MemoryContext oldcxt;
+ relation = heap_open(relid);
+ rulelock = relation->rd_rules;
+ Assert(rulelock != NULL);
+
+ numlock = rulelock->numLocks;
+ for (i = 0; i < numlock; i++)
+ {
+ if (rulelock->rules[i]->ruleId == ruleId)
+ break;
+ }
+ Assert(i < numlock);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ pfree(rulelock->rules[i]);
+ MemoryContextSwitchTo(oldcxt);
+ if (numlock == 1)
+ {
+ relation->rd_rules = NULL;
+
+ /*
+ * we don't have rules any more, flag the relhasrules attribute of
+ * the tuple of this relation in pg_class false.
+ */
+ setRelhasrulesInRelation(relid, FALSE);
+ }
+ else
+ {
+ rulelock->rules[i] = rulelock->rules[numlock - 1];
+ rulelock->rules[numlock - 1] = NULL;
+ rulelock->numLocks--;
+ }
+
+ heap_close(relation);
+}