235 idatum =
datumCopy(idatum, attr->attbyval, attr->attlen);
270 (
errcode(ERRCODE_INTERNAL_ERROR),
271 errmsg(
"failed to re-find tuple within index \"%s\"",
286 newDatum, newCategory,
287 idatum, icategory) == 0)
364 btreeEntry.
findItem(&btreeEntry, stackEntry);
383 goto restartScanEntry;
392 else if (btreeEntry.
findItem(&btreeEntry, stackEntry))
491 int i1 = *(
const int *)
a1;
492 int i2 = *(
const int *)
a2;
493 uint32 n1 =
key->scanEntry[i1]->predictNumberResult;
494 uint32 n2 =
key->scanEntry[i2]->predictNumberResult;
513 key->curItemMatches =
false;
514 key->recheckCurItem =
false;
515 key->isFinished =
false;
539 if (
key->excludeOnly)
544 key->nadditional =
key->nentries;
546 for (
i = 0;
i <
key->nadditional;
i++)
547 key->additionalEntries[
i] =
key->scanEntry[
i];
549 else if (
key->nentries > 1)
553 entryIndexes = (
int *)
palloc(
sizeof(
int) *
key->nentries);
554 for (
i = 0;
i <
key->nentries;
i++)
559 for (
i = 0;
i <
key->nentries - 1;
i++)
562 for (
j = 0;
j <=
i;
j++)
574 key->nrequired =
i + 1;
575 key->nadditional =
key->nentries -
key->nrequired;
580 for (
i = 0;
i <
key->nrequired;
i++)
581 key->requiredEntries[
i] =
key->scanEntry[entryIndexes[
j++]];
583 key->additionalEntries[
i] =
key->scanEntry[entryIndexes[
j++]];
593 key->nadditional = 0;
595 key->requiredEntries[0] =
key->scanEntry[0];
708 elog(
DEBUG2,
"entryLoadMoreItems, %u/%u, skip: %d",
791 #define gin_rand() pg_prng_double(&pg_global_prng_state)
792 #define dropItem(e) ( gin_rand() > ((double)GinFuzzySearchLimit)/((double)((e)->predictNumberResult)) )
1022 for (
i = 0;
i <
key->nrequired;
i++)
1024 entry =
key->requiredEntries[
i];
1043 allFinished =
false;
1048 if (allFinished && !
key->excludeOnly)
1051 key->isFinished =
true;
1055 if (!
key->excludeOnly)
1104 for (
i = 0;
i <
key->nadditional;
i++)
1106 entry =
key->additionalEntries[
i];
1160 key->curItem = minItem;
1163 haveLossyEntry =
false;
1164 for (
i = 0;
i <
key->nentries;
i++)
1166 entry =
key->scanEntry[
i];
1170 if (i < key->nuserentries)
1174 haveLossyEntry =
true;
1195 key->curItem = curPageLossy;
1196 key->curItemMatches =
true;
1197 key->recheckCurItem =
true;
1212 for (
i = 0;
i <
key->nentries;
i++)
1214 entry =
key->scanEntry[
i];
1239 key->curItemMatches =
true;
1244 key->curItemMatches =
false;
1248 key->curItemMatches =
true;
1249 key->recheckCurItem =
true;
1258 key->curItemMatches =
true;
1259 key->recheckCurItem =
true;
1317 for (
i = 0;
i < so->
nkeys && match;
i++)
1338 if (
key->isFinished)
1345 if (!
key->curItemMatches)
1347 advancePast =
key->curItem;
1389 *item =
key->curItem;
1419 for (
i = 0;
i < so->nkeys;
i++)
1423 if (
key->recheckCurItem)
1541 bool *datumExtracted)
1550 while (off < maxoff)
1557 if (datumExtracted[off - 1] ==
false)
1560 &category[off - 1]);
1561 datumExtracted[off - 1] =
true;
1645 for (
j = 0;
j <
key->nentries;
j++)
1653 if (
key->entryRes[
j])
1662 while (StopLow < StopHigh)
1666 StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
1672 if (
key->attnum < attrnum)
1674 StopHigh = StopMiddle;
1677 if (
key->attnum > attrnum)
1679 StopLow = StopMiddle + 1;
1683 if (datumExtracted[StopMiddle - 1] ==
false)
1685 datum[StopMiddle - 1] =
1687 &category[StopMiddle - 1]);
1688 datumExtracted[StopMiddle - 1] =
true;
1714 datum[StopMiddle - 1],
1715 category[StopMiddle - 1]);
1740 key->entryRes[
j] =
true;
1746 StopHigh = StopMiddle;
1748 StopLow = StopMiddle + 1;
1797 elog(
ERROR,
"could not find additional pending pages for same heap tuple");
1859 pos.hasMatchKey =
palloc(
sizeof(
bool) * so->
nkeys);
1889 if (!
key->boolConsistentFn(
key))
1894 recheck |=
key->recheckCurItem;
1907 pfree(pos.hasMatchKey);
1911 #define GinIsVoidRes(s) ( ((GinScanOpaque) scan->opaque)->isVoidRes )
#define InvalidBlockNumber
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(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define Assert(condition)
Datum datumCopy(Datum value, bool typByVal, int typLen)
static void PGresult * res
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)
Buffer ginStepRight(Buffer buffer, Relation index, int lockmode)
GinBtreeStack * ginFindLeafPage(GinBtree btree, bool searchMode, bool rootConflictCheck)
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)
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
if(TABLE==NULL||TABLE_index==NULL)
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)
FormData_pg_attribute * Form_pg_attribute
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)
MemoryContextSwitchTo(old_ctx)
static int cmp(const chr *x, const chr *y, size_t len)
#define RelationGetRelationName(relation)
bool(* findItem)(GinBtree, GinBtreeStack *)
TBMIterateResult * matchResult
GinNullCategory queryCategory
TBMIterator * matchIterator
uint32 predictNumberResult
FmgrInfo comparePartialFn[INDEX_MAX_KEYS]
Oid supportCollation[INDEX_MAX_KEYS]
struct SnapshotData * xs_snapshot
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]
void tbm_free(TIDBitmap *tbm)
TBMIterator * tbm_begin_iterate(TIDBitmap *tbm)
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
bool tbm_is_empty(const TIDBitmap *tbm)
void tbm_end_iterate(TBMIterator *iterator)
void tbm_add_page(TIDBitmap *tbm, BlockNumber pageno)
TIDBitmap * tbm_create(long maxbytes, dsa_area *dsa)
TBMIterateResult * tbm_iterate(TBMIterator *iterator)
#define TupleDescAttr(tupdesc, i)
static StringInfoData tmpbuf