PostgreSQL Source Code  git master
ginutil.c File Reference
#include "postgres.h"
#include "access/gin_private.h"
#include "access/ginxlog.h"
#include "access/reloptions.h"
#include "access/xloginsert.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "commands/vacuum.h"
#include "miscadmin.h"
#include "storage/indexfsm.h"
#include "storage/lmgr.h"
#include "storage/predicate.h"
#include "utils/builtins.h"
#include "utils/index_selfuncs.h"
#include "utils/typcache.h"
Include dependency graph for ginutil.c:

Go to the source code of this file.

Data Structures

struct  keyEntryData
 
struct  cmpEntriesArg
 

Functions

Datum ginhandler (PG_FUNCTION_ARGS)
 
void initGinState (GinState *state, Relation index)
 
OffsetNumber gintuple_get_attrnum (GinState *ginstate, IndexTuple tuple)
 
Datum gintuple_get_key (GinState *ginstate, IndexTuple tuple, GinNullCategory *category)
 
Buffer GinNewBuffer (Relation index)
 
void GinInitPage (Page page, uint32 f, Size pageSize)
 
void GinInitBuffer (Buffer b, uint32 f)
 
void GinInitMetabuffer (Buffer b)
 
int ginCompareEntries (GinState *ginstate, OffsetNumber attnum, Datum a, GinNullCategory categorya, Datum b, GinNullCategory categoryb)
 
int ginCompareAttEntries (GinState *ginstate, OffsetNumber attnuma, Datum a, GinNullCategory categorya, OffsetNumber attnumb, Datum b, GinNullCategory categoryb)
 
static int cmpEntries (const void *a, const void *b, void *arg)
 
DatumginExtractEntries (GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, int32 *nentries, GinNullCategory **categories)
 
byteaginoptions (Datum reloptions, bool validate)
 
void ginGetStats (Relation index, GinStatsData *stats)
 
void ginUpdateStats (Relation index, const GinStatsData *stats, bool is_build)
 

Function Documentation

◆ cmpEntries()

static int cmpEntries ( const void *  a,
const void *  b,
void *  arg 
)
static

Definition at line 449 of file ginutil.c.

References cmpEntriesArg::cmpDatumFunc, cmpEntriesArg::collation, keyEntryData::datum, DatumGetInt32, FunctionCall2Coll(), cmpEntriesArg::haveDups, and keyEntryData::isnull.

Referenced by ginExtractEntries().

450 {
451  const keyEntryData *aa = (const keyEntryData *) a;
452  const keyEntryData *bb = (const keyEntryData *) b;
453  cmpEntriesArg *data = (cmpEntriesArg *) arg;
454  int res;
455 
456  if (aa->isnull)
457  {
458  if (bb->isnull)
459  res = 0; /* NULL "=" NULL */
460  else
461  res = 1; /* NULL ">" not-NULL */
462  }
463  else if (bb->isnull)
464  res = -1; /* not-NULL "<" NULL */
465  else
467  data->collation,
468  aa->datum, bb->datum));
469 
470  /*
471  * Detect if we have any duplicates. If there are equal keys, qsort must
472  * compare them at some point, else it wouldn't know whether one should go
473  * before or after the other.
474  */
475  if (res == 0)
476  data->haveDups = true;
477 
478  return res;
479 }
FmgrInfo * cmpDatumFunc
Definition: ginutil.c:443
#define DatumGetInt32(X)
Definition: postgres.h:472
bool isnull
Definition: ginutil.c:438
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1152
Datum datum
Definition: ginutil.c:437
bool haveDups
Definition: ginutil.c:445
Oid collation
Definition: ginutil.c:444
void * arg

◆ ginCompareAttEntries()

int ginCompareAttEntries ( GinState ginstate,
OffsetNumber  attnuma,
Datum  a,
GinNullCategory  categorya,
OffsetNumber  attnumb,
Datum  b,
GinNullCategory  categoryb 
)

Definition at line 416 of file ginutil.c.

References ginCompareEntries().

Referenced by cmpEntryAccumulator(), entryIsMoveRight(), entryLocateEntry(), and entryLocateLeafEntry().

419 {
420  /* attribute number is the first sort key */
421  if (attnuma != attnumb)
422  return (attnuma < attnumb) ? -1 : 1;
423 
424  return ginCompareEntries(ginstate, attnuma, a, categorya, b, categoryb);
425 }
int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, Datum a, GinNullCategory categorya, Datum b, GinNullCategory categoryb)
Definition: ginutil.c:394

◆ ginCompareEntries()

int ginCompareEntries ( GinState ginstate,
OffsetNumber  attnum,
Datum  a,
GinNullCategory  categorya,
Datum  b,
GinNullCategory  categoryb 
)

Definition at line 394 of file ginutil.c.

References GinState::compareFn, DatumGetInt32, FunctionCall2Coll(), GIN_CAT_NORM_KEY, and GinState::supportCollation.

Referenced by collectMatchBitmap(), collectMatchesForHeapRow(), ginCompareAttEntries(), and ginFillScanEntry().

397 {
398  /* if not of same null category, sort by that first */
399  if (categorya != categoryb)
400  return (categorya < categoryb) ? -1 : 1;
401 
402  /* all null items in same category are equal */
403  if (categorya != GIN_CAT_NORM_KEY)
404  return 0;
405 
406  /* both not null, so safe to call the compareFn */
407  return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
408  ginstate->supportCollation[attnum - 1],
409  a, b));
410 }
Oid supportCollation[INDEX_MAX_KEYS]
Definition: gin_private.h:87
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1152
#define GIN_CAT_NORM_KEY
Definition: ginblock.h:209
int16 attnum
Definition: pg_attribute.h:79
FmgrInfo compareFn[INDEX_MAX_KEYS]
Definition: gin_private.h:78

◆ ginExtractEntries()

Datum* ginExtractEntries ( GinState ginstate,
OffsetNumber  attnum,
Datum  value,
bool  isNull,
int32 nentries,
GinNullCategory **  categories 
)

Definition at line 489 of file ginutil.c.

References arg, cmpEntriesArg::cmpDatumFunc, cmpEntries(), cmpEntriesArg::collation, GinState::compareFn, keyEntryData::datum, DatumGetPointer, GinState::extractValueFn, FunctionCall3Coll(), GIN_CAT_EMPTY_ITEM, GIN_CAT_NORM_KEY, GIN_CAT_NULL_ITEM, GIN_CAT_NULL_KEY, cmpEntriesArg::haveDups, i, keyEntryData::isnull, palloc(), palloc0(), pfree(), PointerGetDatum, qsort_arg(), and GinState::supportCollation.

Referenced by ginHeapTupleBulkInsert(), ginHeapTupleFastCollect(), and ginHeapTupleInsert().

492 {
493  Datum *entries;
494  bool *nullFlags;
495  int32 i;
496 
497  /*
498  * We don't call the extractValueFn on a null item. Instead generate a
499  * placeholder.
500  */
501  if (isNull)
502  {
503  *nentries = 1;
504  entries = (Datum *) palloc(sizeof(Datum));
505  entries[0] = (Datum) 0;
506  *categories = (GinNullCategory *) palloc(sizeof(GinNullCategory));
507  (*categories)[0] = GIN_CAT_NULL_ITEM;
508  return entries;
509  }
510 
511  /* OK, call the opclass's extractValueFn */
512  nullFlags = NULL; /* in case extractValue doesn't set it */
513  entries = (Datum *)
515  ginstate->supportCollation[attnum - 1],
516  value,
517  PointerGetDatum(nentries),
518  PointerGetDatum(&nullFlags)));
519 
520  /*
521  * Generate a placeholder if the item contained no keys.
522  */
523  if (entries == NULL || *nentries <= 0)
524  {
525  *nentries = 1;
526  entries = (Datum *) palloc(sizeof(Datum));
527  entries[0] = (Datum) 0;
528  *categories = (GinNullCategory *) palloc(sizeof(GinNullCategory));
529  (*categories)[0] = GIN_CAT_EMPTY_ITEM;
530  return entries;
531  }
532 
533  /*
534  * If the extractValueFn didn't create a nullFlags array, create one,
535  * assuming that everything's non-null.
536  */
537  if (nullFlags == NULL)
538  nullFlags = (bool *) palloc0(*nentries * sizeof(bool));
539 
540  /*
541  * If there's more than one key, sort and unique-ify.
542  *
543  * XXX Using qsort here is notationally painful, and the overhead is
544  * pretty bad too. For small numbers of keys it'd likely be better to use
545  * a simple insertion sort.
546  */
547  if (*nentries > 1)
548  {
549  keyEntryData *keydata;
551 
552  keydata = (keyEntryData *) palloc(*nentries * sizeof(keyEntryData));
553  for (i = 0; i < *nentries; i++)
554  {
555  keydata[i].datum = entries[i];
556  keydata[i].isnull = nullFlags[i];
557  }
558 
559  arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
560  arg.collation = ginstate->supportCollation[attnum - 1];
561  arg.haveDups = false;
562  qsort_arg(keydata, *nentries, sizeof(keyEntryData),
563  cmpEntries, (void *) &arg);
564 
565  if (arg.haveDups)
566  {
567  /* there are duplicates, must get rid of 'em */
568  int32 j;
569 
570  entries[0] = keydata[0].datum;
571  nullFlags[0] = keydata[0].isnull;
572  j = 1;
573  for (i = 1; i < *nentries; i++)
574  {
575  if (cmpEntries(&keydata[i - 1], &keydata[i], &arg) != 0)
576  {
577  entries[j] = keydata[i].datum;
578  nullFlags[j] = keydata[i].isnull;
579  j++;
580  }
581  }
582  *nentries = j;
583  }
584  else
585  {
586  /* easy, no duplicates */
587  for (i = 0; i < *nentries; i++)
588  {
589  entries[i] = keydata[i].datum;
590  nullFlags[i] = keydata[i].isnull;
591  }
592  }
593 
594  pfree(keydata);
595  }
596 
597  /*
598  * Create GinNullCategory representation from nullFlags.
599  */
600  *categories = (GinNullCategory *) palloc0(*nentries * sizeof(GinNullCategory));
601  for (i = 0; i < *nentries; i++)
602  (*categories)[i] = (nullFlags[i] ? GIN_CAT_NULL_KEY : GIN_CAT_NORM_KEY);
603 
604  return entries;
605 }
Oid supportCollation[INDEX_MAX_KEYS]
Definition: gin_private.h:87
FmgrInfo * cmpDatumFunc
Definition: ginutil.c:443
bool isnull
Definition: ginutil.c:438
#define PointerGetDatum(X)
Definition: postgres.h:556
FmgrInfo extractValueFn[INDEX_MAX_KEYS]
Definition: gin_private.h:79
Datum datum
Definition: ginutil.c:437
signed int int32
Definition: c.h:355
void pfree(void *pointer)
Definition: mcxt.c:1056
signed char GinNullCategory
Definition: ginblock.h:207
bool haveDups
Definition: ginutil.c:445
#define GIN_CAT_NORM_KEY
Definition: ginblock.h:209
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
Definition: qsort_arg.c:113
#define GIN_CAT_NULL_KEY
Definition: ginblock.h:210
void * palloc0(Size size)
Definition: mcxt.c:980
uintptr_t Datum
Definition: postgres.h:367
#define GIN_CAT_NULL_ITEM
Definition: ginblock.h:212
int16 attnum
Definition: pg_attribute.h:79
static struct @143 value
Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3)
Definition: fmgr.c:1174
Oid collation
Definition: ginutil.c:444
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:949
int i
void * arg
#define GIN_CAT_EMPTY_ITEM
Definition: ginblock.h:211
static int cmpEntries(const void *a, const void *b, void *arg)
Definition: ginutil.c:449
FmgrInfo compareFn[INDEX_MAX_KEYS]
Definition: gin_private.h:78

