aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeSort.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1997-08-06 03:42:21 +0000
committerBruce Momjian <bruce@momjian.us>1997-08-06 03:42:21 +0000
commitf5f366e18829c982273540d88a1ac81c9c85d401 (patch)
tree347fc45caa2420d381e963d6b95bd6109085a163 /src/backend/executor/nodeSort.c
parent3bea7b138bbdf6129b36fbdab158526544262980 (diff)
downloadpostgresql-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.c261
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);
}