diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 837837bece0c69c53576b014048d79aa2a784266..4534845b5272e583fdb8810966cf5649c72ff3b0 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.94 2008/08/14 18:47:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.95 2008/08/15 19:20:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -264,36 +264,34 @@ ExecHashJoin(HashJoinState *node) node->hj_NeedNewOuter = true; break; /* out of loop over hash bucket */ } - else + + /* + * In a semijoin, we'll consider returning the first match, + * but after that we're done with this outer tuple. + */ + if (node->js.jointype == JOIN_SEMI) + node->hj_NeedNewOuter = true; + + if (otherqual == NIL || ExecQual(otherqual, econtext, false)) { - /* - * In a semijoin, we'll consider returning the first match, - * but after that we're done with this outer tuple. - */ - if (node->js.jointype == JOIN_SEMI) - node->hj_NeedNewOuter = true; - - if (otherqual == NIL || ExecQual(otherqual, econtext, false)) - { - TupleTableSlot *result; + TupleTableSlot *result; - result = ExecProject(node->js.ps.ps_ProjInfo, &isDone); + result = ExecProject(node->js.ps.ps_ProjInfo, &isDone); - if (isDone != ExprEndResult) - { - node->js.ps.ps_TupFromTlist = - (isDone == ExprMultipleResult); - return result; - } + if (isDone != ExprEndResult) + { + node->js.ps.ps_TupFromTlist = + (isDone == ExprMultipleResult); + return result; } - - /* - * If semijoin and we didn't return the tuple, we're still - * done with this outer tuple. - */ - if (node->js.jointype == JOIN_SEMI) - break; /* out of loop over hash bucket */ } + + /* + * If semijoin and we didn't return the tuple, we're still + * done with this outer tuple. + */ + if (node->js.jointype == JOIN_SEMI) + break; /* out of loop over hash bucket */ } } diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index e9deb5c8da7ca01e0ff8457ea2d7252545144797..d460349ad4505a36aec8df35dffed08788091062 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.92 2008/08/14 18:47:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.93 2008/08/15 19:20:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -757,15 +757,9 @@ ExecMergeJoin(MergeJoinState *node) innerTupleSlot = node->mj_InnerTupleSlot; econtext->ecxt_innertuple = innerTupleSlot; - if (node->js.jointype == JOIN_SEMI && - node->mj_MatchedOuter) - qualResult = false; - else - { - qualResult = (joinqual == NIL || - ExecQual(joinqual, econtext, false)); - MJ_DEBUG_QUAL(joinqual, qualResult); - } + qualResult = (joinqual == NIL || + ExecQual(joinqual, econtext, false)); + MJ_DEBUG_QUAL(joinqual, qualResult); if (qualResult) { @@ -774,7 +768,17 @@ ExecMergeJoin(MergeJoinState *node) /* In an antijoin, we never return a matched tuple */ if (node->js.jointype == JOIN_ANTI) + { + node->mj_JoinState = EXEC_MJ_NEXTOUTER; break; + } + + /* + * In a semijoin, we'll consider returning the first match, + * but after that we're done with this outer tuple. + */ + if (node->js.jointype == JOIN_SEMI) + node->mj_JoinState = EXEC_MJ_NEXTOUTER; qualResult = (otherqual == NIL || ExecQual(otherqual, econtext, false)); diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c index c6a33228582c24e138a7b2e534b3fa853fa29524..27e3582649ec7382e6d1466faab5f48b2b644c02 100644 --- a/src/backend/executor/nodeNestloop.c +++ b/src/backend/executor/nodeNestloop.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeNestloop.c,v 1.47 2008/08/14 18:47:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeNestloop.c,v 1.48 2008/08/15 19:20:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -226,35 +226,36 @@ ExecNestLoop(NestLoopState *node) /* In an antijoin, we never return a matched tuple */ if (node->js.jointype == JOIN_ANTI) + { node->nl_NeedNewOuter = true; - else + continue; /* return to top of loop */ + } + + /* + * In a semijoin, we'll consider returning the first match, + * but after that we're done with this outer tuple. + */ + if (node->js.jointype == JOIN_SEMI) + node->nl_NeedNewOuter = true; + + if (otherqual == NIL || ExecQual(otherqual, econtext, false)) { /* - * In a semijoin, we'll consider returning the first match, - * but after that we're done with this outer tuple. + * qualification was satisfied so we project and return the + * slot containing the result tuple using ExecProject(). */ - if (node->js.jointype == JOIN_SEMI) - node->nl_NeedNewOuter = true; - if (otherqual == NIL || ExecQual(otherqual, econtext, false)) - { - /* - * qualification was satisfied so we project and return - * the slot containing the result tuple using - * ExecProject(). - */ - TupleTableSlot *result; - ExprDoneCond isDone; + TupleTableSlot *result; + ExprDoneCond isDone; - ENL1_printf("qualification succeeded, projecting tuple"); + ENL1_printf("qualification succeeded, projecting tuple"); - result = ExecProject(node->js.ps.ps_ProjInfo, &isDone); + result = ExecProject(node->js.ps.ps_ProjInfo, &isDone); - if (isDone != ExprEndResult) - { - node->js.ps.ps_TupFromTlist = - (isDone == ExprMultipleResult); - return result; - } + if (isDone != ExprEndResult) + { + node->js.ps.ps_TupFromTlist = + (isDone == ExprMultipleResult); + return result; } } }