LCOV - differential code coverage report
Current view: top level - src/backend/access/spgist - spginsert.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 93.9 % 66 62 4 11 51 23
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 4 4 1 3
Baseline: 16@8cea358b128 Branches: 58.3 % 24 14 10 14
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 100.0 % 11 11 11
(240..) days: 92.7 % 55 51 4 51
Function coverage date bins:
(240..) days: 100.0 % 4 4 1 3
Branch coverage date bins:
(240..) days: 58.3 % 24 14 10 14

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * spginsert.c
                                  4                 :                :  *    Externally visible index creation/insertion routines
                                  5                 :                :  *
                                  6                 :                :  * All the actual insertion logic is in spgdoinsert.c.
                                  7                 :                :  *
                                  8                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  9                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 10                 :                :  *
                                 11                 :                :  * IDENTIFICATION
                                 12                 :                :  *          src/backend/access/spgist/spginsert.c
                                 13                 :                :  *
                                 14                 :                :  *-------------------------------------------------------------------------
                                 15                 :                :  */
                                 16                 :                : 
                                 17                 :                : #include "postgres.h"
                                 18                 :                : 
                                 19                 :                : #include "access/genam.h"
                                 20                 :                : #include "access/spgist_private.h"
                                 21                 :                : #include "access/tableam.h"
                                 22                 :                : #include "access/xloginsert.h"
                                 23                 :                : #include "miscadmin.h"
                                 24                 :                : #include "nodes/execnodes.h"
                                 25                 :                : #include "storage/bufmgr.h"
                                 26                 :                : #include "storage/bulk_write.h"
                                 27                 :                : #include "utils/memutils.h"
                                 28                 :                : #include "utils/rel.h"
                                 29                 :                : 
                                 30                 :                : 
                                 31                 :                : typedef struct
                                 32                 :                : {
                                 33                 :                :     SpGistState spgstate;       /* SPGiST's working state */
                                 34                 :                :     int64       indtuples;      /* total number of tuples indexed */
                                 35                 :                :     MemoryContext tmpCtx;       /* per-tuple temporary context */
                                 36                 :                : } SpGistBuildState;
                                 37                 :                : 
                                 38                 :                : 
                                 39                 :                : /* Callback to process one heap tuple during table_index_build_scan */
                                 40                 :                : static void
 1619 andres@anarazel.de         41                 :CBC      281387 : spgistBuildCallback(Relation index, ItemPointer tid, Datum *values,
                                 42                 :                :                     bool *isnull, bool tupleIsAlive, void *state)
                                 43                 :                : {
 4502 tgl@sss.pgh.pa.us          44                 :         281387 :     SpGistBuildState *buildstate = (SpGistBuildState *) state;
                                 45                 :                :     MemoryContext oldCtx;
                                 46                 :                : 
                                 47                 :                :     /* Work in temp context, and reset it after each tuple */
 4417                            48                 :         281387 :     oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx);
                                 49                 :                : 
                                 50                 :                :     /*
                                 51                 :                :      * Even though no concurrent insertions can be happening, we still might
                                 52                 :                :      * get a buffer-locking failure due to bgwriter or checkpointer taking a
                                 53                 :                :      * lock on some buffer.  So we need to be willing to retry.  We can flush
                                 54                 :                :      * any temp data when retrying.
                                 55                 :                :      */
 1619 andres@anarazel.de         56         [ -  + ]:         281387 :     while (!spgdoinsert(index, &buildstate->spgstate, tid,
                                 57                 :                :                         values, isnull))
                                 58                 :                :     {
 3816 tgl@sss.pgh.pa.us          59                 :UBC           0 :         MemoryContextReset(buildstate->tmpCtx);
                                 60                 :                :     }
                                 61                 :                : 
                                 62                 :                :     /* Update total tuple count */
 2215 tgl@sss.pgh.pa.us          63                 :CBC      281387 :     buildstate->indtuples += 1;
                                 64                 :                : 
 4417                            65                 :         281387 :     MemoryContextSwitchTo(oldCtx);
                                 66                 :         281387 :     MemoryContextReset(buildstate->tmpCtx);
 4502                            67                 :         281387 : }
                                 68                 :                : 
                                 69                 :                : /*
                                 70                 :                :  * Build an SP-GiST index.
                                 71                 :                :  */
                                 72                 :                : IndexBuildResult *
 3010                            73                 :            104 : spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
                                 74                 :                : {
                                 75                 :                :     IndexBuildResult *result;
                                 76                 :                :     double      reltuples;
                                 77                 :                :     SpGistBuildState buildstate;
                                 78                 :                :     Buffer      metabuffer,
                                 79                 :                :                 rootbuffer,
                                 80                 :                :                 nullbuffer;
                                 81                 :                : 
 4502                            82         [ -  + ]:            104 :     if (RelationGetNumberOfBlocks(index) != 0)
 4502 tgl@sss.pgh.pa.us          83         [ #  # ]:UBC           0 :         elog(ERROR, "index \"%s\" already contains data",
                                 84                 :                :              RelationGetRelationName(index));
                                 85                 :                : 
                                 86                 :                :     /*
                                 87                 :                :      * Initialize the meta page and root pages
                                 88                 :                :      */
 4502 tgl@sss.pgh.pa.us          89                 :CBC         104 :     metabuffer = SpGistNewBuffer(index);
                                 90                 :            104 :     rootbuffer = SpGistNewBuffer(index);
 4417                            91                 :            104 :     nullbuffer = SpGistNewBuffer(index);
                                 92                 :                : 
 4502                            93         [ -  + ]:            104 :     Assert(BufferGetBlockNumber(metabuffer) == SPGIST_METAPAGE_BLKNO);
 4417                            94         [ -  + ]:            104 :     Assert(BufferGetBlockNumber(rootbuffer) == SPGIST_ROOT_BLKNO);
                                 95         [ -  + ]:            104 :     Assert(BufferGetBlockNumber(nullbuffer) == SPGIST_NULL_BLKNO);
                                 96                 :                : 
 4502                            97                 :            104 :     START_CRIT_SECTION();
                                 98                 :                : 
 2916 kgrittn@postgresql.o       99                 :            104 :     SpGistInitMetapage(BufferGetPage(metabuffer));
 4502 tgl@sss.pgh.pa.us         100                 :            104 :     MarkBufferDirty(metabuffer);
                                101                 :            104 :     SpGistInitBuffer(rootbuffer, SPGIST_LEAF);
                                102                 :            104 :     MarkBufferDirty(rootbuffer);
 4417                           103                 :            104 :     SpGistInitBuffer(nullbuffer, SPGIST_LEAF | SPGIST_NULLS);
                                104                 :            104 :     MarkBufferDirty(nullbuffer);
                                105                 :                : 
                                106                 :                : 
 4502                           107         [ -  + ]:            104 :     END_CRIT_SECTION();
                                108                 :                : 
                                109                 :            104 :     UnlockReleaseBuffer(metabuffer);
                                110                 :            104 :     UnlockReleaseBuffer(rootbuffer);
 4417                           111                 :            104 :     UnlockReleaseBuffer(nullbuffer);
                                112                 :                : 
                                113                 :                :     /*
                                114                 :                :      * Now insert all the heap data into the index
                                115                 :                :      */
 4502                           116                 :            104 :     initSpGistState(&buildstate.spgstate, index);
                                117                 :            104 :     buildstate.spgstate.isBuild = true;
 2215                           118                 :            104 :     buildstate.indtuples = 0;
                                119                 :                : 
 4502                           120                 :            104 :     buildstate.tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
                                121                 :                :                                               "SP-GiST build temporary context",
                                122                 :                :                                               ALLOCSET_DEFAULT_SIZES);
                                123                 :                : 
 1839 alvherre@alvh.no-ip.      124                 :            104 :     reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
                                125                 :                :                                        spgistBuildCallback, (void *) &buildstate,
                                126                 :                :                                        NULL);
                                127                 :                : 
 4502 tgl@sss.pgh.pa.us         128                 :            104 :     MemoryContextDelete(buildstate.tmpCtx);
                                129                 :                : 
                                130                 :            104 :     SpGistUpdateMetaPage(index);
                                131                 :                : 
                                132                 :                :     /*
                                133                 :                :      * We didn't write WAL records as we built the index, so if WAL-logging is
                                134                 :                :      * required, write all pages to the WAL now.
                                135                 :                :      */
 1838 heikki.linnakangas@i      136   [ +  +  +  +  :            104 :     if (RelationNeedsWAL(index))
                                        +  +  -  + ]
                                137                 :                :     {
                                138                 :             37 :         log_newpage_range(index, MAIN_FORKNUM,
                                139                 :                :                           0, RelationGetNumberOfBlocks(index),
                                140                 :                :                           true);
                                141                 :                :     }
                                142                 :                : 
 4502 tgl@sss.pgh.pa.us         143                 :            104 :     result = (IndexBuildResult *) palloc0(sizeof(IndexBuildResult));
 2215                           144                 :            104 :     result->heap_tuples = reltuples;
                                145                 :            104 :     result->index_tuples = buildstate.indtuples;
                                146                 :                : 
 3010                           147                 :            104 :     return result;
                                148                 :                : }
                                149                 :                : 
                                150                 :                : /*
                                151                 :                :  * Build an empty SPGiST index in the initialization fork
                                152                 :                :  */
                                153                 :                : void
                                154                 :              4 : spgbuildempty(Relation index)
                                155                 :                : {
                                156                 :                :     BulkWriteState *bulkstate;
                                157                 :                :     BulkWriteBuffer buf;
                                158                 :                : 
   51 heikki.linnakangas@i      159                 :GNC           4 :     bulkstate = smgr_bulk_start_rel(index, INIT_FORKNUM);
                                160                 :                : 
                                161                 :                :     /* Construct metapage. */
                                162                 :              4 :     buf = smgr_bulk_get_buf(bulkstate);
                                163                 :              4 :     SpGistInitMetapage((Page) buf);
                                164                 :              4 :     smgr_bulk_write(bulkstate, SPGIST_METAPAGE_BLKNO, buf, true);
                                165                 :                : 
                                166                 :                :     /* Likewise for the root page. */
                                167                 :              4 :     buf = smgr_bulk_get_buf(bulkstate);
                                168                 :              4 :     SpGistInitPage((Page) buf, SPGIST_LEAF);
                                169                 :              4 :     smgr_bulk_write(bulkstate, SPGIST_ROOT_BLKNO, buf, true);
                                170                 :                : 
                                171                 :                :     /* Likewise for the null-tuples root page. */
                                172                 :              4 :     buf = smgr_bulk_get_buf(bulkstate);
                                173                 :              4 :     SpGistInitPage((Page) buf, SPGIST_LEAF | SPGIST_NULLS);
                                174                 :              4 :     smgr_bulk_write(bulkstate, SPGIST_NULL_BLKNO, buf, true);
                                175                 :                : 
                                176                 :              4 :     smgr_bulk_finish(bulkstate);
 4502 tgl@sss.pgh.pa.us         177                 :CBC           4 : }
                                178                 :                : 
                                179                 :                : /*
                                180                 :                :  * Insert one new tuple into an SPGiST index.
                                181                 :                :  */
                                182                 :                : bool
 3010                           183                 :         121294 : spginsert(Relation index, Datum *values, bool *isnull,
                                184                 :                :           ItemPointer ht_ctid, Relation heapRel,
                                185                 :                :           IndexUniqueCheck checkUnique,
                                186                 :                :           bool indexUnchanged,
                                187                 :                :           IndexInfo *indexInfo)
                                188                 :                : {
                                189                 :                :     SpGistState spgstate;
                                190                 :                :     MemoryContext oldCtx;
                                191                 :                :     MemoryContext insertCtx;
                                192                 :                : 
 4502                           193                 :         121294 :     insertCtx = AllocSetContextCreate(CurrentMemoryContext,
                                194                 :                :                                       "SP-GiST insert temporary context",
                                195                 :                :                                       ALLOCSET_DEFAULT_SIZES);
                                196                 :         121294 :     oldCtx = MemoryContextSwitchTo(insertCtx);
                                197                 :                : 
                                198                 :         121294 :     initSpGistState(&spgstate, index);
                                199                 :                : 
                                200                 :                :     /*
                                201                 :                :      * We might have to repeat spgdoinsert() multiple times, if conflicts
                                202                 :                :      * occur with concurrent insertions.  If so, reset the insertCtx each time
                                203                 :                :      * to avoid cumulative memory consumption.  That means we also have to
                                204                 :                :      * redo initSpGistState(), but it's cheap enough not to matter.
                                205                 :                :      */
 1105                           206         [ -  + ]:         121294 :     while (!spgdoinsert(index, &spgstate, ht_ctid, values, isnull))
                                207                 :                :     {
 3957 tgl@sss.pgh.pa.us         208                 :UBC           0 :         MemoryContextReset(insertCtx);
                                209                 :              0 :         initSpGistState(&spgstate, index);
                                210                 :                :     }
                                211                 :                : 
 4502 tgl@sss.pgh.pa.us         212                 :CBC      121292 :     SpGistUpdateMetaPage(index);
                                213                 :                : 
                                214                 :         121292 :     MemoryContextSwitchTo(oldCtx);
                                215                 :         121292 :     MemoryContextDelete(insertCtx);
                                216                 :                : 
                                217                 :                :     /* return false since we've not done any unique check */
 3010                           218                 :         121292 :     return false;
                                219                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622