/*--------------------------------------------------------------------------
* gin.h
- * header file for postgres inverted index access method implementation.
+ * Public header file for Generalized Inverted Index access method.
*
- * Copyright (c) 2006, PostgreSQL Global Development Group
- * $PostgreSQL: pgsql/src/include/access/gin.h,v 1.10 2007/01/31 15:09:45 teodor Exp $
+ * Copyright (c) 2006-2017, PostgreSQL Global Development Group
+ *
+ * src/include/access/gin.h
*--------------------------------------------------------------------------
*/
-
-
#ifndef GIN_H
#define GIN_H
-#include "access/relscan.h"
-#include "access/skey.h"
-#include "access/xlog.h"
-#include "access/xlogdefs.h"
-#include "storage/bufpage.h"
-#include "storage/off.h"
-#include "utils/rel.h"
-#include "access/itup.h"
-#include "fmgr.h"
+#include "access/xlogreader.h"
+#include "lib/stringinfo.h"
+#include "storage/block.h"
+#include "utils/relcache.h"
/*
#define GIN_EXTRACTVALUE_PROC 2
#define GIN_EXTRACTQUERY_PROC 3
#define GIN_CONSISTENT_PROC 4
-#define GINNProcs 4
-
-typedef XLogRecPtr GinNSN;
-
-/*
- * Page opaque data in a inverted index page.
- */
-typedef struct GinPageOpaqueData
-{
- uint16 flags;
- OffsetNumber maxoff; /* number entries on GIN_DATA page: number of
- * heap ItemPointer on GIN_DATA|GIN_LEAF page
- * and number of records on GIN_DATA &
- * ~GIN_LEAF page */
- BlockNumber rightlink;
-} GinPageOpaqueData;
-
-typedef GinPageOpaqueData *GinPageOpaque;
-
-#define GIN_ROOT_BLKNO (0)
-
-typedef struct
-{
- BlockIdData child_blkno; /* use it instead of BlockNumber to save space
- * on page */
- ItemPointerData key;
-} PostingItem;
-
-#define PostingItemGetBlockNumber(pointer) \
- BlockIdGetBlockNumber(&(pointer)->child_blkno)
-
-#define PostingItemSetBlockNumber(pointer, blockNumber) \
- BlockIdSet(&((pointer)->child_blkno), (blockNumber))
+#define GIN_COMPARE_PARTIAL_PROC 5
+#define GIN_TRICONSISTENT_PROC 6
+#define GINNProcs 6
/*
- * Page opaque data in a inverted index page.
+ * searchMode settings for extractQueryFn.
*/
-#define GIN_DATA (1 << 0)
-#define GIN_LEAF (1 << 1)
-#define GIN_DELETED (1 << 2)
+#define GIN_SEARCH_MODE_DEFAULT 0
+#define GIN_SEARCH_MODE_INCLUDE_EMPTY 1
+#define GIN_SEARCH_MODE_ALL 2
+#define GIN_SEARCH_MODE_EVERYTHING 3 /* for internal use only */
/*
- * Works on page
+ * GinStatsData represents stats data for planner use
*/
-#define GinPageGetOpaque(page) ( (GinPageOpaque) PageGetSpecialPointer(page) )
-
-#define GinPageIsLeaf(page) ( GinPageGetOpaque(page)->flags & GIN_LEAF )
-#define GinPageSetLeaf(page) ( GinPageGetOpaque(page)->flags |= GIN_LEAF )
-#define GinPageSetNonLeaf(page) ( GinPageGetOpaque(page)->flags &= ~GIN_LEAF )
-#define GinPageIsData(page) ( GinPageGetOpaque(page)->flags & GIN_DATA )
-#define GinPageSetData(page) ( GinPageGetOpaque(page)->flags |= GIN_DATA )
-
-#define GinPageIsDeleted(page) ( GinPageGetOpaque(page)->flags & GIN_DELETED)
-#define GinPageSetDeleted(page) ( GinPageGetOpaque(page)->flags |= GIN_DELETED)
-#define GinPageSetNonDeleted(page) ( GinPageGetOpaque(page)->flags &= ~GIN_DELETED)
-
-#define GinPageRightMost(page) ( GinPageGetOpaque(page)->rightlink == InvalidBlockNumber)
-
-/*
- * Define our ItemPointerGet(BlockNumber|GetOffsetNumber)
- * to prevent asserts
- */
-
-#define GinItemPointerGetBlockNumber(pointer) \
- BlockIdGetBlockNumber(&(pointer)->ip_blkid)
-
-#define GinItemPointerGetOffsetNumber(pointer) \
- ((pointer)->ip_posid)
-
-/*
- * Support work on IndexTuuple on leaf pages
- */
-#define GinGetNPosting(itup) GinItemPointerGetOffsetNumber(&(itup)->t_tid)
-#define GinSetNPosting(itup,n) ItemPointerSetOffsetNumber(&(itup)->t_tid,(n))
-#define GIN_TREE_POSTING ((OffsetNumber)0xffff)
-#define GinIsPostingTree(itup) ( GinGetNPosting(itup)==GIN_TREE_POSTING )
-#define GinSetPostingTree(itup, blkno) ( GinSetNPosting((itup),GIN_TREE_POSTING ), ItemPointerSetBlockNumber(&(itup)->t_tid, blkno) )
-#define GinGetPostingTree(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid)
-
-#define GinGetOrigSizePosting(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid)
-#define GinSetOrigSizePosting(itup,n) ItemPointerSetBlockNumber(&(itup)->t_tid,(n))
-#define GinGetPosting(itup) ( (ItemPointer)(( ((char*)(itup)) + SHORTALIGN(GinGetOrigSizePosting(itup)) )) )
-
-#define GinMaxItemSize \
- ((BLCKSZ - SizeOfPageHeaderData - \
- MAXALIGN(sizeof(GinPageOpaqueData))) / 3 - sizeof(ItemIdData))
-
+typedef struct GinStatsData
+{
+ BlockNumber nPendingPages;
+ BlockNumber nTotalPages;
+ BlockNumber nEntryPages;
+ BlockNumber nDataPages;
+ int64 nEntries;
+ int32 ginVersion;
+} GinStatsData;
/*
- * Data (posting tree) pages
+ * A ternary value used by tri-consistent functions.
+ *
+ * For convenience, this is compatible with booleans. A boolean can be
+ * safely cast to a GinTernaryValue.
*/
-#define GinDataPageGetData(page) \
- (PageGetContents(page)+MAXALIGN(sizeof(ItemPointerData)))
-#define GinDataPageGetRightBound(page) ((ItemPointer)PageGetContents(page))
-#define GinSizeOfItem(page) ( (GinPageIsLeaf(page)) ? sizeof(ItemPointerData) : sizeof(PostingItem) )
-#define GinDataPageGetItem(page,i) ( GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page) )
-
-#define GinDataPageGetFreeSpace(page) \
- ( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GinPageOpaqueData)) - \
- GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) - \
- MAXALIGN(sizeof(ItemPointerData)))
-
-
-
-#define GIN_UNLOCK BUFFER_LOCK_UNLOCK
-#define GIN_SHARE BUFFER_LOCK_SHARE
-#define GIN_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE
-
-typedef struct GinState
-{
- FmgrInfo compareFn;
- FmgrInfo extractValueFn;
- FmgrInfo extractQueryFn;
- FmgrInfo consistentFn;
-
- TupleDesc tupdesc;
-} GinState;
+typedef char GinTernaryValue;
-/* XLog stuff */
+#define GIN_FALSE 0 /* item is not present / does not match */
+#define GIN_TRUE 1 /* item is present / matches */
+#define GIN_MAYBE 2 /* don't know if item is present / don't know
+ * if matches */
-#define XLOG_GIN_CREATE_INDEX 0x00
+#define DatumGetGinTernaryValue(X) ((GinTernaryValue)(X))
+#define GinTernaryValueGetDatum(X) ((Datum)(X))
+#define PG_RETURN_GIN_TERNARY_VALUE(x) return GinTernaryValueGetDatum(x)
-#define XLOG_GIN_CREATE_PTREE 0x10
-
-typedef struct ginxlogCreatePostingTree
-{
- RelFileNode node;
- BlockNumber blkno;
- uint32 nitem;
- /* follows list of heap's ItemPointer */
-} ginxlogCreatePostingTree;
-
-#define XLOG_GIN_INSERT 0x20
-
-typedef struct ginxlogInsert
-{
- RelFileNode node;
- BlockNumber blkno;
- BlockNumber updateBlkno;
- OffsetNumber offset;
- bool isDelete;
- bool isData;
- bool isLeaf;
- OffsetNumber nitem;
-
- /*
- * follows: tuples or ItemPointerData or PostingItem or list of
- * ItemPointerData
- */
-} ginxlogInsert;
-
-#define XLOG_GIN_SPLIT 0x30
-
-typedef struct ginxlogSplit
-{
- RelFileNode node;
- BlockNumber lblkno;
- BlockNumber rootBlkno;
- BlockNumber rblkno;
- BlockNumber rrlink;
- OffsetNumber separator;
- OffsetNumber nitem;
-
- bool isData;
- bool isLeaf;
- bool isRootSplit;
-
- BlockNumber leftChildBlkno;
- BlockNumber updateBlkno;
-
- ItemPointerData rightbound; /* used only in posting tree */
- /* follows: list of tuple or ItemPointerData or PostingItem */
-} ginxlogSplit;
-
-#define XLOG_GIN_VACUUM_PAGE 0x40
-
-typedef struct ginxlogVacuumPage
-{
- RelFileNode node;
- BlockNumber blkno;
- OffsetNumber nitem;
- /* follows content of page */
-} ginxlogVacuumPage;
-
-#define XLOG_GIN_DELETE_PAGE 0x50
-
-typedef struct ginxlogDeletePage
-{
- RelFileNode node;
- BlockNumber blkno;
- BlockNumber parentBlkno;
- OffsetNumber parentOffset;
- BlockNumber leftBlkno;
- BlockNumber rightLink;
-} ginxlogDeletePage;
+/* GUC parameters */
+extern PGDLLIMPORT int GinFuzzySearchLimit;
+extern int gin_pending_list_limit;
/* ginutil.c */
-extern Datum ginoptions(PG_FUNCTION_ARGS);
-extern void initGinState(GinState *state, Relation index);
-extern Buffer GinNewBuffer(Relation index);
-extern void GinInitBuffer(Buffer b, uint32 f);
-extern void GinInitPage(Page page, uint32 f, Size pageSize);
-extern int compareEntries(GinState *ginstate, Datum a, Datum b);
-extern Datum *extractEntriesS(GinState *ginstate, Datum value,
- int32 *nentries, bool *needUnique);
-extern Datum *extractEntriesSU(GinState *ginstate, Datum value, int32 *nentries);
-extern Page GinPageGetCopyPage(Page page);
-
-/* gininsert.c */
-extern Datum ginbuild(PG_FUNCTION_ARGS);
-extern Datum gininsert(PG_FUNCTION_ARGS);
+extern void ginGetStats(Relation index, GinStatsData *stats);
+extern void ginUpdateStats(Relation index, const GinStatsData *stats);
/* ginxlog.c */
-extern void gin_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void gin_desc(StringInfo buf, uint8 xl_info, char *rec);
+extern void gin_redo(XLogReaderState *record);
+extern void gin_desc(StringInfo buf, XLogReaderState *record);
+extern const char *gin_identify(uint8 info);
extern void gin_xlog_startup(void);
extern void gin_xlog_cleanup(void);
-extern bool gin_safe_restartpoint(void);
-
-/* ginbtree.c */
-
-typedef struct GinBtreeStack
-{
- BlockNumber blkno;
- Buffer buffer;
- OffsetNumber off;
- /* predictNumber contains prediction number of pages on current level */
- uint32 predictNumber;
- struct GinBtreeStack *parent;
-} GinBtreeStack;
-
-typedef struct GinBtreeData *GinBtree;
-
-typedef struct GinBtreeData
-{
- /* search methods */
- BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
- bool (*isMoveRight) (GinBtree, Page);
- bool (*findItem) (GinBtree, GinBtreeStack *);
-
- /* insert methods */
- OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
- BlockNumber (*getLeftMostPage) (GinBtree, Page);
- bool (*isEnoughSpace) (GinBtree, Buffer, OffsetNumber);
- void (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **);
- Page (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **);
- void (*fillRoot) (GinBtree, Buffer, Buffer, Buffer);
-
- bool searchMode;
-
- Relation index;
- GinState *ginstate;
- bool fullScan;
- bool isBuild;
-
- BlockNumber rightblkno;
-
- /* Entry options */
- Datum entryValue;
- IndexTuple entry;
- bool isDelete;
-
- /* Data (posting tree) option */
- ItemPointerData *items;
- uint32 nitem;
- uint32 curitem;
-
- PostingItem pitem;
-} GinBtreeData;
-
-extern GinBtreeStack *ginPrepareFindLeafPage(GinBtree btree, BlockNumber blkno);
-extern GinBtreeStack *ginFindLeafPage(GinBtree btree, GinBtreeStack *stack);
-extern void freeGinBtreeStack(GinBtreeStack *stack);
-extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack);
-extern void findParents(GinBtree btree, GinBtreeStack *stack, BlockNumber rootBlkno);
-
-/* ginentrypage.c */
-extern IndexTuple GinFormTuple(GinState *ginstate, Datum key, ItemPointerData *ipd, uint32 nipd);
-extern Datum ginGetHighKey(GinState *ginstate, Page page);
-extern void prepareEntryScan(GinBtree btree, Relation index, Datum value, GinState *ginstate);
-extern void entryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf);
-extern IndexTuple ginPageGetLinkItup(Buffer buf);
-
-/* gindatapage.c */
-extern int compareItemPointers(ItemPointer a, ItemPointer b);
-extern void
-MergeItemPointers(
- ItemPointerData *dst,
- ItemPointerData *a, uint32 na,
- ItemPointerData *b, uint32 nb
-);
-
-extern void GinDataPageAddItem(Page page, void *data, OffsetNumber offset);
-extern void PageDeletePostingItem(Page page, OffsetNumber offset);
-
-typedef struct
-{
- GinBtreeData btree;
- GinBtreeStack *stack;
-} GinPostingTreeScan;
-
-extern GinPostingTreeScan *prepareScanPostingTree(Relation index,
- BlockNumber rootBlkno, bool searchMode);
-extern void insertItemPointer(GinPostingTreeScan *gdi,
- ItemPointerData *items, uint32 nitem);
-extern Buffer scanBeginPostingTree(GinPostingTreeScan *gdi);
-extern void dataFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf);
-extern void prepareDataScan(GinBtree btree, Relation index);
-
-/* ginscan.c */
-
-typedef struct GinScanEntryData *GinScanEntry;
-
-typedef struct GinScanEntryData
-{
- /* link to the equals entry in current scan key */
- GinScanEntry master;
-
- /*
- * link to values reported to consistentFn, points to
- * GinScanKey->entryRes[i]
- */
- bool *pval;
-
- /* entry, got from extractQueryFn */
- Datum entry;
-
- /* current ItemPointer to heap, its offset in buffer and buffer */
- ItemPointerData curItem;
- OffsetNumber offset;
- Buffer buffer;
-
- /* in case of Posing list */
- ItemPointerData *list;
- uint32 nlist;
-
- bool isFinished;
- bool reduceResult;
- uint32 predictNumberResult;
-} GinScanEntryData;
-
-typedef struct GinScanKeyData
-{
- /* Number of entries in query (got by extractQueryFn) */
- uint32 nentries;
-
- /* array of ItemPointer result, reported to consistentFn */
- bool *entryRes;
-
- /* array of scans per entry */
- GinScanEntry scanEntry;
-
- /* for calling consistentFn(GinScanKey->entryRes, strategy, query) */
- StrategyNumber strategy;
- Datum query;
-
- ItemPointerData curItem;
- bool firstCall;
- bool isFinished;
-} GinScanKeyData;
-
-typedef GinScanKeyData *GinScanKey;
-
-typedef struct GinScanOpaqueData
-{
- MemoryContext tempCtx;
- GinState ginstate;
-
- GinScanKey keys;
- uint32 nkeys;
- bool isVoidRes; /* true if ginstate.extractQueryFn
- guarantees that nothing will be found */
-
- GinScanKey markPos;
-} GinScanOpaqueData;
-
-typedef GinScanOpaqueData *GinScanOpaque;
-
-extern Datum ginbeginscan(PG_FUNCTION_ARGS);
-extern Datum ginendscan(PG_FUNCTION_ARGS);
-extern Datum ginrescan(PG_FUNCTION_ARGS);
-extern Datum ginmarkpos(PG_FUNCTION_ARGS);
-extern Datum ginrestrpos(PG_FUNCTION_ARGS);
-extern void newScanKey(IndexScanDesc scan);
-
-/* ginget.c */
-extern DLLIMPORT int GinFuzzySearchLimit;
-
-#define ItemPointerSetMax(p) ItemPointerSet( (p), (BlockNumber)0xffffffff, (OffsetNumber)0xffff )
-#define ItemPointerIsMax(p) ( ItemPointerGetBlockNumber(p) == (BlockNumber)0xffffffff && ItemPointerGetOffsetNumber(p) == (OffsetNumber)0xffff )
-#define ItemPointerSetMin(p) ItemPointerSet( (p), (BlockNumber)0, (OffsetNumber)0)
-#define ItemPointerIsMin(p) ( ItemPointerGetBlockNumber(p) == (BlockNumber)0 && ItemPointerGetOffsetNumber(p) == (OffsetNumber)0 )
-
-extern Datum gingetmulti(PG_FUNCTION_ARGS);
-extern Datum gingettuple(PG_FUNCTION_ARGS);
-
-/* ginvacuum.c */
-extern Datum ginbulkdelete(PG_FUNCTION_ARGS);
-extern Datum ginvacuumcleanup(PG_FUNCTION_ARGS);
-
-/* ginarrayproc.c */
-extern Datum ginarrayextract(PG_FUNCTION_ARGS);
-extern Datum ginarrayconsistent(PG_FUNCTION_ARGS);
-
-/* ginbulk.c */
-typedef struct EntryAccumulator
-{
- Datum value;
- uint32 length;
- uint32 number;
- ItemPointerData *list;
- bool shouldSort;
- struct EntryAccumulator *left;
- struct EntryAccumulator *right;
-} EntryAccumulator;
-
-typedef struct
-{
- GinState *ginstate;
- EntryAccumulator *entries;
- uint32 maxdepth;
- EntryAccumulator **stack;
- uint32 stackpos;
- uint32 allocatedMemory;
-
- uint32 length;
- EntryAccumulator *entryallocator;
-} BuildAccumulator;
-
-extern void ginInitBA(BuildAccumulator *accum);
-extern void ginInsertRecordBA(BuildAccumulator *accum,
- ItemPointer heapptr, Datum *entries, int32 nentry);
-extern ItemPointerData *ginGetEntry(BuildAccumulator *accum, Datum *entry, uint32 *n);
-#endif
+#endif /* GIN_H */