PostgreSQL Source Code git master
spgist.h File Reference
#include "access/amapi.h"
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
Include dependency graph for spgist.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  spgConfigIn
 
struct  spgConfigOut
 
struct  spgChooseIn
 
struct  spgChooseOut
 
struct  spgPickSplitIn
 
struct  spgPickSplitOut
 
struct  spgInnerConsistentIn
 
struct  spgInnerConsistentOut
 
struct  spgLeafConsistentIn
 
struct  spgLeafConsistentOut
 

Macros

#define SPGIST_CONFIG_PROC   1
 
#define SPGIST_CHOOSE_PROC   2
 
#define SPGIST_PICKSPLIT_PROC   3
 
#define SPGIST_INNER_CONSISTENT_PROC   4
 
#define SPGIST_LEAF_CONSISTENT_PROC   5
 
#define SPGIST_COMPRESS_PROC   6
 
#define SPGIST_OPTIONS_PROC   7
 
#define SPGISTNRequiredProc   5
 
#define SPGISTNProc   7
 

Typedefs

typedef struct spgConfigIn spgConfigIn
 
typedef struct spgConfigOut spgConfigOut
 
typedef struct spgChooseIn spgChooseIn
 
typedef enum spgChooseResultType spgChooseResultType
 
typedef struct spgChooseOut spgChooseOut
 
typedef struct spgPickSplitIn spgPickSplitIn
 
typedef struct spgPickSplitOut spgPickSplitOut
 
typedef struct spgInnerConsistentIn spgInnerConsistentIn
 
typedef struct spgInnerConsistentOut spgInnerConsistentOut
 
typedef struct spgLeafConsistentIn spgLeafConsistentIn
 
typedef struct spgLeafConsistentOut spgLeafConsistentOut
 

Enumerations

enum  spgChooseResultType { spgMatchNode = 1 , spgAddNode , spgSplitTuple }
 

Functions

byteaspgoptions (Datum reloptions, bool validate)
 
IndexBuildResultspgbuild (Relation heap, Relation index, struct IndexInfo *indexInfo)
 
void spgbuildempty (Relation index)
 
bool spginsert (Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, struct IndexInfo *indexInfo)
 
IndexScanDesc spgbeginscan (Relation rel, int keysz, int orderbysz)
 
void spgendscan (IndexScanDesc scan)
 
void spgrescan (IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
 
int64 spggetbitmap (IndexScanDesc scan, TIDBitmap *tbm)
 
bool spggettuple (IndexScanDesc scan, ScanDirection dir)
 
bool spgcanreturn (Relation index, int attno)
 
IndexBulkDeleteResultspgbulkdelete (IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
 
IndexBulkDeleteResultspgvacuumcleanup (IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
 
bool spgvalidate (Oid opclassoid)
 
void spgadjustmembers (Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)
 

Macro Definition Documentation

◆ SPGIST_CHOOSE_PROC

#define SPGIST_CHOOSE_PROC   2

Definition at line 24 of file spgist.h.

◆ SPGIST_COMPRESS_PROC

#define SPGIST_COMPRESS_PROC   6

Definition at line 28 of file spgist.h.

◆ SPGIST_CONFIG_PROC

#define SPGIST_CONFIG_PROC   1

Definition at line 23 of file spgist.h.

◆ SPGIST_INNER_CONSISTENT_PROC

#define SPGIST_INNER_CONSISTENT_PROC   4

Definition at line 26 of file spgist.h.

◆ SPGIST_LEAF_CONSISTENT_PROC

#define SPGIST_LEAF_CONSISTENT_PROC   5

Definition at line 27 of file spgist.h.

◆ SPGIST_OPTIONS_PROC

#define SPGIST_OPTIONS_PROC   7

Definition at line 29 of file spgist.h.

◆ SPGIST_PICKSPLIT_PROC

#define SPGIST_PICKSPLIT_PROC   3

Definition at line 25 of file spgist.h.

◆ SPGISTNProc

#define SPGISTNProc   7

Definition at line 31 of file spgist.h.

◆ SPGISTNRequiredProc

#define SPGISTNRequiredProc   5

Definition at line 30 of file spgist.h.

Typedef Documentation

◆ spgChooseIn

typedef struct spgChooseIn spgChooseIn

◆ spgChooseOut

typedef struct spgChooseOut spgChooseOut

◆ spgChooseResultType

◆ spgConfigIn

typedef struct spgConfigIn spgConfigIn

◆ spgConfigOut

typedef struct spgConfigOut spgConfigOut

◆ spgInnerConsistentIn

◆ spgInnerConsistentOut

◆ spgLeafConsistentIn

◆ spgLeafConsistentOut

◆ spgPickSplitIn

◆ spgPickSplitOut

Enumeration Type Documentation

◆ spgChooseResultType

Enumerator
spgMatchNode 
spgAddNode 
spgSplitTuple 

Definition at line 67 of file spgist.h.

68{
69 spgMatchNode = 1, /* descend into existing node */
70 spgAddNode, /* add a node to the inner tuple */
71 spgSplitTuple, /* split inner tuple (change its prefix) */
spgChooseResultType
Definition: spgist.h:68
@ spgMatchNode
Definition: spgist.h:69
@ spgAddNode
Definition: spgist.h:70
@ spgSplitTuple
Definition: spgist.h:71

Function Documentation

◆ spgadjustmembers()

void spgadjustmembers ( Oid  opfamilyoid,
Oid  opclassoid,
List operators,
List functions 
)

Definition at line 332 of file spgvalidate.c.

336{
337 ListCell *lc;
338
339 /*
340 * Operator members of an SP-GiST opfamily should never have hard
341 * dependencies, since their connection to the opfamily depends only on
342 * what the support functions think, and that can be altered. For
343 * consistency, we make all soft dependencies point to the opfamily,
344 * though a soft dependency on the opclass would work as well in the
345 * CREATE OPERATOR CLASS case.
346 */
347 foreach(lc, operators)
348 {
350
351 op->ref_is_hard = false;
352 op->ref_is_family = true;
353 op->refobjid = opfamilyoid;
354 }
355
356 /*
357 * Required support functions should have hard dependencies. Preferably
358 * those are just dependencies on the opclass, but if we're in ALTER
359 * OPERATOR FAMILY, we leave the dependency pointing at the whole
360 * opfamily. (Given that SP-GiST opclasses generally don't share
361 * opfamilies, it seems unlikely to be worth working harder.)
362 */
363 foreach(lc, functions)
364 {
366
367 switch (op->number)
368 {
374 /* Required support function */
375 op->ref_is_hard = true;
376 break;
379 /* Optional, so force it to be a soft family dependency */
380 op->ref_is_hard = false;
381 op->ref_is_family = true;
382 op->refobjid = opfamilyoid;
383 break;
384 default:
386 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
387 errmsg("support function number %d is invalid for access method %s",
388 op->number, "spgist")));
389 break;
390 }
391 }
392}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define lfirst(lc)
Definition: pg_list.h:172
static const struct fns functions
Definition: regcomp.c:358
#define SPGIST_OPTIONS_PROC
Definition: spgist.h:29
#define SPGIST_COMPRESS_PROC
Definition: spgist.h:28
#define SPGIST_CHOOSE_PROC
Definition: spgist.h:24
#define SPGIST_LEAF_CONSISTENT_PROC
Definition: spgist.h:27
#define SPGIST_CONFIG_PROC
Definition: spgist.h:23
#define SPGIST_PICKSPLIT_PROC
Definition: spgist.h:25
#define SPGIST_INNER_CONSISTENT_PROC
Definition: spgist.h:26
Oid refobjid
Definition: amapi.h:94
bool ref_is_family
Definition: amapi.h:93
int number
Definition: amapi.h:88
bool ref_is_hard
Definition: amapi.h:92

References ereport, errcode(), errmsg(), ERROR, functions, lfirst, OpFamilyMember::number, OpFamilyMember::ref_is_family, OpFamilyMember::ref_is_hard, OpFamilyMember::refobjid, SPGIST_CHOOSE_PROC, SPGIST_COMPRESS_PROC, SPGIST_CONFIG_PROC, SPGIST_INNER_CONSISTENT_PROC, SPGIST_LEAF_CONSISTENT_PROC, SPGIST_OPTIONS_PROC, and SPGIST_PICKSPLIT_PROC.

Referenced by spghandler().

◆ spgbeginscan()

IndexScanDesc spgbeginscan ( Relation  rel,
int  keysz,
int  orderbysz 
)

Definition at line 304 of file spgscan.c.

305{
306 IndexScanDesc scan;
308 int i;
309
310 scan = RelationGetIndexScan(rel, keysz, orderbysz);
311
313 if (keysz > 0)
314 so->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * keysz);
315 else
316 so->keyData = NULL;
318
320 "SP-GiST search temporary context",
323 "SP-GiST traversal-value context",
325
326 /*
327 * Set up reconTupDesc and xs_hitupdesc in case it's an index-only scan,
328 * making sure that the key column is shown as being of type attType.
329 * (It's rather annoying to do this work when it might be wasted, but for
330 * most opclasses we can re-use the index reldesc instead of making one.)
331 */
332 so->reconTupDesc = scan->xs_hitupdesc =
334
335 /* Allocate various arrays needed for order-by scans */
336 if (scan->numberOfOrderBys > 0)
337 {
338 /* This will be filled in spgrescan, but allocate the space here */
339 so->orderByTypes = (Oid *)
340 palloc(sizeof(Oid) * scan->numberOfOrderBys);
341 so->nonNullOrderByOffsets = (int *)
342 palloc(sizeof(int) * scan->numberOfOrderBys);
343
344 /* These arrays have constant contents, so we can fill them now */
345 so->zeroDistances = (double *)
346 palloc(sizeof(double) * scan->numberOfOrderBys);
347 so->infDistances = (double *)
348 palloc(sizeof(double) * scan->numberOfOrderBys);
349
350 for (i = 0; i < scan->numberOfOrderBys; i++)
351 {
352 so->zeroDistances[i] = 0.0;
354 }
355
356 scan->xs_orderbyvals = (Datum *)
357 palloc0(sizeof(Datum) * scan->numberOfOrderBys);
358 scan->xs_orderbynulls = (bool *)
359 palloc(sizeof(bool) * scan->numberOfOrderBys);
360 memset(scan->xs_orderbynulls, true,
361 sizeof(bool) * scan->numberOfOrderBys);
362 }
363
367
371
372 so->indexCollation = rel->rd_indcollation[0];
373
374 scan->opaque = so;
375
376 return scan;
377}
static float8 get_float8_infinity(void)
Definition: float.h:94
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:580
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:80
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:862
int i
Definition: isn.c:72
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
uintptr_t Datum
Definition: postgres.h:69
unsigned int Oid
Definition: postgres_ext.h:32
ScanKeyData * ScanKey
Definition: skey.h:75
SpGistScanOpaqueData * SpGistScanOpaque
void initSpGistState(SpGistState *state, Relation index)
Definition: spgutils.c:343
TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
Definition: spgutils.c:310
bool * xs_orderbynulls
Definition: relscan.h:179
int numberOfOrderBys
Definition: relscan.h:138
struct TupleDescData * xs_hitupdesc
Definition: relscan.h:162
Relation indexRelation
Definition: relscan.h:135
Datum * xs_orderbyvals
Definition: relscan.h:178
Oid * rd_indcollation
Definition: rel.h:217
MemoryContext traversalCxt
MemoryContext tempCxt
SpGistTypeDesc attType

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, SpGistState::attType, CurrentMemoryContext, fmgr_info_copy(), get_float8_infinity(), getSpGistTupleDesc(), i, index_getprocinfo(), SpGistScanOpaqueData::indexCollation, IndexScanDescData::indexRelation, SpGistScanOpaqueData::infDistances, initSpGistState(), SpGistScanOpaqueData::innerConsistentFn, SpGistScanOpaqueData::keyData, SpGistScanOpaqueData::leafConsistentFn, SpGistScanOpaqueData::nonNullOrderByOffsets, IndexScanDescData::numberOfOrderBys, IndexScanDescData::opaque, SpGistScanOpaqueData::orderByTypes, palloc(), palloc0(), RelationData::rd_indcollation, SpGistScanOpaqueData::reconTupDesc, RelationGetIndexScan(), SPGIST_INNER_CONSISTENT_PROC, SPGIST_LEAF_CONSISTENT_PROC, SpGistScanOpaqueData::state, SpGistScanOpaqueData::tempCxt, SpGistScanOpaqueData::traversalCxt, IndexScanDescData::xs_hitupdesc, IndexScanDescData::xs_orderbynulls, IndexScanDescData::xs_orderbyvals, and SpGistScanOpaqueData::zeroDistances.

Referenced by spghandler().

◆ spgbuild()

IndexBuildResult * spgbuild ( Relation  heap,
Relation  index,
struct IndexInfo indexInfo 
)

Definition at line 73 of file spginsert.c.

74{
75 IndexBuildResult *result;
76 double reltuples;
77 SpGistBuildState buildstate;
78 Buffer metabuffer,
79 rootbuffer,
80 nullbuffer;
81
83 elog(ERROR, "index \"%s\" already contains data",
85
86 /*
87 * Initialize the meta page and root pages
88 */
89 metabuffer = SpGistNewBuffer(index);
90 rootbuffer = SpGistNewBuffer(index);
91 nullbuffer = SpGistNewBuffer(index);
92
96
98
100 MarkBufferDirty(metabuffer);
101 SpGistInitBuffer(rootbuffer, SPGIST_LEAF);
102 MarkBufferDirty(rootbuffer);
104 MarkBufferDirty(nullbuffer);
105
106
108
109 UnlockReleaseBuffer(metabuffer);
110 UnlockReleaseBuffer(rootbuffer);
111 UnlockReleaseBuffer(nullbuffer);
112
113 /*
114 * Now insert all the heap data into the index
115 */
116 initSpGistState(&buildstate.spgstate, index);
117 buildstate.spgstate.isBuild = true;
118 buildstate.indtuples = 0;
119
121 "SP-GiST build temporary context",
123
124 reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
125 spgistBuildCallback, &buildstate,
126 NULL);
127
128 MemoryContextDelete(buildstate.tmpCtx);
129
131
132 /*
133 * We didn't write WAL records as we built the index, so if WAL-logging is
134 * required, write all pages to the WAL now.
135 */
137 {
140 true);
141 }
142
143 result = (IndexBuildResult *) palloc0(sizeof(IndexBuildResult));
144 result->heap_tuples = reltuples;
145 result->index_tuples = buildstate.indtuples;
146
147 return result;
148}
int Buffer
Definition: buf.h:23
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:3724
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4883
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:2532
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:273
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:396
#define Assert(condition)
Definition: c.h:815
#define elog(elevel,...)
Definition: elog.h:225
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
#define RelationGetRelationName(relation)
Definition: rel.h:539
#define RelationNeedsWAL(relation)
Definition: rel.h:628
@ MAIN_FORKNUM
Definition: relpath.h:58
static void spgistBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition: spginsert.c:41
#define SPGIST_NULL_BLKNO
#define SPGIST_METAPAGE_BLKNO
#define SPGIST_NULLS
#define SPGIST_LEAF
#define SPGIST_ROOT_BLKNO
void SpGistUpdateMetaPage(Relation index)
Definition: spgutils.c:445
Buffer SpGistNewBuffer(Relation index)
Definition: spgutils.c:389
void SpGistInitBuffer(Buffer b, uint16 f)
Definition: spgutils.c:717
void SpGistInitMetapage(Page page)
Definition: spgutils.c:727
double heap_tuples
Definition: genam.h:34
double index_tuples
Definition: genam.h:35
MemoryContext tmpCtx
Definition: spginsert.c:35
SpGistState spgstate
Definition: spginsert.c:33
Definition: type.h:96
static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
Definition: tableam.h:1780
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)
Definition: xloginsert.c:1270

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, BufferGetBlockNumber(), BufferGetPage(), CurrentMemoryContext, elog, END_CRIT_SECTION, ERROR, IndexBuildResult::heap_tuples, IndexBuildResult::index_tuples, SpGistBuildState::indtuples, initSpGistState(), SpGistState::isBuild, log_newpage_range(), MAIN_FORKNUM, MarkBufferDirty(), MemoryContextDelete(), palloc0(), RelationGetNumberOfBlocks, RelationGetRelationName, RelationNeedsWAL, SPGIST_LEAF, SPGIST_METAPAGE_BLKNO, SPGIST_NULL_BLKNO, SPGIST_NULLS, SPGIST_ROOT_BLKNO, spgistBuildCallback(), SpGistInitBuffer(), SpGistInitMetapage(), SpGistNewBuffer(), SpGistUpdateMetaPage(), SpGistBuildState::spgstate, START_CRIT_SECTION, table_index_build_scan(), SpGistBuildState::tmpCtx, and UnlockReleaseBuffer().

