PostgreSQL Source Code  git master
hashfuncs.c File Reference
#include "postgres.h"
#include "pageinspect.h"
#include "access/hash.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "catalog/pg_am.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/rel.h"
Include dependency graph for hashfuncs.c:

Go to the source code of this file.

Data Structures

struct  HashPageStat
 
struct  user_args
 

Macros

#define IS_HASH(r)   ((r)->rd_rel->relam == HASH_AM_OID)
 

Typedefs

typedef struct HashPageStat HashPageStat
 

Functions

 PG_FUNCTION_INFO_V1 (hash_page_type)
 
 PG_FUNCTION_INFO_V1 (hash_page_stats)
 
 PG_FUNCTION_INFO_V1 (hash_page_items)
 
 PG_FUNCTION_INFO_V1 (hash_bitmap_info)
 
 PG_FUNCTION_INFO_V1 (hash_metapage_info)
 
static Page verify_hash_page (bytea *raw_page, int flags)
 
static void GetHashPageStatistics (Page page, HashPageStat *stat)
 
Datum hash_page_type (PG_FUNCTION_ARGS)
 
Datum hash_page_stats (PG_FUNCTION_ARGS)
 
Datum hash_page_items (PG_FUNCTION_ARGS)
 
Datum hash_bitmap_info (PG_FUNCTION_ARGS)
 
Datum hash_metapage_info (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ IS_HASH

#define IS_HASH (   r)    ((r)->rd_rel->relam == HASH_AM_OID)

Definition at line 31 of file hashfuncs.c.

Referenced by hash_bitmap_info().

Typedef Documentation

◆ HashPageStat

Function Documentation

◆ GetHashPageStatistics()

static void GetHashPageStatistics ( Page  page,
HashPageStat stat 
)
static

Definition at line 152 of file hashfuncs.c.

References HashPageStat::dead_items, FirstOffsetNumber, HashPageStat::free_size, HashPageStat::hasho_bucket, HashPageOpaqueData::hasho_bucket, HashPageStat::hasho_flag, HashPageOpaqueData::hasho_flag, HashPageStat::hasho_nextblkno, HashPageOpaqueData::hasho_nextblkno, HashPageStat::hasho_page_id, HashPageOpaqueData::hasho_page_id, HashPageStat::hasho_prevblkno, HashPageOpaqueData::hasho_prevblkno, ItemIdIsDead, HashPageStat::live_items, HashPageStat::page_size, PageGetFreeSpace(), PageGetItemId, PageGetMaxOffsetNumber, PageGetPageSize, and PageGetSpecialPointer.

Referenced by hash_page_stats().

153 {
156  int off;
157 
158  stat->dead_items = stat->live_items = 0;
159  stat->page_size = PageGetPageSize(page);
160 
161  /* hash page opaque data */
162  stat->hasho_prevblkno = opaque->hasho_prevblkno;
163  stat->hasho_nextblkno = opaque->hasho_nextblkno;
164  stat->hasho_bucket = opaque->hasho_bucket;
165  stat->hasho_flag = opaque->hasho_flag;
166  stat->hasho_page_id = opaque->hasho_page_id;
167 
168  /* count live and dead tuples, and free space */
169  for (off = FirstOffsetNumber; off <= maxoff; off++)
170  {
171  ItemId id = PageGetItemId(page, off);
172 
173  if (!ItemIdIsDead(id))
174  stat->live_items++;
175  else
176  stat->dead_items++;
177  }
179 }
uint16 hasho_page_id
Definition: hash.h:82
int free_size
Definition: hashfuncs.c:42
int page_size
Definition: hashfuncs.c:41
Bucket hasho_bucket
Definition: hashfuncs.c:47
#define ItemIdIsDead(itemId)
Definition: itemid.h:113
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:581
int dead_items
Definition: hashfuncs.c:40
uint16 OffsetNumber
Definition: off.h:24
BlockNumber hasho_prevblkno
Definition: hash.h:78
BlockNumber hasho_prevblkno
Definition: hashfuncs.c:45
#define FirstOffsetNumber
Definition: off.h:27
#define PageGetPageSize(page)
Definition: bufpage.h:268
int live_items
Definition: hashfuncs.c:39
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
Page page
Definition: btreefuncs.c:246
uint16 hasho_page_id
Definition: hashfuncs.c:49
Bucket hasho_bucket
Definition: hash.h:80
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:85
uint16 hasho_flag
Definition: hash.h:81
BlockNumber hasho_nextblkno
Definition: hash.h:79
uint16 hasho_flag
Definition: hashfuncs.c:48
BlockNumber hasho_nextblkno
Definition: hashfuncs.c:46

◆ hash_bitmap_info()

Datum hash_bitmap_info ( PG_FUNCTION_ARGS  )

Definition at line 394 of file hashfuncs.c.

References _hash_getbuf(), _hash_ovflblkno_to_bitno(), _hash_relbuf(), AccessShareLock, bit(), BlessTupleDesc(), BMPG_MASK, BMPG_SHIFT, BoolGetDatum, BufferGetPage, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), HASH_METAPAGE, HASH_READ, HashMetaPageData::hashm_mapp, HashMetaPageData::hashm_nmaps, HashPageGetBitmap, HashPageGetMeta, heap_form_tuple(), HeapTupleGetDatum, i, index_close(), index_open(), Int32GetDatum, Int64GetDatum(), IS_HASH, ISSET, LH_BITMAP_PAGE, LH_META_PAGE, MemSet, PG_GETARG_INT64, PG_GETARG_OID, PG_RETURN_DATUM, RELATION_IS_OTHER_TEMP, RelationGetNumberOfBlocks, RelationGetRelationName, superuser(), TYPEFUNC_COMPOSITE, UINT64_FORMAT, and values.

