The patch does 2 things:
authorBruce Momjian
Wed, 21 Oct 1998 16:21:29 +0000 (16:21 +0000)
committerBruce Momjian
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 63534050f1c081aaa871046bc77dfe5f619b089b..1b861c96204944ccb93fc8cbb986c2fffff8d21e 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 
 #include 
 #include 
+#include 
 
 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 f8b7ce15dfc034ee8ea905f7526d9ab6ac9151a3..2d5662aa2604d8813032af3822d33d0fd237766b 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 cf81e8be66f4eb2b9ba31701514669d725c4d2a1..fc5755edd7cd5d6ead5ab6c252fcc66b07eac4ee 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 a0f30698abc6e42b398be087a4f2a585c0e25bf8..8eaa8dbb9417324372db1e822424a9f20fec2920 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,
@@ -550,364 +548,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
@@ -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 */
@@ -2385,6 +2136,28 @@ fireRules(Query *parsetree,
            if (rule_action->commandType == CMD_NOTHING)
                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
index d589943dc5c6bc2cdc7475d4e0557a529fa1236d..64da8479d150b61a83a195aadcd3ed9b58a73797 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 7924f931615e1629503360cb5be561db18b1d645..e1b54829bbc97f9269f9a3074b72b416dc360cb3 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);