Referenced by spghandler().

◆ spgbuildempty()

void spgbuildempty ( Relation  index)

Definition at line 154 of file spginsert.c.

155{
156 BulkWriteState *bulkstate;
158
160
161 /* Construct metapage. */
162 buf = smgr_bulk_get_buf(bulkstate);
164 smgr_bulk_write(bulkstate, SPGIST_METAPAGE_BLKNO, buf, true);
165
166 /* Likewise for the root page. */
167 buf = smgr_bulk_get_buf(bulkstate);
169 smgr_bulk_write(bulkstate, SPGIST_ROOT_BLKNO, buf, true);
170
171 /* Likewise for the null-tuples root page. */
172 buf = smgr_bulk_get_buf(bulkstate);
174 smgr_bulk_write(bulkstate, SPGIST_NULL_BLKNO, buf, true);
175
176 smgr_bulk_finish(bulkstate);
177}
PageData * Page
Definition: bufpage.h:82
BulkWriteState * smgr_bulk_start_rel(Relation rel, ForkNumber forknum)
Definition: bulk_write.c:87
void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std)
Definition: bulk_write.c:323
BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate)
Definition: bulk_write.c:347
void smgr_bulk_finish(BulkWriteState *bulkstate)
Definition: bulk_write.c:130
static char * buf
Definition: pg_test_fsync.c:72
@ INIT_FORKNUM
Definition: relpath.h:61
void SpGistInitPage(Page page, uint16 f)
Definition: spgutils.c:703

References buf, INIT_FORKNUM, smgr_bulk_finish(), smgr_bulk_get_buf(), smgr_bulk_start_rel(), smgr_bulk_write(), SPGIST_LEAF, SPGIST_METAPAGE_BLKNO, SPGIST_NULL_BLKNO, SPGIST_NULLS, SPGIST_ROOT_BLKNO, SpGistInitMetapage(), and SpGistInitPage().

Referenced by spghandler().

◆ spgbulkdelete()

IndexBulkDeleteResult * spgbulkdelete ( IndexVacuumInfo info,
IndexBulkDeleteResult stats,
IndexBulkDeleteCallback  callback,
void *  callback_state 
)

Definition at line 916 of file spgvacuum.c.

918{
920
921 /* allocate stats if first time through, else re-use existing struct */
922 if (stats == NULL)
924 bds.info = info;
925 bds.stats = stats;
926 bds.callback = callback;
927 bds.callback_state = callback_state;
928
929 spgvacuumscan(&bds);
930
931 return stats;
932}
static void spgvacuumscan(spgBulkDeleteState *bds)
Definition: spgvacuum.c:804
IndexBulkDeleteResult * stats
Definition: spgvacuum.c:44
IndexBulkDeleteCallback callback
Definition: spgvacuum.c:45
void * callback_state
Definition: spgvacuum.c:46
IndexVacuumInfo * info
Definition: spgvacuum.c:43
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

References spgBulkDeleteState::callback, callback(), spgBulkDeleteState::callback_state, spgBulkDeleteState::info, palloc0(), spgvacuumscan(), and spgBulkDeleteState::stats.

Referenced by spghandler().

◆ spgcanreturn()

bool spgcanreturn ( Relation  index,
int  attno 
)

Definition at line 1081 of file spgscan.c.

1082{
1083 SpGistCache *cache;
1084
1085 /* INCLUDE attributes can always be fetched for index-only scans */
1086 if (attno > 1)
1087 return true;
1088
1089 /* We can do it if the opclass config function says so */
1090 cache = spgGetCache(index);
1091
1092 return cache->config.canReturnData;
1093}
SpGistCache * spgGetCache(Relation index)
Definition: spgutils.c:183
spgConfigOut config
bool canReturnData
Definition: spgist.h:46

References spgConfigOut::canReturnData, SpGistCache::config, and spgGetCache().

Referenced by spghandler().

◆ spgendscan()

void spgendscan ( IndexScanDesc  scan)

Definition at line 427 of file spgscan.c.

428{
430
433
434 if (so->keyData)
435 pfree(so->keyData);
436
437 if (so->state.leafTupDesc &&
440
441 if (so->state.deadTupleStorage)
443
444 if (scan->numberOfOrderBys > 0)
445 {
446 pfree(so->orderByTypes);
448 pfree(so->zeroDistances);
449 pfree(so->infDistances);
450 pfree(scan->xs_orderbyvals);
451 pfree(scan->xs_orderbynulls);
452 }
453
454 pfree(so);
455}
void pfree(void *pointer)
Definition: mcxt.c:1521
#define RelationGetDescr(relation)
Definition: rel.h:531
Relation index
TupleDesc leafTupDesc
char * deadTupleStorage
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:478

References SpGistState::deadTupleStorage, FreeTupleDesc(), SpGistState::index, SpGistScanOpaqueData::infDistances, SpGistScanOpaqueData::keyData, SpGistState::leafTupDesc, MemoryContextDelete(), SpGistScanOpaqueData::nonNullOrderByOffsets, IndexScanDescData::numberOfOrderBys, IndexScanDescData::opaque, SpGistScanOpaqueData::orderByTypes, pfree(), RelationGetDescr, SpGistScanOpaqueData::state, SpGistScanOpaqueData::tempCxt, SpGistScanOpaqueData::traversalCxt, IndexScanDescData::xs_orderbynulls, IndexScanDescData::xs_orderbyvals, and SpGistScanOpaqueData::zeroDistances.

Referenced by spghandler().

◆ spggetbitmap()

int64 spggetbitmap ( IndexScanDesc  scan,
TIDBitmap tbm 
)

Definition at line 940 of file spgscan.c.

941{
943
944 /* Copy want_itup to *so so we don't need to pass it around separately */
945 so->want_itup = false;
946
947 so->tbm = tbm;
948 so->ntids = 0;
949
950 spgWalk(scan->indexRelation, so, true, storeBitmap);
951
952 return so->ntids;
953}
static void spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, storeRes_func storeRes)
Definition: spgscan.c:815
static void storeBitmap(SpGistScanOpaque so, ItemPointer heapPtr, Datum leafValue, bool isnull, SpGistLeafTuple leafTuple, bool recheck, bool recheckDistances, double *distances)
Definition: spgscan.c:929

References IndexScanDescData::indexRelation, SpGistScanOpaqueData::ntids, IndexScanDescData::opaque, spgWalk(), storeBitmap(), SpGistScanOpaqueData::tbm, and SpGistScanOpaqueData::want_itup.

Referenced by spghandler().

◆ spggettuple()

bool spggettuple ( IndexScanDesc  scan,
ScanDirection  dir 
)

Definition at line 1024 of file spgscan.c.

1025{
1027
1028 if (dir != ForwardScanDirection)
1029 elog(ERROR, "SP-GiST only supports forward scan direction");
1030
1031 /* Copy want_itup to *so so we don't need to pass it around separately */
1032 so->want_itup = scan->xs_want_itup;
1033
1034 for (;;)
1035 {
1036 if (so->iPtr < so->nPtrs)
1037 {
1038 /* continuing to return reported tuples */
1039 scan->xs_heaptid = so->heapPtrs[so->iPtr];
1040 scan->xs_recheck = so->recheck[so->iPtr];
1041 scan->xs_hitup = so->reconTups[so->iPtr];
1042
1043 if (so->numberOfOrderBys > 0)
1045 so->distances[so->iPtr],
1046 so->recheckDistances[so->iPtr]);
1047 so->iPtr++;
1048 return true;
1049 }
1050
1051 if (so->numberOfOrderBys > 0)
1052 {
1053 /* Must pfree distances to avoid memory leak */
1054 int i;
1055
1056 for (i = 0; i < so->nPtrs; i++)
1057 if (so->distances[i])
1058 pfree(so->distances[i]);
1059 }
1060
1061 if (so->want_itup)
1062 {
1063 /* Must pfree reconstructed tuples to avoid memory leak */
1064 int i;
1065
1066 for (i = 0; i < so->nPtrs; i++)
1067 pfree(so->reconTups[i]);
1068 }
1069 so->iPtr = so->nPtrs = 0;
1070
1071 spgWalk(scan->indexRelation, so, false, storeGettuple);
1072
1073 if (so->nPtrs == 0)
1074 break; /* must have completed scan */
1075 }
1076
1077 return false;
1078}
void index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes, IndexOrderByDistance *distances, bool recheckOrderBy)
Definition: indexam.c:930
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
@ ForwardScanDirection
Definition: sdir.h:28
static void storeGettuple(SpGistScanOpaque so, ItemPointer heapPtr, Datum leafValue, bool isnull, SpGistLeafTuple leafTuple, bool recheck, bool recheckDistances, double *nonNullDistances)
Definition: spgscan.c:957
HeapTuple xs_hitup
Definition: relscan.h:161
ItemPointerData xs_heaptid
Definition: relscan.h:164
HeapTuple reconTups[MaxIndexTuplesPerPage]
ItemPointerData heapPtrs[MaxIndexTuplesPerPage]
bool recheckDistances[MaxIndexTuplesPerPage]
IndexOrderByDistance * distances[MaxIndexTuplesPerPage]
bool recheck[MaxIndexTuplesPerPage]

References SpGistScanOpaqueData::distances, elog, ERROR, ForwardScanDirection, SpGistScanOpaqueData::heapPtrs, i, if(), index_store_float8_orderby_distances(), IndexScanDescData::indexRelation, SpGistScanOpaqueData::iPtr, SpGistScanOpaqueData::nPtrs, SpGistScanOpaqueData::numberOfOrderBys, IndexScanDescData::opaque, SpGistScanOpaqueData::orderByTypes, pfree(), SpGistScanOpaqueData::recheck, SpGistScanOpaqueData::recheckDistances, SpGistScanOpaqueData::reconTups, spgWalk(), storeGettuple(), SpGistScanOpaqueData::want_itup, IndexScanDescData::xs_heaptid, IndexScanDescData::xs_hitup, IndexScanDescData::xs_recheck, and IndexScanDescData::xs_want_itup.

Referenced by spghandler().

◆ spginsert()

bool spginsert ( Relation  index,
Datum values,
bool *  isnull,
ItemPointer  ht_ctid,
Relation  heapRel,
IndexUniqueCheck  checkUnique,
bool  indexUnchanged,
struct IndexInfo indexInfo 
)

Definition at line 183 of file spginsert.c.

188{
189 SpGistState spgstate;
190 MemoryContext oldCtx;
191 MemoryContext insertCtx;
192
194 "SP-GiST insert temporary context",
196 oldCtx = MemoryContextSwitchTo(insertCtx);
197
198 initSpGistState(&spgstate, index);
199
200 /*
201 * We might have to repeat spgdoinsert() multiple times, if conflicts
202 * occur with concurrent insertions. If so, reset the insertCtx each time
203 * to avoid cumulative memory consumption. That means we also have to
204 * redo initSpGistState(), but it's cheap enough not to matter.
205 */
206 while (!spgdoinsert(index, &spgstate, ht_ctid, values, isnull))
207 {
208 MemoryContextReset(insertCtx);
209 initSpGistState(&spgstate, index);
210 }
211
213
214 MemoryContextSwitchTo(oldCtx);
215 MemoryContextDelete(insertCtx);
216
217 /* return false since we've not done any unique check */
218 return false;
219}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
Definition: spgdoinsert.c:1914

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, initSpGistState(), MemoryContextDelete(), MemoryContextReset(), MemoryContextSwitchTo(), spgdoinsert(), SpGistUpdateMetaPage(), and values.

Referenced by spghandler().

◆ spgoptions()

bytea * spgoptions ( Datum  reloptions,
bool  validate 
)

Definition at line 754 of file spgutils.c.

755{
756 static const relopt_parse_elt tab[] = {
757 {"fillfactor", RELOPT_TYPE_INT, offsetof(SpGistOptions, fillfactor)},
758 };
759
760 return (bytea *) build_reloptions(reloptions, validate,
762 sizeof(SpGistOptions),
763 tab, lengthof(tab));
764}
#define lengthof(array)
Definition: c.h:745
static int fillfactor
Definition: pgbench.c:187
void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)
Definition: reloptions.c:1908
@ RELOPT_KIND_SPGIST
Definition: reloptions.h:50
@ RELOPT_TYPE_INT
Definition: reloptions.h:32
Definition: c.h:644

References build_reloptions(), fillfactor, lengthof, RELOPT_KIND_SPGIST, and RELOPT_TYPE_INT.

Referenced by spghandler().

◆ spgrescan()

void spgrescan ( IndexScanDesc  scan,
ScanKey  scankey,
int  nscankeys,
ScanKey  orderbys,
int  norderbys 
)

Definition at line 380 of file spgscan.c.

382{
384
385 /* copy scankeys into local storage */
386 if (scankey && scan->numberOfKeys > 0)
387 memcpy(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData));
388
389 /* initialize order-by data if needed */
390 if (orderbys && scan->numberOfOrderBys > 0)
391 {
392 int i;
393
394 memcpy(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData));
395
396 for (i = 0; i < scan->numberOfOrderBys; i++)
397 {
398 ScanKey skey = &scan->orderByData[i];
399
400 /*
401 * Look up the datatype returned by the original ordering
402 * operator. SP-GiST always uses a float8 for the distance
403 * function, but the ordering operator could be anything else.
404 *
405 * XXX: The distance function is only allowed to be lossy if the
406 * ordering operator's result type is float4 or float8. Otherwise
407 * we don't know how to return the distance to the executor. But
408 * we cannot check that here, as we won't know if the distance
409 * function is lossy until it returns *recheck = true for the
410 * first time.
411 */
413 }
414 }
415
416 /* preprocess scankeys, set up the representation in *so */
417 spgPrepareScanKeys(scan);
418
419 /* set up starting queue entries */
421
422 /* count an indexscan for stats */
424}
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1655
#define pgstat_count_index_scan(rel)
Definition: pgstat.h:683
static void resetSpGistScanOpaque(SpGistScanOpaque so)
Definition: spgscan.c:154
static void spgPrepareScanKeys(IndexScanDesc scan)
Definition: spgscan.c:208
Oid fn_oid
Definition: fmgr.h:59
struct ScanKeyData * keyData
Definition: relscan.h:139
struct ScanKeyData * orderByData
Definition: relscan.h:140
FmgrInfo sk_func
Definition: skey.h:71

References FmgrInfo::fn_oid, get_func_rettype(), i, if(), IndexScanDescData::indexRelation, IndexScanDescData::keyData, IndexScanDescData::numberOfKeys, IndexScanDescData::numberOfOrderBys, IndexScanDescData::opaque, IndexScanDescData::orderByData, SpGistScanOpaqueData::orderByTypes, pgstat_count_index_scan, resetSpGistScanOpaque(), ScanKeyData::sk_func, and spgPrepareScanKeys().

Referenced by spghandler().

◆ spgvacuumcleanup()

IndexBulkDeleteResult * spgvacuumcleanup ( IndexVacuumInfo info,
IndexBulkDeleteResult stats 
)

Definition at line 947 of file spgvacuum.c.

948{
950
951 /* No-op in ANALYZE ONLY mode */
952 if (info->analyze_only)
953 return stats;
954
955 /*
956 * We don't need to scan the index if there was a preceding bulkdelete
957 * pass. Otherwise, make a pass that won't delete any live tuples, but
958 * might still accomplish useful stuff with redirect/placeholder cleanup
959 * and/or FSM housekeeping, and in any case will provide stats.
960 */
961 if (stats == NULL)
962 {
964 bds.info = info;
965 bds.stats = stats;
967 bds.callback_state = NULL;
968
969 spgvacuumscan(&bds);
970 }
971
972 /*
973 * It's quite possible for us to be fooled by concurrent tuple moves into
974 * double-counting some index tuples, so disbelieve any total that exceeds
975 * the underlying heap's count ... if we know that accurately. Otherwise
976 * this might just make matters worse.
977 */
978 if (!info->estimated_count)
979 {
980 if (stats->num_index_tuples > info->num_heap_tuples)
981 stats->num_index_tuples = info->num_heap_tuples;
982 }
983
984 return stats;
985}
static bool dummy_callback(ItemPointer itemptr, void *state)
Definition: spgvacuum.c:936
double num_index_tuples
Definition: genam.h:81
double num_heap_tuples
Definition: genam.h:54
bool analyze_only
Definition: genam.h:50
bool estimated_count
Definition: genam.h:52

References IndexVacuumInfo::analyze_only, spgBulkDeleteState::callback, spgBulkDeleteState::callback_state, dummy_callback(), IndexVacuumInfo::estimated_count, spgBulkDeleteState::info, IndexVacuumInfo::num_heap_tuples, IndexBulkDeleteResult::num_index_tuples, palloc0(), spgvacuumscan(), and spgBulkDeleteState::stats.

Referenced by spghandler().

◆ spgvalidate()

bool spgvalidate ( Oid  opclassoid)

Definition at line 39 of file spgvalidate.c.

