66 elog(
ERROR,
"failed to find requested node %d in SPGiST inner tuple",
88 else if (offset > tuple->
nNodes)
89 elog(
ERROR,
"invalid offset for adding node to SPGiST inner tuple");
134 int firststate,
int reststate,
152 memcpy(sortednos, itemnos,
sizeof(
OffsetNumber) * nitems);
158 firstItem = itemnos[0];
160 for (
i = 0;
i < nitems;
i++)
165 tupstate = (itemno == firstItem) ? firststate : reststate;
166 if (tuple == NULL || tuple->
tupstate != tupstate)
170 itemno,
false,
false) != itemno)
171 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
280 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
401 bool replaceDead =
false;
433 toDelete[nDelete] =
i;
443 toDelete[nDelete] =
i;
460 leafdata = leafptr =
palloc(size);
468 for (
i = 0;
i < nDelete;
i++)
482 &startOffset,
false);
484 toInsert[nInsert] = r;
488 memcpy(leafptr, it, it->size);
496 (
Item) newLeafTuple, newLeafTuple->
size,
497 &startOffset,
false);
498 toInsert[nInsert] = r;
500 memcpy(leafptr, newLeafTuple, newLeafTuple->
size);
501 leafptr += newLeafTuple->
size;
618 for (
i = 1;
i < limit;
i++)
680 int level,
bool isNulls,
bool isNew)
682 bool insertedNew =
false;
695 uint8 *leafPageSelect;
706 int currentFreeSpace;
759 oldLeafs[nToInsert] = it;
761 toDelete[nToDelete] =
i;
785 oldLeafs[nToInsert] = it;
787 toDelete[nToDelete] =
i;
798 toDelete[nToDelete] =
i;
818 oldLeafs[in.
nTuples] = newLeafTuple;
821 memset(&out, 0,
sizeof(out));
830 index->rd_indcollation[0],
840 if (
state->leafTupDesc->natts > 1)
873 if (
state->leafTupDesc->natts > 1)
953 for (
i = 0;
i < maxToInclude;
i++)
956 if (n < 0 || n >= out.
nNodes)
957 elog(
ERROR,
"inconsistent result of SPGiST picksplit function");
977 newInnerBuffer = parent->
buffer;
1015 currentFreeSpace = 0;
1019 if (totalLeafSizes <= currentFreeSpace)
1029 for (
i = 0;
i < nToInsert;
i++)
1030 leafPageSelect[
i] = 0;
1046 uint8 *nodePageSelect;
1063 curspace = currentFreeSpace;
1067 if (leafSizes[
i] <= curspace)
1069 nodePageSelect[
i] = 0;
1070 curspace -= leafSizes[
i];
1074 nodePageSelect[
i] = 1;
1075 newspace -= leafSizes[
i];
1078 if (curspace >= 0 && newspace >= 0)
1087 else if (includeNew)
1092 leafSizes[nodeOfNewTuple] -=
1096 curspace = currentFreeSpace;
1100 if (leafSizes[
i] <= curspace)
1102 nodePageSelect[
i] = 0;
1103 curspace -= leafSizes[
i];
1107 nodePageSelect[
i] = 1;
1108 newspace -= leafSizes[
i];
1111 if (curspace < 0 || newspace < 0)
1112 elog(
ERROR,
"failed to divide leaf tuple groups across pages");
1117 elog(
ERROR,
"failed to divide leaf tuple groups across pages");
1120 for (
i = 0;
i < nToInsert;
i++)
1123 leafPageSelect[
i] = nodePageSelect[n];
1133 leafdata = leafptr = (
char *)
palloc(totalLeafSizes);
1150 if (
state->isBuild &&
1167 if (!
state->isBuild)
1176 redirectTuplePos = toDelete[0];
1178 toDelete, nToDelete,
1191 toDelete, nToDelete,
1205 for (
i = 0;
i < nToInsert;
i++)
1213 leafBuffer = leafPageSelect[
i] ? newLeafBuffer : current->
buffer;
1230 &startOffsets[leafPageSelect[
i]],
1232 toInsert[
i] = newoffset;
1238 memcpy(leafptr, newLeafs[
i], newLeafs[
i]->size);
1239 leafptr += newLeafs[
i]->
size;
1253 saveCurrent = *current;
1271 (
Item) innerTuple, innerTuple->
size,
1300 current->
buffer = newInnerBuffer;
1305 (
Item) innerTuple, innerTuple->
size,
1346 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1375 sizeof(
uint8) * xlrec.nInsert);
1399 if (xlrec.initInner)
1409 Assert(xlrec.innerIsParent);
1479 parent->
node = nodeN;
1489 elog(
ERROR,
"failed to find requested node %d in SPGiST inner tuple",
1506 current->
page = NULL;
1516 int nodeN,
Datum nodeLabel)
1525 newInnerTuple =
addNode(
state, innerTuple, nodeLabel, nodeN);
1541 newInnerTuple->
size - innerTuple->
size)
1550 (
Item) newInnerTuple, newInnerTuple->
size,
1552 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1553 newInnerTuple->size);
1588 elog(
ERROR,
"cannot enlarge root tuple any more");
1591 saveCurrent = *current;
1616 elog(
ERROR,
"SPGiST new buffer shouldn't be same as old buffer");
1634 (
Item) newInnerTuple, newInnerTuple->
size,
1659 false,
false) != saveCurrent.
offnum)
1660 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1735 elog(
ERROR,
"invalid number of prefix nodes: %d",
1740 elog(
ERROR,
"invalid child node number: %d",
1768 if (prefixTuple->
size > innerTuple->
size)
1769 elog(
ERROR,
"SPGiST inner-tuple split must not produce longer prefix");
1785 innerTuple->
nNodes, nodes);
1821 (
Item) prefixTuple, prefixTuple->
size,
1822 current->
offnum,
false,
false);
1824 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1832 postfixBlkno = current->
blkno;
1835 (
Item) postfixTuple, postfixTuple->
size,
1844 (
Item) postfixTuple, postfixTuple->
size,
1858 postfixBlkno, postfixOffset);
1862 postfixBlkno, postfixOffset);
1924 int numNoProgressCycles = 0;
1962 if (
state->attType.attlen == -1)
1980 leafDatums[
i] = datums[
i];
1983 leafDatums[
i] = (
Datum) 0;
1998 (isnull || !
state->config.longValuesOK))
2000 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2001 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
2005 errhint(
"Values larger than a buffer page cannot be indexed.")));
2006 bestLeafSize = leafSize;
2011 current.
page = NULL;
2104 elog(
ERROR,
"SPGiST index page %u has wrong nulls flag",
2119 ¤t, &parent, isnull, isNew);
2122 else if ((sizeToSplit =
2140 leafTuple, level, isnull, isNew))
2150 goto process_inner_tuple;
2169 process_inner_tuple:
2188 memset(&out, 0,
sizeof(out));
2194 index->rd_indcollation[0],
2212 elog(
ERROR,
"cannot add a node to an allTheSame inner tuple");
2216 0, innerTuple->
nNodes - 1);
2233 leafDatums, isnulls);
2264 if (
state->config.longValuesOK && !isnull)
2266 if (leafSize < bestLeafSize)
2269 bestLeafSize = leafSize;
2270 numNoProgressCycles = 0;
2272 else if (++numNoProgressCycles < 10)
2277 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2278 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
2282 errhint(
"Values larger than a buffer page cannot be indexed.")));
2295 elog(
ERROR,
"cannot add a node to an inner tuple without node labels");
2306 goto process_inner_tuple;
2314 goto process_inner_tuple;
2317 elog(
ERROR,
"unrecognized SPGiST choose result: %d",
#define InvalidBlockNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
bool ConditionalLockBuffer(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define BufferIsValid(bufnum)
#define BUFFER_LOCK_EXCLUSIVE
#define BufferGetPage(buffer)
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
Size PageGetExactFreeSpace(Page page)
#define PageGetMaxOffsetNumber(page)
#define PageGetItemId(page, offsetNumber)
#define PageGetItem(page, itemId)
#define PageSetLSN(page, lsn)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define OidIsValid(objectId)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
#define PG_DETOAST_DATUM(datum)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
struct ItemIdData ItemIdData
#define ItemPointerGetBlockNumber(pointer)
#define ItemPointerSet(pointer, blockNumber, offNum)
#define ItemPointerIsValid(pointer)
#define ItemPointerGetOffsetNumber(pointer)
#define MaxIndexTuplesPerPage
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
void * palloc0(Size size)
#define INTERRUPTS_CAN_BE_PROCESSED()
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define INTERRUPTS_PENDING_CONDITION()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define FirstOffsetNumber
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
pg_prng_state pg_global_prng_state
#define qsort(a, b, c, d)
#define PointerGetDatum(X)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
static void spgAddNodeAction(Relation index, SpGistState *state, SpGistInnerTuple innerTuple, SPPageDesc *current, SPPageDesc *parent, int nodeN, Datum nodeLabel)
static void setRedirectionTuple(SPPageDesc *current, OffsetNumber position, BlockNumber blkno, OffsetNumber offnum)
static bool checkAllTheSame(spgPickSplitIn *in, spgPickSplitOut *out, bool tooBig, bool *includeNew)
static void spgSplitNodeAction(Relation index, SpGistState *state, SpGistInnerTuple innerTuple, SPPageDesc *current, spgChooseOut *out)
static SpGistInnerTuple addNode(SpGistState *state, SpGistInnerTuple tuple, Datum label, int offset)
bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
void spgPageIndexMultiDelete(SpGistState *state, Page page, OffsetNumber *itemnos, int nitems, int firststate, int reststate, BlockNumber blkno, OffsetNumber offnum)
static void spgMatchNodeAction(Relation index, SpGistState *state, SpGistInnerTuple innerTuple, SPPageDesc *current, SPPageDesc *parent, int nodeN)
static bool doPickSplit(Relation index, SpGistState *state, SPPageDesc *current, SPPageDesc *parent, SpGistLeafTuple newLeafTuple, int level, bool isNulls, bool isNew)
void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN, BlockNumber blkno, OffsetNumber offset)
static void moveLeafs(Relation index, SpGistState *state, SPPageDesc *current, SPPageDesc *parent, SpGistLeafTuple newLeafTuple, bool isNulls)
static void saveNodeLink(Relation index, SPPageDesc *parent, BlockNumber blkno, OffsetNumber offnum)
struct SPPageDesc SPPageDesc
static int checkSplitConditions(Relation index, SpGistState *state, SPPageDesc *current, int *nToSplit)
static void addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple, SPPageDesc *current, SPPageDesc *parent, bool isNulls, bool isNew)
static int cmpOffsetNumbers(const void *a, const void *b)
#define SPGIST_COMPRESS_PROC
#define SPGIST_CHOOSE_PROC
#define SPGIST_PICKSPLIT_PROC
#define SPGIST_NULL_BLKNO
SpGistDeadTupleData * SpGistDeadTuple
SpGistInnerTupleData * SpGistInnerTuple
#define SpGistPageStoresNulls(page)
#define SGLT_GET_NEXTOFFSET(spgLeafTuple)
#define SPGIST_PLACEHOLDER
#define SGITITERATE(x, i, nt)
#define spgFirstIncludeColumn
#define SpGistPageIsLeaf(page)
#define SPGIST_METAPAGE_BLKNO
#define SGLT_SET_NEXTOFFSET(spgLeafTuple, offsetNumber)
#define SpGistBlockIsRoot(blkno)
struct SpGistLeafTupleData * SpGistLeafTuple
#define STORE_STATE(s, d)
#define SPGIST_PAGE_CAPACITY
#define SpGistPageGetOpaque(page)
#define GBUF_INNER_PARITY(x)
#define SPGIST_ROOT_BLKNO
#define SpGistPageGetFreeSpace(p, n)
Datum * spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
SpGistInnerTuple spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, int nNodes, SpGistNodeTuple *nodes)
void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, Datum *datums, bool *isnulls, bool keyColumnIsNull)
SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, BlockNumber blkno, OffsetNumber offnum)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
void SpGistInitBuffer(Buffer b, uint16 f)
Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew)
Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, Datum *datums, bool *isnulls)
void SpGistSetLastUsedPage(Relation index, Buffer buffer)
OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, OffsetNumber *startOffset, bool errorOK)
SpGistNodeTuple spgFormNodeTuple(SpGistState *state, Datum label, bool isnull)
#define XLOG_SPGIST_SPLIT_TUPLE
#define SizeOfSpgxlogPickSplit
#define SizeOfSpgxlogMoveLeafs
#define XLOG_SPGIST_ADD_NODE
#define XLOG_SPGIST_ADD_LEAF
#define XLOG_SPGIST_MOVE_LEAFS
#define XLOG_SPGIST_PICKSPLIT
spgChooseResultType resultType
struct spgChooseOut::@48::@50 addNode
union spgChooseOut::@48 result
struct spgChooseOut::@48::@49 matchNode
struct spgChooseOut::@48::@51 splitTuple
OffsetNumber offnumHeadLeaf
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumPostfix
OffsetNumber offnumPrefix
#define TupleDescAttr(tupdesc, i)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)
void XLogRegisterData(char *data, int len)