1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Allow internal sorts to be stored in memory rather than in files.

This commit is contained in:
Bruce Momjian
1997-08-06 03:42:21 +00:00
parent 3bea7b138b
commit f5f366e188
11 changed files with 633 additions and 516 deletions

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.5 1996/11/10 02:59:54 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.6 1997/08/06 03:41:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -374,6 +374,18 @@ ExecMergeTupleDump(ExprContext *econtext, MergeJoinState *mergestate)
printf("******** \n");
}
static void
CleanUpSort(Plan *plan) {
if (plan == NULL)
return;
if (plan->type == T_Sort) {
Sort *sort = (Sort *)plan;
psort_end(sort);
}
}
/* ----------------------------------------------------------------
* ExecMergeJoin
*
@ -676,6 +688,8 @@ ExecMergeJoin(MergeJoin *node)
*/
if (TupIsNull(outerTupleSlot)) {
MJ_printf("ExecMergeJoin: **** outer tuple is nil ****\n");
CleanUpSort(node->join.lefttree->lefttree);
CleanUpSort(node->join.righttree->lefttree);
return NULL;
}

View File

@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* nodeSort.c--
* Routines to handle sorting of relations into temporaries.
* Routines to handle sorting of relations.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.4 1996/11/08 05:56:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.5 1997/08/06 03:41:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -86,10 +86,9 @@ FormSortKeys(Sort *sortnode)
* ExecSort
*
* old comments
* Retrieves tuples fron the outer subtree and insert them into a
* temporary relation. The temporary relation is then sorted and
* the sorted relation is stored in the relation whose ID is indicated
* in the 'tempid' field of this node.
* Sorts tuples from the outer subtree of the node in psort,
* which saves the results in a temporary file or memory. After the
* initial call, returns a tuple from the file with each call.
* Assumes that heap access method is used.
*
* Conditions:
@ -108,13 +107,8 @@ ExecSort(Sort *node)
ScanDirection dir;
int keycount;
ScanKey sortkeys;
Relation tempRelation;
Relation currentRelation;
HeapScanDesc currentScanDesc;
HeapTuple heapTuple;
TupleTableSlot *slot;
Buffer buffer;
int tupCount = 0;
/* ----------------
* get state info from node
@ -128,10 +122,8 @@ ExecSort(Sort *node)
dir = estate->es_direction;
/* ----------------
* the first time we call this, we retrieve all tuples
* from the subplan into a temporary relation and then
* we sort the relation. Subsequent calls return tuples
* from the temporary relation.
* the first time we call this, psort sorts this into a file.
* Subsequent calls return tuples from psort.
* ----------------
*/
@ -144,78 +136,23 @@ ExecSort(Sort *node)
* ----------------
*/
estate->es_direction = ForwardScanDirection;
/* ----------------
* if we couldn't create the temp or current relations then
* we print a warning and return NULL.
* ----------------
*/
tempRelation = sortstate->sort_TempRelation;
if (tempRelation == NULL) {
elog(DEBUG, "ExecSort: temp relation is NULL! aborting...");
return NULL;
}
currentRelation = sortstate->csstate.css_currentRelation;
if (currentRelation == NULL) {
elog(DEBUG, "ExecSort: current relation is NULL! aborting...");
return NULL;
}
/* ----------------
* retrieve tuples from the subplan and
* insert them in the temporary relation
* prepare information for psort_begin()
* ----------------
*/
outerNode = outerPlan((Plan *) node);
SO1_printf("ExecSort: %s\n",
"inserting tuples into tempRelation");
for (;;) {
slot = ExecProcNode(outerNode, (Plan*)node);
if (TupIsNull(slot))
break;
tupCount++;
heapTuple = slot->val;
heap_insert(tempRelation, /* relation desc */
heapTuple); /* heap tuple to insert */
ExecClearTuple(slot);
}
/* ----------------
* now sort the tuples in our temporary relation
* into a new sorted relation using psort()
*
* psort() seems to require that the relations
* are created and opened in advance.
* -cim 1/25/90
* ----------------
*/
keycount = node->keycount;
sortkeys = (ScanKey)sortstate->sort_Keys;
SO1_printf("ExecSort: %s\n",
"calling psort");
/*
* If no tuples were fetched from the proc node return NULL now
* psort dumps it if 0 tuples are in the relation and I don't want
* to try to debug *that* routine!!
*/
if (tupCount == 0)
return NULL;
psort(tempRelation, /* old relation */
currentRelation, /* new relation */
keycount, /* number keys */
sortkeys); /* keys */
if (currentRelation == NULL) {
elog(DEBUG, "ExecSort: sorted relation is NULL! aborting...");
"calling psort_begin");
if (!psort_begin(node, /* this node */
keycount, /* number keys */
sortkeys)) /* keys */
{
/* Psort says, there are no tuples to be sorted */
return NULL;
}
@ -225,67 +162,56 @@ ExecSort(Sort *node)
*/
estate->es_direction = dir;
/* ----------------
* now initialize the scan descriptor to scan the
* sorted relation and update the sortstate information
* ----------------
*/
currentScanDesc = heap_beginscan(currentRelation, /* relation */
ScanDirectionIsBackward(dir),
/* bkwd flag */
NowTimeQual, /* time qual */
0, /* num scan keys */
NULL); /* scan keys */
sortstate->csstate.css_currentRelation = currentRelation;
sortstate->csstate.css_currentScanDesc = currentScanDesc;
/* ----------------
* make sure the tuple descriptor is up to date
* ----------------
*/
slot = sortstate->csstate.css_ScanTupleSlot;
slot->ttc_tupleDescriptor =
RelationGetTupleDescriptor(currentRelation);
slot = (TupleTableSlot*)sortstate->csstate.cstate.cs_ResultTupleSlot;
/* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
slot->ttc_tupleDescriptor = ExecGetTupType(outerNode);
#ifdef 0
slot->ttc_execTupDescriptor = ExecGetExecTupDesc(outerNode);
#endif
/* ----------------
* finally set the sorted flag to true
* ----------------
*/
sortstate->sort_Flag = true;
SO1_printf(stderr, "ExecSort: sorting done.\n");
}
else {
slot = sortstate->csstate.css_ScanTupleSlot;
slot = (TupleTableSlot*)sortstate->csstate.cstate.cs_ResultTupleSlot;
/* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
/* slot = sortstate->csstate.css_ScanTupleSlot; orig */
}
SO1_printf("ExecSort: %s\n",
"retrieveing tuple from sorted relation");
"retrieving tuple from sorted relation");
/* ----------------
* at this point we know we have a sorted relation so
* we preform a simple scan on it with amgetnext()..
* at this point we grab a tuple from psort
* ----------------
*/
currentScanDesc = sortstate->csstate.css_currentScanDesc;
heapTuple = heap_getnext(currentScanDesc, /* scan desc */
ScanDirectionIsBackward(dir),
/* bkwd flag */
&buffer); /* return: buffer */
/* Increase the pin count on the buffer page, because the tuple stored in
the slot also points to it (as well as the scan descriptor). If we
don't, ExecStoreTuple will decrease the pin count on the next iteration.
- 01/09/93 */
if (buffer != InvalidBuffer)
IncrBufferRefCount(buffer);
return ExecStoreTuple(heapTuple, /* tuple to store */
slot, /* slot to store in */
buffer, /* this tuple's buffer */
false); /* don't free stuff from amgetnext */
heapTuple = psort_grabtuple(node);
if (heapTuple == NULL) {
/* psort_end(node); */
return (ExecClearTuple(slot));
}
ExecStoreTuple(heapTuple, /* tuple to store */
slot, /* slot to store in */
InvalidBuffer, /* no buffer */
true); /* free the palloc'd tuple */
/* printf("ExecSort: (%x)",node);print_slot(slot);printf("\n");*/
return slot;
#if 0
return ExecStoreTuple(heapTuple, /* tuple to store */
slot, /* slot to store in */
InvalidBuffer, /* no buffer */
true); /* free the palloc'd tuple */
#endif
}
/* ----------------------------------------------------------------
@ -302,11 +228,6 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
SortState *sortstate;
Plan *outerPlan;
ScanKey sortkeys;
TupleDesc tupType;
Oid tempOid;
Oid sortOid;
Relation tempDesc;
Relation sortedDesc;
SO1_printf("ExecInitSort: %s\n",
"initializing sort node");
@ -324,7 +245,7 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
sortstate = makeNode(SortState);
sortstate->sort_Flag = 0;
sortstate->sort_Keys = NULL;
sortstate->sort_TempRelation = NULL;
node->cleaned = FALSE;
node->sortstate = sortstate;
@ -348,8 +269,8 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
* relation.
* ----------------
*/
ExecInitScanTupleSlot(estate, &sortstate->csstate);
ExecInitResultTupleSlot(estate, &sortstate->csstate.cstate);
ExecInitResultTupleSlot(estate, &sortstate->csstate.cstate);
ExecInitScanTupleSlot(estate, &sortstate->csstate);
/* ----------------
* initializes child nodes
@ -371,41 +292,10 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
* info because this node doesn't do projections.
* ----------------
*/
ExecAssignScanTypeFromOuterPlan((Plan *) node, &sortstate->csstate);
ExecAssignResultTypeFromOuterPlan((Plan *)node, &sortstate->csstate.cstate);
ExecAssignScanTypeFromOuterPlan((Plan *) node, &sortstate->csstate);
sortstate->csstate.cstate.cs_ProjInfo = NULL;
/* ----------------
* get type information needed for ExecCreatR
* ----------------
*/
tupType = ExecGetScanType(&sortstate->csstate);
/* ----------------
* ExecCreatR wants its second argument to be an object id of
* a relation in the range table or _TEMP_RELATION_ID_
* indicating that the relation is not in the range table.
*
* In the second case ExecCreatR creates a temp relation.
* (currently this is the only case we support -cim 10/16/89)
* ----------------
*/
tempOid = node->tempid;
sortOid = _TEMP_RELATION_ID_;
/* ----------------
* create the temporary relations
* ----------------
*/
/* len = ExecTargetListLength(node->plan.targetlist); */
tempDesc = ExecCreatR(tupType, tempOid);
sortedDesc = ExecCreatR(tupType, sortOid);
/* ----------------
* save the relation descriptor in the sortstate
* ----------------
*/
sortstate->sort_TempRelation = tempDesc;
sortstate->csstate.css_currentRelation = sortedDesc;
SO1_printf("ExecInitSort: %s\n",
"sort node initialized");
@ -429,15 +319,12 @@ ExecCountSlotsSort(Sort *node)
* ExecEndSort(node)
*
* old comments
* destroys the temporary relation.
* ----------------------------------------------------------------
*/
void
ExecEndSort(Sort *node)
{
SortState *sortstate;
Relation tempRelation;
Relation sortedRelation;
Plan *outerPlan;
/* ----------------
@ -448,18 +335,6 @@ ExecEndSort(Sort *node)
"shutting down sort node");
sortstate = node->sortstate;
tempRelation = sortstate->sort_TempRelation;
sortedRelation = sortstate->csstate.css_currentRelation;
heap_destroyr(tempRelation);
heap_destroyr(sortedRelation);
/* ----------------
* close the sorted relation and shut down the scan.
* ----------------
*/
ExecCloseR((Plan *) node);
/* ----------------
* shut down the subplan
@ -473,6 +348,9 @@ ExecEndSort(Sort *node)
* ----------------
*/
ExecClearTuple(sortstate->csstate.css_ScanTupleSlot);
/* Clean up after psort */
psort_end(node);
SO1_printf("ExecEndSort: %s\n",
"sort node shutdown");
@ -480,37 +358,39 @@ ExecEndSort(Sort *node)
/* ----------------------------------------------------------------
* ExecSortMarkPos
*
* Calls psort to save the current position in the sorted file.
* ----------------------------------------------------------------
*/
void
ExecSortMarkPos(Sort *node)
{
SortState *sortstate;
HeapScanDesc sdesc;
SortState *sortstate;
/* ----------------
* if we haven't sorted yet, just return
* if we haven't sorted yet, just return
* ----------------
*/
sortstate = node->sortstate;
if (sortstate->sort_Flag == false)
return;
sdesc = sortstate->csstate.css_currentScanDesc;
heap_markpos(sdesc);
psort_markpos(node);
return;
}
/* ----------------------------------------------------------------
* ExecSortRestrPos
*
* Calls psort to restore the last saved sort file position.
* ----------------------------------------------------------------
*/
void
ExecSortRestrPos(Sort *node)
{
SortState *sortstate;
HeapScanDesc sdesc;
SortState *sortstate;
/* ----------------
* if we haven't sorted yet, just return.
* ----------------
@ -520,9 +400,8 @@ ExecSortRestrPos(Sort *node)
return;
/* ----------------
* restore the scan to the previously marked position
* restore the scan to the previously marked position
* ----------------
*/
sdesc = sortstate->csstate.css_currentScanDesc;
heap_restrpos(sdesc);
psort_restorepos(node);
}