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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * nodeMaterial.c
  4.  *   Routines to handle materialization nodes.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.22 1999/05/25 16:08:44 momjian Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. /*
  15.  * INTERFACE ROUTINES
  16.  * ExecMaterial - generate a temporary relation
  17.  * ExecInitMaterial - initialize node and subnodes..
  18.  * ExecEndMaterial - shutdown node and subnodes
  19.  *
  20.  */
  21. #include "postgres.h"
  22. #include "executor/executor.h"
  23. #include "executor/nodeMaterial.h"
  24. #include "catalog/catalog.h"
  25. #include "catalog/heap.h"
  26. #include "optimizer/internal.h" /* for _NONAME_RELATION_ID_ */
  27. #include "access/heapam.h"
  28. /* ----------------------------------------------------------------
  29.  * ExecMaterial
  30.  *
  31.  * The first time this is called, ExecMaterial retrieves tuples
  32.  * this node's outer subplan and inserts them into a temporary
  33.  * relation.  After this is done, a flag is set indicating that
  34.  * the subplan has been materialized. Once the relation is
  35.  * materialized, the first tuple is then returned.  Successive
  36.  * calls to ExecMaterial return successive tuples from the temp
  37.  * relation.
  38.  *
  39.  * Initial State:
  40.  *
  41.  * ExecMaterial assumes the temporary relation has been
  42.  * created and openend by ExecInitMaterial during the prior
  43.  * InitPlan() phase.
  44.  *
  45.  * ----------------------------------------------------------------
  46.  */
  47. TupleTableSlot * /* result tuple from subplan */
  48. ExecMaterial(Material *node)
  49. {
  50. EState    *estate;
  51. MaterialState *matstate;
  52. Plan    *outerNode;
  53. ScanDirection dir;
  54. Relation tempRelation;
  55. Relation currentRelation;
  56. HeapScanDesc currentScanDesc;
  57. HeapTuple heapTuple;
  58. TupleTableSlot *slot;
  59. /* ----------------
  60.  * get state info from node
  61.  * ----------------
  62.  */
  63. matstate = node->matstate;
  64. estate = node->plan.state;
  65. dir = estate->es_direction;
  66. /* ----------------
  67.  * the first time we call this, we retrieve all tuples
  68.  * from the subplan into a temporary relation and then
  69.  * we sort the relation.  Subsequent calls return tuples
  70.  * from the temporary relation.
  71.  * ----------------
  72.  */
  73. if (matstate->mat_Flag == false)
  74. {
  75. /* ----------------
  76.  * set all relations to be scanned in the forward direction
  77.  * while creating the temporary relation.
  78.  * ----------------
  79.  */
  80. estate->es_direction = ForwardScanDirection;
  81. /* ----------------
  82.  *  if we couldn't create the temp or current relations then
  83.  *  we print a warning and return NULL.
  84.  * ----------------
  85.  */
  86. tempRelation = matstate->mat_TempRelation;
  87. if (tempRelation == NULL)
  88. {
  89. elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
  90. return NULL;
  91. }
  92. currentRelation = matstate->csstate.css_currentRelation;
  93. if (currentRelation == NULL)
  94. {
  95. elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
  96. return NULL;
  97. }
  98. /* ----------------
  99.  *  retrieve tuples from the subplan and
  100.  *  insert them in the temporary relation
  101.  * ----------------
  102.  */
  103. outerNode = outerPlan((Plan *) node);
  104. for (;;)
  105. {
  106. slot = ExecProcNode(outerNode, (Plan *) node);
  107. if (TupIsNull(slot))
  108. break;
  109. /*
  110.  * heap_insert changes something...
  111.  */
  112. if (slot->ttc_buffer != InvalidBuffer)
  113. heapTuple = heap_copytuple(slot->val);
  114. else
  115. heapTuple = slot->val;
  116. heap_insert(tempRelation, heapTuple);
  117. if (slot->ttc_buffer != InvalidBuffer)
  118. pfree(heapTuple);
  119. ExecClearTuple(slot);
  120. }
  121. currentRelation = tempRelation;
  122. /* ----------------
  123.  *  restore to user specified direction
  124.  * ----------------
  125.  */
  126. estate->es_direction = dir;
  127. /* ----------------
  128.  *  now initialize the scan descriptor to scan the
  129.  *  sorted relation and update the sortstate information
  130.  * ----------------
  131.  */
  132. currentScanDesc = heap_beginscan(currentRelation, /* relation */
  133.  ScanDirectionIsBackward(dir),
  134.  SnapshotSelf, /* seeself */
  135.  0, /* num scan keys */
  136.  NULL); /* scan keys */
  137. matstate->csstate.css_currentRelation = currentRelation;
  138. matstate->csstate.css_currentScanDesc = currentScanDesc;
  139. ExecAssignScanType(&matstate->csstate,
  140.    RelationGetDescr(currentRelation));
  141. /* ----------------
  142.  * finally set the sorted flag to true
  143.  * ----------------
  144.  */
  145. matstate->mat_Flag = true;
  146. }
  147. /* ----------------
  148.  * at this point we know we have a sorted relation so
  149.  * we preform a simple scan on it with amgetnext()..
  150.  * ----------------
  151.  */
  152. currentScanDesc = matstate->csstate.css_currentScanDesc;
  153. heapTuple = heap_getnext(currentScanDesc, ScanDirectionIsBackward(dir));
  154. /* ----------------
  155.  * put the tuple into the scan tuple slot and return the slot.
  156.  * Note: since the tuple is really a pointer to a page, we don't want
  157.  * to call pfree() on it..
  158.  * ----------------
  159.  */
  160. slot = (TupleTableSlot *) matstate->csstate.css_ScanTupleSlot;
  161. return ExecStoreTuple(heapTuple, /* tuple to store */
  162.   slot, /* slot to store in */
  163.   currentScanDesc->rs_cbuf, /* buffer for this tuple */
  164.   false); /* don't pfree this pointer */
  165. }
  166. /* ----------------------------------------------------------------
  167.  * ExecInitMaterial
  168.  * ----------------------------------------------------------------
  169.  */
  170. bool /* initialization status */
  171. ExecInitMaterial(Material *node, EState *estate, Plan *parent)
  172. {
  173. MaterialState *matstate;
  174. Plan    *outerPlan;
  175. TupleDesc tupType;
  176. Relation tempDesc;
  177. /* int len; */
  178. /* ----------------
  179.  * assign the node's execution state
  180.  * ----------------
  181.  */
  182. node->plan.state = estate;
  183. /* ----------------
  184.  * create state structure
  185.  * ----------------
  186.  */
  187. matstate = makeNode(MaterialState);
  188. matstate->mat_Flag = false;
  189. matstate->mat_TempRelation = NULL;
  190. node->matstate = matstate;
  191. /* ----------------
  192.  * Miscellanious initialization
  193.  *
  194.  *  + assign node's base_id
  195.  *  + assign debugging hooks and
  196.  *  + assign result tuple slot
  197.  *
  198.  * Materialization nodes don't need ExprContexts because
  199.  * they never call ExecQual or ExecTargetList.
  200.  * ----------------
  201.  */
  202. ExecAssignNodeBaseInfo(estate, &matstate->csstate.cstate, parent);
  203. #define MATERIAL_NSLOTS 1
  204. /* ----------------
  205.  * tuple table initialization
  206.  * ----------------
  207.  */
  208. ExecInitScanTupleSlot(estate, &matstate->csstate);
  209. /* ----------------
  210.  * initializes child nodes
  211.  * ----------------
  212.  */
  213. outerPlan = outerPlan((Plan *) node);
  214. ExecInitNode(outerPlan, estate, (Plan *) node);
  215. /* ----------------
  216.  * initialize matstate information
  217.  * ----------------
  218.  */
  219. matstate->mat_Flag = false;
  220. /* ----------------
  221.  * initialize tuple type. no need to initialize projection
  222.  * info because this node doesn't do projections.
  223.  * ----------------
  224.  */
  225. ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
  226. matstate->csstate.cstate.cs_ProjInfo = NULL;
  227. /* ----------------
  228.  * get type information needed for ExecCreatR
  229.  * ----------------
  230.  */
  231. tupType = ExecGetScanType(&matstate->csstate);
  232. /* ----------------
  233.  * ExecCreatR wants it's second argument to be an object id of
  234.  * a relation in the range table or a _NONAME_RELATION_ID
  235.  * indicating that the relation is not in the range table.
  236.  *
  237.  * In the second case ExecCreatR creates a temp relation.
  238.  * (currently this is the only case we support -cim 10/16/89)
  239.  * ----------------
  240.  */
  241. /* ----------------
  242.  * create the temporary relation
  243.  * ----------------
  244.  */
  245. /*   len = ExecTargetListLength(node->plan.targetlist); */
  246. tempDesc = ExecCreatR(tupType, _NONAME_RELATION_ID_);
  247. /* ----------------
  248.  * save the relation descriptor in the sortstate
  249.  * ----------------
  250.  */
  251. matstate->mat_TempRelation = tempDesc;
  252. matstate->csstate.css_currentRelation = tempDesc;
  253. /* ----------------
  254.  * return relation oid of temporary relation in a list
  255.  * (someday -- for now we return LispTrue... cim 10/12/89)
  256.  * ----------------
  257.  */
  258. return TRUE;
  259. }
  260. int
  261. ExecCountSlotsMaterial(Material *node)
  262. {
  263. return ExecCountSlotsNode(outerPlan((Plan *) node)) +
  264. ExecCountSlotsNode(innerPlan((Plan *) node)) +
  265. MATERIAL_NSLOTS;
  266. }
  267. /* ----------------------------------------------------------------
  268.  * ExecEndMaterial
  269.  *
  270.  * old comments
  271.  * destroys the temporary relation.
  272.  * ----------------------------------------------------------------
  273.  */
  274. void
  275. ExecEndMaterial(Material *node)
  276. {
  277. MaterialState *matstate;
  278. Relation tempRelation;
  279. Plan    *outerPlan;
  280. /* ----------------
  281.  * get info from the material state
  282.  * ----------------
  283.  */
  284. matstate = node->matstate;
  285. tempRelation = matstate->mat_TempRelation;
  286. heap_destroy(tempRelation);
  287. /* ----------------
  288.  * close the temp relation and shut down the scan.
  289.  * ----------------
  290.  */
  291. ExecCloseR((Plan *) node);
  292. /* ----------------
  293.  * shut down the subplan
  294.  * ----------------
  295.  */
  296. outerPlan = outerPlan((Plan *) node);
  297. ExecEndNode(outerPlan, (Plan *) node);
  298. /* ----------------
  299.  * clean out the tuple table
  300.  * ----------------
  301.  */
  302. ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
  303. }
  304. /* ----------------------------------------------------------------
  305.  * ExecMaterialReScan
  306.  *
  307.  * Rescans the temporary relation.
  308.  * ----------------------------------------------------------------
  309.  */
  310. void
  311. ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
  312. {
  313. MaterialState *matstate = node->matstate;
  314. if (matstate->mat_Flag == false)
  315. return;
  316. matstate->csstate.css_currentScanDesc = ExecReScanR(matstate->csstate.css_currentRelation,
  317.    matstate->csstate.css_currentScanDesc,
  318. node->plan.state->es_direction, 0, NULL);
  319. }
  320. #ifdef NOT_USED /* not used */
  321. /* ----------------------------------------------------------------
  322.  * ExecMaterialMarkPos
  323.  * ----------------------------------------------------------------
  324.  */
  325. List /* nothing of interest */
  326. ExecMaterialMarkPos(Material node)
  327. {
  328. MaterialState matstate;
  329. HeapScanDesc scan;
  330. /* ----------------
  331.  * if we haven't materialized yet, just return NIL.
  332.  * ----------------
  333.  */
  334. matstate = get_matstate(node);
  335. if (get_mat_Flag(matstate) == false)
  336. return NIL;
  337. /* ----------------
  338.  * XXX access methods don't return positions yet so
  339.  * for now we return NIL. It's possible that
  340.  * they will never return positions for all I know -cim 10/16/89
  341.  * ----------------
  342.  */
  343. scan = get_css_currentScanDesc((CommonScanState) matstate);
  344. heap_markpos(scan);
  345. return NIL;
  346. }
  347. /* ----------------------------------------------------------------
  348.  * ExecMaterialRestrPos
  349.  * ----------------------------------------------------------------
  350.  */
  351. void
  352. ExecMaterialRestrPos(Material node)
  353. {
  354. MaterialState matstate;
  355. HeapScanDesc scan;
  356. /* ----------------
  357.  * if we haven't materialized yet, just return.
  358.  * ----------------
  359.  */
  360. matstate = get_matstate(node);
  361. if (get_mat_Flag(matstate) == false)
  362. return;
  363. /* ----------------
  364.  * restore the scan to the previously marked position
  365.  * ----------------
  366.  */
  367. scan = get_css_currentScanDesc((CommonScanState) matstate);
  368. heap_restrpos(scan);
  369. }
  370. #endif