32 #include "utils/fmgrprotos.h"
124 Assert(indexcol > 0 && indexcol <= index->rd_index->indnkeyatts);
125 opcintype =
index->rd_opcintype[indexcol - 1];
126 if (!IsPolymorphicType(opcintype))
128 heapcol =
index->rd_index->indkey.values[indexcol - 1];
138 if (
index->rd_indexprs)
139 indexprs =
index->rd_indexprs;
143 for (
int i = 1;
i <=
index->rd_index->indnkeyatts;
i++)
145 if (
index->rd_index->indkey.values[
i - 1] == 0)
148 if (indexpr_item == NULL)
149 elog(
ERROR,
"wrong number of index expressions");
152 indexpr_item =
lnext(indexprs, indexpr_item);
155 elog(
ERROR,
"wrong number of index expressions");
171 desc->
attlen = typtup->typlen;
187 if (
index->rd_amcache == NULL)
245 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
246 errmsg(
"compress method must be defined when leaf type is different from input type")));
263 if (
index->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
274 elog(
ERROR,
"index \"%s\" is not an SP-GiST index",
282 index->rd_amcache = cache;
323 att->atttypid = keyType->
type;
325 att->attlen = keyType->
attlen;
377 state->isBuild =
false;
483 #define GET_LUP(c, f) (&(c)->lastUsedPages.cachedPage[((unsigned int) (f)) % SPGIST_CACHED_PAGES])
569 elog(
ERROR,
"desired SPGiST tuple size is too big");
638 if (freeSpace >= needSpace)
796 memcpy(target, &datum,
sizeof(
Datum));
812 const Datum *datums,
const bool *isnulls)
816 bool needs_null_mask =
false;
817 int natts = tupleDescriptor->
natts;
828 for (
int i = 0;
i < natts;
i++)
832 needs_null_mask =
true;
865 const Datum *datums,
const bool *isnulls)
872 bool needs_null_mask =
false;
873 int natts = tupleDescriptor->
natts;
886 for (
int i = 0;
i < natts;
i++)
890 needs_null_mask =
true;
905 size = hoff + data_size;
922 tp = (
char *) tup + hoff;
939 &tupmask, (
bits8 *) NULL);
957 unsigned short infomask = 0;
970 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
971 errmsg(
"index row requires %zu bytes, maximum size is %zu",
1000 unsigned int prefixSize;
1013 for (
i = 0;
i < nNodes;
i++)
1028 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1029 errmsg(
"SP-GiST inner tuple size %zu exceeds maximum %zu",
1032 errhint(
"Values larger than a buffer page cannot be indexed.")));
1041 elog(
ERROR,
"SPGiST inner tuple header field is too small");
1055 for (
i = 0;
i < nNodes;
i++)
1109 Datum *datums,
bool *isnulls,
bool keyColumnIsNull)
1115 if (keyColumnIsNull && tupleDescriptor->
natts == 1)
1133 tp = (
char *) tup +
SGLTHDRSZ(hasNullsMask);
1138 tp, bp, hasNullsMask);
1166 elog(
ERROR,
"some but not all node labels are null in SPGiST inner tuple");
1177 elog(
ERROR,
"some but not all node labels are null in SPGiST inner tuple");
1217 for (;
i <= maxoff;
i++)
1263 *startOffset = offnum + 1;
1266 elog(
PANIC,
"failed to add item of size %zu to SPGiST index page",
1278 elog(
ERROR,
"failed to add item of size %zu to SPGiST index page",
1293 bool *
res,
bool *isnull)
1345 if (amopform->amoppurpose == AMOP_ORDER &&
1346 (amopform->amoplefttype == opcintype ||
1347 amopform->amoprighttype == opcintype) &&
@ AMPROP_DISTANCE_ORDERABLE
bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid)
#define InvalidBlockNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
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 BUFFER_LOCK_UNLOCK
#define BUFFER_LOCK_SHARE
static Page BufferGetPage(Buffer buffer)
static Size BufferGetPageSize(Buffer buffer)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
void PageInit(Page page, Size pageSize, Size specialSize)
Size PageGetExactFreeSpace(Page page)
PageHeaderData * PageHeader
static bool PageIsEmpty(Page page)
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static bool PageIsNew(Page page)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define Assert(condition)
#define OidIsValid(objectId)
static void PGresult * res
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)
#define PG_RETURN_POINTER(x)
Size heap_compute_data_size(TupleDesc tupleDesc, const Datum *values, const bool *isnull)
void heap_fill_tuple(TupleDesc tupleDesc, const Datum *values, const bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
#define HeapTupleIsValid(tuple)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
BlockNumber GetFreeIndexPage(Relation rel)
void index_deform_tuple_internal(TupleDesc tupleDescriptor, Datum *values, bool *isnull, char *tp, bits8 *bp, int hasnulls)
if(TABLE==NULL||TABLE_index==NULL)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
#define IndexTupleHasNulls(itup)
#define IndexTupleSize(itup)
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
Oid get_op_rettype(Oid opno)
Oid get_index_column_opclass(Oid index_oid, int attno)
Oid getBaseType(Oid typid)
Oid get_atttype(Oid relid, AttrNumber attnum)
void * palloc0(Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
Oid exprType(const Node *expr)
#define InvalidOffsetNumber
#define FirstOffsetNumber
bool IsBinaryCoercible(Oid srctype, Oid targettype)
FormData_pg_amop * Form_pg_amop
FormData_pg_attribute * Form_pg_attribute
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
FormData_pg_type * Form_pg_type
static Datum PointerGetDatum(const void *X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define IndexRelationGetNumberOfAttributes(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
List * RelationGetIndexExpressions(Relation relation)
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 spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
static pg_noinline void Size size
bool spginsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
void spgbuildempty(Relation index)
IndexBuildResult * spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
#define SPGIST_OPTIONS_PROC
#define SPGIST_COMPRESS_PROC
#define SPGIST_CONFIG_PROC
SpGistDeadTupleData * SpGistDeadTuple
#define SGLT_GET_HASNULLMASK(spgLeafTuple)
SpGistInnerTupleData * SpGistInnerTuple
#define SpGistPageStoresNulls(page)
#define SPGIST_PLACEHOLDER
#define SGLT_SET_HASNULLMASK(spgLeafTuple, hasnulls)
#define SGITITERATE(x, i, nt)
#define SpGistGetTargetPageFreeSpace(relation)
#define spgFirstIncludeColumn
#define SpGistPageGetMeta(p)
SpGistNodeTupleData * SpGistNodeTuple
#define SGITMAXPREFIXSIZE
#define SpGistPageIsLeaf(page)
#define SPGIST_METAPAGE_BLKNO
#define SpGistPageIsDeleted(page)
#define SGLTHDRSZ(hasnulls)
#define SGLT_SET_NEXTOFFSET(spgLeafTuple, offsetNumber)
struct SpGistLeafTupleData * SpGistLeafTuple
#define SPGIST_MAGIC_NUMBER
#define SPGIST_CACHED_PAGES
#define GBUF_REQ_NULLS(flags)
#define SPGIST_PAGE_CAPACITY
#define SpGistPageGetOpaque(page)
#define GBUF_INNER_PARITY(x)
#define SpGistBlockIsFixed(blkno)
#define GBUF_REQ_LEAF(flags)
struct SpGistLeafTupleData SpGistLeafTupleData
IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz)
bool spgcanreturn(Relation index, int attno)
bool spggettuple(IndexScanDesc scan, ScanDirection dir)
void spgendscan(IndexScanDesc scan)
void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
bytea * spgoptions(Datum reloptions, bool validate)
Datum * spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
void initSpGistState(SpGistState *state, Relation index)
void SpGistUpdateMetaPage(Relation index)
TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
Buffer SpGistNewBuffer(Relation index)
SpGistInnerTuple spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, int nNodes, SpGistNodeTuple *nodes)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, const Datum *datums, const bool *isnulls)
static void memcpyInnerDatum(void *target, SpGistTypeDesc *att, Datum datum)
void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, Datum *datums, bool *isnulls, bool keyColumnIsNull)
SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, BlockNumber blkno, OffsetNumber offnum)
unsigned int SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum)
static Oid GetIndexInputType(Relation index, AttrNumber indexcol)
void SpGistInitBuffer(Buffer b, uint16 f)
Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew)
static Buffer allocNewBuffer(Relation index, int flags)
bool spgproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
void SpGistSetLastUsedPage(Relation index, Buffer buffer)
static void fillTypeDesc(SpGistTypeDesc *desc, Oid type)
SpGistCache * spgGetCache(Relation index)
OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, OffsetNumber *startOffset, bool errorOK)
Datum spghandler(PG_FUNCTION_ARGS)
Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, const Datum *datums, const bool *isnulls)
void SpGistInitPage(Page page, uint16 f)
SpGistNodeTuple spgFormNodeTuple(SpGistState *state, Datum label, bool isnull)
void SpGistInitMetapage(Page page)
IndexBulkDeleteResult * spgvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
IndexBulkDeleteResult * spgbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
bool spgvalidate(Oid opclassoid)
void spgadjustmembers(Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)
ambuildphasename_function ambuildphasename
ambuildempty_function ambuildempty
amvacuumcleanup_function amvacuumcleanup
amoptions_function amoptions
amestimateparallelscan_function amestimateparallelscan
amrestrpos_function amrestrpos
aminsert_function aminsert
amendscan_function amendscan
amparallelrescan_function amparallelrescan
amcostestimate_function amcostestimate
amadjustmembers_function amadjustmembers
amgettuple_function amgettuple
amcanreturn_function amcanreturn
amgetbitmap_function amgetbitmap
amproperty_function amproperty
ambulkdelete_function ambulkdelete
amvalidate_function amvalidate
ammarkpos_function ammarkpos
bool amusemaintenanceworkmem
ambeginscan_function ambeginscan
amrescan_function amrescan
aminitparallelscan_function aminitparallelscan
uint8 amparallelvacuumoptions
aminsertcleanup_function aminsertcleanup
amgettreeheight_function amgettreeheight
SpGistTypeDesc attPrefixType
SpGistTypeDesc attLeafType
SpGistLUPCache lastUsedPages
SpGistTypeDesc attLabelType
SpGistLastUsedPage cachedPage[SPGIST_CACHED_PAGES]
SpGistLUPCache lastUsedPages
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define ReleaseSysCacheList(x)
#define SearchSysCacheList1(cacheId, key1)
#define InvalidCompressionMethod
#define InvalidTransactionId
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
#define TupleDescAttr(tupdesc, i)
#define VACUUM_OPTION_PARALLEL_BULKDEL
#define VACUUM_OPTION_PARALLEL_COND_CLEANUP
TransactionId GetTopTransactionIdIfAny(void)