395 {
396  Oid indexRelid = PG_GETARG_OID(0);
397  uint64 ovflblkno = PG_GETARG_INT64(1);
398  HashMetaPage metap;
399  Buffer metabuf,
400  mapbuf;
401  BlockNumber bitmapblkno;
402  Page mappage;
403  bool bit = false;
404  TupleDesc tupleDesc;
405  Relation indexRel;
406  uint32 ovflbitno;
407  int32 bitmappage,
408  bitmapbit;
409  HeapTuple tuple;
410  int i,
411  j;
412  Datum values[3];
413  bool nulls[3];
414  uint32 *freep;
415 
416  if (!superuser())
417  ereport(ERROR,
418  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
419  (errmsg("must be superuser to use raw page functions"))));
420 
421  indexRel = index_open(indexRelid, AccessShareLock);
422 
423  if (!IS_HASH(indexRel))
424  elog(ERROR, "relation \"%s\" is not a hash index",
425  RelationGetRelationName(indexRel));
426 
427  if (RELATION_IS_OTHER_TEMP(indexRel))
428  ereport(ERROR,
429  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
430  errmsg("cannot access temporary tables of other sessions")));
431 
432  if (ovflblkno >= RelationGetNumberOfBlocks(indexRel))
433  ereport(ERROR,
434  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
435  errmsg("block number " UINT64_FORMAT " is out of range for relation \"%s\"",
436  ovflblkno, RelationGetRelationName(indexRel))));
437 
438  /* Read the metapage so we can determine which bitmap page to use */
439  metabuf = _hash_getbuf(indexRel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
440  metap = HashPageGetMeta(BufferGetPage(metabuf));
441 
442  /*
443  * Reject attempt to read the bit for a metapage or bitmap page; this is
444  * only meaningful for overflow pages.
445  */
446  if (ovflblkno == 0)
447  ereport(ERROR,
448  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
449  errmsg("invalid overflow block number %u",
450  (BlockNumber) ovflblkno)));
451  for (i = 0; i < metap->hashm_nmaps; i++)
452  if (metap->hashm_mapp[i] == ovflblkno)
453  ereport(ERROR,
454  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
455  errmsg("invalid overflow block number %u",
456  (BlockNumber) ovflblkno)));
457 
458  /*
459  * Identify overflow bit number. This will error out for primary bucket
460  * pages, and we've already rejected the metapage and bitmap pages above.
461  */
462  ovflbitno = _hash_ovflblkno_to_bitno(metap, (BlockNumber) ovflblkno);
463 
464  bitmappage = ovflbitno >> BMPG_SHIFT(metap);
465  bitmapbit = ovflbitno & BMPG_MASK(metap);
466 
467  if (bitmappage >= metap->hashm_nmaps)
468  ereport(ERROR,
469  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
470  errmsg("invalid overflow block number %u",
471  (BlockNumber) ovflblkno)));
472 
473  bitmapblkno = metap->hashm_mapp[bitmappage];
474 
475  _hash_relbuf(indexRel, metabuf);
476 
477  /* Check the status of bitmap bit for overflow page */
478  mapbuf = _hash_getbuf(indexRel, bitmapblkno, HASH_READ, LH_BITMAP_PAGE);
479  mappage = BufferGetPage(mapbuf);
480  freep = HashPageGetBitmap(mappage);
481 
482  bit = ISSET(freep, bitmapbit) != 0;
483 
484  _hash_relbuf(indexRel, mapbuf);
485  index_close(indexRel, AccessShareLock);
486 
487  /* Build a tuple descriptor for our result type */
488  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
489  elog(ERROR, "return type must be a row type");
490  tupleDesc = BlessTupleDesc(tupleDesc);
491 
492  MemSet(nulls, 0, sizeof(nulls));
493 
494  j = 0;
495  values[j++] = Int64GetDatum((int64) bitmapblkno);
496  values[j++] = Int32GetDatum(bitmapbit);
497  values[j++] = BoolGetDatum(bit);
498 
499  tuple = heap_form_tuple(tupleDesc, values, nulls);
500 
502 }
#define HashPageGetBitmap(page)
Definition: hash.h:298
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
#define LH_BITMAP_PAGE
Definition: hash.h:55
#define LH_META_PAGE
Definition: hash.h:56
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:955
uint32 BlockNumber
Definition: block.h:31
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:69
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:346
#define HASH_READ
Definition: hash.h:321
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2048
uint32 hashm_nmaps
Definition: hash.h:257
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define BMPG_MASK(metap)
Definition: hash.h:296
#define RelationGetRelationName(relation)
Definition: rel.h:450
unsigned int uint32
Definition: c.h:358
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
#define BMPG_SHIFT(metap)
Definition: hash.h:295
#define BufferGetPage(buffer)
Definition: bufmgr.h:159
#define ereport(elevel, rest)
Definition: elog.h:141
#define ISSET(A, N)
Definition: hash.h:316
#define HASH_METAPAGE
Definition: hash.h:195
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:198
#define IS_HASH(r)
Definition: hashfuncs.c:31
#define BoolGetDatum(X)
Definition: postgres.h:402
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:265
Datum bit(PG_FUNCTION_ARGS)
Definition: varbit.c:363
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:546
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
uint32 _hash_ovflblkno_to_bitno(HashMetaPage metap, BlockNumber ovflblkno)
Definition: hashovfl.c:61
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:152
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
#define HashPageGetMeta(page)
Definition: hash.h:305
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277
BlockNumber hashm_mapp[HASH_MAX_BITMAPS]
Definition: hash.h:261
int Buffer
Definition: buf.h:23
#define UINT64_FORMAT
Definition: c.h:401
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:126
Pointer Page
Definition: bufpage.h:78

◆ hash_metapage_info()

Datum hash_metapage_info ( PG_FUNCTION_ARGS  )

Definition at line 513 of file hashfuncs.c.

References BlessTupleDesc(), construct_array(), elog, ereport, errcode(), errmsg(), ERROR, Float8GetDatum(), get_call_result_type(), HASH_MAX_BITMAPS, HASH_MAX_SPLITPOINTS, HashMetaPageData::hashm_bmshift, HashMetaPageData::hashm_bmsize, HashMetaPageData::hashm_bsize, HashMetaPageData::hashm_ffactor, HashMetaPageData::hashm_firstfree, HashMetaPageData::hashm_highmask, HashMetaPageData::hashm_lowmask, HashMetaPageData::hashm_magic, HashMetaPageData::hashm_mapp, HashMetaPageData::hashm_maxbucket, HashMetaPageData::hashm_nmaps, HashMetaPageData::hashm_ntuples, HashMetaPageData::hashm_ovflpoint, HashMetaPageData::hashm_procid, HashMetaPageData::hashm_spares, HashMetaPageData::hashm_version, HashPageGetMeta, heap_form_tuple(), HeapTupleGetDatum, i, Int32GetDatum, Int64GetDatum(), LH_META_PAGE, MemSet, ObjectIdGetDatum, user_args::page, PG_GETARG_BYTEA_P, PG_RETURN_DATUM, PointerGetDatum, superuser(), TYPEFUNC_COMPOSITE, values, and verify_hash_page().