◆ ginGetStats()

void ginGetStats ( Relation  index,
GinStatsData stats 
)

Definition at line 629 of file ginutil.c.

References BufferGetPage, GIN_METAPAGE_BLKNO, GIN_SHARE, GinPageGetMeta, GinStatsData::ginVersion, GinMetaPageData::ginVersion, LockBuffer(), GinStatsData::nDataPages, GinMetaPageData::nDataPages, GinStatsData::nEntries, GinMetaPageData::nEntries, GinStatsData::nEntryPages, GinMetaPageData::nEntryPages, GinStatsData::nPendingPages, GinMetaPageData::nPendingPages, GinStatsData::nTotalPages, GinMetaPageData::nTotalPages, ReadBuffer(), and UnlockReleaseBuffer().

Referenced by gincostestimate().

630 {
631  Buffer metabuffer;
632  Page metapage;
633  GinMetaPageData *metadata;
634 
635  metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO);
636  LockBuffer(metabuffer, GIN_SHARE);
637  metapage = BufferGetPage(metabuffer);
638  metadata = GinPageGetMeta(metapage);
639 
640  stats->nPendingPages = metadata->nPendingPages;
641  stats->nTotalPages = metadata->nTotalPages;
642  stats->nEntryPages = metadata->nEntryPages;
643  stats->nDataPages = metadata->nDataPages;
644  stats->nEntries = metadata->nEntries;
645  stats->ginVersion = metadata->ginVersion;
646 
647  UnlockReleaseBuffer(metabuffer);
648 }
BlockNumber nEntryPages
Definition: ginblock.h:80
BlockNumber nEntryPages
Definition: gin.h:46
int64 nEntries
Definition: gin.h:48
BlockNumber nTotalPages
Definition: ginblock.h:79
#define GIN_METAPAGE_BLKNO
Definition: ginblock.h:51
int64 nEntries
Definition: ginblock.h:82
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3506
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define GIN_SHARE
Definition: gin_private.h:49
BlockNumber nPendingPages
Definition: gin.h:44
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3722
BlockNumber nDataPages
Definition: gin.h:47
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:606
BlockNumber nTotalPages
Definition: gin.h:45
int32 ginVersion
Definition: ginblock.h:99
int32 ginVersion
Definition: gin.h:49
BlockNumber nDataPages
Definition: ginblock.h:81
#define GinPageGetMeta(p)
Definition: ginblock.h:104
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:78
BlockNumber nPendingPages
Definition: ginblock.h:73

◆ ginhandler()

Datum ginhandler ( PG_FUNCTION_ARGS  )

Definition at line 38 of file ginutil.c.

References IndexAmRoutine::ambeginscan, IndexAmRoutine::ambuild, IndexAmRoutine::ambuildempty, IndexAmRoutine::ambuildphasename, IndexAmRoutine::ambulkdelete, IndexAmRoutine::amcanbackward, IndexAmRoutine::amcaninclude, IndexAmRoutine::amcanmulticol, IndexAmRoutine::amcanorder, IndexAmRoutine::amcanorderbyop, IndexAmRoutine::amcanparallel, IndexAmRoutine::amcanreturn, IndexAmRoutine::amcanunique, IndexAmRoutine::amclusterable, IndexAmRoutine::amcostestimate, IndexAmRoutine::amendscan, IndexAmRoutine::amestimateparallelscan, IndexAmRoutine::amgetbitmap, IndexAmRoutine::amgettuple, IndexAmRoutine::aminitparallelscan, IndexAmRoutine::aminsert, IndexAmRoutine::amkeytype, IndexAmRoutine::ammarkpos, IndexAmRoutine::amoptionalkey, IndexAmRoutine::amoptions, IndexAmRoutine::amoptsprocnum, IndexAmRoutine::amparallelrescan, IndexAmRoutine::amparallelvacuumoptions, IndexAmRoutine::ampredlocks, IndexAmRoutine::amproperty, IndexAmRoutine::amrescan, IndexAmRoutine::amrestrpos, IndexAmRoutine::amsearcharray, IndexAmRoutine::amsearchnulls, IndexAmRoutine::amstorage, IndexAmRoutine::amstrategies, IndexAmRoutine::amsupport, IndexAmRoutine::amusemaintenanceworkmem, IndexAmRoutine::amvacuumcleanup, IndexAmRoutine::amvalidate, GIN_OPTIONS_PROC, ginbeginscan(), ginbuild(), ginbuildempty(), ginbulkdelete(), gincostestimate(), ginendscan(), gingetbitmap(), gininsert(), GINNProcs, ginoptions(), ginrescan(), ginvacuumcleanup(), ginvalidate(), InvalidOid, makeNode, PG_RETURN_POINTER, VACUUM_OPTION_PARALLEL_BULKDEL, and VACUUM_OPTION_PARALLEL_CLEANUP.

39 {
41 
42  amroutine->amstrategies = 0;
43  amroutine->amsupport = GINNProcs;
44  amroutine->amoptsprocnum = GIN_OPTIONS_PROC;
45  amroutine->amcanorder = false;
46  amroutine->amcanorderbyop = false;
47  amroutine->amcanbackward = false;
48  amroutine->amcanunique = false;
49  amroutine->amcanmulticol = true;
50  amroutine->amoptionalkey = true;
51  amroutine->amsearcharray = false;
52  amroutine->amsearchnulls = false;
53  amroutine->amstorage = true;
54  amroutine->amclusterable = false;
55  amroutine->ampredlocks = true;
56  amroutine->amcanparallel = false;
57  amroutine->amcaninclude = false;
58  amroutine->amusemaintenanceworkmem = true;
59  amroutine->amparallelvacuumoptions =
61  amroutine->amkeytype = InvalidOid;
62 
63  amroutine->ambuild = ginbuild;
64  amroutine->ambuildempty = ginbuildempty;
65  amroutine->aminsert = gininsert;
66  amroutine->ambulkdelete = ginbulkdelete;
67  amroutine->amvacuumcleanup = ginvacuumcleanup;
68  amroutine->amcanreturn = NULL;
69  amroutine->amcostestimate = gincostestimate;
70  amroutine->amoptions = ginoptions;
71  amroutine->amproperty = NULL;
72  amroutine->ambuildphasename = NULL;
73  amroutine->amvalidate = ginvalidate;
74  amroutine->ambeginscan = ginbeginscan;
75  amroutine->amrescan = ginrescan;
76  amroutine->amgettuple = NULL;
77  amroutine->amgetbitmap = gingetbitmap;
78  amroutine->amendscan = ginendscan;
79  amroutine->ammarkpos = NULL;
80  amroutine->amrestrpos = NULL;
81  amroutine->amestimateparallelscan = NULL;
82  amroutine->aminitparallelscan = NULL;
83  amroutine->amparallelrescan = NULL;
84 
85  PG_RETURN_POINTER(amroutine);
86 }
ambeginscan_function ambeginscan
Definition: amapi.h:227
uint8 amparallelvacuumoptions
Definition: amapi.h:205
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:360
IndexBulkDeleteResult * ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
Definition: ginvacuum.c:687
IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys)
Definition: ginscan.c:25
int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
Definition: ginget.c:1913
void ginendscan(IndexScanDesc scan)
Definition: ginscan.c:458
ambulkdelete_function ambulkdelete
Definition: amapi.h:219
void ginrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
Definition: ginscan.c:442
bool amcanmulticol
Definition: amapi.h:185
uint16 amsupport
Definition: amapi.h:173
amgettuple_function amgettuple
Definition: amapi.h:229
void gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
Definition: selfuncs.c:6896
bool amcanorderbyop
Definition: amapi.h:179
amproperty_function amproperty
Definition: amapi.h:224
amparallelrescan_function amparallelrescan
Definition: amapi.h:238
bool amstorage
Definition: amapi.h:193
bool ampredlocks
Definition: amapi.h:197
void ginbuildempty(Relation index)
Definition: gininsert.c:437
aminsert_function aminsert
Definition: amapi.h:218
Oid amkeytype
Definition: amapi.h:207
bool amoptionalkey
Definition: amapi.h:187
amvalidate_function amvalidate
Definition: amapi.h:226
amgetbitmap_function amgetbitmap
Definition: amapi.h:230
IndexBuildResult * ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
Definition: gininsert.c:320
ambuild_function ambuild
Definition: amapi.h:216
amoptions_function amoptions
Definition: amapi.h:223
bool ginvalidate(Oid opclassoid)
Definition: ginvalidate.c:33
bool amcaninclude
Definition: amapi.h:201
amcostestimate_function amcostestimate
Definition: amapi.h:222
bool gininsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
Definition: gininsert.c:488
bool amcanunique
Definition: amapi.h:183
amvacuumcleanup_function amvacuumcleanup
Definition: amapi.h:220
amendscan_function amendscan
Definition: amapi.h:231
bool amcanbackward
Definition: amapi.h:181
#define GINNProcs
Definition: gin.h:29
amrescan_function amrescan
Definition: amapi.h:228
bool amcanparallel
Definition: amapi.h:199
bytea * ginoptions(Datum reloptions, bool validate)
Definition: ginutil.c:608
bool amsearchnulls
Definition: amapi.h:191
#define GIN_OPTIONS_PROC
Definition: gin.h:28
bool amclusterable
Definition: amapi.h:195
bool amsearcharray
Definition: amapi.h:189
#define InvalidOid
Definition: postgres_ext.h:36
bool amusemaintenanceworkmem
Definition: amapi.h:203
#define makeNode(_type_)
Definition: nodes.h:577
IndexBulkDeleteResult * ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
Definition: ginvacuum.c:564
ammarkpos_function ammarkpos
Definition: amapi.h:232
bool amcanorder
Definition: amapi.h:177
ambuildphasename_function ambuildphasename
Definition: amapi.h:225
#define VACUUM_OPTION_PARALLEL_BULKDEL
Definition: vacuum.h:45
amestimateparallelscan_function amestimateparallelscan
Definition: amapi.h:236
uint16 amstrategies
Definition: amapi.h:171
uint16 amoptsprocnum
Definition: amapi.h:175
ambuildempty_function ambuildempty
Definition: amapi.h:217
#define VACUUM_OPTION_PARALLEL_CLEANUP
Definition: vacuum.h:60
amcanreturn_function amcanreturn
Definition: amapi.h:221
aminitparallelscan_function aminitparallelscan
Definition: amapi.h:237
amrestrpos_function amrestrpos
Definition: amapi.h:233

◆ GinInitBuffer()

void GinInitBuffer ( Buffer  b,
uint32  f 
)

Definition at line 356 of file ginutil.c.

References BufferGetPage, BufferGetPageSize, and GinInitPage().

Referenced by ginbuild(), ginbuildempty(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoInsertListPage(), and writeListPage().

357 {
359 }
void GinInitPage(Page page, uint32 f, Size pageSize)
Definition: ginutil.c:343
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define BufferGetPageSize(buffer)
Definition: bufmgr.h:156

◆ GinInitMetabuffer()

void GinInitMetabuffer ( Buffer  b)

Definition at line 362 of file ginutil.c.

References BufferGetPage, BufferGetPageSize, GIN_CURRENT_VERSION, GIN_META, GinInitPage(), GinPageGetMeta, GinMetaPageData::ginVersion, GinMetaPageData::head, InvalidBlockNumber, GinMetaPageData::nDataPages, GinMetaPageData::nEntries, GinMetaPageData::nEntryPages, GinMetaPageData::nPendingHeapTuples, GinMetaPageData::nPendingPages, GinMetaPageData::nTotalPages, GinMetaPageData::tail, and GinMetaPageData::tailFreeSize.

Referenced by ginbuild(), ginbuildempty(), ginRedoDeleteListPages(), and ginRedoUpdateMetapage().

363 {
364  GinMetaPageData *metadata;
365  Page page = BufferGetPage(b);
366 
368 
369  metadata = GinPageGetMeta(page);
370 
371  metadata->head = metadata->tail = InvalidBlockNumber;
372  metadata->tailFreeSize = 0;
373  metadata->nPendingPages = 0;
374  metadata->nPendingHeapTuples = 0;
375  metadata->nTotalPages = 0;
376  metadata->nEntryPages = 0;
377  metadata->nDataPages = 0;
378  metadata->nEntries = 0;
379  metadata->ginVersion = GIN_CURRENT_VERSION;
380 
381  /*
382  * Set pd_lower just past the end of the metadata. This is essential,
383  * because without doing so, metadata will be lost if xlog.c compresses
384  * the page.
385  */
386  ((PageHeader) page)->pd_lower =
387  ((char *) metadata + sizeof(GinMetaPageData)) - (char *) page;
388 }
BlockNumber nEntryPages
Definition: ginblock.h:80
void GinInitPage(Page page, uint32 f, Size pageSize)
Definition: ginutil.c:343
BlockNumber nTotalPages
Definition: ginblock.h:79
int64 nEntries
Definition: ginblock.h:82
int64 nPendingHeapTuples
Definition: ginblock.h:74
#define GIN_META
Definition: ginblock.h:43
BlockNumber head
Definition: ginblock.h:61
BlockNumber tail
Definition: ginblock.h:62
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define BufferGetPageSize(buffer)
Definition: bufmgr.h:156
PageHeaderData * PageHeader
Definition: bufpage.h:166
uint32 tailFreeSize
Definition: ginblock.h:67
#define GIN_CURRENT_VERSION
Definition: ginblock.h:102
#define InvalidBlockNumber
Definition: block.h:33
int32 ginVersion
Definition: ginblock.h:99
BlockNumber nDataPages
Definition: ginblock.h:81
#define GinPageGetMeta(p)
Definition: ginblock.h:104
Pointer Page
Definition: bufpage.h:78
BlockNumber nPendingPages
Definition: ginblock.h:73

◆ GinInitPage()

void GinInitPage ( Page  page,
uint32  f,
Size  pageSize 
)

Definition at line 343 of file ginutil.c.

References GinPageOpaqueData::flags, GinPageGetOpaque, InvalidBlockNumber, PageInit(), and GinPageOpaqueData::rightlink.

Referenced by createPostingTree(), dataPlaceToPageLeafSplit(), dataSplitPageInternal(), entrySplitPage(), GinInitBuffer(), GinInitMetabuffer(), and ginPlaceToPage().

344 {
345  GinPageOpaque opaque;
346 
347  PageInit(page, pageSize, sizeof(GinPageOpaqueData));
348 
349  opaque = GinPageGetOpaque(page);
350  memset(opaque, 0, sizeof(GinPageOpaqueData));
351  opaque->flags = f;
352  opaque->rightlink = InvalidBlockNumber;
353 }
BlockNumber rightlink
Definition: ginblock.h:31
#define GinPageGetOpaque(page)
Definition: ginblock.h:110
#define InvalidBlockNumber
Definition: block.h:33
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42

◆ GinNewBuffer()

Buffer GinNewBuffer ( Relation  index)

Definition at line 297 of file ginutil.c.

References BufferGetPage, ConditionalLockBuffer(), ExclusiveLock, GetFreeIndexPage(), GIN_EXCLUSIVE, GIN_UNLOCK, GinPageIsRecyclable, InvalidBlockNumber, LockBuffer(), LockRelationForExtension(), P_NEW, ReadBuffer(), RELATION_IS_LOCAL, ReleaseBuffer(), and UnlockRelationForExtension().

Referenced by createPostingTree(), ginbuild(), ginPlaceToPage(), and makeSublist().

298 {
299  Buffer buffer;
300  bool needLock;
301 
302  /* First, try to get a page from FSM */
303  for (;;)
304  {
305  BlockNumber blkno = GetFreeIndexPage(index);
306 
307  if (blkno == InvalidBlockNumber)
308  break;
309 
310  buffer = ReadBuffer(index, blkno);
311 
312  /*
313  * We have to guard against the possibility that someone else already
314  * recycled this page; the buffer may be locked if so.
315  */
316  if (ConditionalLockBuffer(buffer))
317  {
318  if (GinPageIsRecyclable(BufferGetPage(buffer)))
319  return buffer; /* OK to use */
320 
321  LockBuffer(buffer, GIN_UNLOCK);
322  }
323 
324  /* Can't use it, so release buffer and try again */
325  ReleaseBuffer(buffer);
326  }
327 
328  /* Must extend the file */
329  needLock = !RELATION_IS_LOCAL(index);
330  if (needLock)
332 
333  buffer = ReadBuffer(index, P_NEW);
334  LockBuffer(buffer, GIN_EXCLUSIVE);
335 
336  if (needLock)
338 
339  return buffer;
340 }
#define GIN_UNLOCK
Definition: gin_private.h:48
#define GinPageIsRecyclable(page)
Definition: ginblock.h:137
#define ExclusiveLock
Definition: lockdefs.h:44
#define RELATION_IS_LOCAL(relation)
Definition: rel.h:583
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3483
#define P_NEW
Definition: bufmgr.h:91
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:3748
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:402
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:452
#define GIN_EXCLUSIVE
Definition: gin_private.h:50
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3722
BlockNumber GetFreeIndexPage(Relation rel)
Definition: indexfsm.c:38
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:606
#define InvalidBlockNumber
Definition: block.h:33
int Buffer
Definition: buf.h:23

◆ ginoptions()

bytea* ginoptions ( Datum  reloptions,
bool  validate 
)

Definition at line 608 of file ginutil.c.

References build_reloptions(), lengthof, offsetof, RELOPT_KIND_GIN, RELOPT_TYPE_BOOL, and RELOPT_TYPE_INT.

Referenced by ginhandler().

609 {
610  static const relopt_parse_elt tab[] = {
611  {"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)},
612  {"gin_pending_list_limit", RELOPT_TYPE_INT, offsetof(GinOptions,
613  pendingListCleanupSize)}
614  };
615 
616  return (bytea *) build_reloptions(reloptions, validate,
618  sizeof(GinOptions),
619  tab, lengthof(tab));
620 }
#define lengthof(array)
Definition: c.h:668
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:1887
Definition: c.h:555
#define offsetof(type, field)
Definition: c.h:661

◆ gintuple_get_attrnum()

OffsetNumber gintuple_get_attrnum ( GinState ginstate,
IndexTuple  tuple 
)

Definition at line 223 of file ginutil.c.

References Assert, DatumGetUInt16, FirstOffsetNumber, index_getattr, GinState::oneCol, and GinState::tupdesc.

Referenced by addItemPointersToLeafTuple(), collectMatchBitmap(), collectMatchesForHeapRow(), entryIsMoveRight(), entryLocateEntry(), entryLocateLeafEntry(), gintuple_get_key(), ginVacuumEntryPage(), matchPartialInPendingList(), and processPendingPage().

224 {
225  OffsetNumber colN;
226 
227  if (ginstate->oneCol)
228  {
229  /* column number is not stored explicitly */
230  colN = FirstOffsetNumber;
231  }
232  else
233  {
234  Datum res;
235  bool isnull;
236 
237  /*
238  * First attribute is always int16, so we can safely use any tuple
239  * descriptor to obtain first attribute of tuple
240  */
241  res = index_getattr(tuple, FirstOffsetNumber, ginstate->tupdesc[0],
242  &isnull);
243  Assert(!isnull);
244 
245  colN = DatumGetUInt16(res);
246  Assert(colN >= FirstOffsetNumber && colN <= ginstate->origTupdesc->natts);
247  }
248 
249  return colN;
250 }
#define DatumGetUInt16(X)
Definition: postgres.h:458
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
uintptr_t Datum
Definition: postgres.h:367
TupleDesc tupdesc[INDEX_MAX_KEYS]
Definition: gin_private.h:73
#define Assert(condition)
Definition: c.h:738
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:100
bool oneCol
Definition: gin_private.h:59

◆ gintuple_get_key()

Datum gintuple_get_key ( GinState ginstate,
IndexTuple  tuple,
GinNullCategory category 
)

Definition at line 256 of file ginutil.c.

References FirstOffsetNumber, GIN_CAT_NORM_KEY, GinGetNullCategory, gintuple_get_attrnum(), index_getattr, OffsetNumberNext, GinState::oneCol, GinState::origTupdesc, and GinState::tupdesc.

Referenced by addItemPointersToLeafTuple(), collectMatchBitmap(), collectMatchesForHeapRow(), entryIsMoveRight(), entryLocateEntry(), entryLocateLeafEntry(), ginVacuumEntryPage(), matchPartialInPendingList(), and processPendingPage().

258 {
259  Datum res;
260  bool isnull;
261 
262  if (ginstate->oneCol)
263  {
264  /*
265  * Single column index doesn't store attribute numbers in tuples
266  */
267  res = index_getattr(tuple, FirstOffsetNumber, ginstate->origTupdesc,
268  &isnull);
269  }
270  else
271  {
272  /*
273  * Since the datum type depends on which index column it's from, we
274  * must be careful to use the right tuple descriptor here.
275  */
276  OffsetNumber colN = gintuple_get_attrnum(ginstate, tuple);
277 
279  ginstate->tupdesc[colN - 1],
280  &isnull);
281  }
282 
283  if (isnull)
284  *category = GinGetNullCategory(tuple, ginstate);
285  else
286  *category = GIN_CAT_NORM_KEY;
287 
288  return res;
289 }
#define GinGetNullCategory(itup, ginstate)
Definition: ginblock.h:221
uint16 OffsetNumber
Definition: off.h:24
OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
Definition: ginutil.c:223
#define GIN_CAT_NORM_KEY
Definition: ginblock.h:209
#define FirstOffsetNumber
Definition: off.h:27
uintptr_t Datum
Definition: postgres.h:367
TupleDesc tupdesc[INDEX_MAX_KEYS]
Definition: gin_private.h:73
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:100
TupleDesc origTupdesc
Definition: gin_private.h:72
bool oneCol
Definition: gin_private.h:59

◆ ginUpdateStats()

void ginUpdateStats ( Relation  index,
const GinStatsData stats,
bool  is_build 
)

Definition at line 656 of file ginutil.c.

References BufferGetPage, END_CRIT_SECTION, GIN_EXCLUSIVE, GIN_METAPAGE_BLKNO, GinPageGetMeta, InvalidBlockNumber, LockBuffer(), MarkBufferDirty(), ginxlogUpdateMeta::metadata, GinStatsData::nDataPages, GinMetaPageData::nDataPages, GinStatsData::nEntries, GinMetaPageData::nEntries, GinStatsData::nEntryPages, GinMetaPageData::nEntryPages, ginxlogUpdateMeta::newRightlink, ginxlogUpdateMeta::node, GinStatsData::nTotalPages, GinMetaPageData::nTotalPages, ginxlogUpdateMeta::ntuples, PageSetLSN, ginxlogUpdateMeta::prevTail, RelationData::rd_node, ReadBuffer(), REGBUF_STANDARD, REGBUF_WILL_INIT, RelationNeedsWAL, START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_GIN_UPDATE_META_PAGE, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by ginbuild(), and ginvacuumcleanup().

657 {
658  Buffer metabuffer;
659  Page metapage;
660  GinMetaPageData *metadata;
661 
662  metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO);
663  LockBuffer(metabuffer, GIN_EXCLUSIVE);
664  metapage = BufferGetPage(metabuffer);
665  metadata = GinPageGetMeta(metapage);
666 
668 
669  metadata->nTotalPages = stats->nTotalPages;
670  metadata->nEntryPages = stats->nEntryPages;
671  metadata->nDataPages = stats->nDataPages;
672  metadata->nEntries = stats->nEntries;
673 
674  /*
675  * Set pd_lower just past the end of the metadata. This is essential,
676  * because without doing so, metadata will be lost if xlog.c compresses
677  * the page. (We must do this here because pre-v11 versions of PG did not
678  * set the metapage's pd_lower correctly, so a pg_upgraded index might
679  * contain the wrong value.)
680  */
681  ((PageHeader) metapage)->pd_lower =
682  ((char *) metadata + sizeof(GinMetaPageData)) - (char *) metapage;
683 
684  MarkBufferDirty(metabuffer);
685 
686  if (RelationNeedsWAL(index) && !is_build)
687  {
688  XLogRecPtr recptr;
689  ginxlogUpdateMeta data;
690 
691  data.node = index->rd_node;
692  data.ntuples = 0;
694  memcpy(&data.metadata, metadata, sizeof(GinMetaPageData));
695 
696  XLogBeginInsert();
697  XLogRegisterData((char *) &data, sizeof(ginxlogUpdateMeta));
699 
700  recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_UPDATE_META_PAGE);
701  PageSetLSN(metapage, recptr);
702  }
703 
704  UnlockReleaseBuffer(metabuffer);
705 
707 }
BlockNumber nEntryPages
Definition: ginblock.h:80
BlockNumber prevTail
Definition: ginxlog.h:172
BlockNumber nEntryPages
Definition: gin.h:46
RelFileNode node
Definition: ginxlog.h:170
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1468
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:214
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
#define REGBUF_WILL_INIT
Definition: xloginsert.h:33
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
int64 nEntries
Definition: gin.h:48
BlockNumber nTotalPages
Definition: ginblock.h:79
#define GIN_METAPAGE_BLKNO
Definition: ginblock.h:51
int64 nEntries
Definition: ginblock.h:82
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3506
#define XLOG_GIN_UPDATE_META_PAGE
Definition: ginxlog.h:162
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
BlockNumber newRightlink
Definition: ginxlog.h:173
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:324
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:416
#define GIN_EXCLUSIVE
Definition: gin_private.h:50
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3722
BlockNumber nDataPages
Definition: gin.h:47
GinMetaPageData metadata
Definition: ginxlog.h:171
RelFileNode rd_node
Definition: rel.h:55
PageHeaderData * PageHeader
Definition: bufpage.h:166
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:606
#define InvalidBlockNumber
Definition: block.h:33
BlockNumber nTotalPages
Definition: gin.h:45
#define RelationNeedsWAL(relation)
Definition: rel.h:562
BlockNumber nDataPages
Definition: ginblock.h:81
#define GinPageGetMeta(p)
Definition: ginblock.h:104
void XLogBeginInsert(void)
Definition: xloginsert.c:121
#define PageSetLSN(page, lsn)
Definition: bufpage.h:368
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:78

◆ initGinState()

void initGinState ( GinState state,
Relation  index 
)

Definition at line 94 of file ginutil.c.

References GinState::canPartialMatch, TypeCacheEntry::cmp_proc_finfo, GinState::compareFn, GinState::comparePartialFn, GinState::consistentFn, CreateTemplateTupleDesc(), CurrentMemoryContext, elog, ereport, errcode(), errmsg(), ERROR, GinState::extractQueryFn, GinState::extractValueFn, fmgr_info_copy(), FmgrInfo::fn_oid, format_type_be(), GIN_COMPARE_PARTIAL_PROC, GIN_COMPARE_PROC, GIN_CONSISTENT_PROC, GIN_EXTRACTQUERY_PROC, GIN_EXTRACTVALUE_PROC, GIN_TRICONSISTENT_PROC, i, GinState::index, index_getprocid(), index_getprocinfo(), InvalidOid, lookup_type_cache(), MemSet, TupleDescData::natts, OidIsValid, GinState::oneCol, GinState::origTupdesc, RelationData::rd_indcollation, RelationGetDescr, RelationGetRelationName, GinState::supportCollation, GinState::triConsistentFn, GinState::tupdesc, TupleDescAttr, TupleDescInitEntry(), TupleDescInitEntryCollation(), and TYPECACHE_CMP_PROC_FINFO.