40{
41 bool result = true;
42 HeapTuple classtup;
43 Form_pg_opclass classform;
44 Oid opfamilyoid;
45 Oid opcintype;
46 Oid opckeytype;
47 char *opclassname;
48 HeapTuple familytup;
49 Form_pg_opfamily familyform;
50 char *opfamilyname;
51 CatCList *proclist,
52 *oprlist;
53 List *grouplist;
54 OpFamilyOpFuncGroup *opclassgroup;
55 int i;
56 ListCell *lc;
57 spgConfigIn configIn;
58 spgConfigOut configOut;
59 Oid configOutLefttype = InvalidOid;
60 Oid configOutRighttype = InvalidOid;
61 Oid configOutLeafType = InvalidOid;
62
63 /* Fetch opclass information */
64 classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassoid));
65 if (!HeapTupleIsValid(classtup))
66 elog(ERROR, "cache lookup failed for operator class %u", opclassoid);
67 classform = (Form_pg_opclass) GETSTRUCT(classtup);
68
69 opfamilyoid = classform->opcfamily;
70 opcintype = classform->opcintype;
71 opckeytype = classform->opckeytype;
72 opclassname = NameStr(classform->opcname);
73
74 /* Fetch opfamily information */
75 familytup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfamilyoid));
76 if (!HeapTupleIsValid(familytup))
77 elog(ERROR, "cache lookup failed for operator family %u", opfamilyoid);
78 familyform = (Form_pg_opfamily) GETSTRUCT(familytup);
79
80 opfamilyname = NameStr(familyform->opfname);
81
82 /* Fetch all operators and support functions of the opfamily */
83 oprlist = SearchSysCacheList1(AMOPSTRATEGY, ObjectIdGetDatum(opfamilyoid));
84 proclist = SearchSysCacheList1(AMPROCNUM, ObjectIdGetDatum(opfamilyoid));
85 grouplist = identify_opfamily_groups(oprlist, proclist);
86
87 /* Check individual support functions */
88 for (i = 0; i < proclist->n_members; i++)
89 {
90 HeapTuple proctup = &proclist->members[i]->tuple;
91 Form_pg_amproc procform = (Form_pg_amproc) GETSTRUCT(proctup);
92 bool ok;
93
94 /*
95 * All SP-GiST support functions should be registered with matching
96 * left/right types
97 */
98 if (procform->amproclefttype != procform->amprocrighttype)
99 {
101 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
102 errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types",
103 opfamilyname, "spgist",
104 format_procedure(procform->amproc))));
105 result = false;
106 }
107
108 /* Check procedure numbers and function signatures */
109 switch (procform->amprocnum)
110 {
112 ok = check_amproc_signature(procform->amproc, VOIDOID, true,
113 2, 2, INTERNALOID, INTERNALOID);
114 configIn.attType = procform->amproclefttype;
115 memset(&configOut, 0, sizeof(configOut));
116
117 OidFunctionCall2(procform->amproc,
118 PointerGetDatum(&configIn),
119 PointerGetDatum(&configOut));
120
121 configOutLefttype = procform->amproclefttype;
122 configOutRighttype = procform->amprocrighttype;
123
124 /* Default leaf type is opckeytype or input type */
125 if (OidIsValid(opckeytype))
126 configOutLeafType = opckeytype;
127 else
128 configOutLeafType = procform->amproclefttype;
129
130 /* If some other leaf datum type is specified, warn */
131 if (OidIsValid(configOut.leafType) &&
132 configOutLeafType != configOut.leafType)
133 {
135 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
136 errmsg("SP-GiST leaf data type %s does not match declared type %s",
137 format_type_be(configOut.leafType),
138 format_type_be(configOutLeafType))));
139 result = false;
140 configOutLeafType = configOut.leafType;
141 }
142
143 /*
144 * When leaf and attribute types are the same, compress
145 * function is not required and we set corresponding bit in
146 * functionset for later group consistency check.
147 */
148 if (configOutLeafType == configIn.attType)
149 {
150 foreach(lc, grouplist)
151 {
152 OpFamilyOpFuncGroup *group = lfirst(lc);
153
154 if (group->lefttype == procform->amproclefttype &&
155 group->righttype == procform->amprocrighttype)
156 {
157 group->functionset |=
159 break;
160 }
161 }
162 }
163 break;
167 ok = check_amproc_signature(procform->amproc, VOIDOID, true,
168 2, 2, INTERNALOID, INTERNALOID);
169 break;
171 ok = check_amproc_signature(procform->amproc, BOOLOID, true,
172 2, 2, INTERNALOID, INTERNALOID);
173 break;
175 if (configOutLefttype != procform->amproclefttype ||
176 configOutRighttype != procform->amprocrighttype)
177 ok = false;
178 else
179 ok = check_amproc_signature(procform->amproc,
180 configOutLeafType, true,
181 1, 1, procform->amproclefttype);
182 break;
184 ok = check_amoptsproc_signature(procform->amproc);
185 break;
186 default:
188 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
189 errmsg("operator family \"%s\" of access method %s contains function %s with invalid support number %d",
190 opfamilyname, "spgist",
191 format_procedure(procform->amproc),
192 procform->amprocnum)));
193 result = false;
194 continue; /* don't want additional message */
195 }
196
197 if (!ok)
198 {
200 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
201 errmsg("operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d",
202 opfamilyname, "spgist",
203 format_procedure(procform->amproc),
204 procform->amprocnum)));
205 result = false;
206 }
207 }
208
209 /* Check individual operators */
210 for (i = 0; i < oprlist->n_members; i++)
211 {
212 HeapTuple oprtup = &oprlist->members[i]->tuple;
213 Form_pg_amop oprform = (Form_pg_amop) GETSTRUCT(oprtup);
214 Oid op_rettype;
215
216 /* TODO: Check that only allowed strategy numbers exist */
217 if (oprform->amopstrategy < 1 || oprform->amopstrategy > 63)
218 {
220 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
221 errmsg("operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d",
222 opfamilyname, "spgist",
223 format_operator(oprform->amopopr),
224 oprform->amopstrategy)));
225 result = false;
226 }
227
228 /* spgist supports ORDER BY operators */
229 if (oprform->amoppurpose != AMOP_SEARCH)
230 {
231 /* ... and operator result must match the claimed btree opfamily */
232 op_rettype = get_op_rettype(oprform->amopopr);
233 if (!opfamily_can_sort_type(oprform->amopsortfamily, op_rettype))
234 {
236 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
237 errmsg("operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s",
238 opfamilyname, "spgist",
239 format_operator(oprform->amopopr))));
240 result = false;
241 }
242 }
243 else
244 op_rettype = BOOLOID;
245
246 /* Check operator signature --- same for all spgist strategies */
247 if (!check_amop_signature(oprform->amopopr, op_rettype,
248 oprform->amoplefttype,
249 oprform->amoprighttype))
250 {
252 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
253 errmsg("operator family \"%s\" of access method %s contains operator %s with wrong signature",
254 opfamilyname, "spgist",
255 format_operator(oprform->amopopr))));
256 result = false;
257 }
258 }
259
260 /* Now check for inconsistent groups of operators/functions */
261 opclassgroup = NULL;
262 foreach(lc, grouplist)
263 {
265
266 /* Remember the group exactly matching the test opclass */
267 if (thisgroup->lefttype == opcintype &&
268 thisgroup->righttype == opcintype)
269 opclassgroup = thisgroup;
270
271 /*
272 * Complain if there are any datatype pairs with functions but no
273 * operators. This is about the best we can do for now to detect
274 * missing operators.
275 */
276 if (thisgroup->operatorset == 0)
277 {
279 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
280 errmsg("operator family \"%s\" of access method %s is missing operator(s) for types %s and %s",
281 opfamilyname, "spgist",
282 format_type_be(thisgroup->lefttype),
283 format_type_be(thisgroup->righttype))));
284 result = false;
285 }
286
287 /*
288 * Complain if we're missing functions for any datatype, remembering
289 * that SP-GiST doesn't use cross-type support functions.
290 */
291 if (thisgroup->lefttype != thisgroup->righttype)
292 continue;
293
294 for (i = 1; i <= SPGISTNProc; i++)
295 {
296 if ((thisgroup->functionset & (((uint64) 1) << i)) != 0)
297 continue; /* got it */
298 if (i == SPGIST_OPTIONS_PROC)
299 continue; /* optional method */
301 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
302 errmsg("operator family \"%s\" of access method %s is missing support function %d for type %s",
303 opfamilyname, "spgist", i,
304 format_type_be(thisgroup->lefttype))));
305 result = false;
306 }
307 }
308
309 /* Check that the originally-named opclass is supported */
310 /* (if group is there, we already checked it adequately above) */
311 if (!opclassgroup)
312 {
314 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
315 errmsg("operator class \"%s\" of access method %s is missing operator(s)",
316 opclassname, "spgist")));
317 result = false;
318 }
319
320 ReleaseCatCacheList(proclist);
321 ReleaseCatCacheList(oprlist);
322 ReleaseSysCache(familytup);
323 ReleaseSysCache(classtup);
324
325 return result;
326}
bool check_amproc_signature(Oid funcid, Oid restype, bool exact, int minargs, int maxargs,...)
Definition: amvalidate.c:152
bool check_amop_signature(Oid opno, Oid restype, Oid lefttype, Oid righttype)
Definition: amvalidate.c:206
List * identify_opfamily_groups(CatCList *oprlist, CatCList *proclist)
Definition: amvalidate.c:43
bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid)
Definition: amvalidate.c:271
bool check_amoptsproc_signature(Oid funcid)
Definition: amvalidate.c:192
#define NameStr(name)
Definition: c.h:703
uint64_t uint64
Definition: c.h:489
#define OidIsValid(objectId)
Definition: c.h:732
void ReleaseCatCacheList(CatCList *list)
Definition: catcache.c:2071
#define INFO
Definition: elog.h:34
#define OidFunctionCall2(functionId, arg1, arg2)
Definition: fmgr.h:681
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
Oid get_op_rettype(Oid opno)
Definition: lsyscache.c:1333
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:88
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define InvalidOid
Definition: postgres_ext.h:37
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:299
char * format_operator(Oid operator_oid)
Definition: regproc.c:793
#define SPGISTNProc
Definition: spgist.h:31
Definition: pg_list.h:54
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:180
int n_members
Definition: catcache.h:178
HeapTupleData tuple
Definition: catcache.h:123
Oid attType
Definition: spgist.h:38
Oid leafType
Definition: spgist.h:45
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:127