514 {
515  bytea *raw_page = PG_GETARG_BYTEA_P(0);
516  Page page;
517  HashMetaPageData *metad;
518  TupleDesc tupleDesc;
519  HeapTuple tuple;
520  int i,
521  j;
522  Datum values[16];
523  bool nulls[16];
524  Datum spares[HASH_MAX_SPLITPOINTS];
525  Datum mapp[HASH_MAX_BITMAPS];
526 
527  if (!superuser())
528  ereport(ERROR,
529  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
530  (errmsg("must be superuser to use raw page functions"))));
531 
532  page = verify_hash_page(raw_page, LH_META_PAGE);
533 
534  /* Build a tuple descriptor for our result type */
535  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
536  elog(ERROR, "return type must be a row type");
537  tupleDesc = BlessTupleDesc(tupleDesc);
538 
539  metad = HashPageGetMeta(page);
540 
541  MemSet(nulls, 0, sizeof(nulls));
542 
543  j = 0;
544  values[j++] = Int64GetDatum((int64) metad->hashm_magic);
545  values[j++] = Int64GetDatum((int64) metad->hashm_version);
546  values[j++] = Float8GetDatum(metad->hashm_ntuples);
547  values[j++] = Int32GetDatum((int32) metad->hashm_ffactor);
548  values[j++] = Int32GetDatum((int32) metad->hashm_bsize);
549  values[j++] = Int32GetDatum((int32) metad->hashm_bmsize);
550  values[j++] = Int32GetDatum((int32) metad->hashm_bmshift);
551  values[j++] = Int64GetDatum((int64) metad->hashm_maxbucket);
552  values[j++] = Int64GetDatum((int64) metad->hashm_highmask);
553  values[j++] = Int64GetDatum((int64) metad->hashm_lowmask);
554  values[j++] = Int64GetDatum((int64) metad->hashm_ovflpoint);
555  values[j++] = Int64GetDatum((int64) metad->hashm_firstfree);
556  values[j++] = Int64GetDatum((int64) metad->hashm_nmaps);
557  values[j++] = ObjectIdGetDatum((Oid) metad->hashm_procid);
558 
559  for (i = 0; i < HASH_MAX_SPLITPOINTS; i++)
560  spares[i] = Int64GetDatum((int64) metad->hashm_spares[i]);
561  values[j++] = PointerGetDatum(construct_array(spares,
562  HASH_MAX_SPLITPOINTS,
563  INT8OID,
564  8, FLOAT8PASSBYVAL, 'd'));
565 
566  for (i = 0; i < HASH_MAX_BITMAPS; i++)
567  mapp[i] = Int64GetDatum((int64) metad->hashm_mapp[i]);
568  values[j++] = PointerGetDatum(construct_array(mapp,
569  HASH_MAX_BITMAPS,
570  INT8OID,
571  8, FLOAT8PASSBYVAL, 'd'));
572 
573  tuple = heap_form_tuple(tupleDesc, values, nulls);
574 
576 }
uint16 hashm_bmshift
Definition: hash.h:250
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
RegProcedure hashm_procid
Definition: hash.h:258
#define LH_META_PAGE
Definition: hash.h:56
#define PointerGetDatum(X)
Definition: postgres.h:556
uint32 hashm_magic
Definition: hash.h:243
uint16 hashm_ffactor
Definition: hash.h:246
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3291
uint32 hashm_highmask
Definition: hash.h:252
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:955
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
unsigned int Oid
Definition: postgres_ext.h:31
uint32 hashm_lowmask
Definition: hash.h:253
signed int int32
Definition: c.h:346
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1723
#define HASH_MAX_SPLITPOINTS
Definition: hash.h:236
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:329
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
uint32 hashm_version
Definition: hash.h:244
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2048
uint32 hashm_nmaps
Definition: hash.h:257
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
#define ereport(elevel, rest)
Definition: elog.h:141
#define HASH_MAX_BITMAPS
Definition: hash.h:227
uint32 hashm_ovflpoint
Definition: hash.h:254
uint16 hashm_bsize
Definition: hash.h:247
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
double hashm_ntuples
Definition: hash.h:245
uint32 hashm_firstfree
Definition: hash.h:256
uint32 hashm_spares[HASH_MAX_SPLITPOINTS]
Definition: hash.h:259
Page page
Definition: btreefuncs.c:246
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
uint32 hashm_maxbucket
Definition: hash.h:251
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
#define HashPageGetMeta(page)
Definition: hash.h:305
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
uint16 hashm_bmsize
Definition: hash.h:248
Definition: c.h:549
static Page verify_hash_page(bytea *raw_page, int flags)
Definition: hashfuncs.c:58
BlockNumber hashm_mapp[HASH_MAX_BITMAPS]
Definition: hash.h:261
Pointer Page
Definition: bufpage.h:78

