Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0a1e284

Browse files
committed
ExecReScan for MergeJoin.
Marked inner tuple now is copied into mergestate->mj_MarkedTupleSlot -no more tricks arround ttc_shouldfree.
1 parentb0571eb commit0a1e284

File tree

2 files changed

+75
-88
lines changed

2 files changed

+75
-88
lines changed

‎src/backend/executor/execAmi.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.19 1998/02/26 04:31:08 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.20 1998/02/27 16:11:26 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -44,6 +44,7 @@
4444
#include"executor/nodeAgg.h"
4545
#include"executor/nodeResult.h"
4646
#include"executor/nodeUnique.h"
47+
#include"executor/nodeMergejoin.h"
4748
#include"executor/nodeSubplan.h"
4849
#include"executor/execdebug.h"
4950
#include"optimizer/internal.h"/* for _TEMP_RELATION_ID_ */
@@ -366,6 +367,10 @@ ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
366367
ExecReScanSort((Sort*)node,exprCtxt,parent);
367368
break;
368369

370+
caseT_MergeJoin:
371+
ExecReScanMergeJoin((MergeJoin*)node,exprCtxt,parent);
372+
break;
373+
369374
/*
370375
* Tee is never used
371376
case T_Tee:

‎src/backend/executor/nodeMergejoin.c

Lines changed: 69 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.13 1998/02/26 04:31:30 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.14 1998/02/27 16:11:28 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -77,6 +77,7 @@
7777
*/
7878
#include"postgres.h"
7979

80+
#include"access/heapam.h"
8081
#include"executor/executor.h"
8182
#include"executor/execdefs.h"
8283
#include"executor/nodeMergejoin.h"
@@ -86,46 +87,14 @@
8687

8788
staticboolMergeCompare(List*eqQual,List*compareQual,ExprContext*econtext);
8889

89-
/* ----------------------------------------------------------------
90-
*MarkInnerTuple and RestoreInnerTuple macros
91-
*
92-
*when we "mark" a tuple, we place a pointer to it
93-
*in the marked tuple slot. now there are two pointers
94-
*to this tuple and we don't want it to be freed until
95-
*next time we mark a tuple, so we move the policy to
96-
*the marked tuple slot and set the inner tuple slot policy
97-
*to false.
98-
*
99-
*But, when we restore the inner tuple, the marked tuple
100-
*retains the policy. Basically once a tuple is marked, it
101-
*should only be freed when we mark another tuple. -cim 9/27/90
102-
*
103-
*Note: now that we store buffers in the tuple table,
104-
* we have to also increment buffer reference counts
105-
* correctly whenever we propagate an additional pointer
106-
* to a buffer item. Later, when ExecStoreTuple() is
107-
* called again on this slot, the refcnt is decremented
108-
* when the old tuple is replaced.
109-
* ----------------------------------------------------------------
110-
*/
11190
#defineMarkInnerTuple(innerTupleSlot,mergestate) \
11291
{ \
113-
bool shouldFree; \
114-
shouldFree = ExecSetSlotPolicy(innerTupleSlot, false); \
115-
ExecStoreTuple(innerTupleSlot->val, \
92+
ExecStoreTuple(heap_copytuple(innerTupleSlot->val), \
11693
mergestate->mj_MarkedTupleSlot, \
117-
innerTupleSlot->ttc_buffer, \
118-
shouldFree); \
119-
ExecIncrSlotBufferRefcnt(innerTupleSlot); \
94+
InvalidBuffer, \
95+
true); \
12096
}
12197

122-
#defineRestoreInnerTuple(innerTupleSlot,markedTupleSlot) \
123-
ExecStoreTuple(markedTupleSlot->val, \
124-
innerTupleSlot, \
125-
markedTupleSlot->ttc_buffer, \
126-
false); \
127-
ExecIncrSlotBufferRefcnt(innerTupleSlot)
128-
12998
/* ----------------------------------------------------------------
13099
*MJFormOSortopI
131100
*
@@ -467,8 +436,6 @@ ExecMergeJoin(MergeJoin *node)
467436
Plan*outerPlan;
468437
TupleTableSlot*outerTupleSlot;
469438

470-
TupleTableSlot*markedTupleSlot;
471-
472439
ExprContext*econtext;
473440

474441
/* ----------------
@@ -528,8 +495,8 @@ ExecMergeJoin(MergeJoin *node)
528495
* means that this is the first time ExecMergeJoin() has
529496
* been called and so we have to initialize the inner,
530497
* outer and marked tuples as well as various stuff in the
531-
* expression context. ********************************
532-
*
498+
* expression context.
499+
* ********************************
533500
*/
534501
caseEXEC_MJ_INITIALIZE:
535502
MJ_printf("ExecMergeJoin: EXEC_MJ_INITIALIZE\n");
@@ -560,19 +527,9 @@ ExecMergeJoin(MergeJoin *node)
560527
econtext->ecxt_innertuple=innerTupleSlot;
561528
econtext->ecxt_outertuple=outerTupleSlot;
562529

