diff options
author | Bruce Momjian <bruce@momjian.us> | 1997-08-06 03:42:21 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1997-08-06 03:42:21 +0000 |
commit | f5f366e18829c982273540d88a1ac81c9c85d401 (patch) | |
tree | 347fc45caa2420d381e963d6b95bd6109085a163 /src/backend/executor/nodeSort.c | |
parent | 3bea7b138bbdf6129b36fbdab158526544262980 (diff) | |
download | postgresql-f5f366e18829c982273540d88a1ac81c9c85d401.tar.gz postgresql-f5f366e18829c982273540d88a1ac81c9c85d401.zip |
Allow internal sorts to be stored in memory rather than in files.
Diffstat (limited to 'src/backend/executor/nodeSort.c')
-rw-r--r-- | src/backend/executor/nodeSort.c | 261 |
1 files changed, 70 insertions, 191 deletions
diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c index 83d78073bb9..84c6db71f79 100644 --- a/src/backend/executor/nodeSort.c +++ b/src/backend/executor/nodeSort.c @@ -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; } @@ -226,66 +163,55 @@ 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); } |