OSDN Git Service

The patch does 2 things:
authorBruce Momjian <bruce@momjian.us>
Wed, 21 Oct 1998 16:21:29 +0000 (16:21 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 21 Oct 1998 16:21:29 +0000 (16:21 +0000)
        Fixes  a  bug  in  the rule system that caused a crashing
        backend when a join-view with calculated column  is  used
        in subselect.

        Modifies  EXPLAIN to explain rewritten queries instead of
        the plain SeqScan on a view. Rules can produce very  deep
MORE

Jan.

src/backend/commands/explain.c
src/backend/commands/recipe.c
src/backend/commands/view.c
src/backend/rewrite/rewriteHandler.c
src/backend/rewrite/rewriteManip.c
src/include/rewrite/rewriteManip.h

index 6353405..1b861c9 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.24 1998/09/01 04:27:53 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.25 1998/10/21 16:21:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,6 +26,7 @@
 #include <optimizer/planner.h>
 #include <access/xact.h>
 #include <utils/relcache.h>
+#include <rewrite/rewriteHandler.h>
 
 typedef struct ExplainState
 {
@@ -37,6 +38,8 @@ typedef struct ExplainState
 } ExplainState;
 
 static char *Explain_PlanToString(Plan *plan, ExplainState *es);
+static void ExplainOneQuery(Query *query, bool verbose, CommandDest dest);
+
 
 /*
  * ExplainQuery -
@@ -46,11 +49,8 @@ static char *Explain_PlanToString(Plan *plan, ExplainState *es);
 void
 ExplainQuery(Query *query, bool verbose, CommandDest dest)
 {
-       char       *s = NULL,
-                          *s2;
-       Plan       *plan;
-       ExplainState *es;
-       int                     len;
+       List    *rewritten;
+       List    *l;
 
        if (IsAbortedTransactionBlockState())
        {
@@ -64,6 +64,35 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
                return;
        }
 
+       /* Rewrite through rule system */
+       rewritten = QueryRewrite(query);
+
+       /* In the case of an INSTEAD NOTHING, tell at least that */
+       if (rewritten == NIL)
+       {
+               elog(NOTICE, "query rewrites to nothing");
+               return;
+       }
+
+       /* Explain every plan */
+       foreach(l, rewritten)
+               ExplainOneQuery(lfirst(l), verbose, dest);
+}
+
+/*
+ * ExplainOneQuery -
+ *       print out the execution plan for one query
+ *
+ */
+static void
+ExplainOneQuery(Query *query, bool verbose, CommandDest dest)
+{
+       char       *s = NULL,
+                          *s2;
+       Plan       *plan;
+       ExplainState *es;
+       int                     len;
+
        /* plan the queries (XXX we've ignored rewrite!!) */
        plan = planner(query);
 
@@ -202,8 +231,13 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
                        {
                                RangeTblEntry *rte = nth(((Scan *) plan)->scanrelid - 1, es->rtable);
 
-                               sprintf(buf, " on %s", rte->refname);
-                               appendStringInfo(str, buf);
+                               appendStringInfo(str, " on ");
+                               if (strcmp(rte->refname, rte->relname) != 0)
+                               {
+                                       sprintf(buf, "%s ", rte->relname);
+                                       appendStringInfo(str, buf);
+                               }
+                               appendStringInfo(str, rte->refname);
                        }
                        break;
                default:
@@ -232,7 +266,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
                        for (i = 0; i < indent; i++)
                                appendStringInfo(str, "  ");
                        appendStringInfo(str, "    ->  ");
-                       explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, indent + 4, es);
+                       explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, indent + 2, es);
                }
                es->rtable = saved_rtable;
        }
