PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "miscadmin.h"
#include "storage/indexfsm.h"
#include "storage/lmgr.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)
 

Function Documentation

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

Definition at line 436 of file ginutil.c.

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

Referenced by ginExtractEntries().

437 {
438  const keyEntryData *aa = (const keyEntryData *) a;
439  const keyEntryData *bb = (const keyEntryData *) b;
440  cmpEntriesArg *data = (cmpEntriesArg *) arg;
441  int res;
442 
443  if (aa->isnull)
444  {
445  if (bb->isnull)
446  res = 0; /* NULL "=" NULL */
447  else
448  res = 1; /* NULL ">" not-NULL */
449  }
450  else if (bb->isnull)
451  res = -1; /* not-NULL "<" NULL */
452  else
454  data->collation,
455  aa->datum, bb->datum));
456 
457  /*
458  * Detect if we have any duplicates. If there are equal keys, qsort must
459  * compare them at some point, else it wouldn't know whether one should go
460  * before or after the other.
461  */
462  if (res == 0)
463  data->haveDups = true;
464 
465  return res;
466 }
FmgrInfo * cmpDatumFunc
Definition: ginutil.c:430
#define DatumGetInt32(X)
Definition: postgres.h:478
bool isnull
Definition: ginutil.c:425
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1047
Datum datum
Definition: ginutil.c:424
bool haveDups
Definition: ginutil.c:432
Oid collation
Definition: ginutil.c:431
void * arg
int ginCompareAttEntries ( GinState ginstate,
OffsetNumber  attnuma,
Datum  a,
GinNullCategory  categorya,
OffsetNumber  attnumb,
Datum  b,
GinNullCategory  categoryb 
)

Definition at line 403 of file ginutil.c.

References ginCompareEntries().

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

406 {
407  /* attribute number is the first sort key */
408  if (attnuma != attnumb)
409  return (attnuma < attnumb) ? -1 : 1;
410 
411  return ginCompareEntries(ginstate, attnuma, a, categorya, b, categoryb);
412 }
int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, Datum a, GinNullCategory categorya, Datum b, GinNullCategory categoryb)
Definition: ginutil.c:381
int ginCompareEntries ( GinState ginstate,
OffsetNumber  attnum,
Datum  a,
GinNullCategory  categorya,
Datum  b,
GinNullCategory  categoryb 
)

Definition at line 381 of file ginutil.c.

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

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

384 {
385  /* if not of same null category, sort by that first */
386  if (categorya != categoryb)
387  return (categorya < categoryb) ? -1 : 1;
388 
389  /* all null items in same category are equal */
390  if (categorya != GIN_CAT_NORM_KEY)
391  return 0;
392 
393  /* both not null, so safe to call the compareFn */
394  return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
395  ginstate->supportCollation[attnum - 1],
396  a, b));
397 }
Oid supportCollation[INDEX_MAX_KEYS]
Definition: gin_private.h:82
#define DatumGetInt32(X)
Definition: postgres.h:478
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1047
#define GIN_CAT_NORM_KEY
Definition: ginblock.h:199
FmgrInfo compareFn[INDEX_MAX_KEYS]
Definition: gin_private.h:73
Datum* ginExtractEntries ( GinState ginstate,
OffsetNumber  attnum,
Datum  value,
bool  isNull,
int32 nentries,
GinNullCategory **  categories 
)

Definition at line 476 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_NULL_ITEM, cmpEntriesArg::haveDups, i, keyEntryData::isnull, NULL, palloc(), palloc0(), pfree(), PointerGetDatum, qsort_arg(), and GinState::supportCollation.

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

479 {
480  Datum *entries;
481  bool *nullFlags;
482  int32 i;
483 
484  /*
485  * We don't call the extractValueFn on a null item. Instead generate a
486  * placeholder.
487  */
488  if (isNull)
489  {
490  *nentries = 1;
491  entries = (Datum *) palloc(sizeof(Datum));
492  entries[0] = (Datum) 0;
493  *categories = (GinNullCategory *) palloc(sizeof(GinNullCategory));
494  (*categories)[0] = GIN_CAT_NULL_ITEM;
495  return entries;
496  }
497 
498  /* OK, call the opclass's extractValueFn */
499  nullFlags = NULL; /* in case extractValue doesn't set it */
500  entries = (Datum *)
501  DatumGetPointer(FunctionCall3Coll(&ginstate->extractValueFn[attnum - 1],
502  ginstate->supportCollation[attnum - 1],
503  value,
504  PointerGetDatum(nentries),
505  PointerGetDatum(&nullFlags)));
506 
507  /*
508  * Generate a placeholder if the item contained no keys.
509  */
510  if (entries == NULL || *nentries <= 0)
511  {
512  *nentries = 1;
513  entries = (Datum *) palloc(sizeof(Datum));
514  entries[0] = (Datum) 0;
515  *categories = (GinNullCategory *) palloc(sizeof(GinNullCategory));
516  (*categories)[0] = GIN_CAT_EMPTY_ITEM;
517  return entries;
518  }
519 
520  /*
521  * If the extractValueFn didn't create a nullFlags array, create one,
522  * assuming that everything's non-null. Otherwise, run through the array
523  * and make sure each value is exactly 0 or 1; this ensures binary
524  * compatibility with the GinNullCategory representation.
525  */
526  if (nullFlags == NULL)
527  nullFlags = (bool *) palloc0(*nentries * sizeof(bool));
528  else
529  {
530  for (i = 0; i < *nentries; i++)
531  nullFlags[i] = (nullFlags[i] ? true : false);
532  }
533  /* now we can use the nullFlags as category codes */
534  *categories = (GinNullCategory *) nullFlags;
535 
536  /*
537  * If there's more than one key, sort and unique-ify.
538  *
539  * XXX Using qsort here is notationally painful, and the overhead is
540  * pretty bad too. For small numbers of keys it'd likely be better to use
541  * a simple insertion sort.
542  */
543  if (*nentries > 1)
544  {
545  keyEntryData *keydata;
547 
548  keydata = (keyEntryData *) palloc(*nentries * sizeof(keyEntryData));
549  for (i = 0; i < *nentries; i++)
550  {
551  keydata[i].datum = entries[i];
552  keydata[i].isnull = nullFlags[i];
553  }
554 
555  arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
556  arg.collation = ginstate->supportCollation[attnum - 1];
557  arg.haveDups = false;
558  qsort_arg(keydata, *nentries, sizeof(keyEntryData),
559  cmpEntries, (void *) &arg);
560 
561  if (arg.haveDups)
562  {
563  /* there are duplicates, must get rid of 'em */
564  int32 j;
565 
566  entries[0] = keydata[0].datum;
567  nullFlags[0] = keydata[0].isnull;
568  j = 1;
569  for (i = 1; i < *nentries; i++)
570  {
571  if (cmpEntries(&keydata[i - 1], &keydata[i], &arg) != 0)
572  {
573  entries[j] = keydata[i].datum;
574  nullFlags[j] = keydata[i].isnull;
575  j++;
576  }
577  }
578  *nentries = j;
579  }
580  else
581  {
582  /* easy, no duplicates */
583  for (i = 0; i < *nentries; i++)
584  {
585  entries[i] = keydata[i].datum;
586  nullFlags[i] = keydata[i].isnull;
587  }
588  }
589 
590  pfree(keydata);
591  }
592 
593  return entries;
594 }
Oid supportCollation[INDEX_MAX_KEYS]
Definition: gin_private.h:82
FmgrInfo * cmpDatumFunc
Definition: ginutil.c:430
bool isnull
Definition: ginutil.c:425
#define PointerGetDatum(X)
Definition: postgres.h:562
FmgrInfo extractValueFn[INDEX_MAX_KEYS]
Definition: gin_private.h:74
Datum datum
Definition: ginutil.c:424
signed int int32
Definition: c.h:256
void pfree(void *pointer)
Definition: mcxt.c:950
signed char GinNullCategory
Definition: ginblock.h:197
bool haveDups
Definition: ginutil.c:432
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
Definition: qsort_arg.c:113
void * palloc0(Size size)
Definition: mcxt.c:878
uintptr_t Datum
Definition: postgres.h:372
#define GIN_CAT_NULL_ITEM
Definition: ginblock.h:202
Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3)
Definition: fmgr.c:1069
#define NULL
Definition: c.h:229
Oid collation
Definition: ginutil.c:431
#define DatumGetPointer(X)
Definition: postgres.h:555
void * palloc(Size size)
Definition: mcxt.c:849
int i
void * arg
static struct @121 value
#define GIN_CAT_EMPTY_ITEM
Definition: ginblock.h:201
static int cmpEntries(const void *a, const void *b, void *arg)
Definition: ginutil.c:436
FmgrInfo compareFn[INDEX_MAX_KEYS]
Definition: gin_private.h:73
void ginGetStats ( Relation  index,
GinStatsData stats 
)

Definition at line 632 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(), and ginNewScanKey().

633 {
634  Buffer metabuffer;
635  Page metapage;
636  GinMetaPageData *metadata;
637 
638  metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO);
639  LockBuffer(metabuffer, GIN_SHARE);
640  metapage = BufferGetPage(metabuffer);
641  metadata = GinPageGetMeta(metapage);
642 
643  stats->nPendingPages = metadata->nPendingPages;
644  stats->nTotalPages = metadata->nTotalPages;
645  stats->nEntryPages = metadata->nEntryPages;
646  stats->nDataPages = metadata->nDataPages;
647  stats->nEntries = metadata->nEntries;
648  stats->ginVersion = metadata->ginVersion;
649 
650  UnlockReleaseBuffer(metabuffer);
651 }
BlockNumber nEntryPages
Definition: ginblock.h:79
BlockNumber nEntryPages
Definition: gin.h:45
int64 nEntries
Definition: gin.h:47
BlockNumber nTotalPages
Definition: ginblock.h:78
#define GIN_METAPAGE_BLKNO
Definition: ginblock.h:50
int64 nEntries
Definition: ginblock.h:81
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define GIN_SHARE
Definition: gin_private.h:44
BlockNumber nPendingPages
Definition: gin.h:43
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
BlockNumber nDataPages
Definition: gin.h:46
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
BlockNumber nTotalPages
Definition: gin.h:44
int32 ginVersion
Definition: ginblock.h:98
int32 ginVersion
Definition: gin.h:48
BlockNumber nDataPages
Definition: ginblock.h:80
#define GinPageGetMeta(p)
Definition: ginblock.h:103
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
BlockNumber nPendingPages
Definition: ginblock.h:72
Datum ginhandler ( PG_FUNCTION_ARGS  )

Definition at line 36 of file ginutil.c.

References IndexAmRoutine::ambeginscan, IndexAmRoutine::ambuild, IndexAmRoutine::ambuildempty, IndexAmRoutine::ambulkdelete, IndexAmRoutine::amcanbackward, 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::amparallelrescan, IndexAmRoutine::ampredlocks, IndexAmRoutine::amproperty, IndexAmRoutine::amrescan, IndexAmRoutine::amrestrpos, IndexAmRoutine::amsearcharray, IndexAmRoutine::amsearchnulls, IndexAmRoutine::amstorage, IndexAmRoutine::amstrategies, IndexAmRoutine::amsupport, IndexAmRoutine::amvacuumcleanup, IndexAmRoutine::amvalidate, ginbeginscan(), ginbuild(), ginbuildempty(), ginbulkdelete(), gincostestimate(), ginendscan(), gingetbitmap(), gininsert(), GINNProcs, ginoptions(), ginrescan(), ginvacuumcleanup(), ginvalidate(), InvalidOid, makeNode, NULL, and PG_RETURN_POINTER.

37 {
39 
40  amroutine->amstrategies = 0;
41  amroutine->amsupport = GINNProcs;
42  amroutine->amcanorder = false;
43  amroutine->amcanorderbyop = false;
44  amroutine->amcanbackward = false;
45  amroutine->amcanunique = false;
46  amroutine->amcanmulticol = true;
47  amroutine->amoptionalkey = true;
48  amroutine->amsearcharray = false;
49  amroutine->amsearchnulls = false;
50  amroutine->amstorage = true;
51  amroutine->amclusterable = false;
52  amroutine->ampredlocks = false;
53  amroutine->amcanparallel = false;
54  amroutine->amkeytype = InvalidOid;
55 
56  amroutine->ambuild = ginbuild;
57  amroutine->ambuildempty = ginbuildempty;
58  amroutine->aminsert = gininsert;
59  amroutine->ambulkdelete = ginbulkdelete;
60  amroutine->amvacuumcleanup = ginvacuumcleanup;
61  amroutine->amcanreturn = NULL;
62  amroutine->amcostestimate = gincostestimate;
63  amroutine->amoptions = ginoptions;
64  amroutine->amproperty = NULL;
65  amroutine->amvalidate = ginvalidate;
66  amroutine->ambeginscan = ginbeginscan;
67  amroutine->amrescan = ginrescan;
68  amroutine->amgettuple = NULL;
69  amroutine->amgetbitmap = gingetbitmap;
70  amroutine->amendscan = ginendscan;
71  amroutine->ammarkpos = NULL;
72  amroutine->amrestrpos = NULL;
73  amroutine->amestimateparallelscan = NULL;
74  amroutine->aminitparallelscan = NULL;
75  amroutine->amparallelrescan = NULL;
76 
77  PG_RETURN_POINTER(amroutine);
78 }
ambeginscan_function ambeginscan
Definition: amapi.h:208
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
IndexBulkDeleteResult * ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
Definition: ginvacuum.c:667
IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys)
Definition: ginscan.c:25
int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
Definition: ginget.c:1795
void ginendscan(IndexScanDesc scan)
Definition: ginscan.c:432
ambulkdelete_function ambulkdelete
Definition: amapi.h:201
void ginrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
Definition: ginscan.c:416
bool amcanmulticol
Definition: amapi.h:179
uint16 amsupport
Definition: amapi.h:169
amgettuple_function amgettuple
Definition: amapi.h:210
void gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
Definition: selfuncs.c:7401
bool amcanorderbyop
Definition: amapi.h:173
amproperty_function amproperty
Definition: amapi.h:206
amparallelrescan_function amparallelrescan
Definition: amapi.h:219
bool amstorage
Definition: amapi.h:187
bool ampredlocks
Definition: amapi.h:191
void ginbuildempty(Relation index)
Definition: gininsert.c:433
aminsert_function aminsert
Definition: amapi.h:200
Oid amkeytype
Definition: amapi.h:195
bool amoptionalkey
Definition: amapi.h:181
amvalidate_function amvalidate
Definition: amapi.h:207
amgetbitmap_function amgetbitmap
Definition: amapi.h:211
IndexBuildResult * ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
Definition: gininsert.c:311
ambuild_function ambuild
Definition: amapi.h:198
amoptions_function amoptions
Definition: amapi.h:205
bool ginvalidate(Oid opclassoid)
Definition: ginvalidate.c:34
amcostestimate_function amcostestimate
Definition: amapi.h:204
bool gininsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
Definition: gininsert.c:484
bool amcanunique
Definition: amapi.h:177
amvacuumcleanup_function amvacuumcleanup
Definition: amapi.h:202
amendscan_function amendscan
Definition: amapi.h:212
bool amcanbackward
Definition: amapi.h:175
#define GINNProcs
Definition: gin.h:28
amrescan_function amrescan
Definition: amapi.h:209
bool amcanparallel
Definition: amapi.h:193
bytea * ginoptions(Datum reloptions, bool validate)
Definition: ginutil.c:597
bool amsearchnulls
Definition: amapi.h:185
bool amclusterable
Definition: amapi.h:189
bool amsearcharray
Definition: amapi.h:183
#define InvalidOid
Definition: postgres_ext.h:36
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
IndexBulkDeleteResult * ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
Definition: ginvacuum.c:544
ammarkpos_function ammarkpos
Definition: amapi.h:213
bool amcanorder
Definition: amapi.h:171
amestimateparallelscan_function amestimateparallelscan
Definition: amapi.h:217
uint16 amstrategies
Definition: amapi.h:167
ambuildempty_function ambuildempty
Definition: amapi.h:199
amcanreturn_function amcanreturn
Definition: amapi.h:203
aminitparallelscan_function aminitparallelscan
Definition: amapi.h:218
amrestrpos_function amrestrpos
Definition: amapi.h:214
void GinInitBuffer ( Buffer  b,
uint32  f 
)

Definition at line 351 of file ginutil.c.

References BufferGetPage, BufferGetPageSize, and GinInitPage().

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

352 {
354 }
void GinInitPage(Page page, uint32 f, Size pageSize)
Definition: ginutil.c:338
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define BufferGetPageSize(buffer)
Definition: bufmgr.h:147
void GinInitMetabuffer ( Buffer  b)

Definition at line 357 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(), and ginRedoCreateIndex().

358 {
359  GinMetaPageData *metadata;
360  Page page = BufferGetPage(b);
361 
363 
364  metadata = GinPageGetMeta(page);
365 
366  metadata->head = metadata->tail = InvalidBlockNumber;
367  metadata->tailFreeSize = 0;
368  metadata->nPendingPages = 0;
369  metadata->nPendingHeapTuples = 0;
370  metadata->nTotalPages = 0;
371  metadata->nEntryPages = 0;
372  metadata->nDataPages = 0;
373  metadata->nEntries = 0;
374  metadata->ginVersion = GIN_CURRENT_VERSION;
375 }
BlockNumber nEntryPages
Definition: ginblock.h:79
void GinInitPage(Page page, uint32 f, Size pageSize)
Definition: ginutil.c:338
BlockNumber nTotalPages
Definition: ginblock.h:78
int64 nEntries
Definition: ginblock.h:81
int64 nPendingHeapTuples
Definition: ginblock.h:73
#define GIN_META
Definition: ginblock.h:42
BlockNumber head
Definition: ginblock.h:60
BlockNumber tail
Definition: ginblock.h:61
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define BufferGetPageSize(buffer)
Definition: bufmgr.h:147
uint32 tailFreeSize
Definition: ginblock.h:66
#define GIN_CURRENT_VERSION
Definition: ginblock.h:101
#define InvalidBlockNumber
Definition: block.h:33
int32 ginVersion
Definition: ginblock.h:98
BlockNumber nDataPages
Definition: ginblock.h:80
#define GinPageGetMeta(p)
Definition: ginblock.h:103
Pointer Page
Definition: bufpage.h:74
BlockNumber nPendingPages
Definition: ginblock.h:72
void GinInitPage ( Page  page,
uint32  f,
Size  pageSize 
)

Definition at line 338 of file ginutil.c.

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

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

339 {
340  GinPageOpaque opaque;
341 
342  PageInit(page, pageSize, sizeof(GinPageOpaqueData));
343 
344  opaque = GinPageGetOpaque(page);
345  memset(opaque, 0, sizeof(GinPageOpaqueData));
346  opaque->flags = f;
347  opaque->rightlink = InvalidBlockNumber;
348 }
BlockNumber rightlink
Definition: ginblock.h:30
#define GinPageGetOpaque(page)
Definition: ginblock.h:109
#define InvalidBlockNumber
Definition: block.h:33
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:41
Buffer GinNewBuffer ( Relation  index)

Definition at line 287 of file ginutil.c.

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

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

288 {
289  Buffer buffer;
290  bool needLock;
291 
292  /* First, try to get a page from FSM */
293  for (;;)
294  {
295  BlockNumber blkno = GetFreeIndexPage(index);
296 
297  if (blkno == InvalidBlockNumber)
298  break;
299 
300  buffer = ReadBuffer(index, blkno);
301 
302  /*
303  * We have to guard against the possibility that someone else already
304  * recycled this page; the buffer may be locked if so.
305  */
306  if (ConditionalLockBuffer(buffer))
307  {
308  Page page = BufferGetPage(buffer);
309 
310  if (PageIsNew(page))
311  return buffer; /* OK to use, if never initialized */
312 
313  if (GinPageIsDeleted(page))
314  return buffer; /* OK to use */
315 
316  LockBuffer(buffer, GIN_UNLOCK);
317  }
318 
319  /* Can't use it, so release buffer and try again */
320  ReleaseBuffer(buffer);
321  }
322 
323  /* Must extend the file */
324  needLock = !RELATION_IS_LOCAL(index);
325  if (needLock)
327 
328  buffer = ReadBuffer(index, P_NEW);
329  LockBuffer(buffer, GIN_EXCLUSIVE);
330 
331  if (needLock)
333 
334  return buffer;
335 }
#define GIN_UNLOCK
Definition: gin_private.h:43
#define ExclusiveLock
Definition: lockdefs.h:44
#define RELATION_IS_LOCAL(relation)
Definition: rel.h:524
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
#define P_NEW
Definition: bufmgr.h:82
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:3572
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:332
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:382
#define GinPageIsDeleted(page)
Definition: ginblock.h:123
#define GIN_EXCLUSIVE
Definition: gin_private.h:45
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
BlockNumber GetFreeIndexPage(Relation rel)
Definition: indexfsm.c:38
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define InvalidBlockNumber
Definition: block.h:33
#define PageIsNew(page)
Definition: bufpage.h:226
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
bytea* ginoptions ( Datum  reloptions,
bool  validate 
)

Definition at line 597 of file ginutil.c.

References allocateReloptStruct(), fillRelOptions(), lengthof, NULL, offsetof, options, parseRelOptions(), pfree(), RELOPT_KIND_GIN, RELOPT_TYPE_BOOL, and RELOPT_TYPE_INT.

Referenced by ginhandler().

598 {
600  GinOptions *rdopts;
601  int numoptions;
602  static const relopt_parse_elt tab[] = {
603  {"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)},
604  {"gin_pending_list_limit", RELOPT_TYPE_INT, offsetof(GinOptions,
605  pendingListCleanupSize)}
606  };
607 
608  options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIN,
609  &numoptions);
610 
611  /* if none set, we're done */
612  if (numoptions == 0)
613  return NULL;
614 
615  rdopts = allocateReloptStruct(sizeof(GinOptions), options, numoptions);
616 
617  fillRelOptions((void *) rdopts, sizeof(GinOptions), options, numoptions,
618  validate, tab, lengthof(tab));
619 
620  pfree(options);
621 
622  return (bytea *) rdopts;
623 }
#define lengthof(array)
Definition: c.h:562
void pfree(void *pointer)
Definition: mcxt.c:950
void * allocateReloptStruct(Size base, relopt_value *options, int numoptions)
Definition: reloptions.c:1215
static char ** options
void fillRelOptions(void *rdopts, Size basesize, relopt_value *options, int numoptions, bool validate, const relopt_parse_elt *elems, int numelems)
Definition: reloptions.c:1239
#define NULL
Definition: c.h:229
Definition: c.h:439
relopt_value * parseRelOptions(Datum options, bool validate, relopt_kind kind, int *numrelopts)
Definition: reloptions.c:1020
#define offsetof(type, field)
Definition: c.h:555
OffsetNumber gintuple_get_attrnum ( GinState ginstate,
IndexTuple  tuple 
)

Definition at line 213 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().

214 {
215  OffsetNumber colN;
216 
217  if (ginstate->oneCol)
218  {
219  /* column number is not stored explicitly */
220  colN = FirstOffsetNumber;
221  }
222  else
223  {
224  Datum res;
225  bool isnull;
226 
227  /*
228  * First attribute is always int16, so we can safely use any tuple
229  * descriptor to obtain first attribute of tuple
230  */
231  res = index_getattr(tuple, FirstOffsetNumber, ginstate->tupdesc[0],
232  &isnull);
233  Assert(!isnull);
234 
235  colN = DatumGetUInt16(res);
236  Assert(colN >= FirstOffsetNumber && colN <= ginstate->origTupdesc->natts);
237  }
238 
239  return colN;
240 }
#define DatumGetUInt16(X)
Definition: postgres.h:464
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
uintptr_t Datum
Definition: postgres.h:372
TupleDesc tupdesc[INDEX_MAX_KEYS]
Definition: gin_private.h:68
#define Assert(condition)
Definition: c.h:675
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:100
bool oneCol
Definition: gin_private.h:54
Datum gintuple_get_key ( GinState ginstate,
IndexTuple  tuple,
GinNullCategory category 
)

Definition at line 246 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().

248 {
249  Datum res;
250  bool isnull;
251 
252  if (ginstate->oneCol)
253  {
254  /*
255  * Single column index doesn't store attribute numbers in tuples
256  */
257  res = index_getattr(tuple, FirstOffsetNumber, ginstate->origTupdesc,
258  &isnull);
259  }
260  else
261  {
262  /*
263  * Since the datum type depends on which index column it's from, we
264  * must be careful to use the right tuple descriptor here.
265  */
266  OffsetNumber colN = gintuple_get_attrnum(ginstate, tuple);
267 
269  ginstate->tupdesc[colN - 1],
270  &isnull);
271  }
272 
273  if (isnull)
274  *category = GinGetNullCategory(tuple, ginstate);
275  else
276  *category = GIN_CAT_NORM_KEY;
277 
278  return res;
279 }
#define GinGetNullCategory(itup, ginstate)
Definition: ginblock.h:211
uint16 OffsetNumber
Definition: off.h:24
OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
Definition: ginutil.c:213
#define GIN_CAT_NORM_KEY
Definition: ginblock.h:199
#define FirstOffsetNumber
Definition: off.h:27
uintptr_t Datum
Definition: postgres.h:372
TupleDesc tupdesc[INDEX_MAX_KEYS]
Definition: gin_private.h:68
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:100
TupleDesc origTupdesc
Definition: gin_private.h:67
bool oneCol
Definition: gin_private.h:54
void ginUpdateStats ( Relation  index,
const GinStatsData stats 
)

Definition at line 659 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_WILL_INIT, RelationNeedsWAL, START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_GIN_UPDATE_META_PAGE, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by ginbuild(), and ginvacuumcleanup().