◆ hash_page_items()

Datum hash_page_items ( PG_FUNCTION_ARGS  )

Definition at line 298 of file hashfuncs.c.

References _hash_get_indextuple_hashkey(), FuncCallContext::attinmeta, BlessTupleDesc(), FuncCallContext::call_cntr, elog, ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum, Int32GetDatum, Int64GetDatum(), ItemIdIsValid, LH_BUCKET_PAGE, LH_OVERFLOW_PAGE, FuncCallContext::max_calls, MemoryContextSwitchTo(), MemSet, FuncCallContext::multi_call_memory_ctx, user_args::offset, user_args::page, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, palloc(), pfree(), PG_GETARG_BYTEA_P, PointerGetDatum, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, superuser(), IndexTupleData::t_tid, AttInMetadata::tupdesc, TupleDescGetAttInMetadata(), TYPEFUNC_COMPOSITE, FuncCallContext::user_fctx, values, and verify_hash_page().

299 {
300  bytea *raw_page = PG_GETARG_BYTEA_P(0);
301  Page page;
302  Datum result;
303  Datum values[3];
304  bool nulls[3];
305  uint32 hashkey;
306  HeapTuple tuple;
307  FuncCallContext *fctx;
308  MemoryContext mctx;
309  struct user_args *uargs;
310 
311  if (!superuser())
312  ereport(ERROR,
313  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
314  (errmsg("must be superuser to use raw page functions"))));
315 
316  if (SRF_IS_FIRSTCALL())
317  {
318  TupleDesc tupleDesc;
319 
320  fctx = SRF_FIRSTCALL_INIT();
321 
323 
325 
326  uargs = palloc(sizeof(struct user_args));
327 
328  uargs->page = page;
329 
330  uargs->offset = FirstOffsetNumber;
331 
332  fctx->max_calls = PageGetMaxOffsetNumber(uargs->page);
333 
334  /* Build a tuple descriptor for our result type */
335  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
336  elog(ERROR, "return type must be a row type");
337  tupleDesc = BlessTupleDesc(tupleDesc);
338 
339  fctx->attinmeta = TupleDescGetAttInMetadata(tupleDesc);
340 
341  fctx->user_fctx = uargs;
342 
343  MemoryContextSwitchTo(mctx);
344  }
345 
346  fctx = SRF_PERCALL_SETUP();
347  uargs = fctx->user_fctx;
348 
349  if (fctx->call_cntr < fctx->max_calls)
350  {
351  ItemId id;
352  IndexTuple itup;
353  int j;
354 
355  id = PageGetItemId(uargs->page, uargs->offset);
356 
357  if (!ItemIdIsValid(id))
358  elog(ERROR, "invalid ItemId");
359 
360  itup = (IndexTuple) PageGetItem(uargs->page, id);
361 
362  MemSet(nulls, 0, sizeof(nulls));
363 
364  j = 0;
365  values[j++] = Int32GetDatum((int32) uargs->offset);
366  values[j++] = PointerGetDatum(&itup->t_tid);
367 
368  hashkey = _hash_get_indextuple_hashkey(itup);
369  values[j] = Int64GetDatum((int64) hashkey);
370 
371  tuple = heap_form_tuple(fctx->attinmeta->tupdesc, values, nulls);
372  result = HeapTupleGetDatum(tuple);
373 
374  uargs->offset = uargs->offset + 1;
375 
376  SRF_RETURN_NEXT(fctx, result);
377  }
378  else
379  {
380  pfree(uargs);
381  SRF_RETURN_DONE(fctx);
382  }
383 }
uint64 call_cntr
Definition: funcapi.h:66
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:283
#define PointerGetDatum(X)
Definition: postgres.h:556
ItemPointerData t_tid
Definition: itup.h:37
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:955
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:287
signed int int32
Definition: c.h:346
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:289
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:329
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ERROR
Definition: elog.h:43
OffsetNumber offset
Definition: btreefuncs.c:247
uint32 _hash_get_indextuple_hashkey(IndexTuple itup)
Definition: hashutil.c:299
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2048
#define FirstOffsetNumber
Definition: off.h:27
AttInMetadata * attinmeta
Definition: funcapi.h:92
IndexTupleData * IndexTuple
Definition: itup.h:53
TupleDesc tupdesc
Definition: funcapi.h:39
unsigned int uint32
Definition: c.h:358
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
#define ereport(elevel, rest)
Definition: elog.h:141
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
uintptr_t Datum
Definition: postgres.h:367
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2063
Page page
Definition: btreefuncs.c:246
#define ItemIdIsValid(itemId)
Definition: itemid.h:86
#define LH_BUCKET_PAGE
Definition: hash.h:54
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:102
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
void * user_fctx
Definition: funcapi.h:83
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
Definition: c.h:549
static Page verify_hash_page(bytea *raw_page, int flags)
Definition: hashfuncs.c:58
uint64 max_calls
Definition: funcapi.h:75
#define PageGetItem(page, itemId)
Definition: bufpage.h:340
Pointer Page
Definition: bufpage.h:78
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:307
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:285

