nodeSort.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:10k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * nodeSort.c
  4.  *   Routines to handle sorting of relations.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.19 1999/06/03 03:17:37 tgl Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "postgres.h"
  15. #include <string.h>
  16. #include "executor/executor.h"
  17. #include "executor/execdebug.h"
  18. #include "executor/nodeSort.h"
  19. #include "access/heapam.h"
  20. #include "utils/palloc.h"
  21. #include "utils/psort.h"
  22. #include "catalog/catalog.h"
  23. #include "catalog/heap.h"
  24. #include "storage/bufmgr.h"
  25. #include "optimizer/internal.h" /* for _NONAME_RELATION_ID_ */
  26. /* ----------------------------------------------------------------
  27.  * FormSortKeys(node)
  28.  *
  29.  * Forms the structure containing information used to sort the relation.
  30.  *
  31.  * Returns an array of ScanKeyData.
  32.  * ----------------------------------------------------------------
  33.  */
  34. static ScanKey
  35. FormSortKeys(Sort *sortnode)
  36. {
  37. ScanKey sortkeys;
  38. List    *targetList;
  39. List    *tl;
  40. int keycount;
  41. Resdom    *resdom;
  42. AttrNumber resno;
  43. Index reskey;
  44. Oid reskeyop;
  45. /* ----------------
  46.  * get information from the node
  47.  * ----------------
  48.  */
  49. targetList = sortnode->plan.targetlist;
  50. keycount = sortnode->keycount;
  51. /* ----------------
  52.  * first allocate space for scan keys
  53.  * ----------------
  54.  */
  55. if (keycount <= 0)
  56. elog(ERROR, "FormSortKeys: keycount <= 0");
  57. sortkeys = (ScanKey) palloc(keycount * sizeof(ScanKeyData));
  58. MemSet((char *) sortkeys, 0, keycount * sizeof(ScanKeyData));
  59. /* ----------------
  60.  * form each scan key from the resdom info in the target list
  61.  * ----------------
  62.  */
  63. foreach(tl, targetList)
  64. {
  65. TargetEntry *target = (TargetEntry *) lfirst(tl);
  66. resdom = target->resdom;
  67. resno = resdom->resno;
  68. reskey = resdom->reskey;
  69. reskeyop = resdom->reskeyop;
  70. if (reskey > 0) /* ignore TLEs that are not sort keys */
  71. {
  72. ScanKeyEntryInitialize(&sortkeys[reskey - 1],
  73.    0,
  74.    resno,
  75.    (RegProcedure) DatumGetInt32(reskeyop),
  76.    (Datum) 0);
  77. }
  78. }
  79. return sortkeys;
  80. }
  81. /* ----------------------------------------------------------------
  82.  * ExecSort
  83.  *
  84.  * old comments
  85.  * Sorts tuples from the outer subtree of the node in psort,
  86.  * which saves the results in a temporary file or memory. After the
  87.  * initial call, returns a tuple from the file with each call.
  88.  * Assumes that heap access method is used.
  89.  *
  90.  * Conditions:
  91.  *   -- none.
  92.  *
  93.  * Initial States:
  94.  *   -- the outer child is prepared to return the first tuple.
  95.  * ----------------------------------------------------------------
  96.  */
  97. TupleTableSlot *
  98. ExecSort(Sort *node)
  99. {
  100. EState    *estate;
  101. SortState  *sortstate;
  102. Plan    *outerNode;
  103. ScanDirection dir;
  104. int keycount;
  105. ScanKey sortkeys;
  106. HeapTuple heapTuple;
  107. TupleTableSlot *slot;
  108. bool should_free;
  109. /* ----------------
  110.  * get state info from node
  111.  * ----------------
  112.  */
  113. SO1_printf("ExecSort: %sn",
  114.    "entering routine");
  115. sortstate = node->sortstate;
  116. estate = node->plan.state;
  117. dir = estate->es_direction;
  118. /* ----------------
  119.  * the first time we call this, psort sorts this into a file.
  120.  * Subsequent calls return tuples from psort.
  121.  * ----------------
  122.  */
  123. if (sortstate->sort_Flag == false)
  124. {
  125. SO1_printf("ExecSort: %sn",
  126.    "sortstate == false -> sorting subplan");
  127. /* ----------------
  128.  * set all relations to be scanned in the forward direction
  129.  * while creating the temporary relation.
  130.  * ----------------
  131.  */
  132. estate->es_direction = ForwardScanDirection;
  133. /* ----------------
  134.  *  prepare information for psort_begin()
  135.  * ----------------
  136.  */
  137. outerNode = outerPlan((Plan *) node);
  138. keycount = node->keycount;
  139. sortkeys = (ScanKey) sortstate->sort_Keys;
  140. SO1_printf("ExecSort: %sn",
  141.    "calling psort_begin");
  142. if (!psort_begin(node, /* this node */
  143.  keycount, /* number keys */
  144.  sortkeys)) /* keys */
  145. {
  146. /* Psort says, there are no tuples to be sorted */
  147. return NULL;
  148. }
  149. /* ----------------
  150.  *  restore to user specified direction
  151.  * ----------------
  152.  */
  153. estate->es_direction = dir;
  154. /* ----------------
  155.  * make sure the tuple descriptor is up to date
  156.  * ----------------
  157.  */
  158. slot = (TupleTableSlot *) sortstate->csstate.cstate.cs_ResultTupleSlot;
  159. slot->ttc_tupleDescriptor = ExecGetTupType(outerNode);
  160. /* ----------------
  161.  * finally set the sorted flag to true
  162.  * ----------------
  163.  */
  164. sortstate->sort_Flag = true;
  165. SO1_printf(stderr, "ExecSort: sorting done.n");
  166. }
  167. else
  168. slot = (TupleTableSlot *) sortstate->csstate.cstate.cs_ResultTupleSlot;
  169. SO1_printf("ExecSort: %sn",
  170.    "retrieving tuple from sorted relation");
  171. /* ----------------
  172.  * at this point we grab a tuple from psort
  173.  * ----------------
  174.  */
  175. heapTuple = psort_grabtuple(node, &should_free);
  176. return ExecStoreTuple(heapTuple, slot, InvalidBuffer, should_free);
  177. }
  178. /* ----------------------------------------------------------------
  179.  * ExecInitSort
  180.  *
  181.  * old comments
  182.  * Creates the run-time state information for the sort node
  183.  * produced by the planner and initailizes its outer subtree.
  184.  * ----------------------------------------------------------------
  185.  */
  186. bool
  187. ExecInitSort(Sort *node, EState *estate, Plan *parent)
  188. {
  189. SortState  *sortstate;
  190. Plan    *outerPlan;
  191. ScanKey sortkeys;
  192. SO1_printf("ExecInitSort: %sn",
  193.    "initializing sort node");
  194. /* ----------------
  195.  * assign the node's execution state
  196.  * ----------------
  197.  */
  198. node->plan.state = estate;
  199. /* ----------------
  200.  * create state structure
  201.  * ----------------
  202.  */
  203. sortstate = makeNode(SortState);
  204. sortstate->sort_Flag = 0;
  205. sortstate->sort_Keys = NULL;
  206. node->cleaned = FALSE;
  207. node->sortstate = sortstate;
  208. /* ----------------
  209.  * Miscellanious initialization
  210.  *
  211.  *  + assign node's base_id
  212.  *  + assign debugging hooks
  213.  *
  214.  * Sort nodes don't initialize their ExprContexts because
  215.  * they never call ExecQual or ExecTargetList.
  216.  * ----------------
  217.  */
  218. ExecAssignNodeBaseInfo(estate, &sortstate->csstate.cstate, parent);
  219. #define SORT_NSLOTS 1
  220. /* ----------------
  221.  * tuple table initialization
  222.  *
  223.  * sort nodes only return scan tuples from their sorted
  224.  * relation.
  225.  * ----------------
  226.  */
  227. ExecInitResultTupleSlot(estate, &sortstate->csstate.cstate);
  228. ExecInitScanTupleSlot(estate, &sortstate->csstate);
  229. /* ----------------
  230.  * initializes child nodes
  231.  * ----------------
  232.  */
  233. outerPlan = outerPlan((Plan *) node);
  234. ExecInitNode(outerPlan, estate, (Plan *) node);
  235. /* ----------------
  236.  * initialize sortstate information
  237.  * ----------------
  238.  */
  239. sortkeys = FormSortKeys(node);
  240. sortstate->sort_Keys = sortkeys;
  241. sortstate->sort_Flag = false;
  242. /* ----------------
  243.  * initialize tuple type. no need to initialize projection
  244.  * info because this node doesn't do projections.
  245.  * ----------------
  246.  */
  247. ExecAssignResultTypeFromOuterPlan((Plan *) node, &sortstate->csstate.cstate);
  248. ExecAssignScanTypeFromOuterPlan((Plan *) node, &sortstate->csstate);
  249. sortstate->csstate.cstate.cs_ProjInfo = NULL;
  250. SO1_printf("ExecInitSort: %sn",
  251.    "sort node initialized");
  252. /* ----------------
  253.  * return relation oid of temporary sort relation in a list
  254.  * (someday -- for now we return LispTrue... cim 10/12/89)
  255.  * ----------------
  256.  */
  257. return TRUE;
  258. }
  259. int
  260. ExecCountSlotsSort(Sort *node)
  261. {
  262. return ExecCountSlotsNode(outerPlan((Plan *) node)) +
  263. ExecCountSlotsNode(innerPlan((Plan *) node)) +
  264. SORT_NSLOTS;
  265. }
  266. /* ----------------------------------------------------------------
  267.  * ExecEndSort(node)
  268.  *
  269.  * old comments
  270.  * ----------------------------------------------------------------
  271.  */
  272. void
  273. ExecEndSort(Sort *node)
  274. {
  275. SortState  *sortstate;
  276. Plan    *outerPlan;
  277. /* ----------------
  278.  * get info from the sort state
  279.  * ----------------
  280.  */
  281. SO1_printf("ExecEndSort: %sn",
  282.    "shutting down sort node");
  283. sortstate = node->sortstate;
  284. /* ----------------
  285.  * shut down the subplan
  286.  * ----------------
  287.  */
  288. outerPlan = outerPlan((Plan *) node);
  289. ExecEndNode(outerPlan, (Plan *) node);
  290. /* ----------------
  291.  * clean out the tuple table
  292.  * ----------------
  293.  */
  294. ExecClearTuple(sortstate->csstate.css_ScanTupleSlot);
  295. /* Clean up after psort */
  296. psort_end(node);
  297. SO1_printf("ExecEndSort: %sn",
  298.    "sort node shutdown");
  299. }
  300. /* ----------------------------------------------------------------
  301.  * ExecSortMarkPos
  302.  *
  303.  * Calls psort to save the current position in the sorted file.
  304.  * ----------------------------------------------------------------
  305.  */
  306. void
  307. ExecSortMarkPos(Sort *node)
  308. {
  309. SortState  *sortstate;
  310. /* ----------------
  311.  * if we haven't sorted yet, just return
  312.  * ----------------
  313.  */
  314. sortstate = node->sortstate;
  315. if (sortstate->sort_Flag == false)
  316. return;
  317. psort_markpos(node);
  318. return;
  319. }
  320. /* ----------------------------------------------------------------
  321.  * ExecSortRestrPos
  322.  *
  323.  * Calls psort to restore the last saved sort file position.
  324.  * ----------------------------------------------------------------
  325.  */
  326. void
  327. ExecSortRestrPos(Sort *node)
  328. {
  329. SortState  *sortstate;
  330. /* ----------------
  331.  * if we haven't sorted yet, just return.
  332.  * ----------------
  333.  */
  334. sortstate = node->sortstate;
  335. if (sortstate->sort_Flag == false)
  336. return;
  337. /* ----------------
  338.  * restore the scan to the previously marked position
  339.  * ----------------
  340.  */
  341. psort_restorepos(node);
  342. }
  343. void
  344. ExecReScanSort(Sort *node, ExprContext *exprCtxt, Plan *parent)
  345. {
  346. SortState  *sortstate = node->sortstate;
  347. /*
  348.  * If we haven't sorted yet, just return. If outerplan' chgParam is
  349.  * not NULL then it will be re-scanned by ExecProcNode, else - no
  350.  * reason to re-scan it at all.
  351.  */
  352. if (sortstate->sort_Flag == false)
  353. return;
  354. ExecClearTuple(sortstate->csstate.cstate.cs_ResultTupleSlot);
  355. psort_rescan(node);
  356. /*
  357.  * If subnode is to be rescanned then we aren't sorted
  358.  */
  359. if (((Plan *) node)->lefttree->chgParam != NULL)
  360. sortstate->sort_Flag = false;
  361. }