Skip to content
Snippets Groups Projects
Commit 0f413d2d authored by Bruce Momjian's avatar Bruce Momjian
Browse files

Make subqueries rewrite properly.

parent 7e46348e
No related branches found
No related tags found
No related merge requests found
...@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment