PostgreSQL Source Code  git master
blutils.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * blutils.c
4  * Bloom index utilities.
5  *
6  * Portions Copyright (c) 2016-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1990-1993, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * contrib/bloom/blutils.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "access/amapi.h"
17 #include "access/generic_xlog.h"
18 #include "access/reloptions.h"
19 #include "bloom.h"
20 #include "catalog/index.h"
21 #include "commands/vacuum.h"
22 #include "miscadmin.h"
23 #include "storage/bufmgr.h"
24 #include "storage/freespace.h"
25 #include "storage/indexfsm.h"
26 #include "storage/lmgr.h"
27 #include "utils/memutils.h"
28 
29 /* Signature dealing macros - note i is assumed to be of type int */
30 #define GETWORD(x,i) ( *( (BloomSignatureWord *)(x) + ( (i) / SIGNWORDBITS ) ) )
31 #define CLRBIT(x,i) GETWORD(x,i) &= ~( 0x01 << ( (i) % SIGNWORDBITS ) )
32 #define SETBIT(x,i) GETWORD(x,i) |= ( 0x01 << ( (i) % SIGNWORDBITS ) )
33 #define GETBIT(x,i) ( (GETWORD(x,i) >> ( (i) % SIGNWORDBITS )) & 0x01 )
34 
36 
37 /* Kind of relation options for bloom index */
39 
40 /* parse table for fillRelOptions */
42 
43 static int32 myRand(void);
44 static void mySrand(uint32 seed);
45 
46 /*
47  * Module initialize function: initialize info about Bloom relation options.
48  *
49  * Note: keep this in sync with makeDefaultBloomOptions().
50  */
51 void
52 _PG_init(void)
53 {
54  int i;
55  char buf[16];
56 
58 
59  /* Option for length of signature */
61  "Length of signature in bits",
64  bl_relopt_tab[0].optname = "length";
66  bl_relopt_tab[0].offset = offsetof(BloomOptions, bloomLength);
67 
68  /* Number of bits for each possible index column: col1, col2, ... */
69  for (i = 0; i < INDEX_MAX_KEYS; i++)
70  {
71  snprintf(buf, sizeof(buf), "col%d", i + 1);
73  "Number of bits generated for each index column",
77  buf);
79  bl_relopt_tab[i + 1].offset = offsetof(BloomOptions, bitSize[0]) + sizeof(int) * i;
80  }
81 }
82 
83 /*
84  * Construct a default set of Bloom options.
85  */
86 static BloomOptions *
88 {
90  int i;
91 
92  opts = (BloomOptions *) palloc0(sizeof(BloomOptions));
93  /* Convert DEFAULT_BLOOM_LENGTH from # of bits to # of words */
94  opts->bloomLength = (DEFAULT_BLOOM_LENGTH + SIGNWORDBITS - 1) / SIGNWORDBITS;
95  for (i = 0; i < INDEX_MAX_KEYS; i++)
96  opts->bitSize[i] = DEFAULT_BLOOM_BITS;
97  SET_VARSIZE(opts, sizeof(BloomOptions));
98  return opts;
99 }
100 
101 /*
102  * Bloom handler function: return IndexAmRoutine with access method parameters
103  * and callbacks.
104  */
105 Datum
107 {
108  IndexAmRoutine *amroutine = makeNode(IndexAmRoutine);
109 
110  amroutine->amstrategies = BLOOM_NSTRATEGIES;
111  amroutine->amsupport = BLOOM_NPROC;
112  amroutine->amoptsprocnum = BLOOM_OPTIONS_PROC;
113  amroutine->amcanorder = false;
114  amroutine->amcanorderbyop = false;
115  amroutine->amcanbackward = false;
116  amroutine->amcanunique = false;
117  amroutine->amcanmulticol = true;
118  amroutine->amoptionalkey = true;
119  amroutine->amsearcharray = false;
120  amroutine->amsearchnulls = false;
121  amroutine->amstorage = false;
122  amroutine->amclusterable = false;
123  amroutine->ampredlocks = false;
124  amroutine->amcanparallel = false;
125  amroutine->amcanbuildparallel = false;
126  amroutine->amcaninclude = false;
127  amroutine->amusemaintenanceworkmem = false;
128  amroutine->amparallelvacuumoptions =
130  amroutine->amkeytype = InvalidOid;
131 
132  amroutine->ambuild = blbuild;
133  amroutine->ambuildempty = blbuildempty;
134  amroutine->aminsert = blinsert;
135  amroutine->aminsertcleanup = NULL;
136  amroutine->ambulkdelete = blbulkdelete;
137  amroutine->amvacuumcleanup = blvacuumcleanup;
138  amroutine->amcanreturn = NULL;
139  amroutine->amcostestimate = blcostestimate;
140  amroutine->amoptions = bloptions;
141  amroutine->amproperty = NULL;
142  amroutine->ambuildphasename = NULL;
143  amroutine->amvalidate = blvalidate;
144  amroutine->amadjustmembers = NULL;
145  amroutine->ambeginscan = blbeginscan;
146  amroutine->amrescan = blrescan;
147  amroutine->amgettuple = NULL;
148  amroutine->amgetbitmap = blgetbitmap;
149  amroutine->amendscan = blendscan;
150  amroutine->ammarkpos = NULL;
151  amroutine->amrestrpos = NULL;
152  amroutine->amestimateparallelscan = NULL;
153  amroutine->aminitparallelscan = NULL;
154  amroutine->amparallelrescan = NULL;
155 
156  PG_RETURN_POINTER(amroutine);
157 }
158 
159 /*
160  * Fill BloomState structure for particular index.
161  */
162 void
164 {
165  int i;
166 
167  state->nColumns = index->rd_att->natts;
168 
169  /* Initialize hash function for each attribute */
170  for (i = 0; i < index->rd_att->natts; i++)
171  {
172  fmgr_info_copy(&(state->hashFn[i]),
175  state->collations[i] = index->rd_indcollation[i];
176  }
177 
178  /* Initialize amcache if needed with options from metapage */
179  if (!index->rd_amcache)
180  {
181  Buffer buffer;
182  Page page;
183  BloomMetaPageData *meta;
185 
186  opts = MemoryContextAlloc(index->rd_indexcxt, sizeof(BloomOptions));
187 
189  LockBuffer(buffer, BUFFER_LOCK_SHARE);
190 
191  page = BufferGetPage(buffer);
192 
193  if (!BloomPageIsMeta(page))
194  elog(ERROR, "Relation is not a bloom index");
195  meta = BloomPageGetMeta(BufferGetPage(buffer));
196 
197  if (meta->magickNumber != BLOOM_MAGICK_NUMBER)
198  elog(ERROR, "Relation is not a bloom index");
199 
200  *opts = meta->opts;
201 
202  UnlockReleaseBuffer(buffer);
203 
204  index->rd_amcache = (void *) opts;
205  }
206 
207  memcpy(&state->opts, index->rd_amcache, sizeof(state->opts));
208  state->sizeOfBloomTuple = BLOOMTUPLEHDRSZ +
209  sizeof(BloomSignatureWord) * state->opts.bloomLength;
210 }
211 
212 /*
213  * Random generator copied from FreeBSD. Using own random generator here for
214  * two reasons:
215  *
216  * 1) In this case random numbers are used for on-disk storage. Usage of
217  * PostgreSQL number generator would obstruct it from all possible changes.
218  * 2) Changing seed of PostgreSQL random generator would be undesirable side
219  * effect.
220  */
221 static int32 next;
222 
223 static int32
224 myRand(void)
225 {
226  /*----------
227  * Compute x = (7^5 * x) mod (2^31 - 1)
228  * without overflowing 31 bits:
229  * (2^31 - 1) = 127773 * (7^5) + 2836
230  * From "Random number generators: good ones are hard to find",
231  * Park and Miller, Communications of the ACM, vol. 31, no. 10,
232  * October 1988, p. 1195.
233  *----------
234  */
235  int32 hi,
236  lo,
237  x;
238 
239  /* Must be in [1, 0x7ffffffe] range at this point. */
240  hi = next / 127773;
241  lo = next % 127773;
242  x = 16807 * lo - 2836 * hi;
243  if (x < 0)
244  x += 0x7fffffff;
245  next = x;
246  /* Transform to [0, 0x7ffffffd] range. */
247  return (x - 1);
248 }
249 
250 static void
252 {
253  next = seed;
254  /* Transform to [1, 0x7ffffffe] range. */
255  next = (next % 0x7ffffffe) + 1;
256 }
257 
258 /*
259  * Add bits of given value to the signature.
260  */
261 void
263 {
264  uint32 hashVal;
265  int nBit,
266  j;
267 
268  /*
269  * init generator with "column's" number to get "hashed" seed for new
270  * value. We don't want to map the same numbers from different columns
271  * into the same bits!
272  */
273  mySrand(attno);
274 
275  /*
276  * Init hash sequence to map our value into bits. the same values in
277  * different columns will be mapped into different bits because of step
278  * above
279  */
280  hashVal = DatumGetInt32(FunctionCall1Coll(&state->hashFn[attno], state->collations[attno], value));
281  mySrand(hashVal ^ myRand());
282 
283  for (j = 0; j < state->opts.bitSize[attno]; j++)
284  {
285  /* prevent multiple evaluation in SETBIT macro */
286  nBit = myRand() % (state->opts.bloomLength * SIGNWORDBITS);
287  SETBIT(sign, nBit);
288  }
289 }
290 
291 /*
292  * Make bloom tuple from values.
293  */
294 BloomTuple *
296 {
297  int i;
298  BloomTuple *res = (BloomTuple *) palloc0(state->sizeOfBloomTuple);
299 
300  res->heapPtr = *iptr;
301 
302  /* Blooming each column */
303  for (i = 0; i < state->nColumns; i++)
304  {
305  /* skip nulls */
306  if (isnull[i])
307  continue;
308 
309  signValue(state, res->sign, values[i], i);
310  }
311 
312  return res;
313 }
314 
315 /*
316  * Add new bloom tuple to the page. Returns true if new tuple was successfully
317  * added to the page. Returns false if it doesn't fit on the page.
318  */
319 bool
321 {
322  BloomTuple *itup;
323  BloomPageOpaque opaque;
324  Pointer ptr;
325 
326  /* We shouldn't be pointed to an invalid page */
327  Assert(!PageIsNew(page) && !BloomPageIsDeleted(page));
328 
329  /* Does new tuple fit on the page? */
330  if (BloomPageGetFreeSpace(state, page) < state->sizeOfBloomTuple)
331  return false;
332 
333  /* Copy new tuple to the end of page */
334  opaque = BloomPageGetOpaque(page);
335  itup = BloomPageGetTuple(state, page, opaque->maxoff + 1);
336  memcpy((Pointer) itup, (Pointer) tuple, state->sizeOfBloomTuple);
337 
338  /* Adjust maxoff and pd_lower */
339  opaque->maxoff++;
340  ptr = (Pointer) BloomPageGetTuple(state, page, opaque->maxoff + 1);
341  ((PageHeader) page)->pd_lower = ptr - page;
342 
343  /* Assert we didn't overrun available space */
344  Assert(((PageHeader) page)->pd_lower <= ((PageHeader) page)->pd_upper);
345 
346  return true;
347 }
348 
349 /*
350  * Allocate a new page (either by recycling, or by extending the index file)
351  * The returned buffer is already pinned and exclusive-locked
352  * Caller is responsible for initializing the page by calling BloomInitPage
353  */
354 Buffer
356 {
357  Buffer buffer;
358 
359  /* First, try to get a page from FSM */
360  for (;;)
361  {
363 
364  if (blkno == InvalidBlockNumber)
365  break;
366 
367  buffer = ReadBuffer(index, blkno);
368 
369  /*
370  * We have to guard against the possibility that someone else already
371  * recycled this page; the buffer may be locked if so.
372  */
373  if (ConditionalLockBuffer(buffer))
374  {
375  Page page = BufferGetPage(buffer);
376 
377  if (PageIsNew(page))
378  return buffer; /* OK to use, if never initialized */
379 
380  if (BloomPageIsDeleted(page))
381  return buffer; /* OK to use */
382 
384  }
385 
386  /* Can't use it, so release buffer and try again */
387  ReleaseBuffer(buffer);
388  }
389 
390  /* Must extend the file */
391  buffer = ExtendBufferedRel(BMR_REL(index), MAIN_FORKNUM, NULL,
392  EB_LOCK_FIRST);
393 
394  return buffer;
395 }
396 
397 /*
398  * Initialize any page of a bloom index.
399  */
400 void
402 {
403  BloomPageOpaque opaque;
404 
405  PageInit(page, BLCKSZ, sizeof(BloomPageOpaqueData));
406 
407  opaque = BloomPageGetOpaque(page);
408  opaque->flags = flags;
409  opaque->bloom_page_id = BLOOM_PAGE_ID;
410 }
411 
412 /*
413  * Fill in metapage for bloom index.
414  */
415 void
417 {
419  BloomMetaPageData *metadata;
420 
421  /*
422  * Choose the index's options. If reloptions have been assigned, use
423  * those, otherwise create default options.
424  */
425  opts = (BloomOptions *) index->rd_options;
426  if (!opts)
428 
429  /*
430  * Initialize contents of meta page, including a copy of the options,
431  * which are now frozen for the life of the index.
432  */
433  BloomInitPage(metaPage, BLOOM_META);
434  metadata = BloomPageGetMeta(metaPage);
435  memset(metadata, 0, sizeof(BloomMetaPageData));
436  metadata->magickNumber = BLOOM_MAGICK_NUMBER;
437  metadata->opts = *opts;
438  ((PageHeader) metaPage)->pd_lower += sizeof(BloomMetaPageData);
439 
440  /* If this fails, probably FreeBlockNumberArray size calc is wrong: */
441  Assert(((PageHeader) metaPage)->pd_lower <= ((PageHeader) metaPage)->pd_upper);
442 }
443 
444 /*
445  * Initialize metapage for bloom index.
446  */
447 void
449 {
450  Buffer metaBuffer;
451  Page metaPage;
453 
454  /*
455  * Make a new page; since it is first page it should be associated with
456  * block number 0 (BLOOM_METAPAGE_BLKNO). No need to hold the extension
457  * lock because there cannot be concurrent inserters yet.
458  */
459  metaBuffer = ReadBufferExtended(index, forknum, P_NEW, RBM_NORMAL, NULL);
460  LockBuffer(metaBuffer, BUFFER_LOCK_EXCLUSIVE);
462 
463  /* Initialize contents of meta page */
465  metaPage = GenericXLogRegisterBuffer(state, metaBuffer,
467  BloomFillMetapage(index, metaPage);
469 
470  UnlockReleaseBuffer(metaBuffer);
471 }
472 
473 /*
474  * Parse reloptions for bloom index, producing a BloomOptions struct.
475  */
476 bytea *
477 bloptions(Datum reloptions, bool validate)
478 {
479  BloomOptions *rdopts;
480 
481  /* Parse the user-given reloptions */
482  rdopts = (BloomOptions *) build_reloptions(reloptions, validate,
484  sizeof(BloomOptions),
487 
488  /* Convert signature length from # of bits to # to words, rounding up */
489  if (rdopts)
490  rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS;
491 
492  return (bytea *) rdopts;
493 }
void blcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
Definition: blcost.c:23
void blbuildempty(Relation index)
Definition: blinsert.c:164
IndexBuildResult * blbuild(Relation heap, Relation index, IndexInfo *indexInfo)
Definition: blinsert.c:121
bool blinsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
Definition: blinsert.c:174
uint32 BlockNumber
Definition: block.h:31
#define InvalidBlockNumber
Definition: block.h:33
#define BloomPageGetOpaque(page)
Definition: bloom.h:60
#define BLOOMTUPLEHDRSZ
Definition: bloom.h:166
#define SIGNWORDBITS
Definition: bloom.h:86
#define BloomPageGetFreeSpace(state, page)
Definition: bloom.h:152
bool blvalidate(Oid opclassoid)
Definition: blvalidate.c:32
#define BLOOM_PAGE_ID
Definition: bloom.h:57
int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
Definition: blscan.c:81
#define BloomPageGetMeta(page)
Definition: bloom.h:136
IndexScanDesc blbeginscan(Relation r, int nkeys, int norderbys)
Definition: blscan.c:28
#define DEFAULT_BLOOM_BITS
Definition: bloom.h:97
#define BLOOM_HASH_PROC
Definition: bloom.h:24
struct BloomMetaPageData BloomMetaPageData
#define BLOOM_MAGICK_NUMBER
Definition: bloom.h:131
#define BLOOM_NPROC
Definition: bloom.h:26
#define BloomPageGetTuple(state, page, offset)
Definition: bloom.h:71
#define BLOOM_NSTRATEGIES
Definition: bloom.h:30
IndexBulkDeleteResult * blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
Definition: blvacuum.c:34
#define BLOOM_OPTIONS_PROC
Definition: bloom.h:25
uint16 BloomSignatureWord
Definition: bloom.h:84
#define BloomPageIsDeleted(page)
Definition: bloom.h:64
#define DEFAULT_BLOOM_LENGTH
Definition: bloom.h:91
IndexBulkDeleteResult * blvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
Definition: blvacuum.c:169
#define BLOOM_META
Definition: bloom.h:46
#define MAX_BLOOM_BITS
Definition: bloom.h:98
void blendscan(IndexScanDesc scan)
Definition: blscan.c:68
#define MAX_BLOOM_LENGTH
Definition: bloom.h:92
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:78
#define BloomPageIsMeta(page)
Definition: bloom.h:62
void blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
Definition: blscan.c:48
bytea * bloptions(Datum reloptions, bool validate)
Definition: blutils.c:477
BloomTuple * BloomFormTuple(BloomState *state, ItemPointer iptr, Datum *values, bool *isnull)
Definition: blutils.c:295
static int32 next
Definition: blutils.c:221
static int32 myRand(void)
Definition: blutils.c:224
void BloomInitPage(Page page, uint16 flags)
Definition: blutils.c:401
void _PG_init(void)
Definition: blutils.c:52
Datum blhandler(PG_FUNCTION_ARGS)
Definition: blutils.c:106
PG_FUNCTION_INFO_V1(blhandler)
bool BloomPageAddItem(BloomState *state, Page page, BloomTuple *tuple)
Definition: blutils.c:320
static relopt_kind bl_relopt_kind
Definition: blutils.c:38
Buffer BloomNewBuffer(Relation index)
Definition: blutils.c:355
void BloomFillMetapage(Relation index, Page metaPage)
Definition: blutils.c:416
void BloomInitMetapage(Relation index, ForkNumber forknum)
Definition: blutils.c:448
#define SETBIT(x, i)
Definition: blutils.c:32
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:262
static void mySrand(uint32 seed)
Definition: blutils.c:251
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:163
static BloomOptions * makeDefaultBloomOptions(void)
Definition: blutils.c:87
static relopt_parse_elt bl_relopt_tab[INDEX_MAX_KEYS+1]
Definition: blutils.c:41
static Datum values[MAXATTR]
Definition: bootstrap.c:152
int Buffer
Definition: buf.h:23
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:3377
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
Definition: bufmgr.c:838
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:4821
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4560
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4577
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4795
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:781
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:734
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:157
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:158
#define P_NEW
Definition: bufmgr.h:152
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:350
@ EB_LOCK_FIRST
Definition: bufmgr.h:85
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:159
@ RBM_NORMAL
Definition: bufmgr.h:44
#define BMR_REL(p_rel)
Definition: bufmgr.h:106
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
PageHeaderData * PageHeader
Definition: bufpage.h:170
Pointer Page
Definition: bufpage.h:78
static bool PageIsNew(Page page)
Definition: bufpage.h:230
unsigned short uint16
Definition: c.h:492
unsigned int uint32
Definition: c.h:493
signed int int32
Definition: c.h:481
char * Pointer
Definition: c.h:470
#define lengthof(array)
Definition: c.h:775
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1129
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:580
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
Definition: generic_xlog.c:299
GenericXLogState * GenericXLogStart(Relation relation)
Definition: generic_xlog.c:269
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:337
#define GENERIC_XLOG_FULL_IMAGE
Definition: generic_xlog.h:26
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:863
BlockNumber GetFreeIndexPage(Relation rel)
Definition: indexfsm.c:38
char sign
Definition: informix.c:668
static struct @150 value
int x
Definition: isn.c:71
int j
Definition: isn.c:74
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Assert(fmt[strlen(fmt) - 1] !='\n')
#define AccessExclusiveLock
Definition: lockdefs.h:43
MemoryContext TopMemoryContext
Definition: mcxt.c:137
void * palloc0(Size size)
Definition: mcxt.c:1334
MemoryContext CurrentMemoryContext
Definition: mcxt.c:131
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1168
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1670
#define makeNode(_type_)
Definition: nodes.h:155
static AmcheckOptions opts
Definition: pg_amcheck.c:111
#define INDEX_MAX_KEYS
static char * buf
Definition: pg_test_fsync.c:73
#define snprintf
Definition: port.h:238
uintptr_t Datum
Definition: postgres.h:64
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
#define InvalidOid
Definition: postgres_ext.h:36
void add_int_reloption(bits32 kinds, const char *name, const char *desc, int default_val, int min_val, int max_val, LOCKMODE lockmode)
Definition: reloptions.c:901
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 add_reloption_kind(void)
Definition: reloptions.c:683
relopt_kind
Definition: reloptions.h:40
@ RELOPT_TYPE_INT
Definition: reloptions.h:32
ForkNumber
Definition: relpath.h:48
@ MAIN_FORKNUM
Definition: relpath.h:50
BloomOptions opts
Definition: bloom.h:126
uint32 magickNumber
Definition: bloom.h:123
int bloomLength
Definition: bloom.h:104
OffsetNumber maxoff
Definition: bloom.h:35
uint16 flags
Definition: bloom.h:36
uint16 bloom_page_id
Definition: bloom.h:40
ambuildphasename_function ambuildphasename
Definition: amapi.h:276
ambuildempty_function ambuildempty
Definition: amapi.h:267
amvacuumcleanup_function amvacuumcleanup
Definition: amapi.h:271
bool amclusterable
Definition: amapi.h:241
amoptions_function amoptions
Definition: amapi.h:274
amestimateparallelscan_function amestimateparallelscan
Definition: amapi.h:288
amrestrpos_function amrestrpos
Definition: amapi.h:285
aminsert_function aminsert
Definition: amapi.h:268
amendscan_function amendscan
Definition: amapi.h:283
uint16 amoptsprocnum
Definition: amapi.h:221
amparallelrescan_function amparallelrescan
Definition: amapi.h:290
Oid amkeytype
Definition: amapi.h:257
bool ampredlocks
Definition: amapi.h:243
uint16 amsupport
Definition: amapi.h:219
amcostestimate_function amcostestimate
Definition: amapi.h:273
bool amcanorderbyop
Definition: amapi.h:225
amadjustmembers_function amadjustmembers
Definition: amapi.h:278
ambuild_function ambuild
Definition: amapi.h:266
bool amstorage
Definition: amapi.h:239
uint16 amstrategies
Definition: amapi.h:217
bool amoptionalkey
Definition: amapi.h:233
amgettuple_function amgettuple
Definition: amapi.h:281
amcanreturn_function amcanreturn
Definition: amapi.h:272
bool amcanunique
Definition: amapi.h:229
amgetbitmap_function amgetbitmap
Definition: amapi.h:282
amproperty_function amproperty
Definition: amapi.h:275
ambulkdelete_function ambulkdelete
Definition: amapi.h:270
bool amsearcharray
Definition: amapi.h:235
amvalidate_function amvalidate
Definition: amapi.h:277
ammarkpos_function ammarkpos
Definition: amapi.h:284
bool amcanmulticol
Definition: amapi.h:231
bool amusemaintenanceworkmem
Definition: amapi.h:251
ambeginscan_function ambeginscan
Definition: amapi.h:279
bool amcanparallel
Definition: amapi.h:245
amrescan_function amrescan
Definition: amapi.h:280
bool amcanorder
Definition: amapi.h:223
bool amcanbuildparallel
Definition: amapi.h:247
aminitparallelscan_function aminitparallelscan
Definition: amapi.h:289
uint8 amparallelvacuumoptions
Definition: amapi.h:255
aminsertcleanup_function aminsertcleanup
Definition: amapi.h:269
bool amcanbackward
Definition: amapi.h:227
bool amcaninclude
Definition: amapi.h:249
bool amsearchnulls
Definition: amapi.h:237
Definition: type.h:95
const char * optname
Definition: reloptions.h:152
relopt_type opttype
Definition: reloptions.h:153
Definition: regguts.h:323
Definition: c.h:674
#define VACUUM_OPTION_PARALLEL_CLEANUP
Definition: vacuum.h:62
#define VACUUM_OPTION_PARALLEL_BULKDEL
Definition: vacuum.h:47
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305