32 Datum leafValue,
bool isNull,
34 bool recheckDistances,
double *distances);
62 for (
i = 0;
i <
so->numberOfNonNullOrderBys;
i++)
70 if (
sa->distances[
i] !=
sb->distances[
i])
71 return (
sa->distances[
i] <
sb->distances[
i]) ? 1 : -1;
76 if (
sa->isLeaf && !
sb->isLeaf)
78 if (!
sa->isLeaf &&
sb->isLeaf)
89 if (!(item->
isLeaf ?
so->state.attType.attbyval :
90 so->state.attLeafType.attbyval) &&
123 if (!isnull &&
so->numberOfNonNullOrderBys > 0)
125 sizeof(item->
distances[0]) *
so->numberOfNonNullOrderBys);
170 if (
so->searchNonNulls)
176 if (
so->numberOfOrderBys > 0)
181 for (
i = 0;
i <
so->nPtrs;
i++)
182 if (
so->distances[
i])
191 for (
i = 0;
i <
so->nPtrs;
i++)
194 so->iPtr =
so->nPtrs = 0;
221 if (
so->numberOfOrderBys <= 0)
222 so->numberOfNonNullOrderBys = 0;
236 so->nonNullOrderByOffsets[
i] = -1;
242 so->nonNullOrderByOffsets[
i] =
j++;
246 so->numberOfNonNullOrderBys =
j;
252 so->searchNulls =
true;
253 so->searchNonNulls =
true;
254 so->numberOfKeys = 0;
279 so->keyData[nkeys++] = *
skey;
294 so->numberOfKeys = nkeys;
298 so->searchNulls =
false;
299 so->searchNonNulls =
false;
300 so->numberOfKeys = 0;
321 "SP-GiST search temporary context",
324 "SP-GiST traversal-value context",
349 so->zeroDistances[
i] = 0.0;
376 ScanKey orderbys,
int norderbys)
434 if (
so->state.leafTupDesc &&
438 if (
so->state.deadTupleStorage)
439 pfree(
so->state.deadTupleStorage);
444 pfree(
so->nonNullOrderByOffsets);
459 Datum leafValue,
bool recheck,
bool recheckDistances,
460 bool isnull,
double *distances)
477 so->state.attType.attlen);
483 if (
so->state.leafTupDesc->natts > 1)
519 bool recheckDistances;
525 leafValue = (
Datum) 0;
528 recheckDistances =
false;
570 if (
so->numberOfNonNullOrderBys > 0)
589 Assert(!recheckDistances);
591 leafTuple, recheck,
false,
NULL);
640 so->state.attLeafType.attbyval,
641 so->state.attLeafType.attlen)
670 memset(&out, 0,
sizeof(out));
689 for (
i = 0;
i < nNodes;
i++)
695 elog(
ERROR,
"inconsistent inner_consistent results for allTheSame inner tuple");
716 Assert(nodeN >= 0 && nodeN < nNodes);
832 Assert(
so->numberOfNonNullOrderBys > 0);
905 elog(
ERROR,
"unexpected SPGiST tuple state: %d",
927 Datum leafValue,
bool isnull,
929 bool recheckDistances,
double *distances)
931 Assert(!recheckDistances && !distances);
942 so->want_itup =
false;
955 Datum leafValue,
bool isnull,
960 so->heapPtrs[
so->nPtrs] = *heapPtr;
961 so->recheck[
so->nPtrs] = recheck;
962 so->recheckDistances[
so->nPtrs] = recheckDistances;
964 if (
so->numberOfOrderBys > 0)
966 if (isnull ||
so->numberOfNonNullOrderBys <= 0)
971 so->numberOfOrderBys);
974 for (
i = 0;
i <
so->numberOfOrderBys;
i++)
976 int offset =
so->nonNullOrderByOffsets[
i];
992 so->distances[
so->nPtrs] = distances;
1006 if (
so->state.leafTupDesc->natts > 1)
1026 elog(
ERROR,
"SP-GiST only supports forward scan direction");
1033 if (
so->iPtr <
so->nPtrs)
1040 if (
so->numberOfOrderBys > 0)
1042 so->distances[
so->iPtr],
1043 so->recheckDistances[
so->iPtr]);
1048 if (
so->numberOfOrderBys > 0)
1053 for (
i = 0;
i <
so->nPtrs;
i++)
1054 if (
so->distances[
i])
1063 for (
i = 0;
i <
so->nPtrs;
i++)
1066 so->iPtr =
so->nPtrs = 0;
BlockNumber BufferGetBlockNumber(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static Page BufferGetPage(Buffer buffer)
static void LockBuffer(Buffer buffer, BufferLockMode mode)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void * PageGetItem(PageData *page, const ItemIdData *itemId)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
#define Assert(condition)
Datum datumCopy(Datum value, bool typByVal, int typLen)
#define palloc_array(type, count)
#define palloc0_array(type, count)
#define palloc0_object(type)
static float8 get_float8_infinity(void)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
void index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes, IndexOrderByDistance *distances, bool recheckOrderBy)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
#define MaxIndexTuplesPerPage
Oid get_func_rettype(Oid funcid)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define CHECK_FOR_INTERRUPTS()
#define InvalidOffsetNumber
#define FirstOffsetNumber
void pairingheap_add(pairingheap *heap, pairingheap_node *node)
pairingheap * pairingheap_allocate(pairingheap_comparator compare, void *arg)
pairingheap_node * pairingheap_remove_first(pairingheap *heap)
#define pairingheap_is_empty(h)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define pgstat_count_index_scan(rel)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
#define RelationGetDescr(relation)
#define SPGIST_LEAF_CONSISTENT_PROC
#define SPGIST_INNER_CONSISTENT_PROC
#define SPGIST_NULL_BLKNO
SpGistDeadTupleData * SpGistDeadTuple
SpGistInnerTupleData * SpGistInnerTuple
#define SpGistPageStoresNulls(page)
#define SGLT_GET_NEXTOFFSET(spgLeafTuple)
#define SizeOfSpGistSearchItem(n_distances)
#define SGITITERATE(x, i, nt)
SpGistScanOpaqueData * SpGistScanOpaque
#define SpGistPageIsLeaf(page)
#define SPGIST_METAPAGE_BLKNO
#define SpGistBlockIsRoot(blkno)
struct SpGistLeafTupleData * SpGistLeafTuple
#define SPGIST_ROOT_BLKNO
IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz)
static int pairingheap_SpGistSearchItem_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg)
bool spgcanreturn(Relation index, int attno)
bool spggettuple(IndexScanDesc scan, ScanDirection dir)
static void spgInitInnerConsistentIn(spgInnerConsistentIn *in, SpGistScanOpaque so, SpGistSearchItem *item, SpGistInnerTuple innerTuple)
static void spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, storeRes_func storeRes)
void spgendscan(IndexScanDesc scan)
static SpGistSearchItem * spgGetNextQueueItem(SpGistScanOpaque so)
static OffsetNumber spgTestLeafTuple(SpGistScanOpaque so, SpGistSearchItem *item, Page page, OffsetNumber offset, bool isnull, bool isroot, bool *reportedSome, storeRes_func storeRes)
static bool spgLeafTest(SpGistScanOpaque so, SpGistSearchItem *item, SpGistLeafTuple leafTuple, bool isnull, bool *reportedSome, storeRes_func storeRes)
static void spgAddStartItem(SpGistScanOpaque so, bool isnull)
static void spgFreeSearchItem(SpGistScanOpaque so, SpGistSearchItem *item)
static SpGistSearchItem * spgNewHeapItem(SpGistScanOpaque so, int level, SpGistLeafTuple leafTuple, Datum leafValue, bool recheck, bool recheckDistances, bool isnull, double *distances)
SpGistSpecialOffsetNumbers
@ SpGistErrorOffsetNumber
@ SpGistBreakOffsetNumber
@ SpGistRedirectOffsetNumber
static void resetSpGistScanOpaque(SpGistScanOpaque so)
static SpGistSearchItem * spgMakeInnerItem(SpGistScanOpaque so, SpGistSearchItem *parentItem, SpGistNodeTuple tuple, spgInnerConsistentOut *out, int i, bool isnull, double *distances)
static void storeGettuple(SpGistScanOpaque so, ItemPointer heapPtr, Datum leafValue, bool isnull, SpGistLeafTuple leafTuple, bool recheck, bool recheckDistances, double *nonNullDistances)
static void storeBitmap(SpGistScanOpaque so, ItemPointer heapPtr, Datum leafValue, bool isnull, SpGistLeafTuple leafTuple, bool recheck, bool recheckDistances, double *distances)
void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
static void spgPrepareScanKeys(IndexScanDesc scan)
static void spgAddSearchItemToQueue(SpGistScanOpaque so, SpGistSearchItem *item)
static SpGistSearchItem * spgAllocSearchItem(SpGistScanOpaque so, bool isnull, double *distances)
void(* storeRes_func)(SpGistScanOpaque so, ItemPointer heapPtr, Datum leafValue, bool isNull, SpGistLeafTuple leafTuple, bool recheck, bool recheckDistances, double *distances)
static void spgInnerTest(SpGistScanOpaque so, SpGistSearchItem *item, SpGistInnerTuple innerTuple, bool isnull)
Datum * spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
void initSpGistState(SpGistState *state, Relation index)
TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
SpGistCache * spgGetCache(Relation index)
void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, Datum *datums, bool *isnulls, bool keyColumnIsNull)
struct ScanKeyData * keyData
struct ScanKeyData * orderByData
struct IndexScanInstrumentation * instrument
struct TupleDescData * xs_hitupdesc
ItemPointerData xs_heaptid
SpGistLeafTuple leafTuple
double distances[FLEXIBLE_ARRAY_MEMBER]
MemoryContext traversalMemoryContext
Datum * reconstructedValues
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointerData *tids, int ntids, bool recheck)
void FreeTupleDesc(TupleDesc tupdesc)