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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * execScan.c
  4.  *   This code provides support for generalized relation scans. ExecScan
  5.  *   is passed a node and a pointer to a function to "do the right thing"
  6.  *   and return a tuple from the relation. ExecScan then does the tedious
  7.  *   stuff - checking the qualification and projecting the tuple
  8.  *   appropriately.
  9.  *
  10.  * Copyright (c) 1994, Regents of the University of California
  11.  *
  12.  *
  13.  * IDENTIFICATION
  14.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/executor/execScan.c,v 1.9 1999/02/13 23:15:18 momjian Exp $
  15.  *
  16.  *-------------------------------------------------------------------------
  17.  */
  18. #include <sys/types.h>
  19. #include <sys/file.h>
  20. #include "postgres.h"
  21. #include "executor/executor.h"
  22. /* ----------------------------------------------------------------
  23.  * ExecScan
  24.  *
  25.  * Scans the relation using the 'access method' indicated and
  26.  * returns the next qualifying tuple in the direction specified
  27.  * in the global variable ExecDirection.
  28.  * The access method returns the next tuple and execScan() is
  29.  * responisble for checking the tuple returned against the qual-clause.
  30.  *
  31.  * Conditions:
  32.  *   -- the "cursor" maintained by the AMI is positioned at the tuple
  33.  *  returned previously.
  34.  *
  35.  * Initial States:
  36.  *   -- the relation indicated is opened for scanning so that the
  37.  *  "cursor" is positioned before the first qualifying tuple.
  38.  *
  39.  * May need to put startmmgr  and endmmgr in here.
  40.  * ----------------------------------------------------------------
  41.  */
  42. TupleTableSlot *
  43. ExecScan(Scan *node,
  44.  TupleTableSlot *(*accessMtd) ()) /* function returning a
  45.  * tuple */
  46. {
  47. CommonScanState *scanstate;
  48. EState    *estate;
  49. List    *qual;
  50. bool isDone;
  51. TupleTableSlot *slot;
  52. TupleTableSlot *resultSlot;
  53. HeapTuple newTuple;
  54. ExprContext *econtext;
  55. ProjectionInfo *projInfo;
  56. /* ----------------
  57.  * initialize misc variables
  58.  * ----------------
  59.  */
  60. newTuple = NULL;
  61. slot = NULL;
  62. estate = node->plan.state;
  63. scanstate = node->scanstate;
  64. /* ----------------
  65.  * get the expression context
  66.  * ----------------
  67.  */
  68. econtext = scanstate->cstate.cs_ExprContext;
  69. /* ----------------
  70.  * initialize fields in ExprContext which don't change
  71.  * in the course of the scan..
  72.  * ----------------
  73.  */
  74. qual = node->plan.qual;
  75. econtext->ecxt_relation = scanstate->css_currentRelation;
  76. econtext->ecxt_relid = node->scanrelid;
  77. if (scanstate->cstate.cs_TupFromTlist)
  78. {
  79. projInfo = scanstate->cstate.cs_ProjInfo;
  80. resultSlot = ExecProject(projInfo, &isDone);
  81. if (!isDone)
  82. return resultSlot;
  83. }
  84. /*
  85.  * get a tuple from the access method loop until we obtain a tuple
  86.  * which passes the qualification.
  87.  */
  88. for (;;)
  89. {
  90. slot = (TupleTableSlot *) (*accessMtd) (node);
  91. /* ----------------
  92.  * if the slot returned by the accessMtd contains
  93.  * NULL, then it means there is nothing more to scan
  94.  * so we just return the empty slot...
  95.  *
  96.  * ... with invalid TupleDesc (not the same as in
  97.  * projInfo->pi_slot) and break upper MergeJoin node.
  98.  * New code below do what ExecProject() does. - vadim 02/26/98
  99.  * ----------------
  100.  */
  101. if (TupIsNull(slot))
  102. {
  103. scanstate->cstate.cs_TupFromTlist = false;
  104. resultSlot = scanstate->cstate.cs_ProjInfo->pi_slot;
  105. return (TupleTableSlot *)
  106. ExecStoreTuple(NULL,
  107.    resultSlot,
  108.    InvalidBuffer,
  109.    true);
  110. }
  111. /* ----------------
  112.  *  place the current tuple into the expr context
  113.  * ----------------
  114.  */
  115. econtext->ecxt_scantuple = slot;
  116. /* ----------------
  117.  * check that the current tuple satisfies the qual-clause
  118.  * if our qualification succeeds then we
  119.  * leave the loop.
  120.  * ----------------
  121.  */
  122. /*
  123.  * add a check for non-nil qual here to avoid a function call to
  124.  * ExecQual() when the qual is nil
  125.  */
  126. if (!qual || ExecQual(qual, econtext) == true)
  127. break;
  128. }
  129. /* ----------------
  130.  * form a projection tuple, store it in the result tuple
  131.  * slot and return it.
  132.  * ----------------
  133.  */
  134. projInfo = scanstate->cstate.cs_ProjInfo;
  135. resultSlot = ExecProject(projInfo, &isDone);
  136. scanstate->cstate.cs_TupFromTlist = !isDone;
  137. return resultSlot;
  138. }