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

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    material.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    Routines to handle materialization nodes.
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *         ExecMaterial        - generate a temporary relation
  10.  *         ExecInitMaterial    - initialize node and subnodes..
  11.  *         ExecEndMaterial        - shutdown node and subnodes
  12.  *
  13.  *   NOTES
  14.  *    
  15.  *   IDENTIFICATION
  16.  *    $Header: /private/postgres/src/executor/RCS/n_material.c,v 1.8 1992/08/04 17:37:55 mer Exp $
  17.  * ----------------------------------------------------------------
  18.  */
  19.  
  20. #include "executor/executor.h"
  21.  
  22.  RcsId("$Header: /private/postgres/src/executor/RCS/n_material.c,v 1.8 1992/08/04 17:37:55 mer Exp $");
  23.  
  24. /* ----------------------------------------------------------------
  25.  *       ExecMaterial
  26.  *
  27.  *    The first time this is called, ExecMaterial retrieves tuples
  28.  *    this node's outer subplan and inserts them into a temporary
  29.  *    relation.  After this is done, a flag is set indicating that
  30.  *    the subplan has been materialized.  Once the relation is
  31.  *    materialized, the first tuple is then returned.  Successive
  32.  *    calls to ExecMaterial return successive tuples from the temp
  33.  *    relation.
  34.  *
  35.  *    Initial State:
  36.  *
  37.  *    ExecMaterial assumes the temporary relation has been
  38.  *    created and openend by ExecInitMaterial during the prior
  39.  *    InitPlan() phase.
  40.  *
  41.  * ----------------------------------------------------------------
  42.  */
  43. /**** xxref:
  44.  *           ExecProcNode
  45.  ****/
  46. TupleTableSlot            /* result tuple from subplan */
  47. ExecMaterial(node)
  48.     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.     Buffer        buffer;
  60.     
  61.     /* ----------------
  62.      *    get state info from node
  63.      * ----------------
  64.      */
  65.     matstate =       get_matstate(node);
  66.     estate =          (EState) get_state((Plan) node);
  67.     dir =             get_es_direction(estate);
  68.     
  69.     /* ----------------
  70.      *    the first time we call this, we retrieve all tuples
  71.      *  from the subplan into a temporary relation and then
  72.      *  we sort the relation.  Subsequent calls return tuples
  73.      *  from the temporary relation.
  74.      * ----------------
  75.      */
  76.     
  77.     if (get_mat_Flag(matstate) == false) {
  78.     /* ----------------
  79.      *  set all relations to be scanned in the forward direction 
  80.      *  while creating the temporary relation.
  81.      * ----------------
  82.      */
  83.     set_es_direction(estate, EXEC_FRWD);
  84.     
  85.     /* ----------------
  86.      *   if we couldn't create the temp or current relations then
  87.      *   we print a warning and return NULL.
  88.      * ----------------
  89.      */
  90.     tempRelation =  get_mat_TempRelation(matstate);
  91.     if (tempRelation == NULL) {
  92.         elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
  93.         return NULL;
  94.     }
  95.     
  96.     currentRelation = get_css_currentRelation((CommonScanState)matstate);
  97.     if (currentRelation == NULL) {
  98.         elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
  99.         return NULL;
  100.     }
  101.     
  102.     /* ----------------
  103.      *   retrieve tuples from the subplan and
  104.      *   insert them in the temporary relation
  105.      * ----------------
  106.      */
  107.     outerNode =     get_outerPlan((Plan) node);
  108.     for (;;) {
  109.         slot = ExecProcNode(outerNode);
  110.         
  111.         heapTuple = (HeapTuple) ExecFetchTuple((Pointer) slot);
  112.         if (heapTuple == NULL)
  113.         break;
  114.         
  115.         aminsert(tempRelation,     /* relation desc */
  116.              heapTuple,        /* heap tuple to insert */
  117.              0);        /* return: offset */
  118.         
  119.         ExecClearTuple((Pointer) slot);
  120.     }
  121.     currentRelation = tempRelation;
  122.     
  123.     /* ----------------
  124.      *   restore to user specified direction
  125.      * ----------------
  126.      */
  127.     set_es_direction(estate, dir);
  128.     
  129.     /* ----------------
  130.      *   now initialize the scan descriptor to scan the
  131.      *   sorted relation and update the sortstate information
  132.      * ----------------
  133.      */
  134.     currentScanDesc = ambeginscan(currentRelation,    /* relation */
  135.                       (dir == EXEC_BKWD), /* bkwd flag */
  136.                       NowTimeQual,        /* time qual */
  137.                       0,           /* num scan keys */
  138.                       NULL);           /* scan keys */
  139.     set_css_currentRelation((CommonScanState)matstate, currentRelation);
  140.     set_css_currentScanDesc((CommonScanState)matstate, currentScanDesc);
  141.     
  142.     ExecAssignScanType((CommonScanState)matstate,
  143.                TupDescToExecTupDesc(¤tRelation->rd_att,
  144.                     currentRelation->rd_rel->relnatts),
  145.                ¤tRelation->rd_att);
  146.     
  147.     /* ----------------
  148.      *  finally set the sorted flag to true
  149.      * ----------------
  150.      */
  151.     set_mat_Flag(matstate, true);
  152.     }
  153.     
  154.     /* ----------------
  155.      *    at this point we know we have a sorted relation so
  156.      *  we preform a simple scan on it with amgetnext()..
  157.      * ----------------
  158.      */
  159.     currentScanDesc = get_css_currentScanDesc((CommonScanState)matstate);
  160.     
  161.     heapTuple = amgetnext(currentScanDesc,     /* scan desc */
  162.               (dir == EXEC_BKWD),     /* bkwd flag */
  163.               &buffer);         /* return: buffer */
  164.  
  165.     /* ----------------
  166.      *    put the tuple into the scan tuple slot and return the slot.
  167.      *  Note: since the tuple is really a pointer to a page, we don't want
  168.      *  to call pfree() on it..
  169.      * ----------------
  170.      */
  171.     slot = (TupleTableSlot)
  172.     get_css_ScanTupleSlot((CommonScanState)matstate);
  173.  
  174.     return (TupleTableSlot)
  175.     ExecStoreTuple((Pointer) heapTuple,  /* tuple to store */
  176.                (Pointer) slot,      /* slot to store in */
  177.                buffer,       /* buffer for this tuple */
  178.                false);     /* don't pfree this pointer */
  179.     
  180. }
  181.  
  182. /* ----------------------------------------------------------------
  183.  *       ExecInitMaterial
  184.  * ----------------------------------------------------------------
  185.  */
  186. /**** xxref:
  187.  *           ExecInitNode
  188.  ****/
  189. List    /* initialization status */
  190. ExecInitMaterial(node, estate, parent)
  191.     Material     node;
  192.     EState     estate;
  193.     Plan    parent;
  194. {
  195.     MaterialState    matstate;
  196.     Plan        outerPlan;
  197.     TupleDescriptor    tupType;
  198.     Relation        tempDesc;
  199.     int            baseid;
  200.     int            len;
  201.     
  202.     /* ----------------
  203.      *  assign the node's execution state
  204.      * ----------------
  205.      */
  206.     set_state((Plan) node, (EStatePtr)estate);
  207.     
  208.     /* ----------------
  209.      * create state structure
  210.      * ----------------
  211.      */
  212.     matstate = MakeMaterialState(false, NULL);
  213.     set_matstate(node, matstate);
  214.     
  215.     /* ----------------
  216.      *  Miscellanious initialization
  217.      *
  218.      *         +    assign node's base_id
  219.      *       +    assign debugging hooks and
  220.      *       +  assign result tuple slot
  221.      *
  222.      *  Materialization nodes don't need ExprContexts because
  223.      *  they never call ExecQual or ExecTargetList.
  224.      * ----------------
  225.      */
  226.     ExecAssignNodeBaseInfo(estate, (BaseNode) matstate, parent);
  227.     ExecAssignDebugHooks((Plan) node, (BaseNode) matstate);
  228.  
  229. #define MATERIAL_NSLOTS 1
  230.     /* ----------------
  231.      * tuple table initialization
  232.      * ----------------
  233.      */
  234.     ExecInitScanTupleSlot(estate, (CommonScanState)matstate);
  235.     
  236.     /* ----------------
  237.      * initializes child nodes
  238.      * ----------------
  239.      */
  240.     outerPlan = get_outerPlan((Plan) node);
  241.     ExecInitNode(outerPlan, estate, (Plan) node);
  242.     
  243.     /* ----------------
  244.      *    initialize matstate information
  245.      * ----------------
  246.      */
  247.     set_mat_Flag(matstate, false);
  248.  
  249.     /* ----------------
  250.      *     initialize tuple type.  no need to initialize projection
  251.      *  info because this node doesn't do projections.
  252.      * ----------------
  253.      */
  254.     ExecAssignScanTypeFromOuterPlan((Plan) node, (CommonState)matstate);
  255.     set_cs_ProjInfo((CommonState)matstate, NULL);
  256.     
  257.     /* ----------------
  258.      *    get type information needed for ExecCreatR
  259.      * ----------------
  260.      */
  261.     tupType = ExecGetScanType((CommonScanState)matstate);
  262.  
  263.     /* ----------------
  264.      *    ExecCreatR wants it's third argument to be an object id of
  265.      *  a relation in the range table or a negative number like -1
  266.      *  indicating that the relation is not in the range table.
  267.      *
  268.      *  In the second case ExecCreatR creates a temp relation.
  269.      *  (currently this is the only case we support -cim 10/16/89)
  270.      * ----------------
  271.      */
  272.     /* ----------------
  273.      *    create the temporary relation
  274.      * ----------------
  275.      */
  276.     len = ExecTargetListLength(get_qptargetlist((Plan) node));
  277.     tempDesc =     ExecCreatR(len, tupType, -1);
  278.     
  279.     /* ----------------
  280.      *    save the relation descriptor in the sortstate
  281.      * ----------------
  282.      */
  283.     set_mat_TempRelation(matstate, tempDesc);
  284.     set_css_currentRelation((CommonScanState)matstate, tempDesc);
  285.     
  286.     /* ----------------
  287.      *  return relation oid of temporary relation in a list
  288.      *    (someday -- for now we return LispTrue... cim 10/12/89)
  289.      * ----------------
  290.      */
  291.     return
  292.     LispTrue;
  293. }
  294.  
  295. int
  296. ExecCountSlotsMaterial(node)
  297.     Plan node;
  298. {
  299.     return ExecCountSlotsNode(get_outerPlan(node)) +
  300.        ExecCountSlotsNode(get_innerPlan(node)) +
  301.        MATERIAL_NSLOTS;
  302. }
  303.  
  304. /* ----------------------------------------------------------------
  305.  *       ExecEndMaterial
  306.  *
  307.  * old comments
  308.  *       destroys the temporary relation.
  309.  * ----------------------------------------------------------------
  310.  */
  311.  
  312. /**** xxref:
  313.  *           ExecEndNode
  314.  ****/
  315. void
  316. ExecEndMaterial(node)
  317.     Material node;
  318. {
  319.     MaterialState    matstate;
  320.     Relation        tempRelation;
  321.     Plan        outerPlan;
  322.     
  323.     /* ----------------
  324.      *    get info from the material state 
  325.      * ----------------
  326.      */
  327.     matstate = get_matstate(node);
  328.     tempRelation = get_mat_TempRelation(matstate);
  329.     
  330.     /* ----------------
  331.      *    the temporary relations are not cataloged so
  332.      *  we can't call DestroyRelation() so we unlink the
  333.      *  unix file explicitly.  Yet another hack -- the
  334.      *  amclose routine should explicitly destroy temp relations
  335.      *  but it doesn't yet -cim 1/25/90
  336.      * ----------------
  337.      */
  338.     if (FileNameUnlink((char *) relpath((char *)
  339.                     &(tempRelation->rd_rel->relname))) < 0)
  340.     elog(WARN, "ExecEndMaterial: unlink: %m");
  341.     amclose(tempRelation);
  342.     
  343.     /* ----------------
  344.      *    close the temp relation and shut down the scan.
  345.      * ----------------
  346.      */
  347.     ExecCloseR((Plan) node);
  348.     
  349.     /* ----------------
  350.      *    shut down the subplan
  351.      * ----------------
  352.      */
  353.     outerPlan = get_outerPlan((Plan) node);
  354.     ExecEndNode(outerPlan);
  355.     
  356.     /* ----------------
  357.      *    clean out the tuple table
  358.      * ----------------
  359.      */
  360.     ExecClearTuple((Pointer) get_css_ScanTupleSlot((CommonScanState)matstate));
  361.  
  362. /* ----------------------------------------------------------------
  363.  *    ExecMaterialMarkPos
  364.  * ----------------------------------------------------------------
  365.  */
  366. /**** xxref:
  367.  *           <apparently-unused>
  368.  ****/
  369. List /* nothing of interest */
  370. ExecMaterialMarkPos(node)
  371.     Material node;
  372. {
  373.     MaterialState     matstate;
  374.     HeapScanDesc     sdesc;
  375.     
  376.     /* ----------------
  377.      *    if we haven't materialized yet, just return LispNil.
  378.      * ----------------
  379.      */
  380.     matstate =          get_matstate(node);
  381.     if (get_mat_Flag(matstate) == false)
  382.     return LispNil;
  383.     
  384.     /* ----------------
  385.      *  XXX access methods don't return positions yet so
  386.      *      for now we return LispNil.  It's possible that
  387.      *      they will never return positions for all I know -cim 10/16/89
  388.      * ----------------
  389.      */
  390.     sdesc = get_css_currentScanDesc((CommonScanState)matstate);
  391.     ammarkpos(sdesc);
  392.     
  393.     return LispNil;
  394. }
  395.  
  396. /* ----------------------------------------------------------------
  397.  *    ExecMaterialRestrPos
  398.  * ----------------------------------------------------------------
  399.  */
  400. /**** xxref:
  401.  *           <apparently-unused>
  402.  ****/
  403. void
  404. ExecMaterialRestrPos(node)
  405.     Material node;
  406. {
  407.     MaterialState    matstate;
  408.     HeapScanDesc     sdesc;
  409.     
  410.     /* ----------------
  411.      *    if we haven't materialized yet, just return.
  412.      * ----------------
  413.      */
  414.     matstate =  get_matstate(node);
  415.     if (get_mat_Flag(matstate) == false)
  416.     return;
  417.     
  418.     /* ----------------
  419.      *    restore the scan to the previously marked position
  420.      * ----------------
  421.      */
  422.     sdesc = get_css_currentScanDesc((CommonScanState)matstate);
  423.     amrestrpos(sdesc);
  424. }
  425.  
  426.