Skip to content

Commit 0f413d2

Browse files
committed
Make subqueries rewrite properly.
1 parent 7e46348 commit 0f413d2

File tree

4 files changed

+237
-106
lines changed

4 files changed

+237
-106
lines changed

src/backend/rewrite/locks.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.7 1998/01/15 19:00:06 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.8 1998/01/21 04:24:34 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -27,7 +27,8 @@
2727
* otherwise, we return false
2828
*/
2929
static bool
30-
nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
30+
nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum,
31+
int sublevels_up)
3132
{
3233
if (node == NULL)
3334
return FALSE;
@@ -46,24 +47,24 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
4647
{
4748
Expr *expr = (Expr *) node;
4849

49-
return
50-
nodeThisLockWasTriggered((Node *) expr->args, varno, attnum);
50+
return nodeThisLockWasTriggered((Node *) expr->args, varno,
51+
attnum, sublevels_up);
5152
}
5253
break;
5354
case T_TargetEntry:
5455
{
5556
TargetEntry *tle = (TargetEntry *) node;
5657

57-
return
58-
nodeThisLockWasTriggered(tle->expr, varno, attnum);
58+
return nodeThisLockWasTriggered(tle->expr, varno, attnum,
59+
sublevels_up);
5960
}
6061
break;
6162
case T_Aggreg:
6263
{
6364
Aggreg *agg = (Aggreg *) node;
6465

65-
return
66-
nodeThisLockWasTriggered(agg->target, varno, attnum);
66+
return nodeThisLockWasTriggered(agg->target, varno, attnum,
67+
sublevels_up);
6768
}
6869
break;
6970
case T_List:
@@ -72,12 +73,22 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
7273

7374
foreach(l, (List *) node)
7475
{
75-
if (nodeThisLockWasTriggered(lfirst(l), varno, attnum))
76+
if (nodeThisLockWasTriggered(lfirst(l), varno, attnum,
77+
sublevels_up))
7678
return TRUE;
7779
}
7880
return FALSE;
7981
}
8082
break;
83+
case T_SubLink:
84+
{
85+
SubLink *sublink = (SubLink *) node;
86+
Query *query = (Query *)sublink->subselect;
87+
88+
return nodeThisLockWasTriggered(query->qual, varno, attnum,
89+
sublevels_up + 1);
90+
}
91+
break;
8192
default:
8293
break;
8394
}
@@ -96,10 +107,10 @@ thisLockWasTriggered(int varno,
96107
Query *parsetree)
97108
{
98109

99-
if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum))
110+
if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum, 0))
100111
return true;
101112

102-
if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum))
113+
if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum, 0))
103114
return true;
104115

105116
return false;

src/backend/rewrite/rewriteHandler.c

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.10 1998/01/09 05:48:17 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.11 1998/01/21 04:24:36 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -29,12 +29,12 @@
2929
#include "commands/creatinh.h"
3030
#include "access/heapam.h"
3131

32-
static void
33-
ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
32+
static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
3433
int rt_index, int relation_level, int *modified);
35-
static List *
36-
fireRules(Query *parsetree, int rt_index, CmdType event,
34+
static List *fireRules(Query *parsetree, int rt_index, CmdType event,
3735
bool *instead_flag, List *locks, List **qual_products);
36+
static void QueryRewriteSubLink(Node *node);
37+
static List *QueryRewriteOne(Query *parsetree);
3838
static List *deepRewriteQuery(Query *parsetree);
3939

4040
/*
@@ -77,11 +77,11 @@ gatherRewriteMeta(Query *parsetree,
7777
OffsetVarNodes((Node *) info->rule_action->targetList, rt_length);
7878
OffsetVarNodes(info->rule_qual, rt_length);
7979
ChangeVarNodes((Node *) info->rule_action->qual,
80-
PRS2_CURRENT_VARNO + rt_length, rt_index);
80+
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
8181
ChangeVarNodes((Node *) info->rule_action->targetList,
82-
PRS2_CURRENT_VARNO + rt_length, rt_index);
82+
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
8383
ChangeVarNodes(info->rule_qual,
84-
PRS2_CURRENT_VARNO + rt_length, rt_index);
84+
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
8585

8686
/*
8787
* bug here about replace CURRENT -- sort of replace current is
@@ -292,10 +292,10 @@ ApplyRetrieveRule(Query *parsetree,
292292
OffsetVarNodes((Node *) rule_action->targetList, rt_length);
293293
OffsetVarNodes(rule_qual, rt_length);
294294
ChangeVarNodes(rule_action->qual,
295-
PRS2_CURRENT_VARNO + rt_length, rt_index);
295+
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
296296
ChangeVarNodes((Node *) rule_action->targetList,
297-
PRS2_CURRENT_VARNO + rt_length, rt_index);
298-
ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index);
297+
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
298+
ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
299299
if (relation_level)
300300
{
301301
HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
@@ -402,7 +402,7 @@ CopyAndAddQual(Query *parsetree,
402402
rtable = append(rtable, listCopy(rule_action->rtable));
403403
new_tree->rtable = rtable;
404404
OffsetVarNodes(new_qual, rt_length);
405-
ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index);
405+
ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
406406
}
407407
/* XXX -- where current doesn't work for instead nothing.... yet */
408408
AddNotQual(new_tree, new_qual);
@@ -627,6 +627,82 @@ static int numQueryRewriteInvoked = 0;
627627
*/
628628
List *
629629
QueryRewrite(Query *parsetree)
630+
{
631+
632+
QueryRewriteSubLink(parsetree->qual);
633+
return QueryRewriteOne(parsetree);
634+
}
635+
636+
/*
637+
* QueryRewriteSubLink
638+
*
639+
* This rewrites the SubLink subqueries first, doing the lowest ones first.
640+
* We already have code in the main rewrite loops to process correlated
641+
* variables from upper queries that exist in subqueries.
642+
*/
643+
static void
644+
QueryRewriteSubLink(Node *node)
645+
{
646+
if (node == NULL)
647+
return;
648+
649+
switch (nodeTag(node))
650+
{
651+
case T_TargetEntry:
652+
break;
653+
case T_Aggreg:
654+
break;
655+
case T_Expr:
656+
{
657+
Expr *expr = (Expr *) node;
658+
659+
QueryRewriteSubLink((Node *)expr->args);
660+
}
661+
break;
662+
case T_Var:
663+
break;
664+
case T_List:
665+
{
666+
List *l;
667+
668+
foreach(l, (List *) node)
669+
QueryRewriteSubLink(lfirst(l));
670+
}
671+
break;
672+
case T_SubLink:
673+
{
674+
SubLink *sublink = (SubLink *) node;
675+
Query *query = (Query *)sublink->subselect;
676+
List *ret;
677+
678+
/*
679+
* Nest down first. We do this so if a rewrite adds a
680+
* SubLink we don't process it as part of this loop.
681+
*/
682+
QueryRewriteSubLink((Node *)query->qual);
683+
684+
ret = QueryRewriteOne(query);
685+
if (!ret)
686+
sublink->subselect = NULL;
687+
else if (lnext(ret) == NIL)
688+
sublink->subselect = lfirst(ret);
689+
else
690+
elog(ERROR,"Don't know how to process subquery that rewrites to multiple queries.");
691+
}
692+
break;
693+
default:
694+
/* ignore the others */
695+
break;
696+
}
697+
return;
698+
}
699+
700+
/*
701+
* QueryOneRewrite -
702+
* rewrite one query
703+
*/
704+
static List *
705+
QueryRewriteOne(Query *parsetree)
630706
{
631707
numQueryRewriteInvoked = 0;
632708

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy