mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 00:02:04 -04:00
Make subqueries rewrite properly.
This commit is contained in:
parent
7e46348e62
commit
0f413d2dc2
@ -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 @@
|
|||||||
* 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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
|||||||
*/
|
*/
|
||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
#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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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;
|
||||||
Node *n;
|
int this_varlevelsup = (int) ((Var *) node)->varlevelsup;
|
||||||
|
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)
|
|||||||
List *l;
|
List *l;
|
||||||
|
|
||||||
foreach(l, (List *) node)
|
foreach(l, (List *) node)
|
||||||
{
|
ResolveNew(info, targetlist, (Node **) &(lfirst(l)),
|
||||||
ResolveNew(info, targetlist, (Node **) &(lfirst(l)));
|
sublevels_up);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case T_SubLink:
|
||||||
|
{
|
||||||
|
SubLink *sublink = (SubLink *) node;
|
||||||
|
Query *query = (Query *)sublink->subselect;
|
||||||
|
|
||||||
|
ResolveNew(info, targetlist, (Node **)&(query->qual), sublevels_up + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* ignore the others */
|
/* ignore the others */
|
||||||
break;
|
break;
|
||||||
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,29 +392,50 @@ 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])
|
||||||
|
{
|
||||||
|
Node *n;
|
||||||
|
|
||||||
|
n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
|
||||||
|
if (n == NULL)
|
||||||
|
*nodePtr = make_null(((Var *) node)->vartype);
|
||||||
|
else
|
||||||
|
*nodePtr = n;
|
||||||
|
*modified = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name_to_look_for.data[0])
|
}
|
||||||
{
|
break;
|
||||||
Node *n;
|
case T_List:
|
||||||
|
{
|
||||||
|
List *i;
|
||||||
|
|
||||||
n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
|
foreach(i, (List *) node)
|
||||||
if (n == NULL)
|
{
|
||||||
{
|
nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
|
||||||
*nodePtr = make_null(((Var *) node)->vartype);
|
targetlist, rt_index, attr_num,
|
||||||
}
|
modified, badsql, sublevels_up);
|
||||||
else
|
|
||||||
{
|
|
||||||
*nodePtr = n;
|
|
||||||
}
|
|
||||||
*modified = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
||||||
default:
|
default:
|
||||||
/* ignore the others */
|
/* ignore the others */
|
||||||
break;
|
break;
|
||||||
@ -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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
{
|
{
|
||||||
|
|
||||||
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 @@
|
|||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
|
|
||||||
/* 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user