Commit 0f413d2d authored by Bruce Momjian's avatar Bruce Momjian

Make subqueries rewrite properly.

parent 7e46348e
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.7 1998/01/15 19:00:06 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.8 1998/01/21 04:24:34 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
* otherwise, we return false * otherwise, we return false
*/ */
static bool static bool
nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum) nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum,
int sublevels_up)
{ {
if (node == NULL) if (node == NULL)
return FALSE; return FALSE;
...@@ -46,24 +47,24 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum) ...@@ -46,24 +47,24 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
{ {
Expr *expr = (Expr *) node; Expr *expr = (Expr *) node;
return return nodeThisLockWasTriggered((Node *) expr->args, varno,
nodeThisLockWasTriggered((Node *) expr->args, varno, attnum); attnum, sublevels_up);
} }
break; break;
case T_TargetEntry: case T_TargetEntry:
{ {
TargetEntry *tle = (TargetEntry *) node; TargetEntry *tle = (TargetEntry *) node;
return return nodeThisLockWasTriggered(tle->expr, varno, attnum,
nodeThisLockWasTriggered(tle->expr, varno, attnum); sublevels_up);
} }
break; break;
case T_Aggreg: case T_Aggreg:
{ {
Aggreg *agg = (Aggreg *) node; Aggreg *agg = (Aggreg *) node;
return return nodeThisLockWasTriggered(agg->target, varno, attnum,
nodeThisLockWasTriggered(agg->target, varno, attnum); sublevels_up);
} }
break; break;
case T_List: case T_List:
...@@ -72,12 +73,22 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum) ...@@ -72,12 +73,22 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
foreach(l, (List *) node) foreach(l, (List *) node)
{ {
if (nodeThisLockWasTriggered(lfirst(l), varno, attnum)) if (nodeThisLockWasTriggered(lfirst(l), varno, attnum,
sublevels_up))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
break; break;
case T_SubLink:
{
SubLink *sublink = (SubLink *) node;
Query *query = (Query *)sublink->subselect;
return nodeThisLockWasTriggered(query->qual, varno, attnum,
sublevels_up + 1);
}
break;
default: default:
break; break;
} }
...@@ -96,10 +107,10 @@ thisLockWasTriggered(int varno, ...@@ -96,10 +107,10 @@ thisLockWasTriggered(int varno,
Query *parsetree) Query *parsetree)
{ {
if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum)) if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum, 0))
return true; return true;
if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum)) if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum, 0))
return true; return true;
return false; return false;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.10 1998/01/09 05:48:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.11 1998/01/21 04:24:36 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,12 +29,12 @@ ...@@ -29,12 +29,12 @@
#include "commands/creatinh.h" #include "commands/creatinh.h"
#include "access/heapam.h" #include "access/heapam.h"
static void static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
int rt_index, int relation_level, int *modified); int rt_index, int relation_level, int *modified);
static List * static List *fireRules(Query *parsetree, int rt_index, CmdType event,
fireRules(Query *parsetree, int rt_index, CmdType event,
bool *instead_flag, List *locks, List **qual_products); bool *instead_flag, List *locks, List **qual_products);
static void QueryRewriteSubLink(Node *node);
static List *QueryRewriteOne(Query *parsetree);
static List *deepRewriteQuery(Query *parsetree); static List *deepRewriteQuery(Query *parsetree);
/* /*
...@@ -77,11 +77,11 @@ gatherRewriteMeta(Query *parsetree, ...@@ -77,11 +77,11 @@ gatherRewriteMeta(Query *parsetree,
OffsetVarNodes((Node *) info->rule_action->targetList, rt_length); OffsetVarNodes((Node *) info->rule_action->targetList, rt_length);
OffsetVarNodes(info->rule_qual, rt_length); OffsetVarNodes(info->rule_qual, rt_length);
ChangeVarNodes((Node *) info->rule_action->qual, ChangeVarNodes((Node *) info->rule_action->qual,
PRS2_CURRENT_VARNO + rt_length, rt_index); PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
ChangeVarNodes((Node *) info->rule_action->targetList, ChangeVarNodes((Node *) info->rule_action->targetList,
PRS2_CURRENT_VARNO + rt_length, rt_index); PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
ChangeVarNodes(info->rule_qual, ChangeVarNodes(info->rule_qual,
PRS2_CURRENT_VARNO + rt_length, rt_index); PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
/* /*
* bug here about replace CURRENT -- sort of replace current is * bug here about replace CURRENT -- sort of replace current is
...@@ -292,10 +292,10 @@ ApplyRetrieveRule(Query *parsetree, ...@@ -292,10 +292,10 @@ ApplyRetrieveRule(Query *parsetree,
OffsetVarNodes((Node *) rule_action->targetList, rt_length); OffsetVarNodes((Node *) rule_action->targetList, rt_length);
OffsetVarNodes(rule_qual, rt_length); OffsetVarNodes(rule_qual, rt_length);
ChangeVarNodes(rule_action->qual, ChangeVarNodes(rule_action->qual,
PRS2_CURRENT_VARNO + rt_length, rt_index); PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
ChangeVarNodes((Node *) rule_action->targetList, ChangeVarNodes((Node *) rule_action->targetList,
PRS2_CURRENT_VARNO + rt_length, rt_index); PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index); ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
if (relation_level) if (relation_level)
{ {
HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index, HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
...@@ -402,7 +402,7 @@ CopyAndAddQual(Query *parsetree, ...@@ -402,7 +402,7 @@ CopyAndAddQual(Query *parsetree,
rtable = append(rtable, listCopy(rule_action->rtable)); rtable = append(rtable, listCopy(rule_action->rtable));
new_tree->rtable = rtable; new_tree->rtable = rtable;
OffsetVarNodes(new_qual, rt_length); OffsetVarNodes(new_qual, rt_length);
ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index); ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
} }
/* XXX -- where current doesn't work for instead nothing.... yet */ /* XXX -- where current doesn't work for instead nothing.... yet */
AddNotQual(new_tree, new_qual); AddNotQual(new_tree, new_qual);
...@@ -627,6 +627,82 @@ static int numQueryRewriteInvoked = 0; ...@@ -627,6 +627,82 @@ static int numQueryRewriteInvoked = 0;
*/ */
List * List *
QueryRewrite(Query *parsetree) QueryRewrite(Query *parsetree)
{
QueryRewriteSubLink(parsetree->qual);
return QueryRewriteOne(parsetree);
}
/*
* QueryRewriteSubLink
*
* This rewrites the SubLink subqueries first, doing the lowest ones first.
* We already have code in the main rewrite loops to process correlated
* variables from upper queries that exist in subqueries.
*/
static void
QueryRewriteSubLink(Node *node)
{
if (node == NULL)
return;
switch (nodeTag(node))
{
case T_TargetEntry:
break;
case T_Aggreg:
break;
case T_Expr:
{
Expr *expr = (Expr *) node;
QueryRewriteSubLink((Node *)expr->args);
}
break;
case T_Var:
break;
case T_List:
{
List *l;
foreach(l, (List *) node)
QueryRewriteSubLink(lfirst(l));
}
break;
case T_SubLink:
{
SubLink *sublink = (SubLink *) node;
Query *query = (Query *)sublink->subselect;
List *ret;
/*
* Nest down first. We do this so if a rewrite adds a
* SubLink we don't process it as part of this loop.
*/
QueryRewriteSubLink((Node *)query->qual);
ret = QueryRewriteOne(query);
if (!ret)
sublink->subselect = NULL;
else if (lnext(ret) == NIL)
sublink->subselect = lfirst(ret);
else
elog(ERROR,"Don't know how to process subquery that rewrites to multiple queries.");
}
break;
default:
/* ignore the others */
break;
}
return;
}
/*
* QueryOneRewrite -
* rewrite one query
*/
static List *
QueryRewriteOne(Query *parsetree)
{ {
numQueryRewriteInvoked = 0; numQueryRewriteInvoked = 0;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.10 1998/01/15 19:00:07 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.11 1998/01/21 04:24:39 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#include "nodes/plannodes.h" #include "nodes/plannodes.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
static void ResolveNew(RewriteInfo *info, List *targetlist, Node **node); static void ResolveNew(RewriteInfo *info, List *targetlist,
Node **node, int sublevels_up);
...@@ -85,7 +86,7 @@ OffsetVarNodes(Node *node, int offset) ...@@ -85,7 +86,7 @@ OffsetVarNodes(Node *node, int offset)
} }
void void
ChangeVarNodes(Node *node, int old_varno, int new_varno) ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
{ {
if (node == NULL) if (node == NULL)
return; return;
...@@ -95,28 +96,29 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno) ...@@ -95,28 +96,29 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno)
{ {
TargetEntry *tle = (TargetEntry *) node; TargetEntry *tle = (TargetEntry *) node;
ChangeVarNodes(tle->expr, old_varno, new_varno); ChangeVarNodes(tle->expr, old_varno, new_varno, sublevels_up);
} }
break; break;
case T_Aggreg: case T_Aggreg:
{ {
Aggreg *agg = (Aggreg *) node; Aggreg *agg = (Aggreg *) node;
ChangeVarNodes(agg->target, old_varno, new_varno); ChangeVarNodes(agg->target, old_varno, new_varno, sublevels_up);
} }
break; break;
case T_Expr: case T_Expr:
{ {
Expr *expr = (Expr *) node; Expr *expr = (Expr *) node;
ChangeVarNodes((Node *) expr->args, old_varno, new_varno); ChangeVarNodes((Node *) expr->args, old_varno, new_varno, sublevels_up);
} }
break; break;
case T_Var: case T_Var:
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
if (var->varno == old_varno) if (var->varno == old_varno &&
var->varlevelsup == sublevels_up)
{ {
var->varno = new_varno; var->varno = new_varno;
var->varnoold = new_varno; var->varnoold = new_varno;
...@@ -128,9 +130,16 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno) ...@@ -128,9 +130,16 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno)
List *l; List *l;
foreach(l, (List *) node) foreach(l, (List *) node)
{ ChangeVarNodes(lfirst(l), old_varno, new_varno, sublevels_up);
ChangeVarNodes(lfirst(l), old_varno, new_varno);
} }
break;
case T_SubLink:
{
SubLink *sublink = (SubLink *) node;
Query *query = (Query *)sublink->subselect;
ChangeVarNodes((Node *)query->qual, old_varno, new_varno,
sublevels_up + 1);
} }
break; break;
default: default:
...@@ -237,7 +246,8 @@ FindMatchingTLEntry(List *tlist, char *e_attname) ...@@ -237,7 +246,8 @@ FindMatchingTLEntry(List *tlist, char *e_attname)
} }
static void static void
ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr) ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
int sublevels_up)
{ {
Node *node = *nodePtr; Node *node = *nodePtr;
...@@ -247,20 +257,25 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr) ...@@ -247,20 +257,25 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
switch (nodeTag(node)) switch (nodeTag(node))
{ {
case T_TargetEntry: case T_TargetEntry:
ResolveNew(info, targetlist, &((TargetEntry *) node)->expr); ResolveNew(info, targetlist, &((TargetEntry *) node)->expr,
sublevels_up);
break; break;
case T_Aggreg: case T_Aggreg:
ResolveNew(info, targetlist, &((Aggreg *) node)->target); ResolveNew(info, targetlist, &((Aggreg *) node)->target,
sublevels_up);
break; break;
case T_Expr: case T_Expr:
ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args))); ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)),
sublevels_up);
break; break;
case T_Var: case T_Var:
{ {
int this_varno = (int) ((Var *) node)->varno; int this_varno = (int) ((Var *) node)->varno;
int this_varlevelsup = (int) ((Var *) node)->varlevelsup;
Node *n; Node *n;
if (this_varno == info->new_varno) if (this_varno == info->new_varno &&
this_varlevelsup == sublevels_up)
{ {
n = FindMatchingNew(targetlist, n = FindMatchingNew(targetlist,
((Var *) node)->varattno); ((Var *) node)->varattno);
...@@ -288,11 +303,18 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr) ...@@ -288,11 +303,18 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
List *l; List *l;
foreach(l, (List *) node) foreach(l, (List *) node)
ResolveNew(info, targetlist, (Node **) &(lfirst(l)),
sublevels_up);
break;
}
case T_SubLink:
{ {
ResolveNew(info, targetlist, (Node **) &(lfirst(l))); SubLink *sublink = (SubLink *) node;
Query *query = (Query *)sublink->subselect;
ResolveNew(info, targetlist, (Node **)&(query->qual), sublevels_up + 1);
} }
break; break;
}
default: default:
/* ignore the others */ /* ignore the others */
break; break;
...@@ -303,8 +325,8 @@ void ...@@ -303,8 +325,8 @@ void
FixNew(RewriteInfo *info, Query *parsetree) FixNew(RewriteInfo *info, Query *parsetree)
{ {
ResolveNew(info, parsetree->targetList, ResolveNew(info, parsetree->targetList,
(Node **) &(info->rule_action->targetList)); (Node **) &(info->rule_action->targetList), 0);
ResolveNew(info, parsetree->targetList, &info->rule_action->qual); ResolveNew(info, parsetree->targetList, &info->rule_action->qual, 0);
} }
static void static void
...@@ -314,7 +336,8 @@ nodeHandleRIRAttributeRule(Node **nodePtr, ...@@ -314,7 +336,8 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
int rt_index, int rt_index,
int attr_num, int attr_num,
int *modified, int *modified,
int *badsql) int *badsql,
int sublevels_up)
{ {
Node *node = *nodePtr; Node *node = *nodePtr;
...@@ -322,24 +345,13 @@ nodeHandleRIRAttributeRule(Node **nodePtr, ...@@ -322,24 +345,13 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
return; return;
switch (nodeTag(node)) switch (nodeTag(node))
{ {
case T_List:
{
List *i;
foreach(i, (List *) node)
{
nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
targetlist, rt_index, attr_num,
modified, badsql);
}
}
break;
case T_TargetEntry: case T_TargetEntry:
{ {
TargetEntry *tle = (TargetEntry *) node; TargetEntry *tle = (TargetEntry *) node;
nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist, nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
rt_index, attr_num, modified, badsql); rt_index, attr_num, modified, badsql,
sublevels_up);
} }
break; break;
case T_Aggreg: case T_Aggreg:
...@@ -347,7 +359,8 @@ nodeHandleRIRAttributeRule(Node **nodePtr, ...@@ -347,7 +359,8 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
Aggreg *agg = (Aggreg *) node; Aggreg *agg = (Aggreg *) node;
nodeHandleRIRAttributeRule(&agg->target, rtable, targetlist, nodeHandleRIRAttributeRule(&agg->target, rtable, targetlist,
rt_index, attr_num, modified, badsql); rt_index, attr_num, modified, badsql,
sublevels_up);
} }
break; break;
case T_Expr: case T_Expr:
...@@ -356,18 +369,19 @@ nodeHandleRIRAttributeRule(Node **nodePtr, ...@@ -356,18 +369,19 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
nodeHandleRIRAttributeRule((Node **) (&(expr->args)), rtable, nodeHandleRIRAttributeRule((Node **) (&(expr->args)), rtable,
targetlist, rt_index, attr_num, targetlist, rt_index, attr_num,
modified, badsql); modified, badsql,
sublevels_up);
} }
break; break;
case T_Var: case T_Var:
{ {
int this_varno = (int) ((Var *) node)->varno; int this_varno = ((Var *) node)->varno;
NameData name_to_look_for; int this_varattno = ((Var *) node)->varattno;
int this_varlevelsup = ((Var *) node)->varlevelsup;
MemSet(name_to_look_for.data, 0, NAMEDATALEN);
if (this_varno == rt_index && if (this_varno == rt_index &&
((Var *) node)->varattno == attr_num) this_varattno == attr_num &&
this_varlevelsup == sublevels_up)
{ {
if (((Var *) node)->vartype == 32) if (((Var *) node)->vartype == 32)
{ /* HACK */ { /* HACK */
...@@ -378,28 +392,49 @@ nodeHandleRIRAttributeRule(Node **nodePtr, ...@@ -378,28 +392,49 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
} }
else else
{ {
NameData name_to_look_for;
name_to_look_for.data[0] = '\0';
namestrcpy(&name_to_look_for, namestrcpy(&name_to_look_for,
(char *) get_attname(getrelid(this_varno, (char *) get_attname(getrelid(this_varno,
rtable), rtable),
attr_num)); attr_num));
}
}
if (name_to_look_for.data[0]) if (name_to_look_for.data[0])
{ {
Node *n; Node *n;
n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for); n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
if (n == NULL) if (n == NULL)
{
*nodePtr = make_null(((Var *) node)->vartype); *nodePtr = make_null(((Var *) node)->vartype);
}
else else
{
*nodePtr = n; *nodePtr = n;
}
*modified = TRUE; *modified = TRUE;
} }
} }
}
}
break;
case T_List:
{
List *i;
foreach(i, (List *) node)
{
nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
targetlist, rt_index, attr_num,
modified, badsql, sublevels_up);
}
}
break;
case T_SubLink:
{
SubLink *sublink = (SubLink *) node;
Query *query = (Query *)sublink->subselect;
nodeHandleRIRAttributeRule((Node **)&(query->qual), rtable, targetlist,
rt_index, attr_num, modified, badsql,
sublevels_up + 1);
}
break; break;
default: default:
/* ignore the others */ /* ignore the others */
...@@ -423,9 +458,9 @@ HandleRIRAttributeRule(Query *parsetree, ...@@ -423,9 +458,9 @@ HandleRIRAttributeRule(Query *parsetree,
nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable, nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
targetlist, rt_index, attr_num, targetlist, rt_index, attr_num,
modified, badsql); modified, badsql, 0);
nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist, nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
rt_index, attr_num, modified, badsql); rt_index, attr_num, modified, badsql, 0);
} }
...@@ -434,7 +469,8 @@ nodeHandleViewRule(Node **nodePtr, ...@@ -434,7 +469,8 @@ nodeHandleViewRule(Node **nodePtr,
List *rtable, List *rtable,
List *targetlist, List *targetlist,
int rt_index, int rt_index,
int *modified) int *modified,
int sublevels_up)
{ {
Node *node = *nodePtr; Node *node = *nodePtr;
...@@ -443,24 +479,12 @@ nodeHandleViewRule(Node **nodePtr, ...@@ -443,24 +479,12 @@ nodeHandleViewRule(Node **nodePtr,
switch (nodeTag(node)) switch (nodeTag(node))
{ {
case T_List:
{
List *l;
foreach(l, (List *) node)
{
nodeHandleViewRule((Node **) (&(lfirst(l))),
rtable, targetlist,
rt_index, modified);
}
}
break;
case T_TargetEntry: case T_TargetEntry:
{ {
TargetEntry *tle = (TargetEntry *) node; TargetEntry *tle = (TargetEntry *) node;
nodeHandleViewRule(&(tle->expr), rtable, targetlist, nodeHandleViewRule(&(tle->expr), rtable, targetlist,
rt_index, modified); rt_index, modified, sublevels_up);
} }
break; break;
case T_Aggreg: case T_Aggreg:
...@@ -468,7 +492,7 @@ nodeHandleViewRule(Node **nodePtr, ...@@ -468,7 +492,7 @@ nodeHandleViewRule(Node **nodePtr,
Aggreg *agg = (Aggreg *) node; Aggreg *agg = (Aggreg *) node;
nodeHandleViewRule(&(agg->target), rtable, targetlist, nodeHandleViewRule(&(agg->target), rtable, targetlist,
rt_index, modified); rt_index, modified, sublevels_up);
} }
break; break;
case T_Expr: case T_Expr:
...@@ -477,33 +501,52 @@ nodeHandleViewRule(Node **nodePtr, ...@@ -477,33 +501,52 @@ nodeHandleViewRule(Node **nodePtr,
nodeHandleViewRule((Node **) (&(expr->args)), nodeHandleViewRule((Node **) (&(expr->args)),
rtable, targetlist, rtable, targetlist,
rt_index, modified); rt_index, modified, sublevels_up);
} }
break; break;
case T_Var: case T_Var:
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
int this_varno = var->varno; int this_varno = var->varno;
int this_varlevelsup = var->varlevelsup;
Node *n; Node *n;
if (this_varno == rt_index) if (this_varno == rt_index &&
this_varlevelsup == sublevels_up)
{ {
n = FindMatchingTLEntry(targetlist, n = FindMatchingTLEntry(targetlist,
get_attname(getrelid(this_varno, get_attname(getrelid(this_varno,
rtable), rtable),
var->varattno)); var->varattno));
if (n == NULL) if (n == NULL)
{
*nodePtr = make_null(((Var *) node)->vartype); *nodePtr = make_null(((Var *) node)->vartype);
}
else else
{
*nodePtr = n; *nodePtr = n;
}
*modified = TRUE; *modified = TRUE;
} }
break; break;
} }
case T_List:
{
List *l;
foreach(l, (List *) node)
{
nodeHandleViewRule((Node **) (&(lfirst(l))),
rtable, targetlist,
rt_index, modified, sublevels_up);
}
}
break;
case T_SubLink:
{
SubLink *sublink = (SubLink *) node;
Query *query = (Query *)sublink->subselect;
nodeHandleViewRule((Node **)&(query->qual), rtable, targetlist,
rt_index, modified, sublevels_up + 1);
}
break;
default: default:
/* ignore the others */ /* ignore the others */
break; break;
...@@ -519,7 +562,7 @@ HandleViewRule(Query *parsetree, ...@@ -519,7 +562,7 @@ HandleViewRule(Query *parsetree,
{ {
nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index, nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
modified); modified, 0);
nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist, nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
rt_index, modified); rt_index, modified, 0);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: rewriteManip.h,v 1.5 1997/11/26 01:14:25 momjian Exp $ * $Id: rewriteManip.h,v 1.6 1998/01/21 04:24:46 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
/* RewriteManip.c */ /* RewriteManip.c */
void OffsetVarNodes(Node *node, int offset); void OffsetVarNodes(Node *node, int offset);
void ChangeVarNodes(Node *node, int old_varno, int new_varno); void ChangeVarNodes(Node *node, int old_varno, int new_varno,
int sublevels_up);
void AddQual(Query *parsetree, Node *qual); void AddQual(Query *parsetree, Node *qual);
void AddNotQual(Query *parsetree, Node *qual); void AddNotQual(Query *parsetree, Node *qual);
void FixResdomTypes(List *user_tlist); void FixResdomTypes(List *user_tlist);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment