270 (
errcode(ERRCODE_INTERNAL_ERROR),
271 errmsg(
"failed to re-find tuple within index \"%s\"",
286 newDatum, newCategory,
287 idatum, icategory) == 0)
365 btreeEntry.
findItem(&btreeEntry, stackEntry);
384 goto restartScanEntry;
394 else if (btreeEntry.
findItem(&btreeEntry, stackEntry))
493 int i1 = *(
const int *)
a1;
494 int i2 = *(
const int *)
a2;
495 uint32 n1 =
key->scanEntry[i1]->predictNumberResult;
496 uint32 n2 =
key->scanEntry[i2]->predictNumberResult;
515 key->curItemMatches =
false;
516 key->recheckCurItem =
false;
517 key->isFinished =
false;
541 if (
key->excludeOnly)
546 key->nadditional =
key->nentries;
548 for (
i = 0;
i <
key->nadditional;
i++)
549 key->additionalEntries[
i] =
key->scanEntry[
i];
551 else if (
key->nentries > 1)
555 entryIndexes = (
int *)
palloc(
sizeof(
int) *
key->nentries);
556 for (
i = 0;
i <
key->nentries;
i++)
561 for (
i = 1;
i <
key->nentries;
i++)
578 key->nrequired =
i + 1;
579 key->nadditional =
key->nentries -
key->nrequired;
584 for (
i = 0;
i <
key->nrequired;
i++)
585 key->requiredEntries[
i] =
key->scanEntry[entryIndexes[
j++]];
587 key->additionalEntries[
i] =
key->scanEntry[entryIndexes[
j++]];
597 key->nadditional = 0;
599 key->requiredEntries[0] =
key->scanEntry[0];
712 elog(
DEBUG2,
"entryLoadMoreItems, %u/%u, skip: %d",
795#define gin_rand() pg_prng_double(&pg_global_prng_state)
796#define dropItem(e) ( gin_rand() > ((double)GinFuzzySearchLimit)/((double)((e)->predictNumberResult)) )
1011 bool haveLossyEntry;
1037 for (
i = 0;
i <
key->nrequired;
i++)
1039 entry =
key->requiredEntries[
i];
1058 allFinished =
false;
1063 if (allFinished && !
key->excludeOnly)
1066 key->isFinished =
true;
1070 if (!
key->excludeOnly)
1119 for (
i = 0;
i <
key->nadditional;
i++)
1121 entry =
key->additionalEntries[
i];
1175 key->curItem = minItem;
1178 haveLossyEntry =
false;
1179 for (
i = 0;
i <
key->nentries;
i++)
1181 entry =
key->scanEntry[
i];
1185 if (i < key->nuserentries)
1189 haveLossyEntry =
true;
1201 res =
key->triConsistentFn(
key);
1210 key->curItem = curPageLossy;
1211 key->curItemMatches =
true;
1212 key->recheckCurItem =
true;
1227 for (
i = 0;
i <
key->nentries;
i++)
1229 entry =
key->scanEntry[
i];
1249 res =
key->triConsistentFn(
key);
1254 key->curItemMatches =
true;
1259 key->curItemMatches =
false;
1263 key->curItemMatches =
true;
1264 key->recheckCurItem =
true;
1273 key->curItemMatches =
true;
1274 key->recheckCurItem =
true;
1332 for (
i = 0;
i < so->
nkeys && match;
i++)
1353 if (
key->isFinished)
1360 if (!
key->curItemMatches)
1362 advancePast =
key->curItem;
1404 *item =
key->curItem;
1434 for (
i = 0;
i < so->nkeys;
i++)
1438 if (
key->recheckCurItem)
1556 bool *datumExtracted)
1565 while (off < maxoff)
1572 if (datumExtracted[off - 1] ==
false)
1575 &category[off - 1]);
1576 datumExtracted[off - 1] =
true;
1660 for (
j = 0;
j <
key->nentries;
j++)
1668 if (
key->entryRes[
j])
1677 while (StopLow < StopHigh)
1681 StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
1687 if (
key->attnum < attrnum)
1689 StopHigh = StopMiddle;
1692 if (
key->attnum > attrnum)
1694 StopLow = StopMiddle + 1;
1698 if (datumExtracted[StopMiddle - 1] ==
false)
1700 datum[StopMiddle - 1] =
1702 &category[StopMiddle - 1]);
1703 datumExtracted[StopMiddle - 1] =
true;
1729 datum[StopMiddle - 1],
1730 category[StopMiddle - 1]);
1755 key->entryRes[
j] =
true;
1761 StopHigh = StopMiddle;
1763 StopLow = StopMiddle + 1;
1812 elog(
ERROR,
"could not find additional pending pages for same heap tuple");
1874 pos.hasMatchKey =
palloc(
sizeof(
bool) * so->
nkeys);
1904 if (!
key->boolConsistentFn(
key))
1909 recheck |=
key->recheckCurItem;
1922 pfree(pos.hasMatchKey);
1926#define GinIsVoidRes(s) ( ((GinScanOpaque) scan->opaque)->isVoidRes )
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
void IncrBufferRefCount(Buffer buffer)
BlockNumber BufferGetBlockNumber(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static Page BufferGetPage(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Datum datumCopy(Datum value, bool typByVal, int typLen)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
#define GIN_SEARCH_MODE_ALL
GinScanOpaqueData * GinScanOpaque
static int ginCompareItemPointers(ItemPointer a, ItemPointer b)
struct GinScanKeyData * GinScanKey
#define ItemPointerSetLossyPage(p, b)
#define GinIsPostingTree(itup)
#define GinItemPointerGetOffsetNumber(pointer)
#define GIN_METAPAGE_BLKNO
#define GinPageHasFullRow(page)
#define GinPageGetOpaque(page)
#define ItemPointerIsMin(p)
#define GinGetNPosting(itup)
#define ItemPointerSetMax(p)
#define GinDataPageGetRightBound(page)
#define GinGetPostingTree(itup)
#define ItemPointerIsLossyPage(p)
signed char GinNullCategory
#define GinPageRightMost(page)
#define GIN_CAT_NULL_ITEM
#define ItemPointerSetMin(p)
#define GinPageGetMeta(p)
#define GIN_CAT_EMPTY_QUERY
#define GinItemPointerGetBlockNumber(pointer)
#define GinPageIsLeaf(page)
void freeGinBtreeStack(GinBtreeStack *stack)
GinBtreeStack * ginFindLeafPage(GinBtree btree, bool searchMode, bool rootConflictCheck)
Buffer ginStepRight(Buffer buffer, Relation index, int lockmode)
GinBtreeStack * ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno)
int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm)
ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, IndexTuple itup, int *nitems)
void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, Datum key, GinNullCategory category, GinState *ginstate)
int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
static void scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids)
static void startScan(IndexScanDesc scan)
struct pendingPosition pendingPosition
static void startScanEntry(GinState *ginstate, GinScanEntry entry, Snapshot snapshot)
static void startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key)
static bool scanGetItem(IndexScanDesc scan, ItemPointerData advancePast, ItemPointerData *item, bool *recheck)
static bool matchPartialInPendingList(GinState *ginstate, Page page, OffsetNumber off, OffsetNumber maxoff, GinScanEntry entry, Datum *datum, GinNullCategory *category, bool *datumExtracted)
static bool scanGetCandidate(IndexScanDesc scan, pendingPosition *pos)
static void scanPostingTree(Relation index, GinScanEntry scanEntry, BlockNumber rootPostingTree)
static bool moveRightIfItNeeded(GinBtreeData *btree, GinBtreeStack *stack, Snapshot snapshot)
static int entryIndexByFrequencyCmp(const void *a1, const void *a2, void *arg)
static bool collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry scanEntry, Snapshot snapshot)
static bool collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos)
static void keyGetItem(GinState *ginstate, MemoryContext tempCtx, GinScanKey key, ItemPointerData advancePast)
static void entryGetItem(GinState *ginstate, GinScanEntry entry, ItemPointerData advancePast)
static void entryLoadMoreItems(GinState *ginstate, GinScanEntry entry, ItemPointerData advancePast)
void ginFreeScanKeys(GinScanOpaque so)
void ginNewScanKey(IndexScanDesc scan)
OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, GinNullCategory *category)
int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, Datum a, GinNullCategory categorya, Datum b, GinNullCategory categoryb)
Assert(PointerIsAligned(start, uint64))
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
struct IndexTupleData IndexTupleData
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
#define CHECK_FOR_INTERRUPTS()
#define InvalidOffsetNumber
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define OffsetNumberPrev(offsetNumber)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static Datum PointerGetDatum(const void *X)
static Datum UInt16GetDatum(uint16 X)
static Pointer DatumGetPointer(Datum X)
static int32 DatumGetInt32(Datum X)
void PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot)
static int cmp(const chr *x, const chr *y, size_t len)
#define RelationGetRelationName(relation)
bool(* findItem)(GinBtree, GinBtreeStack *)
TBMIterateResult matchResult
OffsetNumber matchOffsets[TBM_MAX_TUPLES_PER_PAGE]
TBMPrivateIterator * matchIterator
GinNullCategory queryCategory
uint32 predictNumberResult
FmgrInfo comparePartialFn[INDEX_MAX_KEYS]
Oid supportCollation[INDEX_MAX_KEYS]
struct SnapshotData * xs_snapshot
void tbm_free(TIDBitmap *tbm)
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
bool tbm_is_empty(const TIDBitmap *tbm)
bool tbm_private_iterate(TBMPrivateIterator *iterator, TBMIterateResult *tbmres)
void tbm_add_page(TIDBitmap *tbm, BlockNumber pageno)
int tbm_extract_page_tuple(TBMIterateResult *iteritem, OffsetNumber *offsets, uint32 max_offsets)
void tbm_end_private_iterate(TBMPrivateIterator *iterator)
TIDBitmap * tbm_create(Size maxbytes, dsa_area *dsa)
TBMPrivateIterator * tbm_begin_private_iterate(TIDBitmap *tbm)
#define TBM_MAX_TUPLES_PER_PAGE
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static StringInfoData tmpbuf