65 elog(
ERROR,
"failed to find requested node %d in SPGiST inner tuple",
87 else if (offset > tuple->
nNodes)
88 elog(
ERROR,
"invalid offset for adding node to SPGiST inner tuple");
133 int firststate,
int reststate,
151 memcpy(sortednos, itemnos,
sizeof(
OffsetNumber) * nitems);
157 firstItem = itemnos[0];
159 for (i = 0; i < nitems; i++)
164 tupstate = (itemno == firstItem) ? firststate : reststate;
165 if (tuple == NULL || tuple->
tupstate != tupstate)
169 itemno,
false,
false) != itemno)
170 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
279 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++)
481 &startOffset,
false);
483 toInsert[nInsert] = r;
487 memcpy(leafptr, it, it->size);
495 (
Item) newLeafTuple, newLeafTuple->
size,
496 &startOffset,
false);
497 toInsert[nInsert] = r;
499 memcpy(leafptr, newLeafTuple, newLeafTuple->size);
500 leafptr += newLeafTuple->size;
617 for (i = 1; i < limit; i++)
632 for (i = 0; i < in->
nTuples; i++)
641 for (i = 0; i < out->
nNodes; i++)
678 int level,
bool isNulls,
bool isNew)
680 bool insertedNew =
false;
694 uint8 *leafPageSelect;
702 int currentFreeSpace;
761 heapPtrs[nToInsert] = it->
heapPtr;
763 toDelete[nToDelete] =
i;
786 heapPtrs[nToInsert] = it->
heapPtr;
788 toDelete[nToDelete] =
i;
799 toDelete[nToDelete] =
i;
821 memset(&out, 0,
sizeof(out));
838 for (i = 0; i < in.
nTuples; i++)
861 for (i = 0; i < in.
nTuples; i++)
904 for (i = 0; i < out.
nNodes; i++)
930 for (i = 0; i < maxToInclude; i++)
933 if (n < 0 || n >= out.
nNodes)
934 elog(
ERROR,
"inconsistent result of SPGiST picksplit function");
954 newInnerBuffer = parent->
buffer;
992 currentFreeSpace = 0;
996 if (totalLeafSizes <= currentFreeSpace)
1006 for (i = 0; i < nToInsert; i++)
1007 leafPageSelect[i] = 0;
1023 uint8 *nodePageSelect;
1040 curspace = currentFreeSpace;
1042 for (i = 0; i < out.
nNodes; i++)
1044 if (leafSizes[i] <= curspace)
1046 nodePageSelect[
i] = 0;
1047 curspace -= leafSizes[
i];
1051 nodePageSelect[
i] = 1;
1052 newspace -= leafSizes[
i];
1055 if (curspace >= 0 && newspace >= 0)
1064 else if (includeNew)
1069 leafSizes[nodeOfNewTuple] -=
1073 curspace = currentFreeSpace;
1075 for (i = 0; i < out.
nNodes; i++)
1077 if (leafSizes[i] <= curspace)
1079 nodePageSelect[
i] = 0;
1080 curspace -= leafSizes[
i];
1084 nodePageSelect[
i] = 1;
1085 newspace -= leafSizes[
i];
1088 if (curspace < 0 || newspace < 0)
1089 elog(
ERROR,
"failed to divide leaf tuple groups across pages");
1094 elog(
ERROR,
"failed to divide leaf tuple groups across pages");
1097 for (i = 0; i < nToInsert; i++)
1100 leafPageSelect[
i] = nodePageSelect[n];
1110 leafdata = leafptr = (
char *)
palloc(totalLeafSizes);
1153 redirectTuplePos = toDelete[0];
1155 toDelete, nToDelete,
1168 toDelete, nToDelete,
1182 for (i = 0; i < nToInsert; i++)
1190 leafBuffer = leafPageSelect[
i] ? newLeafBuffer : current->
buffer;
1207 &startOffsets[leafPageSelect[i]],
1209 toInsert[
i] = newoffset;
1215 memcpy(leafptr, newLeafs[i], newLeafs[i]->size);
1216 leafptr += newLeafs[
i]->
size;
1230 saveCurrent = *current;
1248 (
Item) innerTuple, innerTuple->
size,
1277 current->
buffer = newInnerBuffer;
1282 (
Item) innerTuple, innerTuple->
size,
1323 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1352 sizeof(
uint8) * xlrec.nInsert);
1376 if (xlrec.initInner)
1386 Assert(xlrec.innerIsParent);
1456 parent->
node = nodeN;
1466 elog(
ERROR,
"failed to find requested node %d in SPGiST inner tuple",
1483 current->
page = NULL;
1493 int nodeN,
Datum nodeLabel)
1502 newInnerTuple =
addNode(state, innerTuple, nodeLabel, nodeN);
1518 newInnerTuple->
size - innerTuple->
size)
1527 (
Item) newInnerTuple, newInnerTuple->
size,
1529 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1530 newInnerTuple->size);
1565 elog(
ERROR,
"cannot enlarge root tuple any more");
1568 saveCurrent = *current;
1593 elog(
ERROR,
"SPGiST new buffer shouldn't be same as old buffer");
1611 (
Item) newInnerTuple, newInnerTuple->
size,
1636 false,
false) != saveCurrent.
offnum)
1637 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1712 elog(
ERROR,
"invalid number of prefix nodes: %d",
1717 elog(
ERROR,
"invalid child node number: %d",
1745 if (prefixTuple->
size > innerTuple->
size)
1746 elog(
ERROR,
"SPGiST inner-tuple split must not produce longer prefix");
1762 innerTuple->
nNodes, nodes);
1798 (
Item) prefixTuple, prefixTuple->
size,
1799 current->
offnum,
false,
false);
1801 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1809 postfixBlkno = current->
blkno;
1812 (
Item) postfixTuple, postfixTuple->
size,
1821 (
Item) postfixTuple, postfixTuple->
size,
1835 postfixBlkno, postfixOffset);
1839 postfixBlkno, postfixOffset);
1940 leafDatum = (
Datum) 0;
1956 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1957 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
1961 errhint(
"Values larger than a buffer page cannot be indexed.")));
1966 current.
page = NULL;
2042 elog(
ERROR,
"SPGiST index page %u has wrong nulls flag",
2057 ¤t, &parent, isnull, isNew);
2060 else if ((sizeToSplit =
2071 moveLeafs(index, state, ¤t, &parent, leafTuple, isnull);
2078 leafTuple, level, isnull, isNew))
2088 goto process_inner_tuple;
2107 process_inner_tuple:
2122 memset(&out, 0,
sizeof(out));
2146 elog(
ERROR,
"cannot add a node to an allTheSame inner tuple");
2186 elog(
ERROR,
"cannot add a node to an inner tuple without node labels");
2197 goto process_inner_tuple;
2205 goto process_inner_tuple;
2208 elog(
ERROR,
"unrecognized SPGiST choose result: %d",
#define XLOG_SPGIST_MOVE_LEAFS
#define ItemPointerIsValid(pointer)
OffsetNumber offnumPostfix
bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum datum, bool isnull)
void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN, BlockNumber blkno, OffsetNumber offset)
Datum * spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
static void saveNodeLink(Relation index, SPPageDesc *parent, BlockNumber blkno, OffsetNumber offnum)
OffsetNumber offnumParent
SpGistInnerTupleData * SpGistInnerTuple
#define SpGistPageIsLeaf(page)
SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, BlockNumber blkno, OffsetNumber offnum)
int errhint(const char *fmt,...)
#define SpGistPageGetFreeSpace(p, n)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
#define XLOG_SPGIST_SPLIT_TUPLE
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
void MarkBufferDirty(Buffer buffer)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
#define PointerGetDatum(X)
#define SGITITERATE(x, i, nt)
#define SizeOfSpgxlogMoveLeafs
#define SizeOfSpgxlogPickSplit
SpGistTypeDesc attLeafType
#define SPGIST_PLACEHOLDER
#define END_CRIT_SECTION()
void SpGistSetLastUsedPage(Relation index, Buffer buffer)
#define START_CRIT_SECTION()
int errcode(int sqlerrcode)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define XLOG_SPGIST_ADD_NODE
void ReleaseBuffer(Buffer buffer)
#define XLOG_SPGIST_ADD_LEAF
struct spgChooseOut::@45::@47 addNode
#define BUFFER_LOCK_EXCLUSIVE
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
#define SPGIST_ROOT_BLKNO
#define OidIsValid(objectId)
#define PageGetMaxOffsetNumber(page)
union spgChooseOut::@45 result
#define XLOG_SPGIST_PICKSPLIT
static void addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple, SPPageDesc *current, SPPageDesc *parent, bool isNulls, bool isNew)
static SpGistInnerTuple addNode(SpGistState *state, SpGistInnerTuple tuple, Datum label, int offset)
struct spgChooseOut::@45::@46 matchNode
struct SPPageDesc SPPageDesc
void pfree(void *pointer)
static bool doPickSplit(Relation index, SpGistState *state, SPPageDesc *current, SPPageDesc *parent, SpGistLeafTuple newLeafTuple, int level, bool isNulls, bool isNew)
void spgPageIndexMultiDelete(SpGistState *state, Page page, OffsetNumber *itemnos, int nitems, int firststate, int reststate, BlockNumber blkno, OffsetNumber offnum)
void UnlockReleaseBuffer(Buffer buffer)
#define GBUF_INNER_PARITY(x)
OffsetNumber offnumParent
#define SPGIST_NULL_BLKNO
#define FirstOffsetNumber
SpGistInnerTuple spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, int nNodes, SpGistNodeTuple *nodes)
#define SPGIST_METAPAGE_BLKNO
SpGistDeadTupleData * SpGistDeadTuple
static void spgSplitNodeAction(Relation index, SpGistState *state, SpGistInnerTuple innerTuple, SPPageDesc *current, spgChooseOut *out)
#define RelationGetRelationName(relation)
static void setRedirectionTuple(SPPageDesc *current, OffsetNumber position, BlockNumber blkno, OffsetNumber offnum)
struct ItemIdData ItemIdData
static bool checkAllTheSame(spgPickSplitIn *in, spgPickSplitOut *out, bool tooBig, bool *includeNew)
void SpGistInitBuffer(Buffer b, uint16 f)
#define BufferGetPage(buffer)
bool ConditionalLockBuffer(Buffer buffer)
unsigned int SpGistGetTypeSize(SpGistTypeDesc *att, Datum datum)
#define PageGetItemId(page, offsetNumber)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, Datum datum, bool isnull)
void XLogRegisterData(char *data, int len)
OffsetNumber offnumPrefix
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void * palloc0(Size size)
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
OffsetNumber offnumHeadLeaf
void LockBuffer(Buffer buffer, int mode)
#define SPGIST_PAGE_CAPACITY
#define STORE_STATE(s, d)
spgChooseResultType resultType
#define InvalidOffsetNumber
#define ereport(elevel,...)
#define SpGistPageStoresNulls(page)
OffsetNumber offnumParent
static void spgMatchNodeAction(Relation index, SpGistState *state, SpGistInnerTuple innerTuple, SPPageDesc *current, SPPageDesc *parent, int nodeN)
#define Assert(condition)
Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew)
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
#define SPGIST_COMPRESS_PROC
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define SpGistBlockIsRoot(blkno)
#define InvalidBlockNumber
#define BufferIsValid(bufnum)
#define ItemPointerGetOffsetNumber(pointer)
#define RelationNeedsWAL(relation)
Size PageGetExactFreeSpace(Page page)
#define SpGistPageGetOpaque(page)
static void spgAddNodeAction(Relation index, SpGistState *state, SpGistInnerTuple innerTuple, SPPageDesc *current, SPPageDesc *parent, int nodeN, Datum nodeLabel)
BlockNumber BufferGetBlockNumber(Buffer buffer)
#define MaxIndexTuplesPerPage
int errmsg(const char *fmt,...)
OffsetNumber offnumParent
static int checkSplitConditions(Relation index, SpGistState *state, SPPageDesc *current, int *nToSplit)
#define PG_DETOAST_DATUM(datum)
struct spgChooseOut::@45::@48 splitTuple
#define CHECK_FOR_INTERRUPTS()
#define ItemPointerGetBlockNumber(pointer)
#define SPGIST_CHOOSE_PROC
#define qsort(a, b, c, d)
SpGistLeafTupleData * SpGistLeafTuple
static void moveLeafs(Relation index, SpGistState *state, SPPageDesc *current, SPPageDesc *parent, SpGistLeafTuple newLeafTuple, bool isNulls)
void XLogBeginInsert(void)
#define PageSetLSN(page, lsn)
#define SPGIST_PICKSPLIT_PROC
static int cmpOffsetNumbers(const void *a, const void *b)
OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, OffsetNumber *startOffset, bool errorOK)
SpGistNodeTuple spgFormNodeTuple(SpGistState *state, Datum label, bool isnull)
#define PageGetItem(page, itemId)
#define ItemPointerSet(pointer, blockNumber, offNum)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)