#include "postgres.h"
#include "executor/execdebug.h"
#include "executor/nodeSort.h"
#include "miscadmin.h"
#include "utils/tuplesort.h"
Go to the source code of this file.
Functions | |
TupleTableSlot * | ExecSort (SortState *node) |
SortState * | ExecInitSort (Sort *node, EState *estate, int eflags) |
void | ExecEndSort (SortState *node) |
void | ExecSortMarkPos (SortState *node) |
void | ExecSortRestrPos (SortState *node) |
void | ExecReScanSort (SortState *node) |
void ExecEndSort | ( | SortState * | node | ) |
Definition at line 223 of file nodeSort.c.
References ExecClearTuple(), ExecEndNode(), NULL, outerPlanState, ScanState::ps, PlanState::ps_ResultTupleSlot, SO1_printf, SortState::ss, ScanState::ss_ScanTupleSlot, tuplesort_end(), and SortState::tuplesortstate.
Referenced by ExecEndNode().
{ SO1_printf("ExecEndSort: %s\n", "shutting down sort node"); /* * clean out the tuple table */ ExecClearTuple(node->ss.ss_ScanTupleSlot); /* must drop pointer to sort result tuple */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); /* * Release tuplesort resources */ if (node->tuplesortstate != NULL) tuplesort_end((Tuplesortstate *) node->tuplesortstate); node->tuplesortstate = NULL; /* * shut down the subplan */ ExecEndNode(outerPlanState(node)); SO1_printf("ExecEndSort: %s\n", "sort node shutdown"); }
Definition at line 152 of file nodeSort.c.
References SortState::bounded, EXEC_FLAG_BACKWARD, EXEC_FLAG_REWIND, ExecAssignResultTypeFromTL(), ExecAssignScanTypeFromOuterPlan(), ExecInitNode(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), makeNode, outerPlan, outerPlanState, PlanState::plan, ScanState::ps, PlanState::ps_ProjInfo, SortState::randomAccess, SO1_printf, SortState::sort_Done, SortState::ss, PlanState::state, and SortState::tuplesortstate.
Referenced by ExecInitNode().
{ SortState *sortstate; SO1_printf("ExecInitSort: %s\n", "initializing sort node"); /* * create state structure */ sortstate = makeNode(SortState); sortstate->ss.ps.plan = (Plan *) node; sortstate->ss.ps.state = estate; /* * We must have random access to the sort output to do backward scan or * mark/restore. We also prefer to materialize the sort output if we * might be called on to rewind and replay it many times. */ sortstate->randomAccess = (eflags & (EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)) != 0; sortstate->bounded = false; sortstate->sort_Done = false; sortstate->tuplesortstate = NULL; /* * Miscellaneous initialization * * Sort nodes don't initialize their ExprContexts because they never call * ExecQual or ExecProject. */ /* * tuple table initialization * * sort nodes only return scan tuples from their sorted relation. */ ExecInitResultTupleSlot(estate, &sortstate->ss.ps); ExecInitScanTupleSlot(estate, &sortstate->ss); /* * initialize child nodes * * We shield the child node from the need to support REWIND, BACKWARD, or * MARK/RESTORE. */ eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK); outerPlanState(sortstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * initialize tuple type. no need to initialize projection info because * this node doesn't do projections. */ ExecAssignResultTypeFromTL(&sortstate->ss.ps); ExecAssignScanTypeFromOuterPlan(&sortstate->ss); sortstate->ss.ps.ps_ProjInfo = NULL; SO1_printf("ExecInitSort: %s\n", "sort node initialized"); return sortstate; }
void ExecReScanSort | ( | SortState * | node | ) |
Definition at line 291 of file nodeSort.c.
References SortState::bound, SortState::bound_Done, SortState::bounded, SortState::bounded_Done, PlanState::chgParam, ExecClearTuple(), ExecReScan(), PlanState::lefttree, NULL, ScanState::ps, PlanState::ps_ResultTupleSlot, SortState::randomAccess, SortState::sort_Done, SortState::ss, tuplesort_end(), tuplesort_rescan(), and SortState::tuplesortstate.
Referenced by ExecReScan().
{ /* * If we haven't sorted yet, just return. If outerplan's chgParam is not * NULL then it will be re-scanned by ExecProcNode, else no reason to * re-scan it at all. */ if (!node->sort_Done) return; /* must drop pointer to sort result tuple */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); /* * If subnode is to be rescanned then we forget previous sort results; we * have to re-read the subplan and re-sort. Also must re-sort if the * bounded-sort parameters changed or we didn't select randomAccess. * * Otherwise we can just rewind and rescan the sorted output. */ if (node->ss.ps.lefttree->chgParam != NULL || node->bounded != node->bounded_Done || node->bound != node->bound_Done || !node->randomAccess) { node->sort_Done = false; tuplesort_end((Tuplesortstate *) node->tuplesortstate); node->tuplesortstate = NULL; /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ss.ps.lefttree->chgParam == NULL) ExecReScan(node->ss.ps.lefttree); } else tuplesort_rescan((Tuplesortstate *) node->tuplesortstate); }
TupleTableSlot* ExecSort | ( | SortState * | node | ) |
Definition at line 39 of file nodeSort.c.
References SortState::bound, SortState::bound_Done, SortState::bounded, SortState::bounded_Done, Sort::collations, EState::es_direction, ExecGetResultType(), ExecProcNode(), Sort::nullsFirst, Sort::numCols, outerPlanState, PlanState::plan, ScanState::ps, PlanState::ps_ResultTupleSlot, SortState::randomAccess, ScanDirectionIsForward, SO1_printf, SortState::sort_Done, Sort::sortColIdx, Sort::sortOperators, SortState::ss, PlanState::state, TupIsNull, tuplesort_begin_heap(), tuplesort_gettupleslot(), tuplesort_performsort(), tuplesort_puttupleslot(), tuplesort_set_bound(), SortState::tuplesortstate, and work_mem.
Referenced by ExecProcNode().
{ EState *estate; ScanDirection dir; Tuplesortstate *tuplesortstate; TupleTableSlot *slot; /* * get state info from node */ SO1_printf("ExecSort: %s\n", "entering routine"); estate = node->ss.ps.state; dir = estate->es_direction; tuplesortstate = (Tuplesortstate *) node->tuplesortstate; /* * If first time through, read all tuples from outer plan and pass them to * tuplesort.c. Subsequent calls just fetch tuples from tuplesort. */ if (!node->sort_Done) { Sort *plannode = (Sort *) node->ss.ps.plan; PlanState *outerNode; TupleDesc tupDesc; SO1_printf("ExecSort: %s\n", "sorting subplan"); /* * Want to scan subplan in the forward direction while creating the * sorted data. */ estate->es_direction = ForwardScanDirection; /* * Initialize tuplesort module. */ SO1_printf("ExecSort: %s\n", "calling tuplesort_begin"); outerNode = outerPlanState(node); tupDesc = ExecGetResultType(outerNode); tuplesortstate = tuplesort_begin_heap(tupDesc, plannode->numCols, plannode->sortColIdx, plannode->sortOperators, plannode->collations, plannode->nullsFirst, work_mem, node->randomAccess); if (node->bounded) tuplesort_set_bound(tuplesortstate, node->bound); node->tuplesortstate = (void *) tuplesortstate; /* * Scan the subplan and feed all the tuples to tuplesort. */ for (;;) { slot = ExecProcNode(outerNode); if (TupIsNull(slot)) break; tuplesort_puttupleslot(tuplesortstate, slot); } /* * Complete the sort. */ tuplesort_performsort(tuplesortstate); /* * restore to user specified direction */ estate->es_direction = dir; /* * finally set the sorted flag to true */ node->sort_Done = true; node->bounded_Done = node->bounded; node->bound_Done = node->bound; SO1_printf("ExecSort: %s\n", "sorting done"); } SO1_printf("ExecSort: %s\n", "retrieving tuple from tuplesort"); /* * Get the first or next tuple from tuplesort. Returns NULL if no more * tuples. */ slot = node->ss.ps.ps_ResultTupleSlot; (void) tuplesort_gettupleslot(tuplesortstate, ScanDirectionIsForward(dir), slot); return slot; }
void ExecSortMarkPos | ( | SortState * | node | ) |
Definition at line 258 of file nodeSort.c.
References SortState::sort_Done, tuplesort_markpos(), and SortState::tuplesortstate.
Referenced by ExecMarkPos().
{ /* * if we haven't sorted yet, just return */ if (!node->sort_Done) return; tuplesort_markpos((Tuplesortstate *) node->tuplesortstate); }
void ExecSortRestrPos | ( | SortState * | node | ) |
Definition at line 276 of file nodeSort.c.
References SortState::sort_Done, tuplesort_restorepos(), and SortState::tuplesortstate.
Referenced by ExecRestrPos().
{ /* * if we haven't sorted yet, just return. */ if (!node->sort_Done) return; /* * restore the scan to the previously marked position */ tuplesort_restorepos((Tuplesortstate *) node->tuplesortstate); }