summaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteManip.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-01-20 18:55:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-01-20 18:55:07 +0000
commitbdfbfde1b168b3332c4cdac34ac86a80aaf4d442 (patch)
treef35bf1af04733069f3a6b0a2698ac10dbd6544ed /src/backend/rewrite/rewriteManip.c
parentbe2b660ecd5ca205570825633e7b8479379ddc64 (diff)
downloadpostgresql-bdfbfde1b168b3332c4cdac34ac86a80aaf4d442.tar.gz
IN clauses appearing at top level of WHERE can now be handled as joins.
There are two implementation techniques: the executor understands a new JOIN_IN jointype, which emits at most one matching row per left-hand row, or the result of the IN's sub-select can be fed through a DISTINCT filter and then joined as an ordinary relation. Along the way, some minor code cleanup in the optimizer; notably, break out most of the jointree-rearrangement preprocessing in planner.c and put it in a new file prep/prepjointree.c.
Diffstat (limited to 'src/backend/rewrite/rewriteManip.c')
-rw-r--r--src/backend/rewrite/rewriteManip.c60
1 files changed, 55 insertions, 5 deletions
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 4a4f6824b7..4460428966 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.69 2003/01/17 02:01:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.70 2003/01/20 18:54:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -90,8 +90,8 @@ checkExprHasSubLink_walker(Node *node, void *context)
*
* Find all Var nodes in the given tree with varlevelsup == sublevels_up,
* and increment their varno fields (rangetable indexes) by 'offset'.
- * The varnoold fields are adjusted similarly. Also, RangeTblRef and
- * JoinExpr nodes in join trees and setOp trees are adjusted.
+ * The varnoold fields are adjusted similarly. Also, adjust other nodes
+ * that contain rangetable indexes, such as RangeTblRef and JoinExpr.
*
* NOTE: although this has the form of a walker, we cheat and modify the
* nodes in-place. The given expression tree should have been copied
@@ -137,6 +137,25 @@ OffsetVarNodes_walker(Node *node, OffsetVarNodes_context *context)
j->rtindex += context->offset;
/* fall through to examine children */
}
+ if (IsA(node, InClauseInfo))
+ {
+ InClauseInfo *ininfo = (InClauseInfo *) node;
+
+ if (context->sublevels_up == 0)
+ {
+ List *rt;
+
+ foreach(rt, ininfo->lefthand)
+ {
+ lfirsti(rt) += context->offset;
+ }
+ foreach(rt, ininfo->righthand)
+ {
+ lfirsti(rt) += context->offset;
+ }
+ }
+ /* fall through to examine children */
+ }
if (IsA(node, Query))
{
/* Recurse into subselects */
@@ -196,8 +215,8 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
*
* Find all Var nodes in the given tree belonging to a specific relation
* (identified by sublevels_up and rt_index), and change their varno fields
- * to 'new_index'. The varnoold fields are changed too. Also, RangeTblRef
- * and JoinExpr nodes in join trees and setOp trees are adjusted.
+ * to 'new_index'. The varnoold fields are changed too. Also, adjust other
+ * nodes that contain rangetable indexes, such as RangeTblRef and JoinExpr.
*
* NOTE: although this has the form of a walker, we cheat and modify the
* nodes in-place. The given expression tree should have been copied
@@ -247,6 +266,27 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context)
j->rtindex = context->new_index;
/* fall through to examine children */
}
+ if (IsA(node, InClauseInfo))
+ {
+ InClauseInfo *ininfo = (InClauseInfo *) node;
+
+ if (context->sublevels_up == 0)
+ {
+ List *rt;
+
+ foreach(rt, ininfo->lefthand)
+ {
+ if (lfirsti(rt) == context->rt_index)
+ lfirsti(rt) = context->new_index;
+ }
+ foreach(rt, ininfo->righthand)
+ {
+ if (lfirsti(rt) == context->rt_index)
+ lfirsti(rt) = context->new_index;
+ }
+ }
+ /* fall through to examine children */
+ }
if (IsA(node, Query))
{
/* Recurse into subselects */
@@ -423,6 +463,16 @@ rangeTableEntry_used_walker(Node *node,
return true;
/* fall through to examine children */
}
+ if (IsA(node, InClauseInfo))
+ {
+ InClauseInfo *ininfo = (InClauseInfo *) node;
+
+ if (context->sublevels_up == 0 &&
+ (intMember(context->rt_index, ininfo->lefthand) ||
+ intMember(context->rt_index, ininfo->righthand)))
+ return true;
+ /* fall through to examine children */
+ }
if (IsA(node, Query))
{
/* Recurse into subselects */