◆ hash_page_stats()

Datum hash_page_stats ( PG_FUNCTION_ARGS  )

Definition at line 233 of file hashfuncs.c.

References BlessTupleDesc(), HashPageStat::dead_items, elog, ereport, errcode(), errmsg(), ERROR, HashPageStat::free_size, get_call_result_type(), GetHashPageStatistics(), HashPageStat::hasho_bucket, HashPageStat::hasho_flag, HashPageStat::hasho_nextblkno, HashPageStat::hasho_page_id, HashPageStat::hasho_prevblkno, heap_form_tuple(), HeapTupleGetDatum, Int32GetDatum, Int64GetDatum(), InvalidBlockNumber, LH_BUCKET_PAGE, LH_OVERFLOW_PAGE, HashPageStat::live_items, MemSet, HashPageStat::page_size, PG_GETARG_BYTEA_P, PG_RETURN_DATUM, stat, superuser(), TYPEFUNC_COMPOSITE, values, and verify_hash_page().

234 {
235  bytea *raw_page = PG_GETARG_BYTEA_P(0);
236  Page page;
237  int j;
238  Datum values[9];
239  bool nulls[9];
241  HeapTuple tuple;
242  TupleDesc tupleDesc;
243 
244  if (!superuser())
245  ereport(ERROR,
246  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
247  (errmsg("must be superuser to use raw page functions"))));
248 
250 
251  /* keep compiler quiet */
253  stat.hasho_flag = stat.hasho_page_id = stat.free_size = 0;
254 
255  GetHashPageStatistics(page, &stat);
256 
257  /* Build a tuple descriptor for our result type */
258  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
259  elog(ERROR, "return type must be a row type");
260  tupleDesc = BlessTupleDesc(tupleDesc);
261 
262  MemSet(nulls, 0, sizeof(nulls));
263 
264  j = 0;
265  values[j++] = Int32GetDatum(stat.live_items);
266  values[j++] = Int32GetDatum(stat.dead_items);
267  values[j++] = Int32GetDatum(stat.page_size);
268  values[j++] = Int32GetDatum(stat.free_size);
269  values[j++] = Int64GetDatum((int64) stat.hasho_prevblkno);
270  values[j++] = Int64GetDatum((int64) stat.hasho_nextblkno);
271  values[j++] = Int64GetDatum((int64) stat.hasho_bucket);
272  values[j++] = Int32GetDatum((int32) stat.hasho_flag);
273  values[j++] = Int32GetDatum((int32) stat.hasho_page_id);
274 
275  tuple = heap_form_tuple(tupleDesc, values, nulls);
276 
278 }
static void GetHashPageStatistics(Page page, HashPageStat *stat)
Definition: hashfuncs.c:152
int free_size
Definition: hashfuncs.c:42
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
int page_size
Definition: hashfuncs.c:41
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:955
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
Bucket hasho_bucket
Definition: hashfuncs.c:47
int dead_items
Definition: hashfuncs.c:40
signed int int32
Definition: c.h:346
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:329
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2048
BlockNumber hasho_prevblkno
Definition: hashfuncs.c:45
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
#define ereport(elevel, rest)
Definition: elog.h:141
int live_items
Definition: hashfuncs.c:39
#define stat(a, b)
Definition: win32_port.h:264
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
Page page
Definition: btreefuncs.c:246
uint16 hasho_page_id
Definition: hashfuncs.c:49
#define LH_BUCKET_PAGE
Definition: hash.h:54
#define InvalidBlockNumber
Definition: block.h:33
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
Definition: c.h:549
uint16 hasho_flag
Definition: hashfuncs.c:48
static Page verify_hash_page(bytea *raw_page, int flags)
Definition: hashfuncs.c:58
BlockNumber hasho_nextblkno
Definition: hashfuncs.c:46
Pointer Page
Definition: bufpage.h:78

