mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Minor refactoring to eliminate duplicate code and make startup a
tad faster.
This commit is contained in:
parent
05b4293bd8
commit
fabef3044a
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.72 2005/05/13 21:20:16 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.73 2005/05/14 21:29:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -525,6 +525,86 @@ MJCompare(MergeJoinState *mergestate)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate a fake join tuple with nulls for the inner tuple,
|
||||||
|
* and return it if it passes the non-join quals.
|
||||||
|
*/
|
||||||
|
static TupleTableSlot *
|
||||||
|
MJFillOuter(MergeJoinState *node)
|
||||||
|
{
|
||||||
|
ExprContext *econtext = node->js.ps.ps_ExprContext;
|
||||||
|
List *otherqual = node->js.ps.qual;
|
||||||
|
|
||||||
|
ResetExprContext(econtext);
|
||||||
|
|
||||||
|
econtext->ecxt_outertuple = node->mj_OuterTupleSlot;
|
||||||
|
econtext->ecxt_innertuple = node->mj_NullInnerTupleSlot;
|
||||||
|
|
||||||
|
if (ExecQual(otherqual, econtext, false))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* qualification succeeded. now form the desired projection tuple
|
||||||
|
* and return the slot containing it.
|
||||||
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
ExprDoneCond isDone;
|
||||||
|
|
||||||
|
MJ_printf("ExecMergeJoin: returning outer fill tuple\n");
|
||||||
|
|
||||||
|
result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
|
||||||
|
|
||||||
|
if (isDone != ExprEndResult)
|
||||||
|
{
|
||||||
|
node->js.ps.ps_TupFromTlist =
|
||||||
|
(isDone == ExprMultipleResult);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate a fake join tuple with nulls for the outer tuple,
|
||||||
|
* and return it if it passes the non-join quals.
|
||||||
|
*/
|
||||||
|
static TupleTableSlot *
|
||||||
|
MJFillInner(MergeJoinState *node)
|
||||||
|
{
|
||||||
|
ExprContext *econtext = node->js.ps.ps_ExprContext;
|
||||||
|
List *otherqual = node->js.ps.qual;
|
||||||
|
|
||||||
|
ResetExprContext(econtext);
|
||||||
|
|
||||||
|
econtext->ecxt_outertuple = node->mj_NullOuterTupleSlot;
|
||||||
|
econtext->ecxt_innertuple = node->mj_InnerTupleSlot;
|
||||||
|
|
||||||
|
if (ExecQual(otherqual, econtext, false))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* qualification succeeded. now form the desired projection tuple
|
||||||
|
* and return the slot containing it.
|
||||||
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
ExprDoneCond isDone;
|
||||||
|
|
||||||
|
MJ_printf("ExecMergeJoin: returning inner fill tuple\n");
|
||||||
|
|
||||||
|
result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
|
||||||
|
|
||||||
|
if (isDone != ExprEndResult)
|
||||||
|
{
|
||||||
|
node->js.ps.ps_TupFromTlist =
|
||||||
|
(isDone == ExprMultipleResult);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* ExecMergeTupleDump
|
* ExecMergeTupleDump
|
||||||
*
|
*
|
||||||
@ -612,33 +692,8 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
econtext = node->js.ps.ps_ExprContext;
|
econtext = node->js.ps.ps_ExprContext;
|
||||||
joinqual = node->js.joinqual;
|
joinqual = node->js.joinqual;
|
||||||
otherqual = node->js.ps.qual;
|
otherqual = node->js.ps.qual;
|
||||||
|
doFillOuter = node->mj_FillOuter;
|
||||||
switch (node->js.jointype)
|
doFillInner = node->mj_FillInner;
|
||||||
{
|
|
||||||
case JOIN_INNER:
|
|
||||||
case JOIN_IN:
|
|
||||||
doFillOuter = false;
|
|
||||||
doFillInner = false;
|
|
||||||
break;
|
|
||||||
case JOIN_LEFT:
|
|
||||||
doFillOuter = true;
|
|
||||||
doFillInner = false;
|
|
||||||
break;
|
|
||||||
case JOIN_FULL:
|
|
||||||
doFillOuter = true;
|
|
||||||
doFillInner = true;
|
|
||||||
break;
|
|
||||||
case JOIN_RIGHT:
|
|
||||||
doFillOuter = false;
|
|
||||||
doFillInner = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "unrecognized join type: %d",
|
|
||||||
(int) node->js.jointype);
|
|
||||||
doFillOuter = false; /* keep compiler quiet */
|
|
||||||
doFillInner = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if we're still projecting out tuples from a previous
|
* Check to see if we're still projecting out tuples from a previous
|
||||||
@ -707,16 +762,28 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute join values and check for unmatchability */
|
/* Compute join values and check for unmatchability */
|
||||||
if (!MJEvalOuterValues(node) && !doFillOuter)
|
if (MJEvalOuterValues(node))
|
||||||
{
|
|
||||||
/* Stay in same state to fetch next outer tuple */
|
|
||||||
node->mj_JoinState = EXEC_MJ_INITIALIZE_OUTER;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* OK to go get the first inner tuple */
|
/* OK to go get the first inner tuple */
|
||||||
node->mj_JoinState = EXEC_MJ_INITIALIZE_INNER;
|
node->mj_JoinState = EXEC_MJ_INITIALIZE_INNER;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Stay in same state to fetch next outer tuple */
|
||||||
|
if (doFillOuter)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Generate a fake join tuple with nulls for the inner
|
||||||
|
* tuple, and return it if it passes the non-join
|
||||||
|
* quals.
|
||||||
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
|
result = MJFillOuter(node);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXEC_MJ_INITIALIZE_INNER:
|
case EXEC_MJ_INITIALIZE_INNER:
|
||||||
@ -745,12 +812,7 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute join values and check for unmatchability */
|
/* Compute join values and check for unmatchability */
|
||||||
if (!MJEvalInnerValues(node, innerTupleSlot) && !doFillInner)
|
if (MJEvalInnerValues(node, innerTupleSlot))
|
||||||
{
|
|
||||||
/* Stay in same state to fetch next inner tuple */
|
|
||||||
node->mj_JoinState = EXEC_MJ_INITIALIZE_INNER;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* OK, we have the initial tuples. Begin by skipping
|
* OK, we have the initial tuples. Begin by skipping
|
||||||
@ -758,6 +820,23 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
*/
|
*/
|
||||||
node->mj_JoinState = EXEC_MJ_SKIP_TEST;
|
node->mj_JoinState = EXEC_MJ_SKIP_TEST;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Stay in same state to fetch next inner tuple */
|
||||||
|
if (doFillInner)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Generate a fake join tuple with nulls for the outer
|
||||||
|
* tuple, and return it if it passes the non-join
|
||||||
|
* quals.
|
||||||
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
|
result = MJFillInner(node);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -856,38 +935,14 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
* tuple, and return it if it passes the non-join
|
* tuple, and return it if it passes the non-join
|
||||||
* quals.
|
* quals.
|
||||||
*/
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
node->mj_MatchedInner = true; /* do it only once */
|
node->mj_MatchedInner = true; /* do it only once */
|
||||||
|
|
||||||
ResetExprContext(econtext);
|
result = MJFillInner(node);
|
||||||
|
if (result)
|
||||||
outerTupleSlot = node->mj_NullOuterTupleSlot;
|
|
||||||
econtext->ecxt_outertuple = outerTupleSlot;
|
|
||||||
innerTupleSlot = node->mj_InnerTupleSlot;
|
|
||||||
econtext->ecxt_innertuple = innerTupleSlot;
|
|
||||||
|
|
||||||
if (ExecQual(otherqual, econtext, false))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* qualification succeeded. now form the desired
|
|
||||||
* projection tuple and return the slot containing
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
TupleTableSlot *result;
|
|
||||||
ExprDoneCond isDone;
|
|
||||||
|
|
||||||
MJ_printf("ExecMergeJoin: returning fill tuple\n");
|
|
||||||
|
|
||||||
result = ExecProject(node->js.ps.ps_ProjInfo,
|
|
||||||
&isDone);
|
|
||||||
|
|
||||||
if (isDone != ExprEndResult)
|
|
||||||
{
|
|
||||||
node->js.ps.ps_TupFromTlist =
|
|
||||||
(isDone == ExprMultipleResult);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we get the next inner tuple, if any. If there's
|
* now we get the next inner tuple, if any. If there's
|
||||||
@ -961,38 +1016,14 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
* tuple, and return it if it passes the non-join
|
* tuple, and return it if it passes the non-join
|
||||||
* quals.
|
* quals.
|
||||||
*/
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
node->mj_MatchedOuter = true; /* do it only once */
|
node->mj_MatchedOuter = true; /* do it only once */
|
||||||
|
|
||||||
ResetExprContext(econtext);
|
result = MJFillOuter(node);
|
||||||
|
if (result)
|
||||||
outerTupleSlot = node->mj_OuterTupleSlot;
|
|
||||||
econtext->ecxt_outertuple = outerTupleSlot;
|
|
||||||
innerTupleSlot = node->mj_NullInnerTupleSlot;
|
|
||||||
econtext->ecxt_innertuple = innerTupleSlot;
|
|
||||||
|
|
||||||
if (ExecQual(otherqual, econtext, false))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* qualification succeeded. now form the desired
|
|
||||||
* projection tuple and return the slot containing
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
TupleTableSlot *result;
|
|
||||||
ExprDoneCond isDone;
|
|
||||||
|
|
||||||
MJ_printf("ExecMergeJoin: returning fill tuple\n");
|
|
||||||
|
|
||||||
result = ExecProject(node->js.ps.ps_ProjInfo,
|
|
||||||
&isDone);
|
|
||||||
|
|
||||||
if (isDone != ExprEndResult)
|
|
||||||
{
|
|
||||||
node->js.ps.ps_TupFromTlist =
|
|
||||||
(isDone == ExprMultipleResult);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we get the next outer tuple, if any
|
* now we get the next outer tuple, if any
|
||||||
@ -1223,38 +1254,14 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
* tuple, and return it if it passes the non-join
|
* tuple, and return it if it passes the non-join
|
||||||
* quals.
|
* quals.
|
||||||
*/
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
node->mj_MatchedOuter = true; /* do it only once */
|
node->mj_MatchedOuter = true; /* do it only once */
|
||||||
|
|
||||||
ResetExprContext(econtext);
|
result = MJFillOuter(node);
|
||||||
|
if (result)
|
||||||
outerTupleSlot = node->mj_OuterTupleSlot;
|
|
||||||
econtext->ecxt_outertuple = outerTupleSlot;
|
|
||||||
innerTupleSlot = node->mj_NullInnerTupleSlot;
|
|
||||||
econtext->ecxt_innertuple = innerTupleSlot;
|
|
||||||
|
|
||||||
if (ExecQual(otherqual, econtext, false))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* qualification succeeded. now form the desired
|
|
||||||
* projection tuple and return the slot containing
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
TupleTableSlot *result;
|
|
||||||
ExprDoneCond isDone;
|
|
||||||
|
|
||||||
MJ_printf("ExecMergeJoin: returning fill tuple\n");
|
|
||||||
|
|
||||||
result = ExecProject(node->js.ps.ps_ProjInfo,
|
|
||||||
&isDone);
|
|
||||||
|
|
||||||
if (isDone != ExprEndResult)
|
|
||||||
{
|
|
||||||
node->js.ps.ps_TupFromTlist =
|
|
||||||
(isDone == ExprMultipleResult);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we get the next outer tuple, if any
|
* now we get the next outer tuple, if any
|
||||||
@ -1311,38 +1318,14 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
* tuple, and return it if it passes the non-join
|
* tuple, and return it if it passes the non-join
|
||||||
* quals.
|
* quals.
|
||||||
*/
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
node->mj_MatchedInner = true; /* do it only once */
|
node->mj_MatchedInner = true; /* do it only once */
|
||||||
|
|
||||||
ResetExprContext(econtext);
|
result = MJFillInner(node);
|
||||||
|
if (result)
|
||||||
outerTupleSlot = node->mj_NullOuterTupleSlot;
|
|
||||||
econtext->ecxt_outertuple = outerTupleSlot;
|
|
||||||
innerTupleSlot = node->mj_InnerTupleSlot;
|
|
||||||
econtext->ecxt_innertuple = innerTupleSlot;
|
|
||||||
|
|
||||||
if (ExecQual(otherqual, econtext, false))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* qualification succeeded. now form the desired
|
|
||||||
* projection tuple and return the slot containing
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
TupleTableSlot *result;
|
|
||||||
ExprDoneCond isDone;
|
|
||||||
|
|
||||||
MJ_printf("ExecMergeJoin: returning fill tuple\n");
|
|
||||||
|
|
||||||
result = ExecProject(node->js.ps.ps_ProjInfo,
|
|
||||||
&isDone);
|
|
||||||
|
|
||||||
if (isDone != ExprEndResult)
|
|
||||||
{
|
|
||||||
node->js.ps.ps_TupFromTlist =
|
|
||||||
(isDone == ExprMultipleResult);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we get the next inner tuple, if any
|
* now we get the next inner tuple, if any
|
||||||
@ -1402,38 +1385,14 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
* tuple, and return it if it passes the non-join
|
* tuple, and return it if it passes the non-join
|
||||||
* quals.
|
* quals.
|
||||||
*/
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
node->mj_MatchedInner = true; /* do it only once */
|
node->mj_MatchedInner = true; /* do it only once */
|
||||||
|
|
||||||
ResetExprContext(econtext);
|
result = MJFillInner(node);
|
||||||
|
if (result)
|
||||||
outerTupleSlot = node->mj_NullOuterTupleSlot;
|
|
||||||
econtext->ecxt_outertuple = outerTupleSlot;
|
|
||||||
innerTupleSlot = node->mj_InnerTupleSlot;
|
|
||||||
econtext->ecxt_innertuple = innerTupleSlot;
|
|
||||||
|
|
||||||
if (ExecQual(otherqual, econtext, false))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* qualification succeeded. now form the desired
|
|
||||||
* projection tuple and return the slot containing
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
TupleTableSlot *result;
|
|
||||||
ExprDoneCond isDone;
|
|
||||||
|
|
||||||
MJ_printf("ExecMergeJoin: returning fill tuple\n");
|
|
||||||
|
|
||||||
result = ExecProject(node->js.ps.ps_ProjInfo,
|
|
||||||
&isDone);
|
|
||||||
|
|
||||||
if (isDone != ExprEndResult)
|
|
||||||
{
|
|
||||||
node->js.ps.ps_TupFromTlist =
|
|
||||||
(isDone == ExprMultipleResult);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we get the next inner tuple, if any
|
* now we get the next inner tuple, if any
|
||||||
@ -1469,38 +1428,14 @@ ExecMergeJoin(MergeJoinState *node)
|
|||||||
* tuple, and return it if it passes the non-join
|
* tuple, and return it if it passes the non-join
|
||||||
* quals.
|
* quals.
|
||||||
*/
|
*/
|
||||||
|
TupleTableSlot *result;
|
||||||
|
|
||||||
node->mj_MatchedOuter = true; /* do it only once */
|
node->mj_MatchedOuter = true; /* do it only once */
|
||||||
|
|
||||||
ResetExprContext(econtext);
|
result = MJFillOuter(node);
|
||||||
|
if (result)
|
||||||
outerTupleSlot = node->mj_OuterTupleSlot;
|
|
||||||
econtext->ecxt_outertuple = outerTupleSlot;
|
|
||||||
innerTupleSlot = node->mj_NullInnerTupleSlot;
|
|
||||||
econtext->ecxt_innertuple = innerTupleSlot;
|
|
||||||
|
|
||||||
if (ExecQual(otherqual, econtext, false))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* qualification succeeded. now form the desired
|
|
||||||
* projection tuple and return the slot containing
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
TupleTableSlot *result;
|
|
||||||
ExprDoneCond isDone;
|
|
||||||
|
|
||||||
MJ_printf("ExecMergeJoin: returning fill tuple\n");
|
|
||||||
|
|
||||||
result = ExecProject(node->js.ps.ps_ProjInfo,
|
|
||||||
&isDone);
|
|
||||||
|
|
||||||
if (isDone != ExprEndResult)
|
|
||||||
{
|
|
||||||
node->js.ps.ps_TupFromTlist =
|
|
||||||
(isDone == ExprMultipleResult);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now we get the next outer tuple, if any
|
* now we get the next outer tuple, if any
|
||||||
@ -1601,13 +1536,19 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
|
|||||||
{
|
{
|
||||||
case JOIN_INNER:
|
case JOIN_INNER:
|
||||||
case JOIN_IN:
|
case JOIN_IN:
|
||||||
|
mergestate->mj_FillOuter = false;
|
||||||
|
mergestate->mj_FillInner = false;
|
||||||
break;
|
break;
|
||||||
case JOIN_LEFT:
|
case JOIN_LEFT:
|
||||||
|
mergestate->mj_FillOuter = true;
|
||||||
|
mergestate->mj_FillInner = false;
|
||||||
mergestate->mj_NullInnerTupleSlot =
|
mergestate->mj_NullInnerTupleSlot =
|
||||||
ExecInitNullTupleSlot(estate,
|
ExecInitNullTupleSlot(estate,
|
||||||
ExecGetResultType(innerPlanState(mergestate)));
|
ExecGetResultType(innerPlanState(mergestate)));
|
||||||
break;
|
break;
|
||||||
case JOIN_RIGHT:
|
case JOIN_RIGHT:
|
||||||
|
mergestate->mj_FillOuter = false;
|
||||||
|
mergestate->mj_FillInner = true;
|
||||||
mergestate->mj_NullOuterTupleSlot =
|
mergestate->mj_NullOuterTupleSlot =
|
||||||
ExecInitNullTupleSlot(estate,
|
ExecInitNullTupleSlot(estate,
|
||||||
ExecGetResultType(outerPlanState(mergestate)));
|
ExecGetResultType(outerPlanState(mergestate)));
|
||||||
@ -1622,6 +1563,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
|
|||||||
errmsg("RIGHT JOIN is only supported with merge-joinable join conditions")));
|
errmsg("RIGHT JOIN is only supported with merge-joinable join conditions")));
|
||||||
break;
|
break;
|
||||||
case JOIN_FULL:
|
case JOIN_FULL:
|
||||||
|
mergestate->mj_FillOuter = true;
|
||||||
|
mergestate->mj_FillInner = true;
|
||||||
mergestate->mj_NullOuterTupleSlot =
|
mergestate->mj_NullOuterTupleSlot =
|
||||||
ExecInitNullTupleSlot(estate,
|
ExecInitNullTupleSlot(estate,
|
||||||
ExecGetResultType(outerPlanState(mergestate)));
|
ExecGetResultType(outerPlanState(mergestate)));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.132 2005/05/13 21:20:16 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.133 2005/05/14 21:29:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1031,6 +1031,8 @@ typedef struct NestLoopState
|
|||||||
* NumClauses number of mergejoinable join clauses
|
* NumClauses number of mergejoinable join clauses
|
||||||
* Clauses info for each mergejoinable clause
|
* Clauses info for each mergejoinable clause
|
||||||
* JoinState current "state" of join. see execdefs.h
|
* JoinState current "state" of join. see execdefs.h
|
||||||
|
* FillOuter true if should emit unjoined outer tuples anyway
|
||||||
|
* FillInner true if should emit unjoined inner tuples anyway
|
||||||
* MatchedOuter true if found a join match for current outer tuple
|
* MatchedOuter true if found a join match for current outer tuple
|
||||||
* MatchedInner true if found a join match for current inner tuple
|
* MatchedInner true if found a join match for current inner tuple
|
||||||
* OuterTupleSlot slot in tuple table for cur outer tuple
|
* OuterTupleSlot slot in tuple table for cur outer tuple
|
||||||
@ -1051,6 +1053,8 @@ typedef struct MergeJoinState
|
|||||||
int mj_NumClauses;
|
int mj_NumClauses;
|
||||||
MergeJoinClause mj_Clauses; /* array of length mj_NumClauses */
|
MergeJoinClause mj_Clauses; /* array of length mj_NumClauses */
|
||||||
int mj_JoinState;
|
int mj_JoinState;
|
||||||
|
bool mj_FillOuter;
|
||||||
|
bool mj_FillInner;
|
||||||
bool mj_MatchedOuter;
|
bool mj_MatchedOuter;
|
||||||
bool mj_MatchedInner;
|
bool mj_MatchedInner;
|
||||||
TupleTableSlot *mj_OuterTupleSlot;
|
TupleTableSlot *mj_OuterTupleSlot;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user