aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeMergejoin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeMergejoin.c')
-rw-r--r--src/backend/executor/nodeMergejoin.c79
1 files changed, 50 insertions, 29 deletions
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index a1d209db349..dfa3c2e29af 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.75.2.1 2005/11/22 18:23:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.75.2.2 2006/03/17 19:38:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -948,9 +948,6 @@ ExecMergeJoin(MergeJoinState *node)
* now we get the next inner tuple, if any. If there's none,
* advance to next outer tuple (which may be able to join to
* previously marked tuples).
- *
- * If we find one but it cannot join to anything, stay in
- * NEXTINNER state to fetch the next one.
*/
innerTupleSlot = ExecProcNode(innerPlan);
node->mj_InnerTupleSlot = innerTupleSlot;
@@ -963,8 +960,17 @@ ExecMergeJoin(MergeJoinState *node)
break;
}
+ /*
+ * Load up the new inner tuple's comparison values. If we
+ * see that it contains a NULL and hence can't match any
+ * outer tuple, we can skip the comparison and assume the
+ * new tuple is greater than current outer.
+ */
if (!MJEvalInnerValues(node, innerTupleSlot))
- break; /* stay in NEXTINNER state */
+ {
+ node->mj_JoinState = EXEC_MJ_NEXTOUTER;
+ break;
+ }
/*
* Test the new inner tuple to see if it matches outer.
@@ -1054,15 +1060,15 @@ ExecMergeJoin(MergeJoinState *node)
}
/* Compute join values and check for unmatchability */
- if (!MJEvalOuterValues(node))
+ if (MJEvalOuterValues(node))
{
- /* Stay in same state to fetch next outer tuple */
- node->mj_JoinState = EXEC_MJ_NEXTOUTER;
+ /* Go test the new tuple against the marked tuple */
+ node->mj_JoinState = EXEC_MJ_TESTOUTER;
}
else
{
- /* Go test the tuple */
- node->mj_JoinState = EXEC_MJ_TESTOUTER;
+ /* Can't match, so fetch next outer tuple */
+ node->mj_JoinState = EXEC_MJ_NEXTOUTER;
}
break;
@@ -1071,7 +1077,7 @@ ExecMergeJoin(MergeJoinState *node)
* tuple satisfy the merge clause then we know we have
* duplicates in the outer scan so we have to restore the
* inner scan to the marked tuple and proceed to join the
- * new outer tuples with the inner tuples.
+ * new outer tuple with the inner tuples.
*
* This is the case when
* outer inner
@@ -1105,8 +1111,9 @@ ExecMergeJoin(MergeJoinState *node)
MJ_printf("ExecMergeJoin: EXEC_MJ_TESTOUTER\n");
/*
- * here we must compare the outer tuple with the marked inner
- * tuple
+ * Here we must compare the outer tuple with the marked inner
+ * tuple. (We can ignore the result of MJEvalInnerValues,
+ * since the marked inner tuple is certainly matchable.)
*/
innerTupleSlot = node->mj_MarkedTupleSlot;
(void) MJEvalInnerValues(node, innerTupleSlot);
@@ -1179,10 +1186,19 @@ ExecMergeJoin(MergeJoinState *node)
}
/* reload comparison data for current inner */
- (void) MJEvalInnerValues(node, innerTupleSlot);
-
- /* continue on to skip outer tuples */
- node->mj_JoinState = EXEC_MJ_SKIP_TEST;
+ if (MJEvalInnerValues(node, innerTupleSlot))
+ {
+ /* proceed to compare it to the current outer */
+ node->mj_JoinState = EXEC_MJ_SKIP_TEST;
+ }
+ else
+ {
+ /*
+ * current inner can't possibly match any outer;
+ * better to advance the inner scan than the outer.
+ */
+ node->mj_JoinState = EXEC_MJ_SKIPINNER_ADVANCE;
+ }
}
break;
@@ -1293,15 +1309,16 @@ ExecMergeJoin(MergeJoinState *node)
}
/* Compute join values and check for unmatchability */
- if (!MJEvalOuterValues(node))
+ if (MJEvalOuterValues(node))
{
- /* Stay in same state to fetch next outer tuple */
+ /* Go test the new tuple against the current inner */
+ node->mj_JoinState = EXEC_MJ_SKIP_TEST;
+ }
+ else
+ {
+ /* Can't match, so fetch next outer tuple */
node->mj_JoinState = EXEC_MJ_SKIPOUTER_ADVANCE;
- break;
}
-
- /* Test the new tuple against the current inner */
- node->mj_JoinState = EXEC_MJ_SKIP_TEST;
break;
/*
@@ -1356,15 +1373,19 @@ ExecMergeJoin(MergeJoinState *node)
}
/* Compute join values and check for unmatchability */
- if (!MJEvalInnerValues(node, innerTupleSlot))
+ if (MJEvalInnerValues(node, innerTupleSlot))
{
- /* Stay in same state to fetch next inner tuple */
+ /* proceed to compare it to the current outer */
+ node->mj_JoinState = EXEC_MJ_SKIP_TEST;
+ }
+ else
+ {
+ /*
+ * current inner can't possibly match any outer;
+ * better to advance the inner scan than the outer.
+ */
node->mj_JoinState = EXEC_MJ_SKIPINNER_ADVANCE;
- break;
}
-
- /* Test the new tuple against the current outer */
- node->mj_JoinState = EXEC_MJ_SKIP_TEST;
break;
/*