660 {
661  Buffer metabuffer;
662  Page metapage;
663  GinMetaPageData *metadata;
664 
665  metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO);
666  LockBuffer(metabuffer, GIN_EXCLUSIVE);
667  metapage = BufferGetPage(metabuffer);
668  metadata = GinPageGetMeta(metapage);
669 
671 
672  metadata->nTotalPages = stats->nTotalPages;
673  metadata->nEntryPages = stats->nEntryPages;
674  metadata->nDataPages = stats->nDataPages;
675  metadata->nEntries = stats->nEntries;
676 
677  MarkBufferDirty(metabuffer);
678 
679  if (RelationNeedsWAL(index))
680  {
681  XLogRecPtr recptr;
682  ginxlogUpdateMeta data;
683 
684  data.node = index->rd_node;
685  data.ntuples = 0;
687  memcpy(&data.metadata, metadata, sizeof(GinMetaPageData));
688 
689  XLogBeginInsert();
690  XLogRegisterData((char *) &data, sizeof(ginxlogUpdateMeta));
691  XLogRegisterBuffer(0, metabuffer, REGBUF_WILL_INIT);
692 
693  recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_UPDATE_META_PAGE);
694  PageSetLSN(metapage, recptr);
695  }
696 
697  UnlockReleaseBuffer(metabuffer);
698 
700 }
BlockNumber nEntryPages
Definition: ginblock.h:79
BlockNumber prevTail
Definition: ginxlog.h:173
BlockNumber nEntryPages
Definition: gin.h:45
RelFileNode node
Definition: ginxlog.h:171
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
#define REGBUF_WILL_INIT
Definition: xloginsert.h:32
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
int64 nEntries
Definition: gin.h:47
BlockNumber nTotalPages
Definition: ginblock.h:78
#define GIN_METAPAGE_BLKNO
Definition: ginblock.h:50
int64 nEntries
Definition: ginblock.h:81
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define XLOG_GIN_UPDATE_META_PAGE
Definition: ginxlog.h:163
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
BlockNumber newRightlink
Definition: ginxlog.h:174
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
#define GIN_EXCLUSIVE
Definition: gin_private.h:45
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
BlockNumber nDataPages
Definition: gin.h:46
GinMetaPageData metadata
Definition: ginxlog.h:172
RelFileNode rd_node
Definition: rel.h:85
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define InvalidBlockNumber
Definition: block.h:33
BlockNumber nTotalPages
Definition: gin.h:44
#define RelationNeedsWAL(relation)
Definition: rel.h:506
BlockNumber nDataPages
Definition: ginblock.h:80
#define GinPageGetMeta(p)
Definition: ginblock.h:103
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:365
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
void initGinState ( GinState state,
Relation  index 
)

Definition at line 86 of file ginutil.c.

References tupleDesc::attrs, GinState::canPartialMatch, TypeCacheEntry::cmp_proc_finfo, GinState::compareFn, GinState::comparePartialFn, GinState::consistentFn, CreateTemplateTupleDesc(), CurrentMemoryContext, DEFAULT_COLLATION_OID, 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(), INT2OID, InvalidOid, lookup_type_cache(), MemSet, tupleDesc::natts, NULL, OidIsValid, GinState::oneCol, GinState::origTupdesc, RelationData::rd_indcollation, RelationGetDescr, RelationGetRelationName, GinState::supportCollation, GinState::triConsistentFn, GinState::tupdesc, TupleDescInitEntry(), TupleDescInitEntryCollation(), and TYPECACHE_CMP_PROC_FINFO.

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