index f8b7ce1..2d5662a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.24 1998/09/01 04:27:56 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.25 1998/10/21 16:21:21 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -350,8 +350,8 @@ tg_rewriteQuery(TgRecipe * r,
                         * need to offset the var nodes in the qual and targetlist
                         * because they are indexed off the original rtable
                         */
-                       OffsetVarNodes((Node *) inputQ->qual, rt_length);
-                       OffsetVarNodes((Node *) inputQ->targetList, rt_length);
+                       OffsetVarNodes((Node *) inputQ->qual, rt_length, 0);
+                       OffsetVarNodes((Node *) inputQ->targetList, rt_length, 0);
 
                        /* append the range tables from the children nodes      */
                        rtable = nconc(rtable, input_rtable);
index cf81e8b..fc5755e 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.25 1998/09/01 04:28:10 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.26 1998/10/21 16:21:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -219,10 +219,10 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
        /*
         * first offset all var nodes by 2
         */
-       OffsetVarNodes((Node *) viewParse->targetList, 2);
-       OffsetVarNodes(viewParse->qual, 2);
+       OffsetVarNodes((Node *) viewParse->targetList, 2, 0);
+       OffsetVarNodes(viewParse->qual, 2, 0);
 
-       OffsetVarNodes(viewParse->havingQual, 2);
+       OffsetVarNodes(viewParse->havingQual, 2, 0);
 
 
        /*
index a0f3069..8eaa8db 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.24 1998/10/20 17:21:43 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.25 1998/10/21 16:21:24 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,8 +48,6 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree,
                                  bool *instead_flag);
 static bool rangeTableEntry_used(Node *node, int rt_index, int sublevels_up);
 static bool attribute_used(Node *node, int rt_index, int attno, int sublevels_up);
-static void offset_varnodes(Node *node, int offset, int sublevels_up);
-static void change_varnodes(Node *node, int rt_index, int new_index, int sublevels_up);
 static void modifyAggregUplevel(Node *node);
 static void modifyAggregChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int sublevels_up);
 static void modifyAggregDropQual(Node **nodePtr, Node *orignode, Expr *expr);
@@ -107,9 +105,9 @@ gatherRewriteMeta(Query *parsetree,
                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);
+               OffsetVarNodes(info->rule_action->qual, rt_length, 0);
+               OffsetVarNodes((Node *) info->rule_action->targetList, rt_length, 0);
+               OffsetVarNodes(info->rule_qual, rt_length, 0);
                ChangeVarNodes((Node *) info->rule_action->qual,
                                           PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
                ChangeVarNodes((Node *) info->rule_action->targetList,
@@ -551,364 +549,6 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
 
 
 /*
- * offset_varnodes -
- *     We need another version of OffsetVarNodes() when processing
- *     RIR rules
- */
-static void
-offset_varnodes(Node *node, int offset, int sublevels_up)
-{
-       if (node == NULL)
-               return;
-
-       switch(nodeTag(node)) {
-               case T_TargetEntry:
-                       {
-                               TargetEntry     *tle = (TargetEntry *)node;
-
-                               offset_varnodes(
-                                               (Node *)(tle->expr),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Aggreg:
-                       {
-                               Aggreg  *agg = (Aggreg *)node;
-
-                               offset_varnodes(
-                                               (Node *)(agg->target),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_GroupClause:
-                       {
-                               GroupClause     *grp = (GroupClause *)node;
-
-                               offset_varnodes(
-                                               (Node *)(grp->entry),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Expr:
-                       {
-                               Expr    *exp = (Expr *)node;
-
-                               offset_varnodes(
-                                               (Node *)(exp->args),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Iter:
-                       {
-                               Iter    *iter = (Iter *)node;
-
-                               offset_varnodes(
-                                               (Node *)(iter->iterexpr),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_ArrayRef:
-                       {
-                               ArrayRef        *ref = (ArrayRef *)node;
-
-                               offset_varnodes(
-                                               (Node *)(ref->refupperindexpr),
-                                               offset,
-                                               sublevels_up);
-                               offset_varnodes(
-                                               (Node *)(ref->reflowerindexpr),
-                                               offset,
-                                               sublevels_up);
-                               offset_varnodes(
-                                               (Node *)(ref->refexpr),
-                                               offset,
-                                               sublevels_up);
-                               offset_varnodes(
-                                               (Node *)(ref->refassgnexpr),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Var:
-                       {
-                               Var     *var = (Var *)node;
-
-                               if (var->varlevelsup == sublevels_up) {
-                                       var->varno += offset;
-                                       var->varnoold += offset;
-                               }
-                       }
-                       break;
-
-               case T_Param:
-                       break;
-
-               case T_Const:
-                       break;
-
-               case T_List:
-                       {
-                               List    *l;
-
-                               foreach (l, (List *)node)
-                                       offset_varnodes(
-                                                       (Node *)lfirst(l),
-                                                       offset,
-                                                       sublevels_up);
-                       }
-                       break;
-
-               case T_SubLink:
-                       {
-                               SubLink *sub = (SubLink *)node;
-
-                               offset_varnodes(
-                                               (Node *)(sub->lefthand),
-                                               offset,
-                                               sublevels_up);
-
-                               offset_varnodes(
-                                               (Node *)(sub->subselect),
-                                               offset,
-                                               sublevels_up + 1);
-                       }
-                       break;
-
-               case T_Query:
-                       {
-                               Query   *qry = (Query *)node;
-
-                               offset_varnodes(
-                                               (Node *)(qry->targetList),
-                                               offset,
-                                               sublevels_up);
-
-                               offset_varnodes(
-                                               (Node *)(qry->qual),
-                                               offset,
-                                               sublevels_up);
-
-                               offset_varnodes(
-                                               (Node *)(qry->havingQual),
-                                               offset,
-                                               sublevels_up);
-
-                               offset_varnodes(
-                                               (Node *)(qry->groupClause),
-                                               offset,
-                                               sublevels_up);
-                       }
-                       break;
-
-               default:
-                       elog(NOTICE, "unknown node tag %d in offset_varnodes()", nodeTag(node));
-                       elog(NOTICE, "Node is: %s", nodeToString(node));
-                       break;
-
-
-       }
-}
-
-
-/*
- * change_varnodes -
- *     and another ChangeVarNodes() too
- */
-static void
-change_varnodes(Node *node, int rt_index, int new_index, int sublevels_up)
-{
-       if (node == NULL)
-               return;
-
-       switch(nodeTag(node)) {
-               case T_TargetEntry:
-                       {
-                               TargetEntry     *tle = (TargetEntry *)node;
-
-                               change_varnodes(
-                                               (Node *)(tle->expr),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Aggreg:
-                       {
-                               Aggreg  *agg = (Aggreg *)node;
-
-                               change_varnodes(
-                                               (Node *)(agg->target),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_GroupClause:
-                       {
-                               GroupClause     *grp = (GroupClause *)node;
-
-                               change_varnodes(
-                                               (Node *)(grp->entry),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Expr:
-                       {
-                               Expr    *exp = (Expr *)node;
-
-                               change_varnodes(
-                                               (Node *)(exp->args),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Iter:
-                       {
-                               Iter    *iter = (Iter *)node;
-
-                               change_varnodes(
-                                               (Node *)(iter->iterexpr),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_ArrayRef:
-                       {
-                               ArrayRef        *ref = (ArrayRef *)node;
-
-                               change_varnodes(
-                                               (Node *)(ref->refupperindexpr),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                               change_varnodes(
-                                               (Node *)(ref->reflowerindexpr),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                               change_varnodes(
-                                               (Node *)(ref->refexpr),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                               change_varnodes(
-                                               (Node *)(ref->refassgnexpr),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               case T_Var:
-                       {
-                               Var     *var = (Var *)node;
-
-                               if (var->varlevelsup == sublevels_up &&
-                                               var->varno == rt_index) {
-                                       var->varno = new_index;
-                                       var->varnoold = new_index;
-                               }
-                       }
-                       break;
-
-               case T_Param:
-                       break;
-
-               case T_Const:
-                       break;
-
-               case T_List:
-                       {
-                               List    *l;
-
-                               foreach (l, (List *)node)
-                                       change_varnodes(
-                                                       (Node *)lfirst(l),
-                                                       rt_index,
-                                                       new_index,
-                                                       sublevels_up);
-                       }
-                       break;
-
-               case T_SubLink:
-                       {
-                               SubLink *sub = (SubLink *)node;
-
-                               change_varnodes(
-                                               (Node *)(sub->lefthand),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-
-                               change_varnodes(
-                                               (Node *)(sub->subselect),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up + 1);
-                       }
-                       break;
-
-               case T_Query:
-                       {
-                               Query   *qry = (Query *)node;
-
-                               change_varnodes(
-                                               (Node *)(qry->targetList),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-
-                               change_varnodes(
-                                               (Node *)(qry->qual),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-
-                               change_varnodes(
-                                               (Node *)(qry->havingQual),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-
-                               change_varnodes(
-                                               (Node *)(qry->groupClause),
-                                               rt_index,
-                                               new_index,
-                                               sublevels_up);
-                       }
-                       break;
-
-               default:
-                       elog(NOTICE, "unknown node tag %d in change_varnodes()", nodeTag(node));
-                       elog(NOTICE, "Node is: %s", nodeToString(node));
-                       break;
-
-
-       }
-}
-
-
-/*
  * modifyAggregUplevel -
  *     In the newly created sublink for an aggregate column used in
  *     the qualification, we must adjust the varlevelsup in all the
@@ -1655,6 +1295,121 @@ make_null(Oid type)
 }
 
 
+static void 
+apply_RIR_adjust_sublevel(Node *node, int sublevels_up)
+{
+       if (node == NULL)
+               return;
+
+       switch(nodeTag(node)) {
+               case T_TargetEntry:
+                       {
+                               TargetEntry     *tle = (TargetEntry *)node;
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(tle->expr),
+                                               sublevels_up);
+                       }
+                       break;
+
+               case T_Aggreg:
+                       {
+                               Aggreg  *agg = (Aggreg *)node;
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(agg->target),
+                                               sublevels_up);
+                       }
+                       break;
+
+               case T_GroupClause:
+                       {
+                               GroupClause     *grp = (GroupClause *)node;
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(grp->entry),
+                                               sublevels_up);
+                       }
+                       break;
+
+               case T_Expr:
+                       {
+                               Expr    *exp = (Expr *)node;
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(exp->args),
+                                               sublevels_up);
+                       }
+                       break;
+
+               case T_Iter:
+                       {
+                               Iter    *iter = (Iter *)node;
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(iter->iterexpr),
+                                               sublevels_up);
+                       }
+                       break;
+
+               case T_ArrayRef:
+                       {
+                               ArrayRef        *ref = (ArrayRef *)node;
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(ref->refupperindexpr),
+                                               sublevels_up);
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(ref->reflowerindexpr),
+                                               sublevels_up);
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(ref->refexpr),
+                                               sublevels_up);
+
+                               apply_RIR_adjust_sublevel(
+                                               (Node *)(ref->refassgnexpr),
+                                               sublevels_up);
+                       }
+                       break;
+
+               case T_Var:
+                       {
+                               Var     *var = (Var *)node;
+
+                               var->varlevelsup = sublevels_up;
+                       }
+                       break;
+
+               case T_Param:
+                       break;
+
+               case T_Const:
+                       break;
+
+               case T_List:
+                       {
+                               List    *l;
+
+                               foreach (l, (List *)node) {
+                                       apply_RIR_adjust_sublevel(
+                                                       (Node *)lfirst(l),
+                                                       sublevels_up);
+                               }
+                       }
+                       break;
+
+               default:
+                       elog(NOTICE, "unknown node tag %d in attribute_used()", nodeTag(node));
+                       elog(NOTICE, "Node is: %s", nodeToString(node));
+                       break;
+
+
+       }
+}
+
+
 static void
 apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, int *modified, int sublevels_up)
 {
@@ -1790,10 +1545,8 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
                                        }
 
                                        exp = copyObject(exp);
-                                       if (var->varlevelsup > 0 &&
-                                                       nodeTag(exp) == T_Var) {
-                                               ((Var *)exp)->varlevelsup = var->varlevelsup;
-                                       } 
+                                       if (var->varlevelsup > 0)
+                                               apply_RIR_adjust_sublevel(exp, var->varlevelsup);
                                        *nodePtr = exp;
                                        *modified = TRUE;
                                }
@@ -1885,8 +1638,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
                        elog(NOTICE, "unknown node tag %d in apply_RIR_view()", nodeTag(node));
                        elog(NOTICE, "Node is: %s", nodeToString(node));
                        break;
-
-
        }
 }
 
@@ -1938,12 +1689,12 @@ ApplyRetrieveRule(Query *parsetree,
        parsetree->rtable = rtable;
 
        rule_action->rtable = rtable;
-       offset_varnodes((Node *) rule_qual,   rt_length, 0);
-       offset_varnodes((Node *) rule_action, rt_length, 0);
+       OffsetVarNodes((Node *) rule_qual,   rt_length, 0);
+       OffsetVarNodes((Node *) rule_action, rt_length, 0);
 
-       change_varnodes((Node *) rule_qual, 
+       ChangeVarNodes((Node *) rule_qual, 
                                   PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
-       change_varnodes((Node *) rule_action,
+       ChangeVarNodes((Node *) rule_action,
                                   PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
 
        if (relation_level)
@@ -2246,7 +1997,7 @@ CopyAndAddQual(Query *parsetree,
                rt_length = length(rtable);
                rtable = append(rtable, listCopy(rule_action->rtable));
                new_tree->rtable = rtable;
-               OffsetVarNodes(new_qual, rt_length);
+               OffsetVarNodes(new_qual, rt_length, 0);
                ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
        }
        /* XXX -- where current doesn't work for instead nothing.... yet */
@@ -2386,6 +2137,28 @@ fireRules(Query *parsetree,
                                continue;
 
                        /*--------------------------------------------------
+                        * We copy the qualifications of the parsetree
+                        * to the action and vice versa. So force
+                        * hasSubLinks if one of them has it.
+                        *
+                        * As of 6.4 only parsetree qualifications can
+                        * have sublinks. If this changes, we must make
+                        * this a node lookup at the end of rewriting.
+                        *
+                        * Jan
+                        *--------------------------------------------------
+                        */
+                       if (parsetree->hasSubLinks && !rule_action->hasSubLinks)
+                       {
+                               rule_action = copyObject(rule_action);
+                               rule_action->hasSubLinks = TRUE;
+                       }
+                       if (!parsetree->hasSubLinks && rule_action->hasSubLinks)
+                       {
+                               parsetree->hasSubLinks = TRUE;
+                       }
+
+                       /*--------------------------------------------------
                         * Step 1:
                         *        Rewrite current.attribute or current to tuple variable
                         *        this appears to be done in parser?
index d589943..64da847 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.21 1998/10/20 17:21:44 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.22 1998/10/21 16:21:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,222 +32,362 @@ static void ResolveNew(RewriteInfo *info, List *targetlist,
                   Node **node, int sublevels_up);
 
 
-
+/*
+ * OffsetVarnodes -
+ */
 void
-OffsetVarNodes(Node *node, int offset)
+OffsetVarNodes(Node *node, int offset, int sublevels_up)
 {
        if (node == NULL)
                return;
-       switch (nodeTag(node))
-       {
+
+       switch(nodeTag(node)) {
                case T_TargetEntry:
                        {
-                               TargetEntry *tle = (TargetEntry *) node;
+                               TargetEntry     *tle = (TargetEntry *)node;
 
-                               OffsetVarNodes(tle->expr, offset);
+                               OffsetVarNodes(
+                                               (Node *)(tle->expr),
+                                               offset,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Aggreg:
                        {
-                               Aggreg     *agg = (Aggreg *) node;
+                               Aggreg  *agg = (Aggreg *)node;
 
-                               OffsetVarNodes(agg->target, offset);
+                               OffsetVarNodes(
+                                               (Node *)(agg->target),
+                                               offset,
+                                               sublevels_up);
                        }
                        break;
 
-                       /*
-                        * This has to be done to make queries using groupclauses work
-                        * on views
-                        */
                case T_GroupClause:
                        {
-                               GroupClause *group = (GroupClause *) node;
+                               GroupClause     *grp = (GroupClause *)node;
 
-                               OffsetVarNodes((Node *) (group->entry), offset);
+                               OffsetVarNodes(
+                                               (Node *)(grp->entry),
+                                               offset,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Expr:
                        {
-                               Expr       *expr = (Expr *) node;
+                               Expr    *exp = (Expr *)node;
 
-                               OffsetVarNodes((Node *) expr->args, offset);
+                               OffsetVarNodes(
+                                               (Node *)(exp->args),
+                                               offset,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Iter:
                        {
-                               Iter       *iter = (Iter *) node;
+                               Iter    *iter = (Iter *)node;
 
-                               OffsetVarNodes((Node *) iter->iterexpr, offset);
+                               OffsetVarNodes(
+                                               (Node *)(iter->iterexpr),
+                                               offset,
+                                               sublevels_up);
                        }
                        break;
+
                case T_ArrayRef:
                        {
-                               ArrayRef           *ref = (ArrayRef *) node;
+                               ArrayRef        *ref = (ArrayRef *)node;
 
-                               OffsetVarNodes((Node *) ref->refupperindexpr, offset);
-                               OffsetVarNodes((Node *) ref->reflowerindexpr, offset);
-                               OffsetVarNodes((Node *) ref->refexpr, offset);
-                               OffsetVarNodes((Node *) ref->refassgnexpr, offset);
+                               OffsetVarNodes(
+                                               (Node *)(ref->refupperindexpr),
+                                               offset,
+                                               sublevels_up);
+                               OffsetVarNodes(
+                                               (Node *)(ref->reflowerindexpr),
+                                               offset,
+                                               sublevels_up);
+                               OffsetVarNodes(
+                                               (Node *)(ref->refexpr),
+                                               offset,
+                                               sublevels_up);
+                               OffsetVarNodes(
+                                               (Node *)(ref->refassgnexpr),
+                                               offset,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Var:
                        {
-                               Var                *var = (Var *) node;
+                               Var     *var = (Var *)node;
 
-                               var->varno += offset;
-                               var->varnoold += offset;
+                               if (var->varlevelsup == sublevels_up) {
+                                       var->varno += offset;
+                                       var->varnoold += offset;
+                               }
                        }
                        break;
+
+               case T_Param:
+                       break;
+
+               case T_Const:
+                       break;
+
                case T_List:
                        {
-                               List       *l;
+                               List    *l;
 
-                               foreach(l, (List *) node)
-                                       OffsetVarNodes(lfirst(l), offset);
+                               foreach (l, (List *)node)
+                                       OffsetVarNodes(
+                                                       (Node *)lfirst(l),
+                                                       offset,
+                                                       sublevels_up);
                        }
                        break;
+
                case T_SubLink:
                        {
-                               SubLink    *sublink = (SubLink *) node;
+                               SubLink *sub = (SubLink *)node;
 
-                               /*
-                                * We also have to adapt the variables used in
-                                * sublink->lefthand and sublink->oper
-                                */
-                               OffsetVarNodes((Node *) (sublink->lefthand), offset);
+                               OffsetVarNodes(
+                                               (Node *)(sub->lefthand),
+                                               offset,
+                                               sublevels_up);
 
-                               /*
-                                * Make sure the first argument of sublink->oper points to
-                                * the same var as sublink->lefthand does otherwise we
-                                * will run into troubles using aggregates (aggno will not
-                                * be set correctly)
-                                */
-                               lfirst(((Expr *) lfirst(sublink->oper))->args) =
-                                       lfirst(sublink->lefthand);
+                               OffsetVarNodes(
+                                               (Node *)(sub->subselect),
+                                               offset,
+                                               sublevels_up + 1);
                        }
                        break;
+
+               case T_Query:
+                       {
+                               Query   *qry = (Query *)node;
+
+                               OffsetVarNodes(
+                                               (Node *)(qry->targetList),
+                                               offset,
+                                               sublevels_up);
+
+                               OffsetVarNodes(
+                                               (Node *)(qry->qual),
+                                               offset,
+                                               sublevels_up);
+
+                               OffsetVarNodes(
+                                               (Node *)(qry->havingQual),
+                                               offset,
+                                               sublevels_up);
+
+                               OffsetVarNodes(
+                                               (Node *)(qry->groupClause),
+                                               offset,
+                                               sublevels_up);
+                       }
+                       break;
+
                default:
-                       /* ignore the others */
+                       elog(NOTICE, "unknown node tag %d in OffsetVarNodes()", nodeTag(node));
+                       elog(NOTICE, "Node is: %s", nodeToString(node));
                        break;
+
+
        }
 }
 
+
+/*
+ * ChangeVarNodes -
+ */
 void
-ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
+ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
 {
        if (node == NULL)
                return;
-       switch (nodeTag(node))
-       {
+
+       switch(nodeTag(node)) {
                case T_TargetEntry:
                        {
-                               TargetEntry *tle = (TargetEntry *) node;
+                               TargetEntry     *tle = (TargetEntry *)node;
 
-                               ChangeVarNodes(tle->expr, old_varno, new_varno, sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(tle->expr),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Aggreg:
                        {
-                               Aggreg     *agg = (Aggreg *) node;
+                               Aggreg  *agg = (Aggreg *)node;
 
-                               ChangeVarNodes(agg->target, old_varno, new_varno, sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(agg->target),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
 
-                       /*
-                        * This has to be done to make queries using groupclauses work
-                        * on views
-                        */
                case T_GroupClause:
                        {
-                               GroupClause *group = (GroupClause *) node;
+                               GroupClause     *grp = (GroupClause *)node;
 
-                               ChangeVarNodes((Node *) (group->entry), old_varno, new_varno,
-                                                          sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(grp->entry),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
 
                case T_Expr:
                        {
-                               Expr       *expr = (Expr *) node;
+                               Expr    *exp = (Expr *)node;
 
-                               ChangeVarNodes((Node *) expr->args, old_varno, new_varno, sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(exp->args),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Iter:
                        {
-                               Iter       *iter = (Iter *) node;
+                               Iter    *iter = (Iter *)node;
 
-                               ChangeVarNodes((Node *) iter->iterexpr, old_varno, new_varno, sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(iter->iterexpr),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
+
                case T_ArrayRef:
                        {
-                               ArrayRef           *ref = (ArrayRef *) node;
-
-                               ChangeVarNodes((Node *) ref->refupperindexpr, old_varno, new_varno, sublevels_up);
-                               ChangeVarNodes((Node *) ref->reflowerindexpr, old_varno, new_varno, sublevels_up);
-                               ChangeVarNodes((Node *) ref->refexpr, old_varno, new_varno, sublevels_up);
-                               ChangeVarNodes((Node *) ref->refassgnexpr, old_varno, new_varno, sublevels_up);
+                               ArrayRef        *ref = (ArrayRef *)node;
+
+                               ChangeVarNodes(
+                                               (Node *)(ref->refupperindexpr),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(ref->reflowerindexpr),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(ref->refexpr),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(ref->refassgnexpr),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
+
                case T_Var:
                        {
-                               Var                *var = (Var *) node;
+                               Var     *var = (Var *)node;
 
-                               if (var->varno == old_varno &&
-                                       var->varlevelsup == sublevels_up)
-                               {
-                                       var->varno = new_varno;
-                                       var->varnoold = new_varno;
+                               if (var->varlevelsup == sublevels_up &&
+                                               var->varno == rt_index) {
+                                       var->varno = new_index;
+                                       var->varnoold = new_index;
                                }
-                               if (var->varlevelsup > 0)
-                                       OffsetVarNodes((Node *) var, 3);
-
                        }
                        break;
+
+               case T_Param:
+                       break;
+
+               case T_Const:
+                       break;
+
                case T_List:
                        {
-                               List       *l;
+                               List    *l;
 
-                               foreach(l, (List *) node)
-                                       ChangeVarNodes(lfirst(l), old_varno, new_varno, sublevels_up);
+                               foreach (l, (List *)node)
+                                       ChangeVarNodes(
+                                                       (Node *)lfirst(l),
+                                                       rt_index,
+                                                       new_index,
+                                                       sublevels_up);
                        }
                        break;
+
                case T_SubLink:
                        {
-                               SubLink    *sublink = (SubLink *) node;
-                               Query      *query = (Query *) sublink->subselect;
+                               SubLink *sub = (SubLink *)node;
 
-                               ChangeVarNodes((Node *) query->qual, old_varno, new_varno,
-                                                          sublevels_up + 1);
+                               ChangeVarNodes(
+                                               (Node *)(sub->lefthand),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
 
-                               /*
-                                * We also have to adapt the variables used in
-                                * sublink->lefthand and sublink->oper
-                                */
-                               ChangeVarNodes((Node *) (sublink->lefthand), old_varno, new_varno,
-                                                          sublevels_up);
+                               ChangeVarNodes(
+                                               (Node *)(sub->subselect),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up + 1);
+                       }
+                       break;
 
-                               /*
-                                * Make sure the first argument of sublink->oper points to
-                                * the same var as sublink->lefthand does otherwise we
-                                * will run into troubles using aggregates (aggno will not
-                                * be set correctly
-                                */
+               case T_Query:
+                       {
+                               Query   *qry = (Query *)node;
 
-                               /*
-                                * lfirst(((Expr *) lfirst(sublink->oper))->args) =
-                                * lfirst(sublink->lefthand);
-                                */
+                               ChangeVarNodes(
+                                               (Node *)(qry->targetList),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
+
+                               ChangeVarNodes(
+                                               (Node *)(qry->qual),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
+
+                               ChangeVarNodes(
+                                               (Node *)(qry->havingQual),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
+
+                               ChangeVarNodes(
+                                               (Node *)(qry->groupClause),
+                                               rt_index,
+                                               new_index,
+                                               sublevels_up);
                        }
                        break;
+
                default:
-                       /* ignore the others */
+                       elog(NOTICE, "unknown node tag %d in ChangeVarNodes()", nodeTag(node));
+                       elog(NOTICE, "Node is: %s", nodeToString(node));
                        break;
+
+
        }
 }
 
+
+
 void
 AddQual(Query *parsetree, Node *qual)
 {
index 7924f93..e1b5482 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: rewriteManip.h,v 1.10 1998/10/08 18:30:41 momjian Exp $
+ * $Id: rewriteManip.h,v 1.11 1998/10/21 16:21:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,7 +18,7 @@
 #include "rewrite/rewriteHandler.h"
 
 /* RewriteManip.c */
-void           OffsetVarNodes(Node *node, int offset);
+void           OffsetVarNodes(Node *node, int offset, int sublevels_up);
 void ChangeVarNodes(Node *node, int old_varno, int new_varno,
                           int sublevels_up);
 void           AddQual(Query *parsetree, Node *qual);