LTP GCOV extension - code coverage report
Current view: directory - access/index - genam.c
Test: unnamed
Date: 2008-07-03 Instrumented lines: 53
Code covered: 100.0 % Executed lines: 53
Legend: not executed executed

       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * genam.c
       4                 :  *        general index access method routines
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
       7                 :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :  *
       9                 :  *
      10                 :  * IDENTIFICATION
      11                 :  *        $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.63 2007/09/20 17:56:30 tgl Exp $
      12                 :  *
      13                 :  * NOTES
      14                 :  *        many of the old access method routines have been turned into
      15                 :  *        macros and moved to genam.h -cim 4/30/91
      16                 :  *
      17                 :  *-------------------------------------------------------------------------
      18                 :  */
      19                 : 
      20                 : #include "postgres.h"
      21                 : 
      22                 : #include "access/genam.h"
      23                 : #include "access/heapam.h"
      24                 : #include "access/transam.h"
      25                 : #include "miscadmin.h"
      26                 : #include "pgstat.h"
      27                 : 
      28                 : 
      29                 : /* ----------------------------------------------------------------
      30                 :  *              general access method routines
      31                 :  *
      32                 :  *              All indexed access methods use an identical scan structure.
      33                 :  *              We don't know how the various AMs do locking, however, so we don't
      34                 :  *              do anything about that here.
      35                 :  *
      36                 :  *              The intent is that an AM implementor will define a beginscan routine
      37                 :  *              that calls RelationGetIndexScan, to fill in the scan, and then does
      38                 :  *              whatever kind of locking he wants.
      39                 :  *
      40                 :  *              At the end of a scan, the AM's endscan routine undoes the locking,
      41                 :  *              but does *not* call IndexScanEnd --- the higher-level index_endscan
      42                 :  *              routine does that.      (We can't do it in the AM because index_endscan
      43                 :  *              still needs to touch the IndexScanDesc after calling the AM.)
      44                 :  *
      45                 :  *              Because of this, the AM does not have a choice whether to call
      46                 :  *              RelationGetIndexScan or not; its beginscan routine must return an
      47                 :  *              object made by RelationGetIndexScan.  This is kinda ugly but not
      48                 :  *              worth cleaning up now.
      49                 :  * ----------------------------------------------------------------
      50                 :  */
      51                 : 
      52                 : /* ----------------
      53                 :  *      RelationGetIndexScan -- Create and fill an IndexScanDesc.
      54                 :  *
      55                 :  *              This routine creates an index scan structure and sets its contents
      56                 :  *              up correctly. This routine calls AMrescan to set up the scan with
      57                 :  *              the passed key.
      58                 :  *
      59                 :  *              Parameters:
      60                 :  *                              indexRelation -- index relation for scan.
      61                 :  *                              nkeys -- count of scan keys.
      62                 :  *                              key -- array of scan keys to restrict the index scan.
      63                 :  *
      64                 :  *              Returns:
      65                 :  *                              An initialized IndexScanDesc.
      66                 :  * ----------------
      67                 :  */
      68                 : IndexScanDesc
      69                 : RelationGetIndexScan(Relation indexRelation,
      70                 :                                          int nkeys, ScanKey key)
      71          118528 : {
      72                 :         IndexScanDesc scan;
      73                 : 
      74          118528 :         scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData));
      75                 : 
      76          118528 :         scan->heapRelation = NULL;   /* may be set later */
      77          118528 :         scan->indexRelation = indexRelation;
      78          118528 :         scan->xs_snapshot = SnapshotNow;     /* may be set later */
      79          118528 :         scan->numberOfKeys = nkeys;
      80                 : 
      81                 :         /*
      82                 :          * We allocate the key space here, but the AM is responsible for actually
      83                 :          * filling it from the passed key array.
      84                 :          */
      85          118528 :         if (nkeys > 0)
      86          118488 :                 scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
      87                 :         else
      88              40 :                 scan->keyData = NULL;
      89                 : 
      90          118528 :         scan->is_multiscan = false; /* caller may change this */
      91          118528 :         scan->kill_prior_tuple = false;
      92          118528 :         scan->ignore_killed_tuples = true;   /* default setting */
      93                 : 
      94          118528 :         scan->opaque = NULL;
      95                 : 
      96          118528 :         ItemPointerSetInvalid(&scan->xs_ctup.t_self);
      97          118528 :         scan->xs_ctup.t_data = NULL;
      98          118528 :         scan->xs_cbuf = InvalidBuffer;
      99          118528 :         scan->xs_prev_xmax = InvalidTransactionId;
     100          118528 :         scan->xs_next_hot = InvalidOffsetNumber;
     101          118528 :         scan->xs_hot_dead = false;
     102                 : 
     103                 :         /*
     104                 :          * Let the AM fill in the key and any opaque data it wants.
     105                 :          */
     106          118528 :         index_rescan(scan, key);
     107                 : 
     108          118528 :         return scan;
     109                 : }
     110                 : 
     111                 : /* ----------------
     112                 :  *      IndexScanEnd -- End an index scan.
     113                 :  *
     114                 :  *              This routine just releases the storage acquired by
     115                 :  *              RelationGetIndexScan().  Any AM-level resources are
     116                 :  *              assumed to already have been released by the AM's
     117                 :  *              endscan routine.
     118                 :  *
     119                 :  *      Returns:
     120                 :  *              None.
     121                 :  * ----------------
     122                 :  */
     123                 : void
     124                 : IndexScanEnd(IndexScanDesc scan)
     125          118502 : {
     126          118502 :         if (scan->keyData != NULL)
     127          118464 :                 pfree(scan->keyData);
     128                 : 
     129          118502 :         pfree(scan);
     130          118502 : }
     131                 : 
     132                 : 
     133                 : /* ----------------------------------------------------------------
     134                 :  *              heap-or-index-scan access to system catalogs
     135                 :  *
     136                 :  *              These functions support system catalog accesses that normally use
     137                 :  *              an index but need to be capable of being switched to heap scans
     138                 :  *              if the system indexes are unavailable.
     139                 :  *
     140                 :  *              The specified scan keys must be compatible with the named index.
     141                 :  *              Generally this means that they must constrain either all columns
     142                 :  *              of the index, or the first K columns of an N-column index.
     143                 :  *
     144                 :  *              These routines could work with non-system tables, actually,
     145                 :  *              but they're only useful when there is a known index to use with
     146                 :  *              the given scan keys; so in practice they're only good for
     147                 :  *              predetermined types of scans of system catalogs.
     148                 :  * ----------------------------------------------------------------
     149                 :  */
     150                 : 
     151                 : /*
     152                 :  * systable_beginscan --- set up for heap-or-index scan
     153                 :  *
     154                 :  *      rel: catalog to scan, already opened and suitably locked
     155                 :  *      indexId: OID of index to conditionally use
     156                 :  *      indexOK: if false, forces a heap scan (see notes below)
     157                 :  *      snapshot: time qual to use (usually should be SnapshotNow)
     158                 :  *      nkeys, key: scan keys
     159                 :  *
     160                 :  * The attribute numbers in the scan key should be set for the heap case.
     161                 :  * If we choose to index, we reset them to 1..n to reference the index
     162                 :  * columns.  Note this means there must be one scankey qualification per
     163                 :  * index column!  This is checked by the Asserts in the normal, index-using
     164                 :  * case, but won't be checked if the heapscan path is taken.
     165                 :  *
     166                 :  * The routine checks the normal cases for whether an indexscan is safe,
     167                 :  * but caller can make additional checks and pass indexOK=false if needed.
     168                 :  * In standard case indexOK can simply be constant TRUE.
     169                 :  */
     170                 : SysScanDesc
     171                 : systable_beginscan(Relation heapRelation,
     172                 :                                    Oid indexId,
     173                 :                                    bool indexOK,
     174                 :                                    Snapshot snapshot,
     175                 :                                    int nkeys, ScanKey key)
     176          114256 : {
     177                 :         SysScanDesc sysscan;
     178                 :         Relation        irel;
     179                 : 
     180          222987 :         if (indexOK &&
     181                 :                 !IgnoreSystemIndexes &&
     182                 :                 !ReindexIsProcessingIndex(indexId))
     183          108731 :                 irel = index_open(indexId, AccessShareLock);
     184                 :         else
     185            5525 :                 irel = NULL;
     186                 : 
     187          114256 :         sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));
     188                 : 
     189          114256 :         sysscan->heap_rel = heapRelation;
     190          114256 :         sysscan->irel = irel;
     191                 : 
     192          114256 :         if (irel)
     193                 :         {
     194                 :                 int                     i;
     195                 : 
     196                 :                 /*
     197                 :                  * Change attribute numbers to be index column numbers.
     198                 :                  *
     199                 :                  * This code could be generalized to search for the index key numbers
     200                 :                  * to substitute, but for now there's no need.
     201                 :                  */
     202          293440 :                 for (i = 0; i < nkeys; i++)
     203                 :                 {
     204                 :                         Assert(key[i].sk_attno == irel->rd_index->indkey.values[i]);
     205          184709 :                         key[i].sk_attno = i + 1;
     206                 :                 }
     207                 : 
     208          108731 :                 sysscan->iscan = index_beginscan(heapRelation, irel,
     209                 :                                                                                  snapshot, nkeys, key);
     210          108731 :                 sysscan->scan = NULL;
     211                 :         }
     212                 :         else
     213                 :         {
     214            5525 :                 sysscan->scan = heap_beginscan(heapRelation, snapshot, nkeys, key);
     215            5525 :                 sysscan->iscan = NULL;
     216                 :         }
     217                 : 
     218          114256 :         return sysscan;
     219                 : }
     220                 : 
     221                 : /*
     222                 :  * systable_getnext --- get next tuple in a heap-or-index scan
     223                 :  *
     224                 :  * Returns NULL if no more tuples available.
     225                 :  *
     226                 :  * Note that returned tuple is a reference to data in a disk buffer;
     227                 :  * it must not be modified, and should be presumed inaccessible after
     228                 :  * next getnext() or endscan() call.
     229                 :  */
     230                 : HeapTuple
     231                 : systable_getnext(SysScanDesc sysscan)
     232          196364 : {
     233                 :         HeapTuple       htup;
     234                 : 
     235          196364 :         if (sysscan->irel)
     236          179663 :                 htup = index_getnext(sysscan->iscan, ForwardScanDirection);
     237                 :         else
     238           16701 :                 htup = heap_getnext(sysscan->scan, ForwardScanDirection);
     239                 : 
     240          196364 :         return htup;
     241                 : }
     242                 : 
     243                 : /*
     244                 :  * systable_endscan --- close scan, release resources
     245                 :  *
     246                 :  * Note that it's still up to the caller to close the heap relation.
     247                 :  */
     248                 : void
     249                 : systable_endscan(SysScanDesc sysscan)
     250          114246 : {
     251          114246 :         if (sysscan->irel)
     252                 :         {
     253          108721 :                 index_endscan(sysscan->iscan);
     254          108721 :                 index_close(sysscan->irel, AccessShareLock);
     255                 :         }
     256                 :         else
     257            5525 :                 heap_endscan(sysscan->scan);
     258                 : 
     259          114246 :         pfree(sysscan);
     260          114246 : }

Generated by: LTP GCOV extension version 1.5