563-
/* ----------------
564-
* set the marked tuple to nil
565-
* and initialize its tuple descriptor atttributes.
566-
*-jeff 10 july 1991
567-
* ----------------
568-
*/
569-
ExecClearTuple(mergestate->mj_MarkedTupleSlot);
570530
mergestate->mj_MarkedTupleSlot->ttc_tupleDescriptor=
571531
innerTupleSlot->ttc_tupleDescriptor;
572-
/*
573-
mergestate->mj_MarkedTupleSlot->ttc_execTupDescriptor =
574-
innerTupleSlot->ttc_execTupDescriptor;
575-
*/
532+
576533
/* ----------------
577534
*initialize merge join state to skip inner tuples.
578535
* ----------------
@@ -584,15 +541,14 @@ ExecMergeJoin(MergeJoin *node)
584541
* ******************************** EXEC_MJ_JOINMARK means
585542
* we have just found a new outer tuple and a possible
586543
* matching inner tuple. This is the case after the
587-
* INITIALIZE, SKIPOUTER or SKIPINNER states.********************************
588-
*
544+
* INITIALIZE, SKIPOUTER or SKIPINNER states.
545+
* ********************************
589546
*/
590547
caseEXEC_MJ_JOINMARK:
591548
MJ_printf("ExecMergeJoin: EXEC_MJ_JOINMARK\n");
592549
ExecMarkPos(innerPlan);
593550

594-
innerTupleSlot=econtext->ecxt_innertuple;
595-
MarkInnerTuple(innerTupleSlot,mergestate);
551+
MarkInnerTuple(econtext->ecxt_innertuple,mergestate);
596552

597553
mergestate->mj_JoinState=EXEC_MJ_JOINTEST;
598554
break;
@@ -724,8 +680,8 @@ ExecMergeJoin(MergeJoin *node)
724680
break;
725681

726682
/*
727-
* ******************************** EXEC_MJ_TESTOUTERIf
728-
* the new outer tuple and the marked tuple satisify the
683+
* ******************************** EXEC_MJ_TESTOUTER
684+
*Ifthe new outer tuple and the marked tuple satisify the
729685
* merge clause then we know we have duplicates in the
730686
* outer scan so we have to restore the inner scan to the
731687
* marked tuple and proceed to join the new outer tuples
@@ -749,12 +705,7 @@ ExecMergeJoin(MergeJoin *node)
749705
*
750706
* new outer tuple > marked tuple
751707
*
752-
****************************
753-
*
754-
*
755-
*
756-
*
757-
*
708+
* ****************************
758709
*/
759710
caseEXEC_MJ_TESTOUTER:
760711
MJ_printf("ExecMergeJoin: EXEC_MJ_TESTOUTER\n");
@@ -765,29 +716,32 @@ ExecMergeJoin(MergeJoin *node)
765716
* ----------------
766717
*/
767718
innerTupleSlot=econtext->ecxt_innertuple;
768-
markedTupleSlot=mergestate->mj_MarkedTupleSlot;
769-
econtext->ecxt_innertuple=markedTupleSlot;
719+
econtext->ecxt_innertuple=mergestate->mj_MarkedTupleSlot;
770720

771721
qualResult=ExecQual((List*)mergeclauses,econtext);
772722
MJ_DEBUG_QUAL(mergeclauses,qualResult);
773723

