67 elog(
ERROR,
"failed to find requested node %d in SPGiST inner tuple",
89 else if (offset > tuple->
nNodes)
90 elog(
ERROR,
"invalid offset for adding node to SPGiST inner tuple");
133 int firststate,
int reststate,
157 firstItem = itemnos[0];
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",
399 bool replaceDead =
false;
431 toDelete[nDelete] =
i;
441 toDelete[nDelete] =
i;
466 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)
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 Assert(condition)
#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)
static int pg_cmp_u16(uint16 a, uint16 b)
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
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 pg_noinline void Size size
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)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, const Datum *datums, const bool *isnulls)
void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, Datum *datums, bool *isnulls, bool keyColumnIsNull)
SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, BlockNumber blkno, OffsetNumber offnum)
void SpGistInitBuffer(Buffer b, uint16 f)
Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew)
void SpGistSetLastUsedPage(Relation index, Buffer buffer)
OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, OffsetNumber *startOffset, bool errorOK)
Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, const Datum *datums, const bool *isnulls)
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::@51::@54 splitTuple
struct spgChooseOut::@51::@53 addNode
struct spgChooseOut::@51::@52 matchNode
union spgChooseOut::@51 result
OffsetNumber offnumHeadLeaf
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumParent
OffsetNumber offnumPostfix
OffsetNumber offnumPrefix
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)