References spgConfigIn::attType, check_amop_signature(), check_amoptsproc_signature(), check_amproc_signature(), elog, ereport, errcode(), errmsg(), ERROR, format_operator(), format_procedure(), format_type_be(), OpFamilyOpFuncGroup::functionset, get_op_rettype(), GETSTRUCT, HeapTupleIsValid, i, identify_opfamily_groups(), INFO, InvalidOid, spgConfigOut::leafType, OpFamilyOpFuncGroup::lefttype, lfirst, catclist::members, catclist::n_members, NameStr, ObjectIdGetDatum(), OidFunctionCall2, OidIsValid, OpFamilyOpFuncGroup::operatorset, opfamily_can_sort_type(), PointerGetDatum(), ReleaseCatCacheList(), ReleaseSysCache(), OpFamilyOpFuncGroup::righttype, SearchSysCache1(), SearchSysCacheList1, SPGIST_CHOOSE_PROC, SPGIST_COMPRESS_PROC, SPGIST_CONFIG_PROC, SPGIST_INNER_CONSISTENT_PROC, SPGIST_LEAF_CONSISTENT_PROC, SPGIST_OPTIONS_PROC, SPGIST_PICKSPLIT_PROC, SPGISTNProc, and catctup::tuple.

Referenced by spghandler().