LCOV - code coverage report
Current view: top level - src/include/access - gin_private.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 19 19
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 100.0 % 6 6

             Branch data     Line data    Source code
       1                 :             : /*--------------------------------------------------------------------------
       2                 :             :  * gin_private.h
       3                 :             :  *        header file for postgres inverted index access method implementation.
       4                 :             :  *
       5                 :             :  *      Copyright (c) 2006-2026, PostgreSQL Global Development Group
       6                 :             :  *
       7                 :             :  *      src/include/access/gin_private.h
       8                 :             :  *--------------------------------------------------------------------------
       9                 :             :  */
      10                 :             : #ifndef GIN_PRIVATE_H
      11                 :             : #define GIN_PRIVATE_H
      12                 :             : 
      13                 :             : #include "access/amapi.h"
      14                 :             : #include "access/gin.h"
      15                 :             : #include "access/ginblock.h"
      16                 :             : #include "access/htup_details.h"
      17                 :             : #include "access/itup.h"
      18                 :             : #include "common/int.h"
      19                 :             : #include "catalog/pg_am_d.h"
      20                 :             : #include "fmgr.h"
      21                 :             : #include "lib/rbtree.h"
      22                 :             : #include "storage/bufmgr.h"
      23                 :             : 
      24                 :             : /*
      25                 :             :  * Storage type for GIN's reloptions
      26                 :             :  */
      27                 :             : typedef struct GinOptions
      28                 :             : {
      29                 :             :         int32           vl_len_;                /* varlena header (do not touch directly!) */
      30                 :             :         bool            useFastUpdate;  /* use fast updates? */
      31                 :             :         int                     pendingListCleanupSize; /* maximum size of pending list */
      32                 :             : } GinOptions;
      33                 :             : 
      34                 :             : #define GIN_DEFAULT_USE_FASTUPDATE      true
      35                 :             : #define GinGetUseFastUpdate(relation) \
      36                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
      37                 :             :                                  relation->rd_rel->relam == GIN_AM_OID), \
      38                 :             :          (relation)->rd_options ? \
      39                 :             :          ((GinOptions *) (relation)->rd_options)->useFastUpdate : GIN_DEFAULT_USE_FASTUPDATE)
      40                 :             : #define GinGetPendingListCleanupSize(relation) \
      41                 :             :         (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
      42                 :             :                                  relation->rd_rel->relam == GIN_AM_OID), \
      43                 :             :          (relation)->rd_options && \
      44                 :             :          ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize != -1 ? \
      45                 :             :          ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize : \
      46                 :             :          gin_pending_list_limit)
      47                 :             : 
      48                 :             : 
      49                 :             : /* Macros for buffer lock/unlock operations */
      50                 :             : #define GIN_UNLOCK      BUFFER_LOCK_UNLOCK
      51                 :             : #define GIN_SHARE       BUFFER_LOCK_SHARE
      52                 :             : #define GIN_EXCLUSIVE  BUFFER_LOCK_EXCLUSIVE
      53                 :             : 
      54                 :             : 
      55                 :             : /*
      56                 :             :  * GinState: working data structure describing the index being worked on
      57                 :             :  */
      58                 :             : typedef struct GinState
      59                 :             : {
      60                 :             :         Relation        index;
      61                 :             :         bool            oneCol;                 /* true if single-column index */
      62                 :             : 
      63                 :             :         /*
      64                 :             :          * origTupdesc is the nominal tuple descriptor of the index, ie, the i'th
      65                 :             :          * attribute shows the key type (not the input data type!) of the i'th
      66                 :             :          * index column.  In a single-column index this describes the actual leaf
      67                 :             :          * index tuples.  In a multi-column index, the actual leaf tuples contain
      68                 :             :          * a smallint column number followed by a key datum of the appropriate
      69                 :             :          * type for that column.  We set up tupdesc[i] to describe the actual
      70                 :             :          * rowtype of the index tuples for the i'th column, ie, (int2, keytype).
      71                 :             :          * Note that in any case, leaf tuples contain more data than is known to
      72                 :             :          * the TupleDesc; see access/gin/README for details.
      73                 :             :          */
      74                 :             :         TupleDesc       origTupdesc;
      75                 :             :         TupleDesc       tupdesc[INDEX_MAX_KEYS];
      76                 :             : 
      77                 :             :         /*
      78                 :             :          * Per-index-column opclass support functions
      79                 :             :          */
      80                 :             :         FmgrInfo        compareFn[INDEX_MAX_KEYS];
      81                 :             :         FmgrInfo        extractValueFn[INDEX_MAX_KEYS];
      82                 :             :         FmgrInfo        extractQueryFn[INDEX_MAX_KEYS];
      83                 :             :         FmgrInfo        consistentFn[INDEX_MAX_KEYS];
      84                 :             :         FmgrInfo        triConsistentFn[INDEX_MAX_KEYS];
      85                 :             :         FmgrInfo        comparePartialFn[INDEX_MAX_KEYS];       /* optional method */
      86                 :             :         /* canPartialMatch[i] is true if comparePartialFn[i] is valid */
      87                 :             :         bool            canPartialMatch[INDEX_MAX_KEYS];
      88                 :             :         /* Collations to pass to the support functions */
      89                 :             :         Oid                     supportCollation[INDEX_MAX_KEYS];
      90                 :             : } GinState;
      91                 :             : 
      92                 :             : 
      93                 :             : /* ginutil.c */
      94                 :             : extern bytea *ginoptions(Datum reloptions, bool validate);
      95                 :             : extern void initGinState(GinState *state, Relation index);
      96                 :             : extern Buffer GinNewBuffer(Relation index);
      97                 :             : extern void GinInitBuffer(Buffer b, uint32 f);
      98                 :             : extern void GinInitPage(Page page, uint32 f, Size pageSize);
      99                 :             : extern void GinInitMetabuffer(Buffer b);
     100                 :             : extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
     101                 :             :                                                                 Datum value, bool isNull,
     102                 :             :                                                                 int32 *nentries, GinNullCategory **categories);
     103                 :             : 
     104                 :             : extern OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple);
     105                 :             : extern Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple,
     106                 :             :                                                           GinNullCategory *category);
     107                 :             : extern char *ginbuildphasename(int64 phasenum);
     108                 :             : 
     109                 :             : /* gininsert.c */
     110                 :             : extern IndexBuildResult *ginbuild(Relation heap, Relation index,
     111                 :             :                                                                   struct IndexInfo *indexInfo);
     112                 :             : extern void ginbuildempty(Relation index);
     113                 :             : extern bool gininsert(Relation index, Datum *values, bool *isnull,
     114                 :             :                                           ItemPointer ht_ctid, Relation heapRel,
     115                 :             :                                           IndexUniqueCheck checkUnique,
     116                 :             :                                           bool indexUnchanged,
     117                 :             :                                           struct IndexInfo *indexInfo);
     118                 :             : extern void ginEntryInsert(GinState *ginstate,
     119                 :             :                                                    OffsetNumber attnum, Datum key, GinNullCategory category,
     120                 :             :                                                    ItemPointerData *items, uint32 nitem,
     121                 :             :                                                    GinStatsData *buildStats);
     122                 :             : 
     123                 :             : /* ginbtree.c */
     124                 :             : 
     125                 :             : typedef struct GinBtreeStack
     126                 :             : {
     127                 :             :         BlockNumber blkno;
     128                 :             :         Buffer          buffer;
     129                 :             :         OffsetNumber off;
     130                 :             :         ItemPointerData iptr;
     131                 :             :         /* predictNumber contains predicted number of pages on current level */
     132                 :             :         uint32          predictNumber;
     133                 :             :         struct GinBtreeStack *parent;
     134                 :             : } GinBtreeStack;
     135                 :             : 
     136                 :             : typedef struct GinBtreeData *GinBtree;
     137                 :             : 
     138                 :             : /* Return codes for GinBtreeData.beginPlaceToPage method */
     139                 :             : typedef enum
     140                 :             : {
     141                 :             :         GPTP_NO_WORK,
     142                 :             :         GPTP_INSERT,
     143                 :             :         GPTP_SPLIT,
     144                 :             : } GinPlaceToPageRC;
     145                 :             : 
     146                 :             : typedef struct GinBtreeData
     147                 :             : {
     148                 :             :         /* search methods */
     149                 :             :         BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
     150                 :             :         BlockNumber (*getLeftMostChild) (GinBtree, Page);
     151                 :             :         bool            (*isMoveRight) (GinBtree, Page);
     152                 :             :         bool            (*findItem) (GinBtree, GinBtreeStack *);
     153                 :             : 
     154                 :             :         /* insert methods */
     155                 :             :         OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
     156                 :             :         GinPlaceToPageRC (*beginPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void **, Page *, Page *);
     157                 :             :         void            (*execPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void *);
     158                 :             :         void       *(*prepareDownlink) (GinBtree, Buffer);
     159                 :             :         void            (*fillRoot) (GinBtree, Page, BlockNumber, Page, BlockNumber, Page);
     160                 :             : 
     161                 :             :         bool            isData;
     162                 :             : 
     163                 :             :         Relation        index;
     164                 :             :         BlockNumber rootBlkno;
     165                 :             :         GinState   *ginstate;           /* not valid in a data scan */
     166                 :             :         bool            fullScan;
     167                 :             :         bool            isBuild;
     168                 :             : 
     169                 :             :         /* Search key for Entry tree */
     170                 :             :         OffsetNumber entryAttnum;
     171                 :             :         Datum           entryKey;
     172                 :             :         GinNullCategory entryCategory;
     173                 :             : 
     174                 :             :         /* Search key for data tree (posting tree) */
     175                 :             :         ItemPointerData itemptr;
     176                 :             : } GinBtreeData;
     177                 :             : 
     178                 :             : /* This represents a tuple to be inserted to entry tree. */
     179                 :             : typedef struct
     180                 :             : {
     181                 :             :         IndexTuple      entry;                  /* tuple to insert */
     182                 :             :         bool            isDelete;               /* delete old tuple at same offset? */
     183                 :             : } GinBtreeEntryInsertData;
     184                 :             : 
     185                 :             : /*
     186                 :             :  * This represents an itempointer, or many itempointers, to be inserted to
     187                 :             :  * a data (posting tree) leaf page
     188                 :             :  */
     189                 :             : typedef struct
     190                 :             : {
     191                 :             :         ItemPointerData *items;
     192                 :             :         uint32          nitem;
     193                 :             :         uint32          curitem;
     194                 :             : } GinBtreeDataLeafInsertData;
     195                 :             : 
     196                 :             : /*
     197                 :             :  * For internal data (posting tree) pages, the insertion payload is a
     198                 :             :  * PostingItem
     199                 :             :  */
     200                 :             : 
     201                 :             : extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode,
     202                 :             :                                                                           bool rootConflictCheck);
     203                 :             : extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
     204                 :             : extern void freeGinBtreeStack(GinBtreeStack *stack);
     205                 :             : extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,
     206                 :             :                                                    void *insertdata, GinStatsData *buildStats);
     207                 :             : 
     208                 :             : /* ginentrypage.c */
     209                 :             : extern IndexTuple GinFormTuple(GinState *ginstate,
     210                 :             :                                                            OffsetNumber attnum, Datum key, GinNullCategory category,
     211                 :             :                                                            Pointer data, Size dataSize, int nipd, bool errorTooBig);
     212                 :             : extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
     213                 :             :                                                                 Datum key, GinNullCategory category,
     214                 :             :                                                                 GinState *ginstate);
     215                 :             : extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
     216                 :             : extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum,
     217                 :             :                                                                 IndexTuple itup, int *nitems);
     218                 :             : 
     219                 :             : /* gindatapage.c */
     220                 :             : extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
     221                 :             : extern int      GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
     222                 :             : extern BlockNumber createPostingTree(Relation index,
     223                 :             :                                                                          ItemPointerData *items, uint32 nitems,
     224                 :             :                                                                          GinStatsData *buildStats, Buffer entrybuffer);
     225                 :             : extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
     226                 :             : extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
     227                 :             : extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
     228                 :             :                                                                   ItemPointerData *items, uint32 nitem,
     229                 :             :                                                                   GinStatsData *buildStats);
     230                 :             : extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno);
     231                 :             : extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
     232                 :             : 
     233                 :             : /*
     234                 :             :  * This is declared in ginvacuum.c, but is passed between ginVacuumItemPointers
     235                 :             :  * and ginVacuumPostingTreeLeaf and as an opaque struct, so we need a forward
     236                 :             :  * declaration for it.
     237                 :             :  */
     238                 :             : typedef struct GinVacuumState GinVacuumState;
     239                 :             : 
     240                 :             : extern void ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer,
     241                 :             :                                                                          GinVacuumState *gvs);
     242                 :             : 
     243                 :             : /* ginscan.c */
     244                 :             : 
     245                 :             : /*
     246                 :             :  * GinScanKeyData describes a single GIN index qualifier expression.
     247                 :             :  *
     248                 :             :  * From each qual expression, we extract one or more specific index search
     249                 :             :  * conditions, which are represented by GinScanEntryData.  It's quite
     250                 :             :  * possible for identical search conditions to be requested by more than
     251                 :             :  * one qual expression, in which case we merge such conditions to have just
     252                 :             :  * one unique GinScanEntry --- this is particularly important for efficiency
     253                 :             :  * when dealing with full-index-scan entries.  So there can be multiple
     254                 :             :  * GinScanKeyData.scanEntry pointers to the same GinScanEntryData.
     255                 :             :  *
     256                 :             :  * In each GinScanKeyData, nentries is the true number of entries, while
     257                 :             :  * nuserentries is the number that extractQueryFn returned (which is what
     258                 :             :  * we report to consistentFn).  The "user" entries must come first.
     259                 :             :  */
     260                 :             : typedef struct GinScanKeyData *GinScanKey;
     261                 :             : 
     262                 :             : typedef struct GinScanEntryData *GinScanEntry;
     263                 :             : 
     264                 :             : typedef struct GinScanKeyData
     265                 :             : {
     266                 :             :         /* Real number of entries in scanEntry[] (always > 0) */
     267                 :             :         uint32          nentries;
     268                 :             :         /* Number of entries that extractQueryFn and consistentFn know about */
     269                 :             :         uint32          nuserentries;
     270                 :             : 
     271                 :             :         /* array of GinScanEntry pointers, one per extracted search condition */
     272                 :             :         GinScanEntry *scanEntry;
     273                 :             : 
     274                 :             :         /*
     275                 :             :          * At least one of the entries in requiredEntries must be present for a
     276                 :             :          * tuple to match the overall qual.
     277                 :             :          *
     278                 :             :          * additionalEntries contains entries that are needed by the consistent
     279                 :             :          * function to decide if an item matches, but are not sufficient to
     280                 :             :          * satisfy the qual without entries from requiredEntries.
     281                 :             :          */
     282                 :             :         GinScanEntry *requiredEntries;
     283                 :             :         int                     nrequired;
     284                 :             :         GinScanEntry *additionalEntries;
     285                 :             :         int                     nadditional;
     286                 :             : 
     287                 :             :         /* array of check flags, reported to consistentFn */
     288                 :             :         GinTernaryValue *entryRes;
     289                 :             :         bool            (*boolConsistentFn) (GinScanKey key);
     290                 :             :         GinTernaryValue (*triConsistentFn) (GinScanKey key);
     291                 :             :         FmgrInfo   *consistentFmgrInfo;
     292                 :             :         FmgrInfo   *triConsistentFmgrInfo;
     293                 :             :         Oid                     collation;
     294                 :             : 
     295                 :             :         /* other data needed for calling consistentFn */
     296                 :             :         Datum           query;
     297                 :             :         /* NB: these three arrays have only nuserentries elements! */
     298                 :             :         Datum      *queryValues;
     299                 :             :         GinNullCategory *queryCategories;
     300                 :             :         Pointer    *extra_data;
     301                 :             :         StrategyNumber strategy;
     302                 :             :         int32           searchMode;
     303                 :             :         OffsetNumber attnum;
     304                 :             : 
     305                 :             :         /*
     306                 :             :          * An excludeOnly scan key is not able to enumerate all matching tuples.
     307                 :             :          * That is, to be semantically correct on its own, it would need to have a
     308                 :             :          * GIN_CAT_EMPTY_QUERY scanEntry, but it doesn't.  Such a key can still be
     309                 :             :          * used to filter tuples returned by other scan keys, so we will get the
     310                 :             :          * right answers as long as there's at least one non-excludeOnly scan key
     311                 :             :          * for each index attribute considered by the search.  For efficiency
     312                 :             :          * reasons we don't want to have unnecessary GIN_CAT_EMPTY_QUERY entries,
     313                 :             :          * so we will convert an excludeOnly scan key to non-excludeOnly (by
     314                 :             :          * adding a GIN_CAT_EMPTY_QUERY scanEntry) only if there are no other
     315                 :             :          * non-excludeOnly scan keys.
     316                 :             :          */
     317                 :             :         bool            excludeOnly;
     318                 :             : 
     319                 :             :         /*
     320                 :             :          * Match status data.  curItem is the TID most recently tested (could be a
     321                 :             :          * lossy-page pointer).  curItemMatches is true if it passes the
     322                 :             :          * consistentFn test; if so, recheckCurItem is the recheck flag.
     323                 :             :          * isFinished means that all the input entry streams are finished, so this
     324                 :             :          * key cannot succeed for any later TIDs.
     325                 :             :          */
     326                 :             :         ItemPointerData curItem;
     327                 :             :         bool            curItemMatches;
     328                 :             :         bool            recheckCurItem;
     329                 :             :         bool            isFinished;
     330                 :             : } GinScanKeyData;
     331                 :             : 
     332                 :             : typedef struct GinScanEntryData
     333                 :             : {
     334                 :             :         /* query key and other information from extractQueryFn */
     335                 :             :         Datum           queryKey;
     336                 :             :         GinNullCategory queryCategory;
     337                 :             :         bool            isPartialMatch;
     338                 :             :         Pointer         extra_data;
     339                 :             :         StrategyNumber strategy;
     340                 :             :         int32           searchMode;
     341                 :             :         OffsetNumber attnum;
     342                 :             : 
     343                 :             :         /* Current page in posting tree */
     344                 :             :         Buffer          buffer;
     345                 :             : 
     346                 :             :         /* current ItemPointer to heap */
     347                 :             :         ItemPointerData curItem;
     348                 :             : 
     349                 :             :         /* for a partial-match or full-scan query, we accumulate all TIDs here */
     350                 :             :         TIDBitmap  *matchBitmap;
     351                 :             :         TBMPrivateIterator *matchIterator;
     352                 :             : 
     353                 :             :         /*
     354                 :             :          * If blockno is InvalidBlockNumber, all of the other fields in the
     355                 :             :          * matchResult are meaningless.
     356                 :             :          */
     357                 :             :         TBMIterateResult matchResult;
     358                 :             :         OffsetNumber matchOffsets[TBM_MAX_TUPLES_PER_PAGE];
     359                 :             :         int                     matchNtuples;
     360                 :             : 
     361                 :             :         /* used for Posting list and one page in Posting tree */
     362                 :             :         ItemPointerData *list;
     363                 :             :         int                     nlist;
     364                 :             :         OffsetNumber offset;
     365                 :             : 
     366                 :             :         bool            isFinished;
     367                 :             :         bool            reduceResult;
     368                 :             :         uint32          predictNumberResult;
     369                 :             :         GinBtreeData btree;
     370                 :             : } GinScanEntryData;
     371                 :             : 
     372                 :             : typedef struct GinScanOpaqueData
     373                 :             : {
     374                 :             :         MemoryContext tempCtx;
     375                 :             :         GinState        ginstate;
     376                 :             : 
     377                 :             :         GinScanKey      keys;                   /* one per scan qualifier expr */
     378                 :             :         uint32          nkeys;
     379                 :             : 
     380                 :             :         GinScanEntry *entries;          /* one per index search condition */
     381                 :             :         uint32          totalentries;
     382                 :             :         uint32          allocentries;   /* allocated length of entries[] */
     383                 :             : 
     384                 :             :         MemoryContext keyCtx;           /* used to hold key and entry data */
     385                 :             : 
     386                 :             :         bool            isVoidRes;              /* true if query is unsatisfiable */
     387                 :             : } GinScanOpaqueData;
     388                 :             : 
     389                 :             : typedef GinScanOpaqueData *GinScanOpaque;
     390                 :             : 
     391                 :             : extern IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys);
     392                 :             : extern void ginendscan(IndexScanDesc scan);
     393                 :             : extern void ginrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
     394                 :             :                                           ScanKey orderbys, int norderbys);
     395                 :             : extern void ginNewScanKey(IndexScanDesc scan);
     396                 :             : extern void ginFreeScanKeys(GinScanOpaque so);
     397                 :             : 
     398                 :             : /* ginget.c */
     399                 :             : extern int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
     400                 :             : 
     401                 :             : /* ginlogic.c */
     402                 :             : extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key);
     403                 :             : 
     404                 :             : /* ginvacuum.c */
     405                 :             : extern IndexBulkDeleteResult *ginbulkdelete(IndexVacuumInfo *info,
     406                 :             :                                                                                         IndexBulkDeleteResult *stats,
     407                 :             :                                                                                         IndexBulkDeleteCallback callback,
     408                 :             :                                                                                         void *callback_state);
     409                 :             : extern IndexBulkDeleteResult *ginvacuumcleanup(IndexVacuumInfo *info,
     410                 :             :                                                                                            IndexBulkDeleteResult *stats);
     411                 :             : extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs,
     412                 :             :                                                                                  ItemPointerData *items, int nitem, int *nremaining);
     413                 :             : 
     414                 :             : /* ginvalidate.c */
     415                 :             : extern bool ginvalidate(Oid opclassoid);
     416                 :             : extern void ginadjustmembers(Oid opfamilyoid,
     417                 :             :                                                          Oid opclassoid,
     418                 :             :                                                          List *operators,
     419                 :             :                                                          List *functions);
     420                 :             : 
     421                 :             : /* ginbulk.c */
     422                 :             : typedef struct GinEntryAccumulator
     423                 :             : {
     424                 :             :         RBTNode         rbtnode;
     425                 :             :         Datum           key;
     426                 :             :         GinNullCategory category;
     427                 :             :         OffsetNumber attnum;
     428                 :             :         bool            shouldSort;
     429                 :             :         ItemPointerData *list;
     430                 :             :         uint32          maxcount;               /* allocated size of list[] */
     431                 :             :         uint32          count;                  /* current number of list[] entries */
     432                 :             : } GinEntryAccumulator;
     433                 :             : 
     434                 :             : typedef struct
     435                 :             : {
     436                 :             :         GinState   *ginstate;
     437                 :             :         Size            allocatedMemory;
     438                 :             :         GinEntryAccumulator *entryallocator;
     439                 :             :         uint32          eas_used;
     440                 :             :         RBTree     *tree;
     441                 :             :         RBTreeIterator tree_walk;
     442                 :             : } BuildAccumulator;
     443                 :             : 
     444                 :             : extern void ginInitBA(BuildAccumulator *accum);
     445                 :             : extern void ginInsertBAEntries(BuildAccumulator *accum,
     446                 :             :                                                            ItemPointer heapptr, OffsetNumber attnum,
     447                 :             :                                                            Datum *entries, GinNullCategory *categories,
     448                 :             :                                                            int32 nentries);
     449                 :             : extern void ginBeginBAScan(BuildAccumulator *accum);
     450                 :             : extern ItemPointerData *ginGetBAEntry(BuildAccumulator *accum,
     451                 :             :                                                                           OffsetNumber *attnum, Datum *key, GinNullCategory *category,
     452                 :             :                                                                           uint32 *n);
     453                 :             : 
     454                 :             : /* ginfast.c */
     455                 :             : 
     456                 :             : typedef struct GinTupleCollector
     457                 :             : {
     458                 :             :         IndexTuple *tuples;
     459                 :             :         uint32          ntuples;
     460                 :             :         uint32          lentuples;
     461                 :             :         uint32          sumsize;
     462                 :             : } GinTupleCollector;
     463                 :             : 
     464                 :             : extern void ginHeapTupleFastInsert(GinState *ginstate,
     465                 :             :                                                                    GinTupleCollector *collector);
     466                 :             : extern void ginHeapTupleFastCollect(GinState *ginstate,
     467                 :             :                                                                         GinTupleCollector *collector,
     468                 :             :                                                                         OffsetNumber attnum, Datum value, bool isNull,
     469                 :             :                                                                         ItemPointer ht_ctid);
     470                 :             : extern void ginInsertCleanup(GinState *ginstate, bool full_clean,
     471                 :             :                                                          bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats);
     472                 :             : 
     473                 :             : /* ginpostinglist.c */
     474                 :             : 
     475                 :             : extern GinPostingList *ginCompressPostingList(const ItemPointerData *ipd, int nipd,
     476                 :             :                                                                                           int maxsize, int *nwritten);
     477                 :             : extern int      ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int len, TIDBitmap *tbm);
     478                 :             : 
     479                 :             : extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len,
     480                 :             :                                                                                                    int *ndecoded_out);
     481                 :             : extern ItemPointer ginPostingListDecode(GinPostingList *plist, int *ndecoded_out);
     482                 :             : extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na,
     483                 :             :                                                                                 ItemPointerData *b, uint32 nb,
     484                 :             :                                                                                 int *nmerged);
     485                 :             : 
     486                 :             : /*
     487                 :             :  * Merging the results of several gin scans compares item pointers a lot,
     488                 :             :  * so we want this to be inlined.
     489                 :             :  */
     490                 :             : static inline int
     491                 :     1364538 : ginCompareItemPointers(ItemPointer a, ItemPointer b)
     492                 :             : {
     493                 :     1364538 :         uint64          ia = (uint64) GinItemPointerGetBlockNumber(a) << 32 | GinItemPointerGetOffsetNumber(a);
     494                 :     1364538 :         uint64          ib = (uint64) GinItemPointerGetBlockNumber(b) << 32 | GinItemPointerGetOffsetNumber(b);
     495                 :             : 
     496                 :     2729076 :         return pg_cmp_u64(ia, ib);
     497                 :     1364538 : }
     498                 :             : 
     499                 :             : /*
     500                 :             :  * Compare two keys of the same index column
     501                 :             :  */
     502                 :             : static inline int
     503                 :     4702223 : ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
     504                 :             :                                   Datum a, GinNullCategory categorya,
     505                 :             :                                   Datum b, GinNullCategory categoryb)
     506                 :             : {
     507                 :             :         /* if not of same null category, sort by that first */
     508         [ +  + ]:     4702223 :         if (categorya != categoryb)
     509                 :      102939 :                 return (categorya < categoryb) ? -1 : 1;
     510                 :             : 
     511                 :             :         /* all null items in same category are equal */
     512         [ +  + ]:     4599284 :         if (categorya != GIN_CAT_NORM_KEY)
     513                 :        1260 :                 return 0;
     514                 :             : 
     515                 :             :         /* both not null, so safe to call the compareFn */
     516                 :     9196048 :         return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
     517                 :     4598024 :                                                                                    ginstate->supportCollation[attnum - 1],
     518                 :     4598024 :                                                                                    a, b));
     519                 :     4702223 : }
     520                 :             : 
     521                 :             : /*
     522                 :             :  * Compare two keys of possibly different index columns
     523                 :             :  */
     524                 :             : static inline int
     525                 :     4791548 : ginCompareAttEntries(GinState *ginstate,
     526                 :             :                                          OffsetNumber attnuma, Datum a, GinNullCategory categorya,
     527                 :             :                                          OffsetNumber attnumb, Datum b, GinNullCategory categoryb)
     528                 :             : {
     529                 :             :         /* attribute number is the first sort key */
     530         [ +  + ]:     4791548 :         if (attnuma != attnumb)
     531                 :       89630 :                 return (attnuma < attnumb) ? -1 : 1;
     532                 :             : 
     533                 :     4701918 :         return ginCompareEntries(ginstate, attnuma, a, categorya, b, categoryb);
     534                 :             : 
     535                 :     4791548 : }
     536                 :             : 
     537                 :             : extern int      ginTraverseLock(Buffer buffer, bool searchMode);
     538                 :             : 
     539                 :             : #endif                                                  /* GIN_PRIVATE_H */
        

Generated by: LCOV version 2.3.2-1