87 {
88  TupleDesc origTupdesc = RelationGetDescr(index);
89  int i;
90 
91  MemSet(state, 0, sizeof(GinState));
92 
93  state->index = index;
94  state->oneCol = (origTupdesc->natts == 1) ? true : false;
95  state->origTupdesc = origTupdesc;
96 
97  for (i = 0; i < origTupdesc->natts; i++)
98  {
99  if (state->oneCol)
100  state->tupdesc[i] = state->origTupdesc;
101  else
102  {
103  state->tupdesc[i] = CreateTemplateTupleDesc(2, false);
104 
105  TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 1, NULL,
106  INT2OID, -1, 0);
107  TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 2, NULL,
108  origTupdesc->attrs[i]->atttypid,
109  origTupdesc->attrs[i]->atttypmod,
110  origTupdesc->attrs[i]->attndims);
112  origTupdesc->attrs[i]->attcollation);
113  }
114 
115  /*
116  * If the compare proc isn't specified in the opclass definition, look
117  * up the index key type's default btree comparator.
118  */
119  if (index_getprocid(index, i + 1, GIN_COMPARE_PROC) != InvalidOid)
120  {
121  fmgr_info_copy(&(state->compareFn[i]),
122  index_getprocinfo(index, i + 1, GIN_COMPARE_PROC),
124  }
125  else
126  {
127  TypeCacheEntry *typentry;
128 
129  typentry = lookup_type_cache(origTupdesc->attrs[i]->atttypid,
131  if (!OidIsValid(typentry->cmp_proc_finfo.fn_oid))
132  ereport(ERROR,
133  (errcode(ERRCODE_UNDEFINED_FUNCTION),
134  errmsg("could not identify a comparison function for type %s",
135  format_type_be(origTupdesc->attrs[i]->atttypid))));
136  fmgr_info_copy(&(state->compareFn[i]),
137  &(typentry->cmp_proc_finfo),
139  }
140 
141  /* Opclass must always provide extract procs */
142  fmgr_info_copy(&(state->extractValueFn[i]),
145  fmgr_info_copy(&(state->extractQueryFn[i]),
148 
149  /*
150  * Check opclass capability to do tri-state or binary logic consistent
151  * check.
152  */
153  if (index_getprocid(index, i + 1, GIN_TRICONSISTENT_PROC) != InvalidOid)
154  {
155  fmgr_info_copy(&(state->triConsistentFn[i]),
158  }
159 
160  if (index_getprocid(index, i + 1, GIN_CONSISTENT_PROC) != InvalidOid)
161  {
162  fmgr_info_copy(&(state->consistentFn[i]),
163  index_getprocinfo(index, i + 1, GIN_CONSISTENT_PROC),
165  }
166 
167  if (state->consistentFn[i].fn_oid == InvalidOid &&
168  state->triConsistentFn[i].fn_oid == InvalidOid)
169  {
170  elog(ERROR, "missing GIN support function (%d or %d) for attribute %d of index \"%s\"",
172  i + 1, RelationGetRelationName(index));
173  }
174 
175  /*
176  * Check opclass capability to do partial match.
177  */
179  {
180  fmgr_info_copy(&(state->comparePartialFn[i]),
183  state->canPartialMatch[i] = true;
184  }
185  else
186  {
187  state->canPartialMatch[i] = false;
188  }
189 
190  /*
191  * If the index column has a specified collation, we should honor that
192  * while doing comparisons. However, we may have a collatable storage
193  * type for a noncollatable indexed data type (for instance, hstore
194  * uses text index entries). If there's no index collation then
195  * specify default collation in case the support functions need
196  * collation. This is harmless if the support functions don't care
197  * about collation, so we just do it unconditionally. (We could
198  * alternatively call get_typcollation, but that seems like expensive
199  * overkill --- there aren't going to be any cases where a GIN storage
200  * type has a nondefault collation.)
201  */
202  if (OidIsValid(index->rd_indcollation[i]))
203  state->supportCollation[i] = index->rd_indcollation[i];
204  else
206  }
207 }
Oid supportCollation[INDEX_MAX_KEYS]
Definition: gin_private.h:82
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:855
#define GIN_EXTRACTQUERY_PROC
Definition: gin.h:24
Relation index
Definition: gin_private.h:53
#define RelationGetDescr(relation)
Definition: rel.h:429
Form_pg_attribute * attrs
Definition: tupdesc.h:74
bool canPartialMatch[INDEX_MAX_KEYS]
Definition: gin_private.h:80
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:857
FmgrInfo consistentFn[INDEX_MAX_KEYS]
Definition: gin_private.h:76
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
FmgrInfo extractValueFn[INDEX_MAX_KEYS]
Definition: gin_private.h:74
#define GIN_TRICONSISTENT_PROC
Definition: gin.h:27
#define GIN_COMPARE_PARTIAL_PROC
Definition: gin.h:26
#define OidIsValid(objectId)
Definition: c.h:538
int natts
Definition: tupdesc.h:73
FmgrInfo cmp_proc_finfo
Definition: typcache.h:68
Oid * rd_indcollation
Definition: rel.h:193
#define ERROR
Definition: elog.h:43
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:656
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:524
#define INT2OID
Definition: pg_type.h:308
FmgrInfo comparePartialFn[INDEX_MAX_KEYS]
Definition: gin_private.h:78
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:75
#define GIN_CONSISTENT_PROC
Definition: gin.h:25
#define RelationGetRelationName(relation)
Definition: rel.h:437
FmgrInfo extractQueryFn[INDEX_MAX_KEYS]
Definition: gin_private.h:75
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:497
#define ereport(elevel, rest)
Definition: elog.h:122
TupleDesc tupdesc[INDEX_MAX_KEYS]
Definition: gin_private.h:68
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:191
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:59
#define NULL
Definition: c.h:229
#define GIN_EXTRACTVALUE_PROC
Definition: gin.h:23
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
TupleDesc origTupdesc
Definition: gin_private.h:67
#define TYPECACHE_CMP_PROC_FINFO
Definition: typcache.h:116
#define elog
Definition: elog.h:219
FmgrInfo triConsistentFn[INDEX_MAX_KEYS]
Definition: gin_private.h:77
bool oneCol
Definition: gin_private.h:54
int16 AttrNumber
Definition: attnum.h:21
#define GIN_COMPARE_PROC
Definition: gin.h:22
FmgrInfo compareFn[INDEX_MAX_KEYS]
Definition: gin_private.h:73
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:821