119 Assert(indexcol > 0 && indexcol <= index->rd_index->indnkeyatts);
121 if (!IsPolymorphicType(opcintype))
123 heapcol = index->
rd_index->indkey.values[indexcol - 1];
138 for (
int i = 1;
i <= index->
rd_index->indnkeyatts;
i++)
140 if (index->
rd_index->indkey.values[
i - 1] == 0)
143 if (indexpr_item == NULL)
144 elog(
ERROR,
"wrong number of index expressions");
147 indexpr_item =
lnext(indexprs, indexpr_item);
150 elog(
ERROR,
"wrong number of index expressions");
164 elog(
ERROR,
"cache lookup failed for type %u", type);
166 desc->
attlen = typtup->typlen;
231 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
232 errmsg(
"compress method must be defined when leaf type is different from input type")));
252 elog(
ERROR,
"index \"%s\" is not an SP-GiST index",
300 att->atttypid = keyType->
type;
302 att->attlen = keyType->
attlen;
322 state->
index = index;
458 #define GET_LUP(c, f) (&(c)->lastUsedPages.cachedPage[((unsigned int) (f)) % SPGIST_CACHED_PAGES]) 544 elog(
ERROR,
"desired SPGiST tuple size is too big");
613 if (freeSpace >= needSpace)
753 size =
sizeof(
Datum);
772 memcpy(target, &datum,
sizeof(
Datum));
788 Datum *datums,
bool *isnulls)
792 bool needs_null_mask =
false;
793 int natts = tupleDescriptor->
natts;
804 for (
int i = 0;
i < natts;
i++)
808 needs_null_mask =
true;
841 Datum *datums,
bool *isnulls)
848 bool needs_null_mask =
false;
849 int natts = tupleDescriptor->
natts;
862 for (
int i = 0;
i < natts;
i++)
866 needs_null_mask =
true;
881 size = hoff + data_size;
898 tp = (
char *) tup + hoff;
915 &tupmask, (
bits8 *) NULL);
933 unsigned short infomask = 0;
946 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
947 errmsg(
"index row requires %zu bytes, maximum size is %zu",
948 (
Size) size, (
Size) INDEX_SIZE_MASK)));
976 unsigned int prefixSize;
989 for (i = 0; i < nNodes; i++)
1004 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1005 errmsg(
"SP-GiST inner tuple size %zu exceeds maximum %zu",
1008 errhint(
"Values larger than a buffer page cannot be indexed.")));
1017 elog(
ERROR,
"SPGiST inner tuple header field is too small");
1031 for (i = 0; i < nNodes; i++)
1086 Datum *datums,
bool *isnulls,
bool keyColumnIsNull)
1092 if (keyColumnIsNull && tupleDescriptor->
natts == 1)
1110 tp = (
char *) tup +
SGLTHDRSZ(hasNullsMask);
1115 tp, bp, hasNullsMask);
1143 elog(
ERROR,
"some but not all node labels are null in SPGiST inner tuple");
1154 elog(
ERROR,
"some but not all node labels are null in SPGiST inner tuple");
1194 for (; i <= maxoff; i++)
1227 offnum =
PageAddItem(page, item, size, offnum,
false,
false);
1240 *startOffset = offnum + 1;
1243 elog(
PANIC,
"failed to add item of size %u to SPGiST index page",
1255 elog(
ERROR,
"failed to add item of size %u to SPGiST index page",
1270 bool *res,
bool *isnull)
1317 for (i = 0; i < catlist->
n_members; i++)
1322 if (amopform->amoppurpose == AMOP_ORDER &&
1323 (amopform->amoplefttype == opcintype ||
1324 amopform->amoprighttype == opcintype) &&
ambeginscan_function ambeginscan
void SpGistUpdateMetaPage(Relation index)
uint8 amparallelvacuumoptions
#define PG_RETURN_POINTER(x)
SpGistTypeDesc attLeafType
#define BUFFER_LOCK_UNLOCK
void heap_fill_tuple(TupleDesc tupleDesc, Datum *values, bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
SpGistTypeDesc attPrefixType
ambulkdelete_function ambulkdelete
Datum * spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
SpGistInnerTupleData * SpGistInnerTuple
#define PageIsEmpty(page)
#define SpGistPageIsLeaf(page)
SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, BlockNumber blkno, OffsetNumber offnum)
int errhint(const char *fmt,...)
#define SPGIST_OPTIONS_PROC
SpGistCache * spgGetCache(Relation index)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
#define SGITMAXPREFIXSIZE
bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid)
#define SGLT_SET_NEXTOFFSET(spgLeafTuple, offsetNumber)
amgettuple_function amgettuple
static ListCell * lnext(const List *l, const ListCell *c)
#define RelationGetDescr(relation)
amproperty_function amproperty
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
void MarkBufferDirty(Buffer buffer)
#define PointerGetDatum(X)
bool spginsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
bool spgproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
#define TupleDescAttr(tupdesc, i)
IndexBulkDeleteResult * spgvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
#define SGITITERATE(x, i, nt)
#define RELATION_IS_LOCAL(relation)
SpGistTypeDesc attLeafType
#define SPGIST_PLACEHOLDER
amparallelrescan_function amparallelrescan
void SpGistSetLastUsedPage(Relation index, Buffer buffer)
#define SGLT_GET_HASNULLMASK(spgLeafTuple)
int errcode(int sqlerrcode)
void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
static Buffer allocNewBuffer(Relation index, int flags)
void ReleaseBuffer(Buffer buffer)
SpGistTypeDesc attLabelType
#define IndexTupleHasNulls(itup)
aminsert_function aminsert
#define BUFFER_LOCK_EXCLUSIVE
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void spgendscan(IndexScanDesc scan)
#define OidIsValid(objectId)
#define PageGetMaxOffsetNumber(page)
Oid get_op_rettype(Oid opno)
struct SpGistLeafTupleData SpGistLeafTupleData
amvalidate_function amvalidate
SpGistLUPCache lastUsedPages
bool spgcanreturn(Relation index, int attno)
void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)
void index_deform_tuple_internal(TupleDesc tupleDescriptor, Datum *values, bool *isnull, char *tp, bits8 *bp, int hasnulls)
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
SpGistLastUsedPage cachedPage[SPGIST_CACHED_PAGES]
#define GBUF_REQ_NULLS(flags)
amgetbitmap_function amgetbitmap
void UnlockReleaseBuffer(Buffer buffer)
#define ObjectIdGetDatum(X)
IndexBulkDeleteResult * spgbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
amoptions_function amoptions
#define GBUF_INNER_PARITY(x)
amcostestimate_function amcostestimate
struct SpGistLeafTupleData * SpGistLeafTuple
#define SGLTHDRSZ(hasnulls)
amvacuumcleanup_function amvacuumcleanup
amendscan_function amendscan
List * RelationGetIndexExpressions(Relation relation)
void spgadjustmembers(Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)
#define FirstOffsetNumber
SpGistInnerTuple spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, int nNodes, SpGistNodeTuple *nodes)
#define SPGIST_METAPAGE_BLKNO
#define IndexRelationGetNumberOfAttributes(relation)
void initSpGistState(SpGistState *state, Relation index)
SpGistDeadTupleData * SpGistDeadTuple
#define InvalidTransactionId
#define RelationGetRelationName(relation)
static ListCell * list_head(const List *l)
int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
FormData_pg_attribute * Form_pg_attribute
#define SearchSysCacheList1(cacheId, key1)
#define SpGistBlockIsFixed(blkno)
void spgbuildempty(Relation index)
Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, Datum *datums, bool *isnulls)
#define IndexRelationGetNumberOfKeyAttributes(relation)
TransactionId GetTopTransactionIdIfAny(void)
void SpGistInitBuffer(Buffer b, uint16 f)
Oid get_atttype(Oid relid, AttrNumber attnum)
#define BufferGetPage(buffer)
amrescan_function amrescan
bool ConditionalLockBuffer(Buffer buffer)
bytea * spgoptions(Datum reloptions, bool validate)
#define SPGIST_MAGIC_NUMBER
#define PageGetItemId(page, offsetNumber)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
#define ReleaseSysCacheList(x)
#define spgFirstIncludeColumn
SpGistLUPCache lastUsedPages
void * palloc0(Size size)
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
void ReleaseSysCache(HeapTuple tuple)
#define BufferGetPageSize(buffer)
void LockBuffer(Buffer buffer, int mode)
#define SPGIST_PAGE_CAPACITY
static void memcpyInnerDatum(void *target, SpGistTypeDesc *att, Datum datum)
void * MemoryContextAllocZero(MemoryContext context, Size size)
Buffer SpGistNewBuffer(Relation index)
#define InvalidOffsetNumber
#define ereport(elevel,...)
bool amusemaintenanceworkmem
BlockNumber GetFreeIndexPage(Relation rel)
#define SpGistPageStoresNulls(page)
void spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
PageHeaderData * PageHeader
#define HeapTupleIsValid(tuple)
amadjustmembers_function amadjustmembers
#define Assert(condition)
#define VACUUM_OPTION_PARALLEL_COND_CLEANUP
#define SpGistPageIsDeleted(page)
Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew)
#define SPGIST_COMPRESS_PROC
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define SPGIST_CONFIG_PROC
unsigned int SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum)
Oid exprType(const Node *expr)
void SpGistInitMetapage(Page page)
#define InvalidBlockNumber
FormData_pg_type * Form_pg_type
ammarkpos_function ammarkpos
ambuildphasename_function ambuildphasename
#define VACUUM_OPTION_PARALLEL_BULKDEL
#define SPGIST_CACHED_PAGES
#define SpGistPageGetMeta(p)
amestimateparallelscan_function amestimateparallelscan
SpGistTypeDesc attLabelType
IndexBuildResult * spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
Size heap_compute_data_size(TupleDesc tupleDesc, Datum *values, bool *isnull)
#define SGLT_SET_HASNULLMASK(spgLeafTuple, hasnulls)
#define DatumGetPointer(X)
Size PageGetExactFreeSpace(Page page)
#define SpGistPageGetOpaque(page)
#define InvalidCompressionMethod
BlockNumber BufferGetBlockNumber(Buffer buffer)
#define ItemPointerSetInvalid(pointer)
Oid get_index_column_opclass(Oid index_oid, int attno)
void SpGistInitPage(Page page, uint16 f)
int errmsg(const char *fmt,...)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
bool spgvalidate(Oid opclassoid)
FormData_pg_amop * Form_pg_amop
bool spggettuple(IndexScanDesc scan, ScanDirection dir)
static Oid GetIndexInputType(Relation index, AttrNumber indexcol)
ambuildempty_function ambuildempty
MemoryContext rd_indexcxt
void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, Datum *datums, bool *isnulls, bool keyColumnIsNull)
#define BUFFER_LOCK_SHARE
#define SpGistGetTargetPageFreeSpace(relation)
SpGistTypeDesc attPrefixType
IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz)
static void fillTypeDesc(SpGistTypeDesc *desc, Oid type)
#define TransactionIdIsValid(xid)
Oid getBaseType(Oid typid)
amcanreturn_function amcanreturn
OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, OffsetNumber *startOffset, bool errorOK)
SpGistNodeTuple spgFormNodeTuple(SpGistState *state, Datum label, bool isnull)
#define offsetof(type, field)
#define PageGetItem(page, itemId)
#define IndexTupleSize(itup)
#define ItemPointerSet(pointer, blockNumber, offNum)
aminitparallelscan_function aminitparallelscan
Datum spghandler(PG_FUNCTION_ARGS)
amrestrpos_function amrestrpos
SpGistNodeTupleData * SpGistNodeTuple
void PageInit(Page page, Size pageSize, Size specialSize)
#define GBUF_REQ_LEAF(flags)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)