*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#include <optimizer/planner.h>
#include <access/xact.h>
#include <utils/relcache.h>
+#include <rewrite/rewriteHandler.h>
typedef struct ExplainState
{
} ExplainState;
static char *Explain_PlanToString(Plan *plan, ExplainState *es);
+static void ExplainOneQuery(Query *query, bool verbose, CommandDest dest);
+
/*
* ExplainQuery -
void
ExplainQuery(Query *query, bool verbose, CommandDest dest)
{
- char *s = NULL,
- *s2;
- Plan *plan;
- ExplainState *es;
- int len;
+ List *rewritten;
+ List *l;
if (IsAbortedTransactionBlockState())
{
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);
{
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:
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;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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);
/*
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
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,
}
-/*
- * 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
}
+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)
{
}
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;
}
elog(NOTICE, "unknown node tag %d in apply_RIR_view()", nodeTag(node));
elog(NOTICE, "Node is: %s", nodeToString(node));
break;
-
-
}
}
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)
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 */
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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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)
{
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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);