◆ hash_page_type()

Datum hash_page_type ( PG_FUNCTION_ARGS  )

Definition at line 188 of file hashfuncs.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, HashPageOpaqueData::hasho_flag, LH_BITMAP_PAGE, LH_BUCKET_PAGE, LH_META_PAGE, LH_OVERFLOW_PAGE, LH_PAGE_TYPE, PageGetSpecialPointer, PageIsNew, PG_GETARG_BYTEA_P, PG_RETURN_TEXT_P, superuser(), generate_unaccent_rules::type, and verify_hash_page().

189 {
190  bytea *raw_page = PG_GETARG_BYTEA_P(0);
191  Page page;
192  HashPageOpaque opaque;
193  int pagetype;
194  const char *type;
195 
196  if (!superuser())
197  ereport(ERROR,
198  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
199  (errmsg("must be superuser to use raw page functions"))));
200 
201  page = verify_hash_page(raw_page, 0);
202 
203  if (PageIsNew(page))
204  type = "unused";
205  else
206  {
207  opaque = (HashPageOpaque) PageGetSpecialPointer(page);
208 
209  /* page type (flags) */
210  pagetype = opaque->hasho_flag & LH_PAGE_TYPE;
211  if (pagetype == LH_META_PAGE)
212  type = "metapage";
213  else if (pagetype == LH_OVERFLOW_PAGE)
214  type = "overflow";
215  else if (pagetype == LH_BUCKET_PAGE)
216  type = "bucket";
217  else if (pagetype == LH_BITMAP_PAGE)
218  type = "bitmap";
219  else
220  type = "unused";
221  }
222 
224 }
#define LH_BITMAP_PAGE
Definition: hash.h:55
#define LH_META_PAGE
Definition: hash.h:56
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define LH_PAGE_TYPE
Definition: hash.h:62
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:329
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
Page page
Definition: btreefuncs.c:246
#define LH_BUCKET_PAGE
Definition: hash.h:54
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:85
uint16 hasho_flag
Definition: hash.h:81
#define PageIsNew(page)
Definition: bufpage.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: c.h:549
static Page verify_hash_page(bytea *raw_page, int flags)
Definition: hashfuncs.c:58
Pointer Page
Definition: bufpage.h:78

◆ PG_FUNCTION_INFO_V1() [1/5]

PG_FUNCTION_INFO_V1 ( hash_page_type  )

◆ PG_FUNCTION_INFO_V1() [2/5]

PG_FUNCTION_INFO_V1 ( hash_page_stats  )

◆ PG_FUNCTION_INFO_V1() [3/5]

PG_FUNCTION_INFO_V1 ( hash_page_items  )

◆ PG_FUNCTION_INFO_V1() [4/5]

PG_FUNCTION_INFO_V1 ( hash_bitmap_info  )

◆ PG_FUNCTION_INFO_V1() [5/5]

PG_FUNCTION_INFO_V1 ( hash_metapage_info  )

◆ verify_hash_page()

static Page verify_hash_page ( bytea raw_page,
int  flags 
)
static

Definition at line 58 of file hashfuncs.c.

References elog, ereport, errcode(), errdetail(), errmsg(), ERROR, get_page_from_raw(), HASH_MAGIC, HASH_VERSION, HashMetaPageData::hashm_magic, HashMetaPageData::hashm_version, HashPageOpaqueData::hasho_flag, HashPageOpaqueData::hasho_page_id, HASHO_PAGE_ID, HashPageGetMeta, LH_BITMAP_PAGE, LH_BUCKET_PAGE, LH_META_PAGE, LH_OVERFLOW_PAGE, LH_PAGE_TYPE, LH_UNUSED_PAGE, MAXALIGN, PageGetSpecialPointer, PageGetSpecialSize, and PageIsNew.

Referenced by hash_metapage_info(), hash_page_items(), hash_page_stats(), and hash_page_type().

59 {
60  Page page = get_page_from_raw(raw_page);
61  int pagetype = LH_UNUSED_PAGE;
62 
63  /* Treat new pages as unused. */
64  if (!PageIsNew(page))
65  {
66  HashPageOpaque pageopaque;
67 
68  if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
69  ereport(ERROR,
70  (errcode(ERRCODE_INDEX_CORRUPTED),
71  errmsg("index table contains corrupted page")));
72 
73  pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
74  if (pageopaque->hasho_page_id != HASHO_PAGE_ID)
75  ereport(ERROR,
76  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
77  errmsg("page is not a hash page"),
78  errdetail("Expected %08x, got %08x.",
79  HASHO_PAGE_ID, pageopaque->hasho_page_id)));
80 
81  pagetype = pageopaque->hasho_flag & LH_PAGE_TYPE;
82  }
83 
84  /* Check that page type is sane. */
85  if (pagetype != LH_OVERFLOW_PAGE && pagetype != LH_BUCKET_PAGE &&
86  pagetype != LH_BITMAP_PAGE && pagetype != LH_META_PAGE &&
87  pagetype != LH_UNUSED_PAGE)
88  ereport(ERROR,
89  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
90  errmsg("invalid hash page type %08x", pagetype)));
91 
92  /* If requested, verify page type. */
93  if (flags != 0 && (pagetype & flags) == 0)
94  {
95  switch (flags)
96  {
97  case LH_META_PAGE:
98  ereport(ERROR,
99  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
100  errmsg("page is not a hash meta page")));
101  break;
103  ereport(ERROR,
104  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
105  errmsg("page is not a hash bucket or overflow page")));
106  break;
107  case LH_OVERFLOW_PAGE:
108  ereport(ERROR,
109  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
110  errmsg("page is not a hash overflow page")));
111  break;
112  default:
113  elog(ERROR,
114  "hash page of type %08x not in mask %08x",
115  pagetype, flags);
116  break;
117  }
118  }
119 
120  /*
121  * If it is the metapage, also verify magic number and version.
122  */
123  if (pagetype == LH_META_PAGE)
124  {
125  HashMetaPage metap = HashPageGetMeta(page);
126 
127  if (metap->hashm_magic != HASH_MAGIC)
128  ereport(ERROR,
129  (errcode(ERRCODE_INDEX_CORRUPTED),
130  errmsg("invalid magic number for metadata"),
131  errdetail("Expected 0x%08x, got 0x%08x.",
132  HASH_MAGIC, metap->hashm_magic)));
133 
134  if (metap->hashm_version != HASH_VERSION)
135  ereport(ERROR,
136  (errcode(ERRCODE_INDEX_CORRUPTED),
137  errmsg("invalid version for metadata"),
138  errdetail("Expected %d, got %d",
139  HASH_VERSION, metap->hashm_version)));
140  }
141 
142  return page;
143 }
uint16 hasho_page_id
Definition: hash.h:82
#define LH_BITMAP_PAGE
Definition: hash.h:55
#define LH_META_PAGE
Definition: hash.h:56
uint32 hashm_magic
Definition: hash.h:243
int errcode(int sqlerrcode)
Definition: elog.c:570
#define HASH_VERSION
Definition: hash.h:198
#define LH_UNUSED_PAGE
Definition: hash.h:52
#define HASH_MAGIC
Definition: hash.h:197
#define LH_PAGE_TYPE
Definition: hash.h:62
#define ERROR
Definition: elog.h:43
uint32 hashm_version
Definition: hash.h:244
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define ereport(elevel, rest)
Definition: elog.h:141
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
Page page
Definition: btreefuncs.c:246
#define LH_BUCKET_PAGE
Definition: hash.h:54
Page get_page_from_raw(bytea *raw_page)
Definition: rawpage.c:188
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:85
#define HASHO_PAGE_ID
Definition: hash.h:98
#define MAXALIGN(LEN)
Definition: c.h:685
#define PageGetSpecialSize(page)
Definition: bufpage.h:300
uint16 hasho_flag
Definition: hash.h:81
#define PageIsNew(page)
Definition: bufpage.h:229
#define HashPageGetMeta(page)
Definition: hash.h:305
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
Pointer Page
Definition: bufpage.h:78