home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / executor / n_result.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  9.5 KB  |  353 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    result.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    support for constant nodes needing special code.
  7.  *
  8.  *    Example: in constant queries where no relations are scanned,
  9.  *    the planner generates result nodes.  Examples of such queries are:
  10.  *
  11.  *        retrieve (x = 1)
  12.  *    and
  13.  *        append emp (name = "mike", salary = 15000)
  14.  *
  15.  *    Result nodes are also used to optimise queries
  16.  *    with tautological qualifications like:
  17.  *
  18.  *        retrieve (emp.all) where 2 > 1
  19.  *
  20.  *    In this case, the plan generated is
  21.  *
  22.  *            Result  (with 2 > 1 qual)
  23.  *            /
  24.  *           SeqScan (emp.all)
  25.  *
  26.  *   INTERFACE ROUTINES
  27.  *    ExecResult    - fetch a tuple from the node
  28.  *       ExecInitResult    - initialize the node
  29.  *       ExecEndResult    - shutdown the node
  30.  *
  31.  *   NOTES
  32.  *    
  33.  *    
  34.  *   IDENTIFICATION
  35.  *    $Header: /private/postgres/src/executor/RCS/n_result.c,v 1.5 1992/08/04 17:38:00 mer Exp $
  36.  * ----------------------------------------------------------------
  37.  */
  38.  
  39. #include "executor/executor.h"
  40.  
  41.  RcsId("$Header: /private/postgres/src/executor/RCS/n_result.c,v 1.5 1992/08/04 17:38:00 mer Exp $");
  42.  
  43. /* ----------------------------------------------------------------
  44.  *       ExecResult(node)
  45.  *
  46.  *    returns the tuples from the outer plan which satisify the
  47.  *    qualification clause.  Since result nodes with right
  48.  *    subtrees are never planned, we ignore the right subtree
  49.  *    entirely (for now).. -cim 10/7/89
  50.  *
  51.  * old comments:
  52.  *       Returns the tuple joined from inner and outer tuples which 
  53.  *       satisfies the qualification clause.
  54.  *
  55.  *    It scans the inner relation to join with current outer tuple.
  56.  *
  57.  *    If none is found, next tuple form the outer relation
  58.  *    is retrieved and the inner relation is scanned from the
  59.  *    beginning again to join with the outer tuple.
  60.  *
  61.  *       Nil is returned if all the remaining outer tuples are tried and
  62.  *       all fail to join with the inner tuples.
  63.  *   
  64.  *       If inner subtree is not present, only outer subtree is processed.
  65.  *       
  66.  *       Also, the qualification containing only constant clauses are
  67.  *       checked first before any processing is done. It always returns
  68.  *        'nil' if the constant qualification is not satisfied.
  69.  * ----------------------------------------------------------------
  70.  */
  71. /**** xxref:
  72.  *           ExecProcNode
  73.  *           ExecResult
  74.  ****/
  75. TupleTableSlot
  76. ExecResult(node)
  77.     Result node;
  78. {
  79.     ResultState        resstate;
  80.     TupleTableSlot    outerTupleSlot;
  81.     TupleTableSlot    resultSlot;
  82.     Plan           outerPlan;
  83.     TupleDescriptor     outerType;
  84.     Buffer           outerBuffer;
  85.     
  86.     TupleDescriptor     tupType;
  87.     Pointer        tupValue;
  88.     List        targetList;
  89.     int            len;
  90.     ExprContext        econtext;
  91.     List        qual;
  92.     bool        qualResult;
  93.     bool        isDone;
  94.     int            resloop;
  95.     
  96.     /* ----------------
  97.      *    initialize the result node's state
  98.      * ----------------
  99.      */
  100.     resstate =  get_resstate(node);
  101.     
  102.     /* ----------------
  103.      *    get the expression context
  104.      * ----------------
  105.      */
  106.     econtext = get_cs_ExprContext((CommonState) resstate);
  107.     
  108.     /* ----------------
  109.      *   check tautological qualifications like (2 > 1)
  110.      * ----------------
  111.      */
  112.     qual = get_resconstantqual(node);
  113.     if (! lispNullp(qual)) {
  114.     qualResult = ExecQual(qual, econtext);
  115.     /* ----------------
  116.      *  if we failed the constant qual, then there
  117.      *  is no need to continue processing because regardless of
  118.      *  what happens, the constant qual will be false..
  119.      * ----------------
  120.      */
  121.     if (qualResult == false)
  122.         return NULL;
  123.     
  124.     /* ----------------
  125.      *  our constant qualification succeeded so now we
  126.      *  throw away the qual because we know it will always
  127.      *  succeed.
  128.      * ----------------
  129.      */
  130.     set_resconstantqual(node, LispNil);
  131.     }
  132.     
  133.     if (get_cs_TupFromTlist((CommonState) resstate)) {
  134.     ProjectionInfo projInfo;
  135.  
  136.     projInfo = get_cs_ProjInfo((CommonState)resstate);
  137.     resultSlot = ExecProject(projInfo, &isDone);
  138.     if (!isDone)
  139.         return resultSlot;
  140.     }
  141.     /* ----------------
  142.      *  retrieve tuples from the outer plan until there are no more.
  143.      * ----------------
  144.      */
  145.     for(;;) {
  146.     /* ----------------
  147.      *    if (resloop == 1) then it means that we were asked to return
  148.      *    a constant tuple and we alread did the last time ExecResult()
  149.      *    was called, so now we are through.
  150.      * ----------------
  151.      */
  152.     resloop = get_rs_Loop(resstate);
  153.     if (resloop == 1)
  154.         return NULL;
  155.         
  156.     /* ----------------
  157.      *    get next outer tuple if necessary.
  158.      * ----------------
  159.      */
  160.     outerPlan = (Plan) get_outerPlan((Plan) node);
  161.     
  162.     if (outerPlan != NULL) {
  163.         outerTupleSlot = ExecProcNode(outerPlan);
  164.         
  165.         if (TupIsNull((Pointer) outerTupleSlot))
  166.         return NULL;
  167.         
  168.         set_cs_OuterTupleSlot((CommonState) resstate, outerTupleSlot);
  169.     }
  170.     
  171.     /* ----------------
  172.      *    get the information to place into the expr context
  173.      * ----------------
  174.      */
  175.     qual =            get_resrellevelqual(node);
  176.     resstate =      get_resstate(node);
  177.     outerPlan =     (Plan) get_outerPlan((Plan) node);
  178.     
  179.     outerTupleSlot = get_cs_OuterTupleSlot((CommonState)resstate);
  180.     
  181.     /* ----------------
  182.      *   fill in the information in the expression context
  183.      *   XXX gross hack. use outer tuple as scan tuple
  184.      * ----------------
  185.      */
  186.     set_ecxt_outertuple(econtext,   outerTupleSlot);
  187.     set_ecxt_scantuple(econtext,    outerTupleSlot);
  188.     
  189.     /* ----------------
  190.      *  if we don't have an outer plan, then it's probably
  191.      *  the case that we are doing a retrieve or an append
  192.      *  with a constant target list, so we should only return
  193.      *  the constant tuple once or never if we fail the qual.
  194.      * ----------------
  195.      */
  196.     if (outerPlan == NULL)
  197.         set_rs_Loop(resstate, 1);
  198.             
  199.     /* ----------------
  200.      *    test qualification
  201.      * ----------------
  202.      */
  203.     qualResult = ExecQual(qual, econtext);
  204.     
  205.     if (qualResult == true) {
  206.         /* ----------------
  207.          *   qualification passed, form the result tuple and
  208.          *   pass it back using ExecProject()
  209.          * ----------------
  210.          */
  211.         ProjectionInfo projInfo;
  212.  
  213.         projInfo = get_cs_ProjInfo((CommonState)resstate);
  214.         resultSlot = ExecProject(projInfo, &isDone);
  215.         set_cs_TupFromTlist((CommonState) resstate, !isDone);
  216.         return resultSlot;
  217.     }
  218.     }
  219. }
  220.  
  221. /* ----------------------------------------------------------------
  222.  *       ExecInitResult
  223.  *   
  224.  *       Creates the run-time state information for the nestloop node
  225.  *       produced by the planner and initailizes inner and outer relations 
  226.  *       (child nodes).
  227.  * ----------------------------------------------------------------
  228.  */
  229. /**** xxref:
  230.  *           ExecInitNode
  231.  ****/
  232. List
  233. ExecInitResult(node, estate, parent)
  234.     Plan   node;
  235.     EState estate;
  236.     Plan   parent;
  237. {
  238.     ResultState        resstate;
  239.     TupleDescriptor tupType;
  240.     Pointer        tupValue;
  241.     List        targetList;
  242.     int            len;
  243.     ParamListInfo   paraminfo;
  244.     ExprContext        econtext;
  245.     int            baseid;
  246.     
  247.     /* ----------------
  248.      *    assign execution state to node
  249.      * ----------------
  250.      */
  251.     set_state( node, (EStatePtr)estate);
  252.     
  253.     /* ----------------
  254.      *    create new ResultState for node
  255.      * ----------------
  256.      */
  257.     resstate = MakeResultState(0);
  258.     set_resstate((Result) node, resstate);
  259.         
  260.     /* ----------------
  261.      *  Miscellanious initialization
  262.      *
  263.      *         +    assign node's base_id
  264.      *       +    assign debugging hooks and
  265.      *       +    create expression context for node
  266.      * ----------------
  267.      */
  268.     ExecAssignNodeBaseInfo(estate, (BaseNode) resstate, parent);
  269.     ExecAssignDebugHooks( node, (BaseNode) resstate);
  270.     ExecAssignExprContext(estate, (CommonState) resstate);
  271.  
  272. #define RESULT_NSLOTS 1
  273.     /* ----------------
  274.      *    tuple table initialization
  275.      * ----------------
  276.      */
  277.     ExecInitResultTupleSlot(estate, (CommonState) resstate);
  278.          
  279.     /* ----------------
  280.      *    then initialize children
  281.      * ----------------
  282.      */
  283.     ExecInitNode((Plan) get_outerPlan(node), estate, node);
  284.     ExecInitNode((Plan) get_innerPlan(node), estate, node);
  285.         
  286.     /* ----------------
  287.      *     initialize tuple type and projection info
  288.      * ----------------
  289.      */
  290.     ExecAssignResultTypeFromTL(node, (CommonState)resstate);
  291.     ExecAssignProjectionInfo(node, (CommonState) resstate);
  292.  
  293.     /* ----------------
  294.      *    set "are we done yet" to false
  295.      * ----------------
  296.      */
  297.     set_rs_Loop(resstate, 0);
  298.     
  299.     return LispTrue;
  300. }
  301.  
  302. int
  303. ExecCountSlotsResult(node)
  304.     Plan node;
  305. {
  306.     return ExecCountSlotsNode(get_outerPlan(node)) +
  307.        ExecCountSlotsNode(get_innerPlan(node)) +
  308.        RESULT_NSLOTS;
  309. }
  310.  
  311. /* ----------------------------------------------------------------
  312.  *       ExecEndResult
  313.  *   
  314.  *       fees up storage allocated through C routines
  315.  * ----------------------------------------------------------------
  316.  */
  317. /**** xxref:
  318.  *           ExecEndNode
  319.  ****/
  320. void
  321. ExecEndResult(node)
  322.     Result node;
  323. {
  324.     ResultState        resstate;
  325.     Pointer        tupValue;
  326.     
  327.     resstate = get_resstate(node);
  328.  
  329.     /* ----------------
  330.      *    Free the projection info
  331.      *
  332.      *  Note: we don't ExecFreeResultType(resstate) 
  333.      *        because the rule manager depends on the tupType
  334.      *          returned by ExecMain().  So for now, this
  335.      *          is freed at end-transaction time.  -cim 6/2/91     
  336.      * ----------------
  337.      */    
  338.     ExecFreeProjectionInfo((CommonState)resstate);
  339.     
  340.     /* ----------------
  341.      *    shut down subplans
  342.      * ----------------
  343.      */
  344.     ExecEndNode((Plan) get_outerPlan((Plan)node));
  345.     ExecEndNode((Plan) get_innerPlan((Plan)node));
  346.  
  347.     /* ----------------
  348.      *    clean out the tuple table
  349.      * ----------------
  350.      */
  351.     ExecClearTuple((Pointer)get_cs_ResultTupleSlot((CommonState)resstate));
  352. }
  353.