Referenced by gin_clean_pending_list(), ginbeginscan(), ginbuild(), ginbulkdelete(), gininsert(), and ginvacuumcleanup().

95 {
96  TupleDesc origTupdesc = RelationGetDescr(index);
97  int i;
98 
99  MemSet(state, 0, sizeof(GinState));
100 
101  state->index = index;
102  state->oneCol = (origTupdesc->natts == 1) ? true : false;
103  state->origTupdesc = origTupdesc;
104 
105  for (i = 0; i < origTupdesc->natts; i++)
106  {
107  Form_pg_attribute attr = TupleDescAttr(origTupdesc, i);
108 
109  if (state->oneCol)
110  state->tupdesc[i] = state->origTupdesc;
111  else
112  {
113  state->tupdesc[i] = CreateTemplateTupleDesc(2);
114 
115  TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 1, NULL,
116  INT2OID, -1, 0);
117  TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 2, NULL,
118  attr->atttypid,
119  attr->atttypmod,
120  attr->attndims);
122  attr->attcollation);
123  }
124 
125  /*
126  * If the compare proc isn't specified in the opclass definition, look
127  * up the index key type's default btree comparator.
128  */
129  if (index_getprocid(index, i + 1, GIN_COMPARE_PROC) != InvalidOid)
130  {
131  fmgr_info_copy(&(state->compareFn[i]),
132  index_getprocinfo(index, i + 1, GIN_COMPARE_PROC),
134  }
135  else
136  {
137  TypeCacheEntry *typentry;
138 
139  typentry = lookup_type_cache(attr->atttypid,
141  if (!OidIsValid(typentry->cmp_proc_finfo.fn_oid))
142  ereport(ERROR,
143  (errcode(ERRCODE_UNDEFINED_FUNCTION),
144  errmsg("could not identify a comparison function for type %s",
145  format_type_be(attr->atttypid))));
146  fmgr_info_copy(&(state->compareFn[i]),
147  &(typentry->cmp_proc_finfo),
149  }
150 
151  /* Opclass must always provide extract procs */
152  fmgr_info_copy(&(state->extractValueFn[i]),
155  fmgr_info_copy(&(state->extractQueryFn[i]),
158 
159  /*
160  * Check opclass capability to do tri-state or binary logic consistent
161  * check.
162  */
163  if (index_getprocid(index, i + 1, GIN_TRICONSISTENT_PROC) != InvalidOid)
164  {
165  fmgr_info_copy(&(state->triConsistentFn[i]),
168  }
169 
170  if (index_getprocid(index, i + 1, GIN_CONSISTENT_PROC) != InvalidOid)
171  {
172  fmgr_info_copy(&(state->consistentFn[i]),
173  index_getprocinfo(index, i + 1, GIN_CONSISTENT_PROC),
175  }
176 
177  if (state->consistentFn[i].fn_oid == InvalidOid &&
178  state->triConsistentFn[i].fn_oid == InvalidOid)
179  {
180  elog(ERROR, "missing GIN support function (%d or %d) for attribute %d of index \"%s\"",
182  i + 1, RelationGetRelationName(index));
183  }
184 
185  /*
186  * Check opclass capability to do partial match.
187  */
189  {
190  fmgr_info_copy(&(state->comparePartialFn[i]),
193  state->canPartialMatch[i] = true;
194  }
195  else
196  {
197  state->canPartialMatch[i] = false;
198  }
199 
200  /*
201  * If the index column has a specified collation, we should honor that
202  * while doing comparisons. However, we may have a collatable storage
203  * type for a noncollatable indexed data type (for instance, hstore
204  * uses text index entries). If there's no index collation then
205  * specify default collation in case the support functions need
206  * collation. This is harmless if the support functions don't care
207  * about collation, so we just do it unconditionally. (We could
208  * alternatively call get_typcollation, but that seems like expensive
209  * overkill --- there aren't going to be any cases where a GIN storage
210  * type has a nondefault collation.)
211  */
212  if (OidIsValid(index->rd_indcollation[i]))
213  state->supportCollation[i] = index->rd_indcollation[i];
214  else
215  state->supportCollation[i] = DEFAULT_COLLATION_OID;
216  }
217 }
Oid supportCollation[INDEX_MAX_KEYS]
Definition: gin_private.h:87
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:800
#define GIN_EXTRACTQUERY_PROC
Definition: gin.h:24
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
Relation index
Definition: gin_private.h:58
#define RelationGetDescr(relation)
Definition: rel.h:482
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
bool canPartialMatch[INDEX_MAX_KEYS]
Definition: gin_private.h:85
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
FmgrInfo consistentFn[INDEX_MAX_KEYS]
Definition: gin_private.h:81
char * format_type_be(Oid type_oid)
Definition: format_type.c:327
FmgrInfo extractValueFn[INDEX_MAX_KEYS]
Definition: gin_private.h:79
#define GIN_TRICONSISTENT_PROC
Definition: gin.h:27
#define GIN_COMPARE_PARTIAL_PROC
Definition: gin.h:26
#define OidIsValid(objectId)
Definition: c.h:644
FmgrInfo cmp_proc_finfo
Definition: typcache.h:75
Oid * rd_indcollation
Definition: rel.h:199
#define ERROR
Definition: elog.h:43
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:769
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:612
FmgrInfo comparePartialFn[INDEX_MAX_KEYS]
Definition: gin_private.h:83
#define GIN_CONSISTENT_PROC
Definition: gin.h:25
#define RelationGetRelationName(relation)
Definition: rel.h:490
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
FmgrInfo extractQueryFn[INDEX_MAX_KEYS]
Definition: gin_private.h:80
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
TupleDesc tupdesc[INDEX_MAX_KEYS]
Definition: gin_private.h:73
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:331
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:144
#define GIN_EXTRACTVALUE_PROC
Definition: gin.h:23
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
int i
TupleDesc origTupdesc
Definition: gin_private.h:72
#define TYPECACHE_CMP_PROC_FINFO
Definition: typcache.h:136
FmgrInfo triConsistentFn[INDEX_MAX_KEYS]
Definition: gin_private.h:82
bool oneCol
Definition: gin_private.h:59
int16 AttrNumber
Definition: attnum.h:21
#define GIN_COMPARE_PROC
Definition: gin.h:22
FmgrInfo compareFn[INDEX_MAX_KEYS]
Definition: gin_private.h:78
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:766