774724
if (qualResult)
775725
{
776-
/*----------------
726+
/*
777727
*the merge clause matched so now we juggle the slots
778728
*back the way they were and proceed to JOINTEST.
779-
* ----------------
729+
*
730+
* I can't understand why we have to go to JOINTEST
731+
* and compare outer tuple with the same inner one
732+
* again -> go to JOINTUPLES...- vadim 02/27/98
780733
*/
781-
econtext->ecxt_innertuple=innerTupleSlot;
782-
783-
RestoreInnerTuple(innerTupleSlot,markedTupleSlot);
784734

785735
ExecRestrPos(innerPlan);
736+
#if0
786737
mergestate->mj_JoinState=EXEC_MJ_JOINTEST;
738+
#endif
739+
mergestate->mj_JoinState=EXEC_MJ_JOINTUPLES;
787740

788741
}
789742
else
790743
{
744+
econtext->ecxt_innertuple=innerTupleSlot;
791745
/* ----------------
792746
*if the inner tuple was nil and the new outer
793747
*tuple didn't match the marked outer tuple then
@@ -809,12 +763,7 @@ ExecMergeJoin(MergeJoin *node)
809763
returnNULL;
810764
}
811765

812-
/* ----------------
813-
*restore the inner tuple and continue on to
814-
*skip outer tuples.
815-
* ----------------
816-
*/
817-
econtext->ecxt_innertuple=innerTupleSlot;
766+
/*continue on to skip outer tuples */
818767
mergestate->mj_JoinState=EXEC_MJ_SKIPOUTER;
819768
}
820769
break;
@@ -853,9 +802,8 @@ ExecMergeJoin(MergeJoin *node)
853802
if (qualResult)
854803
{
855804
ExecMarkPos(innerPlan);
856-
innerTupleSlot=econtext->ecxt_innertuple;
857805

858-
MarkInnerTuple(innerTupleSlot,mergestate);
806+
MarkInnerTuple(econtext->ecxt_innertuple,mergestate);
859807

860808
mergestate->mj_JoinState=EXEC_MJ_JOINTUPLES;
861809
break;
@@ -958,9 +906,8 @@ ExecMergeJoin(MergeJoin *node)
958906
if (qualResult)
959907
{
960908
ExecMarkPos(innerPlan);
961-
innerTupleSlot=econtext->ecxt_innertuple;
962909

963-
MarkInnerTuple(innerTupleSlot,mergestate);
910+
MarkInnerTuple(econtext->ecxt_innertuple,mergestate);
964911

965912
mergestate->mj_JoinState=EXEC_MJ_JOINTUPLES;
966913
break;
@@ -1074,10 +1021,11 @@ bool
10741021
ExecInitMergeJoin(MergeJoin*node,EState*estate,Plan*parent)
10751022
{
10761023
MergeJoinState*mergestate;
1077-
List*joinclauses;
1078-
RegProcedurerightsortop;
1079-
RegProcedureleftsortop;
1080-
RegProceduresortop;
1024+
List*joinclauses;
1025+
RegProcedurerightsortop;
1026+
RegProcedureleftsortop;
1027+
RegProceduresortop;
1028+
TupleTableSlot*mjSlot;
10811029

10821030
List*OSortopI;
10831031
List*ISortopO;
@@ -1120,8 +1068,14 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, Plan *parent)
11201068
* ----------------
11211069
*/
11221070
ExecInitResultTupleSlot(estate,&mergestate->jstate);
1123-
ExecInitMarkedTupleSlot(estate,mergestate);
1124-
1071+
mjSlot= (TupleTableSlot*)palloc(sizeof(TupleTableSlot));
1072+
mjSlot->val=NULL;
1073+
mjSlot->ttc_shouldFree= true;
1074+
mjSlot->ttc_tupleDescriptor=NULL;
1075+
mjSlot->ttc_whichplan=-1;
1076+
mjSlot->ttc_descIsNew= true;
1077+
mergestate->mj_MarkedTupleSlot=mjSlot;
1078+
11251079
/* ----------------
11261080
*get merge sort operators.
11271081
*
@@ -1245,7 +1199,35 @@ ExecEndMergeJoin(MergeJoin *node)
12451199
*/
12461200
ExecClearTuple(mergestate->jstate.cs_ResultTupleSlot);
12471201
ExecClearTuple(mergestate->mj_MarkedTupleSlot);
1248-
1202+
pfree (mergestate->mj_MarkedTupleSlot);
1203+
mergestate->mj_MarkedTupleSlot=NULL;
1204+
12491205
MJ1_printf("ExecEndMergeJoin: %s\n",
12501206
"node processing ended");
12511207
}
1208+
1209+
void
1210+
ExecReScanMergeJoin(MergeJoin*node,ExprContext*exprCtxt,Plan*parent)
1211+
{
1212+
MergeJoinState*mergestate=node->mergestate;
1213+
TupleTableSlot*mjSlot=mergestate->mj_MarkedTupleSlot;
1214+
1215+
ExecClearTuple(mjSlot);
1216+
mjSlot->val=NULL;
1217+
mjSlot->ttc_shouldFree= true;
1218+
mjSlot->ttc_tupleDescriptor=NULL;
1219+
mjSlot->ttc_whichplan=-1;
1220+
mjSlot->ttc_descIsNew= true;
1221+
1222+
mergestate->mj_JoinState=EXEC_MJ_INITIALIZE;
1223+
1224+
/*
1225+
* if chgParam of subnodes is not null then plans will be re-scanned by
1226+
* first ExecProcNode.
1227+
*/
1228+
if (((Plan*)node)->lefttree->chgParam==NULL)
1229+
ExecReScan(((Plan*)node)->lefttree,exprCtxt, (Plan*)node);
1230+
if (((Plan*)node)->righttree->chgParam==NULL)
1231+
ExecReScan(((Plan*)node)->righttree,exprCtxt, (Plan*)node);
1232+
1233+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp