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,
158 firstItem = itemnos[0];
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",
400 bool replaceDead =
false;
432 toDelete[nDelete] =
i;
442 toDelete[nDelete] =
i;
459 leafdata = leafptr =
palloc(size);
467 for (
i = 0;
i < nDelete;
i++)
483 &startOffset,
false);
485 toInsert[nInsert] = r;
489 memcpy(leafptr, it, it->
size);
497 (
Item) newLeafTuple, newLeafTuple->
size,
498 &startOffset,
false);
499 toInsert[nInsert] = r;
501 memcpy(leafptr, newLeafTuple, newLeafTuple->
size);
502 leafptr += newLeafTuple->
size;
619 for (
i = 1;
i < limit;
i++)
681 int level,
bool isNulls,
bool isNew)
683 bool insertedNew =
false;
696 uint8 *leafPageSelect;
707 int currentFreeSpace;
760 oldLeafs[nToInsert] = it;
762 toDelete[nToDelete] =
i;
786 oldLeafs[nToInsert] = it;
788 toDelete[nToDelete] =
i;
799 toDelete[nToDelete] =
i;
819 oldLeafs[in.
nTuples] = newLeafTuple;
822 memset(&out, 0,
sizeof(out));
831 index->rd_indcollation[0],
841 if (
state->leafTupDesc->natts > 1)
874 if (
state->leafTupDesc->natts > 1)
954 for (
i = 0;
i < maxToInclude;
i++)
957 if (n < 0 || n >= out.
nNodes)
958 elog(
ERROR,
"inconsistent result of SPGiST picksplit function");
978 newInnerBuffer = parent->
buffer;
1016 currentFreeSpace = 0;
1020 if (totalLeafSizes <= currentFreeSpace)
1030 for (
i = 0;
i < nToInsert;
i++)
1031 leafPageSelect[
i] = 0;
1047 uint8 *nodePageSelect;
1064 curspace = currentFreeSpace;
1068 if (leafSizes[
i] <= curspace)
1070 nodePageSelect[
i] = 0;
1071 curspace -= leafSizes[
i];
1075 nodePageSelect[
i] = 1;
1076 newspace -= leafSizes[
i];
1079 if (curspace >= 0 && newspace >= 0)
1088 else if (includeNew)
1093 leafSizes[nodeOfNewTuple] -=
1097 curspace = currentFreeSpace;
1101 if (leafSizes[
i] <= curspace)
1103 nodePageSelect[
i] = 0;
1104 curspace -= leafSizes[
i];
1108 nodePageSelect[
i] = 1;
1109 newspace -= leafSizes[
i];
1112 if (curspace < 0 || newspace < 0)
1113 elog(
ERROR,
"failed to divide leaf tuple groups across pages");
1118 elog(
ERROR,
"failed to divide leaf tuple groups across pages");
1121 for (
i = 0;
i < nToInsert;
i++)
1124 leafPageSelect[
i] = nodePageSelect[n];
1134 leafdata = leafptr = (
char *)
palloc(totalLeafSizes);
1151 if (
state->isBuild &&
1168 if (!
state->isBuild)
1177 redirectTuplePos = toDelete[0];
1179 toDelete, nToDelete,
1192 toDelete, nToDelete,
1206 for (
i = 0;
i < nToInsert;
i++)
1214 leafBuffer = leafPageSelect[
i] ? newLeafBuffer : current->
buffer;
1231 &startOffsets[leafPageSelect[
i]],
1233 toInsert[
i] = newoffset;
1239 memcpy(leafptr, newLeafs[
i], newLeafs[
i]->size);
1240 leafptr += newLeafs[
i]->
size;
1254 saveCurrent = *current;
1272 (
Item) innerTuple, innerTuple->
size,
1301 current->
buffer = newInnerBuffer;
1306 (
Item) innerTuple, innerTuple->
size,
1347 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1376 sizeof(
uint8) * xlrec.nInsert);
1400 if (xlrec.initInner)
1410 Assert(xlrec.innerIsParent);
1480 parent->
node = nodeN;
1490 elog(
ERROR,
"failed to find requested node %d in SPGiST inner tuple",
1507 current->
page = NULL;
1517 int nodeN,
Datum nodeLabel)
1526 newInnerTuple =
addNode(
state, innerTuple, nodeLabel, nodeN);
1542 newInnerTuple->
size - innerTuple->
size)
1551 (
Item) newInnerTuple, newInnerTuple->
size,
1553 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1554 newInnerTuple->size);
1589 elog(
ERROR,
"cannot enlarge root tuple any more");
1592 saveCurrent = *current;
1617 elog(
ERROR,
"SPGiST new buffer shouldn't be same as old buffer");
1635 (
Item) newInnerTuple, newInnerTuple->
size,
1660 false,
false) != saveCurrent.
offnum)
1661 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1736 elog(
ERROR,
"invalid number of prefix nodes: %d",
1741 elog(
ERROR,
"invalid child node number: %d",
1769 if (prefixTuple->
size > innerTuple->
size)
1770 elog(
ERROR,
"SPGiST inner-tuple split must not produce longer prefix");
1786 innerTuple->
nNodes, nodes);
1822 (
Item) prefixTuple, prefixTuple->
size,
1823 current->
offnum,
false,
false);
1825 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1833 postfixBlkno = current->
blkno;
1836 (
Item) postfixTuple, postfixTuple->
size,
1845 (
Item) postfixTuple, postfixTuple->
size,
1859 postfixBlkno, postfixOffset);
1863 postfixBlkno, postfixOffset);
1925 int numNoProgressCycles = 0;
1963 if (
state->attType.attlen == -1)
1981 leafDatums[
i] = datums[
i];
1984 leafDatums[
i] = (
Datum) 0;
1999 (isnull || !
state->config.longValuesOK))
2001 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2002 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
2006 errhint(
"Values larger than a buffer page cannot be indexed.")));
2007 bestLeafSize = leafSize;
2012 current.
page = NULL;
2105 elog(
ERROR,
"SPGiST index page %u has wrong nulls flag",
2120 ¤t, &parent, isnull, isNew);
2123 else if ((sizeToSplit =
2141 leafTuple, level, isnull, isNew))
2151 goto process_inner_tuple;
2170 process_inner_tuple:
2189 memset(&out, 0,
sizeof(out));
2195 index->rd_indcollation[0],
2213 elog(
ERROR,
"cannot add a node to an allTheSame inner tuple");
2217 0, innerTuple->
nNodes - 1);
2234 leafDatums, isnulls);
2265 if (
state->config.longValuesOK && !isnull)
2267 if (leafSize < bestLeafSize)
2270 bestLeafSize = leafSize;
2271 numNoProgressCycles = 0;
2273 else if (++numNoProgressCycles < 10)
2278 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2279 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
2283 errhint(
"Values larger than a buffer page cannot be indexed.")));
2296 elog(
ERROR,
"cannot add a node to an inner tuple without node labels");
2307 goto process_inner_tuple;
2315 goto process_inner_tuple;
2318 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)
static Page BufferGetPage(Buffer buffer)
#define BUFFER_LOCK_EXCLUSIVE
static bool BufferIsValid(Buffer bufnum)
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
Size PageGetExactFreeSpace(Page page)
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define OidIsValid(objectId)
elog(ERROR, "%s: %s", p2, msg)
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)
if(TABLE==NULL||TABLE_index==NULL)
struct ItemIdData ItemIdData
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
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)
static Datum PointerGetDatum(const void *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::@46::@48 addNode
struct spgChooseOut::@46::@49 splitTuple
union spgChooseOut::@46 result
struct spgChooseOut::@46::@47 matchNode
OffsetNumber offnumHeadLeaf
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumPostfix
OffsetNumber offnumPrefix
#define TupleDescAttr(tupdesc, i)
void XLogRegisterData(char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)