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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * nodeResult.c
  4.  *   support for constant nodes needing special code.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * DESCRIPTION
  10.  *
  11.  * Example: in constant queries where no relations are scanned,
  12.  * the planner generates result nodes.  Examples of such queries are:
  13.  *
  14.  * retrieve (x = 1)
  15.  * and
  16.  * append emp (name = "mike", salary = 15000)
  17.  *
  18.  * Result nodes are also used to optimise queries
  19.  * with tautological qualifications like:
  20.  *
  21.  * retrieve (emp.all) where 2 > 1
  22.  *
  23.  * In this case, the plan generated is
  24.  *
  25.  * Result (with 2 > 1 qual)
  26.  * /
  27.  *    SeqScan (emp.all)
  28.  *
  29.  * IDENTIFICATION
  30.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.11 1999/05/25 16:08:46 momjian Exp $
  31.  *
  32.  *-------------------------------------------------------------------------
  33.  */
  34. #include "postgres.h"
  35. #include "executor/executor.h"
  36. #include "executor/nodeResult.h"
  37. /* ----------------------------------------------------------------
  38.  * ExecResult(node)
  39.  *
  40.  * returns the tuples from the outer plan which satisify the
  41.  * qualification clause.  Since result nodes with right
  42.  * subtrees are never planned, we ignore the right subtree
  43.  * entirely (for now).. -cim 10/7/89
  44.  *
  45.  * The qualification containing only constant clauses are
  46.  * checked first before any processing is done. It always returns
  47.  * 'nil' if the constant qualification is not satisfied.
  48.  * ----------------------------------------------------------------
  49.  */
  50. TupleTableSlot *
  51. ExecResult(Result *node)
  52. {
  53. ResultState *resstate;
  54. TupleTableSlot *outerTupleSlot;
  55. TupleTableSlot *resultSlot;
  56. Plan    *outerPlan;
  57. ExprContext *econtext;
  58. bool isDone;
  59. ProjectionInfo *projInfo;
  60. /* ----------------
  61.  * initialize the result node's state
  62.  * ----------------
  63.  */
  64. resstate = node->resstate;
  65. /* ----------------
  66.  * get the expression context
  67.  * ----------------
  68.  */
  69. econtext = resstate->cstate.cs_ExprContext;
  70. /* ----------------
  71.  *  check tautological qualifications like (2 > 1)
  72.  * ----------------
  73.  */
  74. if (resstate->rs_checkqual)
  75. {
  76. bool qualResult = ExecQual((List *) node->resconstantqual, econtext);
  77. resstate->rs_checkqual = false;
  78. if (qualResult == false)
  79. {
  80. resstate->rs_done = true;
  81. return NULL;
  82. }
  83. }
  84. if (resstate->cstate.cs_TupFromTlist)
  85. {
  86. ProjectionInfo *projInfo;
  87. projInfo = resstate->cstate.cs_ProjInfo;
  88. resultSlot = ExecProject(projInfo, &isDone);
  89. if (!isDone)
  90. return resultSlot;
  91. }
  92. /* ----------------
  93.  * retrieve a tuple that satisfy the qual from the outer plan until
  94.  * there are no more.
  95.  *
  96.  * if rs_done is 1 then it means that we were asked to return
  97.  * a constant tuple and we alread did the last time ExecResult()
  98.  * was called, so now we are through.
  99.  * ----------------
  100.  */
  101. outerPlan = outerPlan(node);
  102. while (!resstate->rs_done)
  103. {
  104. /* ----------------
  105.  *   get next outer tuple if necessary.
  106.  * ----------------
  107.  */
  108. if (outerPlan != NULL)
  109. {
  110. outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
  111. if (TupIsNull(outerTupleSlot))
  112. return NULL;
  113. resstate->cstate.cs_OuterTupleSlot = outerTupleSlot;
  114. }
  115. else
  116. {
  117. /* ----------------
  118.  * if we don't have an outer plan, then it's probably
  119.  * the case that we are doing a retrieve or an append
  120.  * with a constant target list, so we should only return
  121.  * the constant tuple once or never if we fail the qual.
  122.  * ----------------
  123.  */
  124. resstate->rs_done = 1;
  125. }
  126. /* ----------------
  127.  *   get the information to place into the expr context
  128.  * ----------------
  129.  */
  130. resstate = node->resstate;
  131. outerTupleSlot = resstate->cstate.cs_OuterTupleSlot;
  132. /* ----------------
  133.  *  fill in the information in the expression context
  134.  *  XXX gross hack. use outer tuple as scan tuple
  135.  * ----------------
  136.  */
  137. econtext->ecxt_outertuple = outerTupleSlot;
  138. econtext->ecxt_scantuple = outerTupleSlot;
  139. /* ----------------
  140.  *  form the result tuple and pass it back using ExecProject()
  141.  * ----------------
  142.  */
  143. projInfo = resstate->cstate.cs_ProjInfo;
  144. resultSlot = ExecProject(projInfo, &isDone);
  145. resstate->cstate.cs_TupFromTlist = !isDone;
  146. return resultSlot;
  147. }
  148. return NULL;
  149. }
  150. /* ----------------------------------------------------------------
  151.  * ExecInitResult
  152.  *
  153.  * Creates the run-time state information for the result node
  154.  * produced by the planner and initailizes outer relations
  155.  * (child nodes).
  156.  * ----------------------------------------------------------------
  157.  */
  158. bool
  159. ExecInitResult(Result *node, EState *estate, Plan *parent)
  160. {
  161. ResultState *resstate;
  162. /* ----------------
  163.  * assign execution state to node
  164.  * ----------------
  165.  */
  166. node->plan.state = estate;
  167. /* ----------------
  168.  * create new ResultState for node
  169.  * ----------------
  170.  */
  171. resstate = makeNode(ResultState);
  172. resstate->rs_done = false;
  173. resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
  174. node->resstate = resstate;
  175. /* ----------------
  176.  * Miscellanious initialization
  177.  *
  178.  *  + assign node's base_id
  179.  *  + assign debugging hooks and
  180.  *  + create expression context for node
  181.  * ----------------
  182.  */
  183. ExecAssignNodeBaseInfo(estate, &resstate->cstate, parent);
  184. ExecAssignExprContext(estate, &resstate->cstate);
  185. #define RESULT_NSLOTS 1
  186. /* ----------------
  187.  * tuple table initialization
  188.  * ----------------
  189.  */
  190. ExecInitResultTupleSlot(estate, &resstate->cstate);
  191. /* ----------------
  192.  * then initialize children
  193.  * ----------------
  194.  */
  195. ExecInitNode(outerPlan(node), estate, (Plan *) node);
  196. /*
  197.  * we don't use inner plan
  198.  */
  199. Assert(innerPlan(node) == NULL);
  200. /* ----------------
  201.  * initialize tuple type and projection info
  202.  * ----------------
  203.  */
  204. ExecAssignResultTypeFromTL((Plan *) node, &resstate->cstate);
  205. ExecAssignProjectionInfo((Plan *) node, &resstate->cstate);
  206. return TRUE;
  207. }
  208. int
  209. ExecCountSlotsResult(Result *node)
  210. {
  211. return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;
  212. }
  213. /* ----------------------------------------------------------------
  214.  * ExecEndResult
  215.  *
  216.  * fees up storage allocated through C routines
  217.  * ----------------------------------------------------------------
  218.  */
  219. void
  220. ExecEndResult(Result *node)
  221. {
  222. ResultState *resstate;
  223. resstate = node->resstate;
  224. /* ----------------
  225.  * Free the projection info
  226.  *
  227.  * Note: we don't ExecFreeResultType(resstate)
  228.  *   because the rule manager depends on the tupType
  229.  *   returned by ExecMain().  So for now, this
  230.  *   is freed at end-transaction time.  -cim 6/2/91
  231.  * ----------------
  232.  */
  233. ExecFreeExprContext(&resstate->cstate); /* XXX - new for us - er1p */
  234. ExecFreeTypeInfo(&resstate->cstate); /* XXX - new for us - er1p */
  235. ExecFreeProjectionInfo(&resstate->cstate);
  236. /* ----------------
  237.  * shut down subplans
  238.  * ----------------
  239.  */
  240. ExecEndNode(outerPlan(node), (Plan *) node);
  241. /* ----------------
  242.  * clean out the tuple table
  243.  * ----------------
  244.  */
  245. ExecClearTuple(resstate->cstate.cs_ResultTupleSlot);
  246. pfree(resstate);
  247. node->resstate = NULL; /* XXX - new for us - er1p */
  248. }
  249. void
  250. ExecReScanResult(Result *node, ExprContext *exprCtxt, Plan *parent)
  251. {
  252. ResultState *resstate = node->resstate;
  253. resstate->rs_done = false;
  254. resstate->cstate.cs_TupFromTlist = false;
  255. resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
  256. /*
  257.  * if chgParam of subnode is not null then plan will be re-scanned by
  258.  * first ExecProcNode.
  259.  */
  260. if (((Plan *) node)->lefttree &&
  261. ((Plan *) node)->lefttree->chgParam == NULL)
  262. ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
  263. }