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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * execAmi.c
  4.  *   miscellanious executor access method routines
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  * $Id: execAmi.c,v 1.35 1999/05/25 16:08:34 momjian Exp $
  9.  *
  10.  *-------------------------------------------------------------------------
  11.  */
  12. /*
  13.  *  INTERFACE ROUTINES
  14.  *
  15.  * ExecOpenScanR   / amopen
  16.  * ExecBeginScan    / ambeginscan
  17.  * ExecCloseR    / amclose
  18.  * ExecInsert      executor interface   / aminsert
  19.  * ExecReScanNode    /  to access methods     amrescan
  20.  * ExecReScanR   / amrescan
  21.  * ExecMarkPos  /   ammarkpos
  22.  * ExecRestrPos /    amrestpos
  23.  *
  24.  * ExecCreatR function to create temporary relations
  25.  *
  26.  */
  27. #include <stdio.h>
  28. #include "postgres.h"
  29. #include "executor/executor.h"
  30. #include "storage/smgr.h"
  31. #include "utils/mcxt.h"
  32. #include "executor/nodeSeqscan.h"
  33. #include "executor/nodeIndexscan.h"
  34. #include "executor/nodeSort.h"
  35. #include "executor/nodeMaterial.h"
  36. #include "executor/nodeNestloop.h"
  37. #include "executor/nodeHashjoin.h"
  38. #include "executor/nodeHash.h"
  39. /***S*I***/
  40. #include "executor/nodeGroup.h"
  41. #include "executor/nodeAgg.h"
  42. #include "executor/nodeGroup.h"
  43. #include "executor/nodeResult.h"
  44. #include "executor/nodeUnique.h"
  45. #include "executor/nodeMergejoin.h"
  46. #include "executor/nodeAppend.h"
  47. #include "executor/nodeSubplan.h"
  48. #include "executor/execdebug.h"
  49. #include "optimizer/internal.h" /* for _NONAME_RELATION_ID_ */
  50. #include "access/genam.h"
  51. #include "access/heapam.h"
  52. #include "catalog/heap.h"
  53. static Pointer ExecBeginScan(Relation relation, int nkeys, ScanKey skeys,
  54.   bool isindex, ScanDirection dir, Snapshot snapshot);
  55. static Relation ExecOpenR(Oid relationOid, bool isindex);
  56. /* ----------------------------------------------------------------
  57.  * ExecOpenScanR
  58.  *
  59.  * old comments:
  60.  * Parameters:
  61.  *   relation -- relation to be opened and scanned.
  62.  *   nkeys    -- number of keys
  63.  *   skeys    -- keys to restrict scanning
  64.  *  isindex  -- if this is true, the relation is the relid of
  65.  *  an index relation, else it is an index into the
  66.  *  range table.
  67.  * Returns the relation as(relDesc scanDesc)
  68.  *    If this structure is changed, need to modify the access macros
  69.  * defined in execInt.h.
  70.  * ----------------------------------------------------------------
  71.  */
  72. void
  73. ExecOpenScanR(Oid relOid,
  74.   int nkeys,
  75.   ScanKey skeys,
  76.   bool isindex,
  77.   ScanDirection dir,
  78.   Snapshot snapshot,
  79.   Relation *returnRelation, /* return */
  80.   Pointer *returnScanDesc) /* return */
  81. {
  82. Relation relation;
  83. Pointer scanDesc;
  84. /* ----------------
  85.  * note: scanDesc returned by ExecBeginScan can be either
  86.  *   a HeapScanDesc or an IndexScanDesc so for now we
  87.  *   make it a Pointer.  There should be a better scan
  88.  *   abstraction someday -cim 9/9/89
  89.  * ----------------
  90.  */
  91. relation = ExecOpenR(relOid, isindex);
  92. scanDesc = ExecBeginScan(relation,
  93.  nkeys,
  94.  skeys,
  95.  isindex,
  96.  dir,
  97.  snapshot);
  98. if (returnRelation != NULL)
  99. *returnRelation = relation;
  100. if (scanDesc != NULL)
  101. *returnScanDesc = scanDesc;
  102. }
  103. /* ----------------------------------------------------------------
  104.  * ExecOpenR
  105.  *
  106.  * returns a relation descriptor given an object id.
  107.  * ----------------------------------------------------------------
  108.  */
  109. static Relation
  110. ExecOpenR(Oid relationOid, bool isindex)
  111. {
  112. Relation relation;
  113. relation = (Relation) NULL;
  114. /* ----------------
  115.  * open the relation with the correct call depending
  116.  * on whether this is a heap relation or an index relation.
  117.  * ----------------
  118.  */
  119. if (isindex)
  120. relation = index_open(relationOid);
  121. else
  122. relation = heap_open(relationOid);
  123. if (relation == NULL)
  124. elog(DEBUG, "ExecOpenR: relation == NULL, heap_open failed.");
  125. return relation;
  126. }
  127. /* ----------------------------------------------------------------
  128.  * ExecBeginScan
  129.  *
  130.  * beginscans a relation in current direction.
  131.  *
  132.  * XXX fix parameters to AMbeginscan (and btbeginscan)
  133.  * currently we need to pass a flag stating whether
  134.  * or not the scan should begin at an endpoint of
  135.  * the relation.. Right now we always pass false
  136.  * -cim 9/14/89
  137.  * ----------------------------------------------------------------
  138.  */
  139. static Pointer
  140. ExecBeginScan(Relation relation,
  141.   int nkeys,
  142.   ScanKey skeys,
  143.   bool isindex,
  144.   ScanDirection dir,
  145.   Snapshot snapshot)
  146. {
  147. Pointer scanDesc;
  148. scanDesc = NULL;
  149. /* ----------------
  150.  * open the appropriate type of scan.
  151.  *
  152.  * Note: ambeginscan()'s second arg is a boolean indicating
  153.  *   that the scan should be done in reverse..  That is,
  154.  *   if you pass it true, then the scan is backward.
  155.  * ----------------
  156.  */
  157. if (isindex)
  158. {
  159. scanDesc = (Pointer) index_beginscan(relation,
  160.  false, /* see above comment */
  161.  nkeys,
  162.  skeys);
  163. }
  164. else
  165. {
  166. scanDesc = (Pointer) heap_beginscan(relation,
  167. ScanDirectionIsBackward(dir),
  168. snapshot,
  169. nkeys,
  170. skeys);
  171. }
  172. if (scanDesc == NULL)
  173. elog(DEBUG, "ExecBeginScan: scanDesc = NULL, heap_beginscan failed.");
  174. return scanDesc;
  175. }
  176. /* ----------------------------------------------------------------
  177.  * ExecCloseR
  178.  *
  179.  * closes the relation and scan descriptor for a scan or sort
  180.  * node.  Also closes index relations and scans for index scans.
  181.  *
  182.  * old comments
  183.  * closes the relation indicated in 'relID'
  184.  * ----------------------------------------------------------------
  185.  */
  186. void
  187. ExecCloseR(Plan *node)
  188. {
  189. CommonScanState *state;
  190. Relation relation;
  191. HeapScanDesc scanDesc;
  192. /* ----------------
  193.  * shut down the heap scan and close the heap relation
  194.  * ----------------
  195.  */
  196. switch (nodeTag(node))
  197. {
  198. case T_SeqScan:
  199. state = ((SeqScan *) node)->scanstate;
  200. break;
  201. case T_IndexScan:
  202. state = ((IndexScan *) node)->scan.scanstate;
  203. break;
  204. case T_Material:
  205. state = &(((Material *) node)->matstate->csstate);
  206. break;
  207. case T_Sort:
  208. state = &(((Sort *) node)->sortstate->csstate);
  209. break;
  210. case T_Agg:
  211. state = &(((Agg *) node)->aggstate->csstate);
  212. break;
  213. default:
  214. elog(DEBUG, "ExecCloseR: not a scan, material, or sort node!");
  215. return;
  216. }
  217. relation = state->css_currentRelation;
  218. scanDesc = state->css_currentScanDesc;
  219. if (scanDesc != NULL)
  220. heap_endscan(scanDesc);
  221. if (relation != NULL)
  222. heap_close(relation);
  223. /* ----------------
  224.  * if this is an index scan then we have to take care
  225.  * of the index relations as well..
  226.  * ----------------
  227.  */
  228. if (nodeTag(node) == T_IndexScan)
  229. {
  230. IndexScan  *iscan = (IndexScan *) node;
  231. IndexScanState *indexstate;
  232. int numIndices;
  233. RelationPtr indexRelationDescs;
  234. IndexScanDescPtr indexScanDescs;
  235. int i;
  236. indexstate = iscan->indxstate;
  237. numIndices = indexstate->iss_NumIndices;
  238. indexRelationDescs = indexstate->iss_RelationDescs;
  239. indexScanDescs = indexstate->iss_ScanDescs;
  240. for (i = 0; i < numIndices; i++)
  241. {
  242. /* ----------------
  243.  * shut down each of the scans and
  244.  * close each of the index relations
  245.  * ----------------
  246.  */
  247. if (indexScanDescs[i] != NULL)
  248. index_endscan(indexScanDescs[i]);
  249. if (indexRelationDescs[i] != NULL)
  250. index_close(indexRelationDescs[i]);
  251. }
  252. }
  253. }
  254. /* ----------------------------------------------------------------
  255.  * ExecReScan
  256.  *
  257.  * XXX this should be extended to cope with all the node types..
  258.  *
  259.  * takes the new expression context as an argument, so that
  260.  * index scans needn't have their scan keys updated separately
  261.  * - marcel 09/20/94
  262.  * ----------------------------------------------------------------
  263.  */
  264. void
  265. ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
  266. {
  267. if (node->chgParam != NULL) /* Wow! */
  268. {
  269. List    *lst;
  270. foreach(lst, node->initPlan)
  271. {
  272. Plan    *splan = ((SubPlan *) lfirst(lst))->plan;
  273. if (splan->extParam != NULL) /* don't care about child
  274.  * locParam */
  275. SetChangedParamList(splan, node->chgParam);
  276. if (splan->chgParam != NULL)
  277. ExecReScanSetParamPlan((SubPlan *) lfirst(lst), node);
  278. }
  279. foreach(lst, node->subPlan)
  280. {
  281. Plan    *splan = ((SubPlan *) lfirst(lst))->plan;
  282. if (splan->extParam != NULL)
  283. SetChangedParamList(splan, node->chgParam);
  284. }
  285. /* Well. Now set chgParam for left/right trees. */
  286. if (node->lefttree != NULL)
  287. SetChangedParamList(node->lefttree, node->chgParam);
  288. if (node->righttree != NULL)
  289. SetChangedParamList(node->righttree, node->chgParam);
  290. }
  291. switch (nodeTag(node))
  292. {
  293. case T_SeqScan:
  294. ExecSeqReScan((SeqScan *) node, exprCtxt, parent);
  295. break;
  296. case T_IndexScan:
  297. ExecIndexReScan((IndexScan *) node, exprCtxt, parent);
  298. break;
  299. case T_Material:
  300. ExecMaterialReScan((Material *) node, exprCtxt, parent);
  301. break;
  302. case T_NestLoop:
  303. ExecReScanNestLoop((NestLoop *) node, exprCtxt, parent);
  304. break;
  305. case T_HashJoin:
  306. ExecReScanHashJoin((HashJoin *) node, exprCtxt, parent);
  307. break;
  308. case T_Hash:
  309. ExecReScanHash((Hash *) node, exprCtxt, parent);
  310. break;
  311. case T_Agg:
  312. ExecReScanAgg((Agg *) node, exprCtxt, parent);
  313. break;
  314. case T_Group:
  315. ExecReScanGroup((Group *) node, exprCtxt, parent);
  316. break;
  317. case T_Result:
  318. ExecReScanResult((Result *) node, exprCtxt, parent);
  319. break;
  320. case T_Unique:
  321. ExecReScanUnique((Unique *) node, exprCtxt, parent);
  322. break;
  323. case T_Sort:
  324. ExecReScanSort((Sort *) node, exprCtxt, parent);
  325. break;
  326. case T_MergeJoin:
  327. ExecReScanMergeJoin((MergeJoin *) node, exprCtxt, parent);
  328. break;
  329. case T_Append:
  330. ExecReScanAppend((Append *) node, exprCtxt, parent);
  331. break;
  332. default:
  333. elog(ERROR, "ExecReScan: node type %u not supported", nodeTag(node));
  334. return;
  335. }
  336. if (node->chgParam != NULL)
  337. {
  338. freeList(node->chgParam);
  339. node->chgParam = NULL;
  340. }
  341. }
  342. /* ----------------------------------------------------------------
  343.  * ExecReScanR
  344.  *
  345.  * XXX this does not do the right thing with indices yet.
  346.  * ----------------------------------------------------------------
  347.  */
  348. HeapScanDesc
  349. ExecReScanR(Relation relDesc, /* LLL relDesc unused  */
  350. HeapScanDesc scanDesc,
  351. ScanDirection direction,
  352. int nkeys, /* LLL nkeys unused  */
  353. ScanKey skeys)
  354. {
  355. if (scanDesc != NULL)
  356. heap_rescan(scanDesc, /* scan desc */
  357. ScanDirectionIsBackward(direction), /* backward flag */
  358. skeys); /* scan keys */
  359. return scanDesc;
  360. }
  361. /* ----------------------------------------------------------------
  362.  * ExecMarkPos
  363.  *
  364.  * Marks the current scan position.
  365.  *
  366.  * XXX Needs to be extended to include all the node types.
  367.  * ----------------------------------------------------------------
  368.  */
  369. void
  370. ExecMarkPos(Plan *node)
  371. {
  372. switch (nodeTag(node))
  373. {
  374. case T_SeqScan:
  375. ExecSeqMarkPos((SeqScan *) node);
  376. break;
  377. case T_IndexScan:
  378. ExecIndexMarkPos((IndexScan *) node);
  379. break;
  380. case T_Sort:
  381. ExecSortMarkPos((Sort *) node);
  382. break;
  383. default:
  384. elog(DEBUG, "ExecMarkPos: node type %u not supported", nodeTag(node));
  385. break;
  386. }
  387. return;
  388. }
  389. /* ----------------------------------------------------------------
  390.  * ExecRestrPos
  391.  *
  392.  * restores the scan position previously saved with ExecMarkPos()
  393.  * ----------------------------------------------------------------
  394.  */
  395. void
  396. ExecRestrPos(Plan *node)
  397. {
  398. switch (nodeTag(node))
  399. {
  400. case T_SeqScan:
  401. ExecSeqRestrPos((SeqScan *) node);
  402. return;
  403. case T_IndexScan:
  404. ExecIndexRestrPos((IndexScan *) node);
  405. return;
  406. case T_Sort:
  407. ExecSortRestrPos((Sort *) node);
  408. return;
  409. default:
  410. elog(DEBUG, "ExecRestrPos: node type %u not supported", nodeTag(node));
  411. return;
  412. }
  413. }
  414. /* ----------------------------------------------------------------
  415.  * ExecCreatR
  416.  *
  417.  * old comments
  418.  * Creates a relation.
  419.  *
  420.  * Parameters:
  421.  *   attrType -- type information on the attributes.
  422.  *   accessMtd -- access methods used to access the created relation.
  423.  *   relation -- optional. Either an index to the range table or
  424.  *    negative number indicating a temporary relation.
  425.  *    A temporary relation is assume if this field is absent.
  426.  * ----------------------------------------------------------------
  427.  */
  428. Relation
  429. ExecCreatR(TupleDesc tupType,
  430.    Oid relationOid)
  431. {
  432. Relation relDesc;
  433. EU3_printf("ExecCreatR: %s type=%d oid=%un",
  434.    "entering: ", tupType, relationOid);
  435. CXT1_printf("ExecCreatR: context is %dn", CurrentMemoryContext);
  436. relDesc = NULL;
  437. if (relationOid == _NONAME_RELATION_ID_)
  438. {
  439. /* ----------------
  440.  *  create a temporary relation
  441.  *  (currently the planner always puts a _NONAME_RELATION_ID
  442.  *  in the relation argument so we expect this to be the case although
  443.  *  it's possible that someday we'll get the name from
  444.  *  from the range table.. -cim 10/12/89)
  445.  * ----------------
  446.  */
  447. /*
  448.  * heap_create creates a name if the argument to heap_create is
  449.  * ' '
  450.  */
  451. relDesc = heap_create(NULL, tupType, true, false);
  452. }
  453. else
  454. {
  455. /* ----------------
  456.  * use a relation from the range table
  457.  * ----------------
  458.  */
  459. elog(DEBUG, "ExecCreatR: %s",
  460.  "stuff using range table id's is not functional");
  461. }
  462. if (relDesc == NULL)
  463. elog(DEBUG, "ExecCreatR: failed to create relation.");
  464. EU1_printf("ExecCreatR: returning relDesc=%dn", relDesc);
  465. return relDesc;
  466. }