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

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    ex_ami.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    miscellanious executor access method routines
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *
  10.  *       ExecOpenScanR    \                  /    amopen
  11.  *       ExecBeginScan     \                 /    ambeginscan
  12.  *       ExecCloseR      \                /    amclose
  13.  *        ExecInsert       \  executor interface   /    aminsert
  14.  *       ExecReScanNode       /  to access methods    \    amrescan
  15.  *       ExecReScanR      /                \    amrescan
  16.  *       ExecMarkPos     /                 \    ammarkpos
  17.  *       ExecRestrPos    /                  \    amrestpos
  18.  *
  19.  *    ExecCreatR    function to create temporary relations
  20.  *
  21.  *   NOTES
  22.  *    
  23.  *   IDENTIFICATION
  24.  *    $Header: /private/postgres/src/executor/RCS/ex_ami.c,v 1.8 1992/02/27 05:24:53 mer Exp $
  25.  * ----------------------------------------------------------------
  26.  */
  27.  
  28. #include "executor/executor.h"
  29. #include "storage/smgr.h"
  30.  
  31.  RcsId("$Header: /private/postgres/src/executor/RCS/ex_ami.c,v 1.8 1992/02/27 05:24:53 mer Exp $");
  32.  
  33. /* ----------------------------------------------------------------
  34.  *       ExecOpenScanR
  35.  *
  36.  * old comments:
  37.  *       Parameters:
  38.  *         relation -- relation to be opened and scanned.
  39.  *         nkeys       -- number of keys
  40.  *         skeys    -- keys to restrict scanning
  41.  *           isindex  -- if this is true, the relation is the relid of
  42.  *                       an index relation, else it is an index into the
  43.  *                       range table.
  44.  *       Returns the relation as(relDesc scanDesc)
  45.  *         If this structure is changed, need to modify the access macros
  46.  *       defined in execInt.h.
  47.  * ----------------------------------------------------------------
  48.  */
  49.  
  50. /**** xxref:
  51.  *           ExecInitIndexScan
  52.  *           ExecInitSeqScan
  53.  ****/
  54. void
  55. ExecOpenScanR(relOid, nkeys, skeys, isindex, dir, timeRange,
  56.           returnRelation, returnScanDesc)
  57.     ObjectId       relOid;
  58.     int       nkeys;
  59.     ScanKey       skeys;
  60.     bool       isindex;
  61.     ScanDirection dir;
  62.     TimeQual       timeRange;
  63.     Relation       *returnRelation;        /* return */
  64.     Pointer      *returnScanDesc;         /* return */
  65. {
  66.     Relation relation;
  67.     Pointer  scanDesc;
  68.     
  69.     /* ----------------
  70.      *    note: scanDesc returned by ExecBeginScan can be either
  71.      *          a HeapScanDesc or an IndexScanDesc so for now we
  72.      *          make it a Pointer.  There should be a better scan
  73.      *          abstraction someday -cim 9/9/89
  74.      * ----------------
  75.      */
  76.     relation = ExecOpenR(relOid, isindex);
  77.     scanDesc = ExecBeginScan(relation,
  78.                  nkeys,
  79.                  skeys,
  80.                  isindex,
  81.                  dir,
  82.                  timeRange);
  83.     
  84.     if (returnRelation != NULL)
  85.     *returnRelation = relation;
  86.     if (scanDesc != NULL)
  87.     *returnScanDesc = scanDesc;
  88. }
  89.  
  90. /* ----------------------------------------------------------------
  91.  *    ExecOpenR
  92.  *
  93.  *    returns a relation descriptor given an object id.
  94.  * ----------------------------------------------------------------
  95.  */
  96. /**** xxref:
  97.  *           ExecOpenScanR
  98.  ****/
  99. Relation
  100. ExecOpenR(relationOid, isindex)
  101.     ObjectId     relationOid;
  102.     bool    isindex;
  103. {
  104.     Relation relation;
  105.     relation = (Relation) NULL;
  106.  
  107.     /* ----------------
  108.      *    open the relation with the correct call depending
  109.      *  on whether this is a heap relation or an index relation.
  110.      *  note: I am not certain that AMopen supports index scans
  111.      *        correctly yet! -cim 9/9/89
  112.      * ----------------
  113.      */
  114.     if (isindex) {
  115.     relation = AMopen(relationOid);
  116.     } else
  117.     relation = amopen(relationOid);
  118.     
  119.     if (relation == NULL)
  120.     elog(DEBUG, "ExecOpenR: relation == NULL, amopen failed.");
  121.  
  122.     return relation;
  123. }
  124.  
  125. /* ----------------------------------------------------------------
  126.  *       ExecBeginScan
  127.  *
  128.  *       beginscans a relation in current direction.
  129.  *
  130.  *    XXX fix parameters to AMbeginscan (and btbeginscan)
  131.  *        currently we need to pass a flag stating whether
  132.  *        or not the scan should begin at an endpoint of
  133.  *        the relation.. Right now we always pass false
  134.  *        -cim 9/14/89
  135.  * ----------------------------------------------------------------
  136.  */
  137. /**** xxref:
  138.  *           ExecOpenScanR
  139.  ****/
  140. Pointer
  141. ExecBeginScan(relation, nkeys, skeys, isindex, dir, time_range)
  142.     Relation       relation;
  143.     int       nkeys;
  144.     ScanKey      skeys;
  145.     bool      isindex;
  146.     ScanDirection dir;
  147.     TimeQual      time_range;
  148. {
  149.     Pointer     scanDesc;
  150.     
  151.     scanDesc =      NULL;
  152.  
  153.     /* ----------------
  154.      *    open the appropriate type of scan.
  155.      *    
  156.      *  Note: ambeginscan()'s second arg is a boolean indicating
  157.      *          that the scan should be done in reverse..  That is,
  158.      *          if you pass it true, then the scan is backward.
  159.      * ----------------
  160.      */
  161.     if (isindex) {
  162.     scanDesc = (Pointer) AMbeginscan(relation,
  163.                      false,    /* see above comment */
  164.                      nkeys,
  165.                      skeys);
  166.     } else {
  167.     scanDesc = (Pointer) ambeginscan(relation,
  168.                      (dir == EXEC_BKWD),
  169.                      time_range,
  170.                      nkeys,
  171.                      skeys);
  172.     }
  173.    
  174.     if (scanDesc == NULL)
  175.     elog(DEBUG, "ExecBeginScan: scanDesc = NULL, ambeginscan failed.");
  176.     
  177.     
  178.     return scanDesc;
  179. }
  180.  
  181. /* ----------------------------------------------------------------
  182.  *       ExecCloseR
  183.  *
  184.  *    closes the relation and scan descriptor for a scan or sort
  185.  *    node.  Also closes index relations and scans for index scans.
  186.  *
  187.  * old comments
  188.  *       closes the relation indicated in 'relID'
  189.  * ----------------------------------------------------------------
  190.  */
  191.  
  192. /**** xxref:
  193.  *           ExecEndHashJoin
  194.  *           ExecEndIndexScan
  195.  *           ExecEndMaterial
  196.  *           ExecEndSeqScan
  197.  *           ExecEndSort
  198.  ****/
  199. void
  200. ExecCloseR(node)
  201.     Plan    node;
  202. {
  203.     Pointer     state;
  204.     Relation     relation;
  205.     HeapScanDesc scanDesc;
  206.     
  207.     /* ----------------
  208.      *  shut down the heap scan and close the heap relation
  209.      * ----------------
  210.      */
  211.     switch (NodeType(node)) {
  212.     
  213.     case classTag(SeqScan):
  214.     case classTag(IndexScan):
  215.     state =  (Pointer) get_scanstate((Scan) node);
  216.     break;
  217.     
  218.     case classTag(Material):
  219.     state =  (Pointer) get_matstate((Material) node);
  220.     break;
  221.     
  222.     case classTag(Sort):
  223.     state =  (Pointer) get_sortstate((Sort) node);
  224.     break;
  225.  
  226.     case classTag(Agg):
  227.     state = (Pointer) get_aggstate((Agg) node);
  228.     break;
  229.  
  230.     default:
  231.     elog(DEBUG, "ExecCloseR: not a scan, material, or sort node!");
  232.     return;
  233.     }
  234.     
  235.     relation = get_css_currentRelation((CommonScanState) state);
  236.     scanDesc = get_css_currentScanDesc((CommonScanState) state);
  237.     
  238.     if (scanDesc != NULL)
  239.     amendscan(scanDesc);
  240.     
  241.     if (relation != NULL)
  242.     amclose(relation);
  243.     
  244.     /* ----------------
  245.      *    if this is an index scan then we have to take care
  246.      *  of the index relations as well..
  247.      * ----------------
  248.      */
  249.     if (ExecIsIndexScan(node)) {
  250.     IndexScanState     indexstate;
  251.     int         numIndices;
  252.     RelationPtr     indexRelationDescs;
  253.     IndexScanDescPtr indexScanDescs;
  254.     int         i;
  255.     
  256.     indexstate =          get_indxstate((IndexScan) node);
  257.     numIndices =         get_iss_NumIndices(indexstate);
  258.     indexRelationDescs = get_iss_RelationDescs(indexstate);
  259.     indexScanDescs =     get_iss_ScanDescs(indexstate);
  260.     
  261.     for (i = 0; i<numIndices; i++) {
  262.         /* ----------------
  263.          *    shut down each of the scans and
  264.          *  close each of the index relations
  265.          *
  266.          *  note: should this be using AMendscan and AMclose??
  267.          *        -cim 9/10/89
  268.          *  YES!! -mer 2/26/92
  269.          * ----------------
  270.          */
  271.         if (indexScanDescs[i] != NULL)
  272.         AMendscan(indexScanDescs[i]);
  273.         
  274.         if (indexRelationDescs[i] != NULL)
  275.         AMclose(indexRelationDescs[i]);
  276.     }
  277.     }
  278. }
  279.  
  280. /* ----------------------------------------------------------------
  281.  *       ExecReScan
  282.  *
  283.  *    XXX this should be extended to cope with all the node types..
  284.  * ----------------------------------------------------------------
  285.  */
  286.  
  287. /**** xxref:
  288.  *           ExecNestLoop
  289.  *           ExecSeqReScan
  290.  ****/
  291. void
  292. ExecReScan(node)
  293.     Plan node;
  294. {
  295.     switch(NodeType(node)) {
  296.     case classTag(SeqScan):
  297.     ExecSeqReScan((Plan)  node);
  298.     return;
  299.     
  300.     case classTag(IndexScan):
  301.     ExecIndexReScan((IndexScan) node);
  302.     return;
  303.  
  304.     case classTag(Material):
  305.     /* the first call to ExecReScan should have no effect because
  306.      * everything is initialized properly already.  the following
  307.      * calls will be handled by ExecSeqReScan() because the nodes
  308.      * below the Material node have already been materialized into
  309.      * a temp relation.
  310.      */
  311.     return;
  312.     default:
  313.     elog(DEBUG, "ExecReScan: not a seqscan or indexscan node.");
  314.     return;
  315.     }
  316. }
  317.  
  318. /* ----------------------------------------------------------------
  319.  *       ExecReScanR
  320.  *
  321.  *    XXX this does not do the right thing with indices yet.
  322.  * ----------------------------------------------------------------
  323.  */
  324.  
  325. /**** xxref:
  326.  *           ExecSeqReScan
  327.  ****/
  328. HeapScanDesc
  329. ExecReScanR(relDesc, scanDesc, direction, nkeys, skeys)
  330.     Relation      relDesc;    /* LLL relDesc unused  */
  331.     HeapScanDesc  scanDesc;
  332.     ScanDirection direction;
  333.     int          nkeys;    /* LLL nkeys unused  */
  334.     ScanKey      skeys;
  335. {
  336.     if (scanDesc != NULL)
  337.     amrescan(scanDesc,            /* scan desc */
  338.          (direction == EXEC_BKWD),      /* backward flag */
  339.          skeys);            /* scan keys */
  340.     
  341.     return scanDesc;
  342. }
  343.  
  344. /* ----------------------------------------------------------------
  345.  *       ExecMarkPos
  346.  *
  347.  *    Marks the current scan position.  Someday mabey the scan
  348.  *    position will be returned but currently the routines 
  349.  *    just return LispNil.
  350.  *
  351.  *    XXX Needs to be extended to include all the node types.
  352.  * ----------------------------------------------------------------
  353.  */
  354.  
  355. /**** xxref:
  356.  *           ExecMergeJoin
  357.  *           ExecNestLoop
  358.  *           ExecSeqMarkPos
  359.  ****/
  360. List
  361. ExecMarkPos(node)
  362.     Plan node;
  363. {
  364.     switch(NodeType(node)) {
  365.     case classTag(SeqScan):
  366.     return ExecSeqMarkPos((Plan) node);
  367.     
  368.     case classTag(IndexScan):
  369.     return ExecIndexMarkPos((IndexScan) node);
  370.     
  371.     case classTag(Sort):
  372.     return ExecSortMarkPos((Plan) node);
  373.  
  374.     default:
  375.     /* elog(DEBUG, "ExecMarkPos: unsupported node type"); */
  376.     return LispNil;
  377.     }
  378. }
  379.  
  380. /* ----------------------------------------------------------------
  381.  *       ExecRestrPos
  382.  *
  383.  *       restores the scan position previously saved with ExecMarkPos()
  384.  * ----------------------------------------------------------------
  385.  */
  386.  
  387. /**** xxref:
  388.  *           ExecMergeJoin
  389.  *           ExecNestLoop
  390.  *           ExecSeqRestrPos
  391.  ****/
  392. void
  393. ExecRestrPos(node)
  394.     Plan node;
  395. {
  396.     switch(NodeType(node)) {
  397.     case classTag(SeqScan):
  398.     ExecSeqRestrPos((Plan) node);
  399.     return;
  400.     
  401.     case classTag(IndexScan):
  402.     ExecIndexRestrPos((IndexScan) node);
  403.     return;
  404.     
  405.     case classTag(Sort):
  406.     ExecSortRestrPos((Plan) node);
  407.     return;
  408.  
  409.     default:
  410.     /* elog(DEBUG, "ExecRestrPos: node type not supported"); */
  411.     return;
  412.     }
  413. }
  414.  
  415. /* ----------------------------------------------------------------
  416.  *       ExecCreatR
  417.  *
  418.  * old comments
  419.  *       Creates a relation.
  420.  *
  421.  *       Parameters:
  422.  *         noAttr    -- number of attributes in the created relation.
  423.  *         attrType  -- type information on the attributes.
  424.  *         accessMtd -- access methods used to access the created relation.
  425.  *         relation  -- optional. Either an index to the range table or
  426.  *                  negative number indicating a temporary relation.
  427.  *                  A temporary relation is assume is this field is absent.
  428.  * ----------------------------------------------------------------
  429.  */
  430. int tmpcnt = 0;            /* used to generate unique temp names */
  431.  
  432. /**** xxref:
  433.  *           ExecInitHashJoin
  434.  *           ExecInitMaterial
  435.  *           ExecInitSort
  436.  ****/
  437. Relation
  438. ExecCreatR(numberAttributes, tupType, relationOid)
  439.     int          numberAttributes;
  440.     TupleDescriptor    tupType;
  441.     int            relationOid;
  442. {
  443.     char     tempname[40];
  444.     char     archiveMode;
  445.     Relation     relDesc;
  446.     
  447.     EU4_printf("ExecCreatR: %s numatts=%d type=%d oid=%d\n",
  448.            "entering: ", numberAttributes, tupType, relationOid);
  449.     CXT1_printf("ExecCreatR: context is %d\n", CurrentMemoryContext);
  450.     
  451.     relDesc = NULL;
  452.     bzero(tempname, 40);
  453.     
  454.     if (relationOid < 0) {
  455.     /* ----------------
  456.      *   create a temporary relation
  457.      *   (currently the planner always puts a -1 in the relation
  458.      *    argument so we expect this to be the case although
  459.      *    it's possible that someday we'll get the name from
  460.      *    from the range table.. -cim 10/12/89)
  461.      * ----------------
  462.      */
  463.     sprintf(tempname, "temp_%d.%d", getpid(), tmpcnt++);
  464.     EU1_printf("ExecCreatR: attempting to create %s\n", tempname);
  465.     relDesc = amcreatr(tempname,
  466.                numberAttributes,
  467.                DEFAULT_SMGR,
  468.                (struct attribute **)tupType);
  469.     } else {
  470.     /* ----------------
  471.      *    use a relation from the range table
  472.      * ----------------
  473.      */
  474.     elog(DEBUG, "ExecCreatR: %s",
  475.          "stuff using range table id's is not functional");
  476.     }
  477.     
  478.     if (relDesc == NULL)
  479.     elog(DEBUG, "ExecCreatR: failed to create relation.");
  480.     
  481.     EU1_printf("ExecCreatR: returning relDesc=%d\n", relDesc);
  482.     
  483.     return relDesc;
  484. }
  485.  
  486.