PostgreSQL Source Code  git master
brinfuncs.c File Reference
#include "postgres.h"
#include "access/brin.h"
#include "access/brin_internal.h"
#include "access/brin_page.h"
#include "access/brin_revmap.h"
#include "access/brin_tuple.h"
#include "access/htup_details.h"
#include "catalog/index.h"
#include "catalog/pg_am_d.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "pageinspect.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
Include dependency graph for brinfuncs.c:

Go to the source code of this file.

Data Structures

struct  brin_column_state
 

Macros

#define IS_BRIN(r)   ((r)->rd_rel->relam == BRIN_AM_OID)
 

Typedefs

typedef struct brin_column_state brin_column_state
 

Functions

 PG_FUNCTION_INFO_V1 (brin_page_type)
 
 PG_FUNCTION_INFO_V1 (brin_page_items)
 
 PG_FUNCTION_INFO_V1 (brin_metapage_info)
 
 PG_FUNCTION_INFO_V1 (brin_revmap_data)
 
static Page verify_brin_page (bytea *raw_page, uint16 type, const char *strtype)
 
Datum brin_page_type (PG_FUNCTION_ARGS)
 
Datum brin_page_items (PG_FUNCTION_ARGS)
 
Datum brin_metapage_info (PG_FUNCTION_ARGS)
 
Datum brin_revmap_data (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ IS_BRIN

#define IS_BRIN (   r)    ((r)->rd_rel->relam == BRIN_AM_OID)

Definition at line 35 of file brinfuncs.c.

Typedef Documentation

◆ brin_column_state

Function Documentation

◆ brin_metapage_info()

Datum brin_metapage_info ( PG_FUNCTION_ARGS  )

Definition at line 330 of file brinfuncs.c.

331 {
332  bytea *raw_page = PG_GETARG_BYTEA_P(0);
333  Page page;
334  BrinMetaPageData *meta;
335  TupleDesc tupdesc;
336  Datum values[4];
337  bool nulls[4] = {0};
338  HeapTuple htup;
339 
340  if (!superuser())
341  ereport(ERROR,
342  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
343  errmsg("must be superuser to use raw page functions")));
344 
345  page = verify_brin_page(raw_page, BRIN_PAGETYPE_META, "metapage");
346 
347  if (PageIsNew(page))
348  PG_RETURN_NULL();
349 
350  /* Build a tuple descriptor for our result type */
351  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
352  elog(ERROR, "return type must be a row type");
353  tupdesc = BlessTupleDesc(tupdesc);
354 
355  /* Extract values from the metapage */
356  meta = (BrinMetaPageData *) PageGetContents(page);
357  values[0] = CStringGetTextDatum(psprintf("0x%08X", meta->brinMagic));
358  values[1] = Int32GetDatum(meta->brinVersion);
359  values[2] = Int32GetDatum(meta->pagesPerRange);
360  values[3] = Int64GetDatum(meta->lastRevmapPage);
361 
362  htup = heap_form_tuple(tupdesc, values, nulls);
363 
365 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define BRIN_PAGETYPE_META
Definition: brin_page.h:51
static Page verify_brin_page(bytea *raw_page, uint16 type, const char *strtype)
Definition: brinfuncs.c:97
static char * PageGetContents(Page page)
Definition: bufpage.h:254
Pointer Page
Definition: bufpage.h:78
static bool PageIsNew(Page page)
Definition: bufpage.h:230
#define CStringGetTextDatum(s)
Definition: builtins.h:94
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2072
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1790
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:335
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
uintptr_t Datum
Definition: postgres.h:64
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
uint32 brinVersion
Definition: brin_page.h:67
uint32 brinMagic
Definition: brin_page.h:66
BlockNumber lastRevmapPage
Definition: brin_page.h:69
BlockNumber pagesPerRange
Definition: brin_page.h:68
Definition: c.h:676
bool superuser(void)
Definition: superuser.c:46

References BlessTupleDesc(), BRIN_PAGETYPE_META, BrinMetaPageData::brinMagic, BrinMetaPageData::brinVersion, CStringGetTextDatum, elog(), ereport, errcode(), errmsg(), ERROR, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum(), Int32GetDatum(), Int64GetDatum(), BrinMetaPageData::lastRevmapPage, PageGetContents(), PageIsNew(), BrinMetaPageData::pagesPerRange, PG_GETARG_BYTEA_P, PG_RETURN_DATUM, PG_RETURN_NULL, psprintf(), superuser(), TYPEFUNC_COMPOSITE, values, and verify_brin_page().

◆ brin_page_items()

Datum brin_page_items ( PG_FUNCTION_ARGS  )

Definition at line 131 of file brinfuncs.c.

132 {
133  bytea *raw_page = PG_GETARG_BYTEA_P(0);
134  Oid indexRelid = PG_GETARG_OID(1);
135  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
136  Relation indexRel;
137  brin_column_state **columns;
138  BrinDesc *bdesc;
139  BrinMemTuple *dtup;
140  Page page;
141  OffsetNumber offset;
142  AttrNumber attno;
143  bool unusedItem;
144 
145  if (!superuser())
146  ereport(ERROR,
147  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
148  errmsg("must be superuser to use raw page functions")));
149 
150  InitMaterializedSRF(fcinfo, 0);
151 
152  indexRel = index_open(indexRelid, AccessShareLock);
153 
154  if (!IS_BRIN(indexRel))
155  ereport(ERROR,
156  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
157  errmsg("\"%s\" is not a %s index",
158  RelationGetRelationName(indexRel), "BRIN")));
159 
160  bdesc = brin_build_desc(indexRel);
161 
162  /* minimally verify the page we got */
163  page = verify_brin_page(raw_page, BRIN_PAGETYPE_REGULAR, "regular");
164 
165  if (PageIsNew(page))
166  {
167  brin_free_desc(bdesc);
168  index_close(indexRel, AccessShareLock);
169  PG_RETURN_NULL();
170  }
171 
172  /*
173  * Initialize output functions for all indexed datatypes; simplifies
174  * calling them later.
175  */
176  columns = palloc(sizeof(brin_column_state *) * RelationGetDescr(indexRel)->natts);
177  for (attno = 1; attno <= bdesc->bd_tupdesc->natts; attno++)
178  {
179  Oid output;
180  bool isVarlena;
181  BrinOpcInfo *opcinfo;
182  int i;
183  brin_column_state *column;
184 
185  opcinfo = bdesc->bd_info[attno - 1];
186  column = palloc(offsetof(brin_column_state, outputFn) +
187  sizeof(FmgrInfo) * opcinfo->oi_nstored);
188 
189  column->nstored = opcinfo->oi_nstored;
190  for (i = 0; i < opcinfo->oi_nstored; i++)
191  {
192  getTypeOutputInfo(opcinfo->oi_typcache[i]->type_id, &output, &isVarlena);
193  fmgr_info(output, &column->outputFn[i]);
194  }
195 
196  columns[attno - 1] = column;
197  }
198 
199  offset = FirstOffsetNumber;
200  unusedItem = false;
201  dtup = NULL;
202  for (;;)
203  {
204  Datum values[8];
205  bool nulls[8] = {0};
206 
207  /*
208  * This loop is called once for every attribute of every tuple in the
209  * page. At the start of a tuple, we get a NULL dtup; that's our
210  * signal for obtaining and decoding the next one. If that's not the
211  * case, we output the next attribute.
212  */
213  if (dtup == NULL)
214  {
215  ItemId itemId;
216 
217  /* verify item status: if there's no data, we can't decode */
218  itemId = PageGetItemId(page, offset);
219  if (ItemIdIsUsed(itemId))
220  {
221  dtup = brin_deform_tuple(bdesc,
222  (BrinTuple *) PageGetItem(page, itemId),
223  NULL);
224  attno = 1;
225  unusedItem = false;
226  }
227  else
228  unusedItem = true;
229  }
230  else
231  attno++;
232 
233  if (unusedItem)
234  {
235  values[0] = UInt16GetDatum(offset);
236  nulls[1] = true;
237  nulls[2] = true;
238  nulls[3] = true;
239  nulls[4] = true;
240  nulls[5] = true;
241  nulls[6] = true;
242  nulls[7] = true;
243  }
244  else
245  {
246  int att = attno - 1;
247 
248  values[0] = UInt16GetDatum(offset);
249  switch (TupleDescAttr(rsinfo->setDesc, 1)->atttypid)
250  {
251  case INT8OID:
252  values[1] = Int64GetDatum((int64) dtup->bt_blkno);
253  break;
254  case INT4OID:
255  /* support for old extension version */
256  values[1] = UInt32GetDatum(dtup->bt_blkno);
257  break;
258  default:
259  elog(ERROR, "incorrect output types");
260  }
261  values[2] = UInt16GetDatum(attno);
262  values[3] = BoolGetDatum(dtup->bt_columns[att].bv_allnulls);
263  values[4] = BoolGetDatum(dtup->bt_columns[att].bv_hasnulls);
264  values[5] = BoolGetDatum(dtup->bt_placeholder);
265  values[6] = BoolGetDatum(dtup->bt_empty_range);
266  if (!dtup->bt_columns[att].bv_allnulls)
267  {
268  BrinValues *bvalues = &dtup->bt_columns[att];
269  StringInfoData s;
270  bool first;
271  int i;
272 
273  initStringInfo(&s);
274  appendStringInfoChar(&s, '{');
275 
276  first = true;
277  for (i = 0; i < columns[att]->nstored; i++)
278  {
279  char *val;
280 
281  if (!first)
282  appendStringInfoString(&s, " .. ");
283  first = false;
284  val = OutputFunctionCall(&columns[att]->outputFn[i],
285  bvalues->bv_values[i]);
287  pfree(val);
288  }
289  appendStringInfoChar(&s, '}');
290 
292  pfree(s.data);
293  }
294  else
295  {
296  nulls[7] = true;
297  }
298  }
299 
300  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
301 
302  /*
303  * If the item was unused, jump straight to the next one; otherwise,
304  * the only cleanup needed here is to set our signal to go to the next
305  * tuple in the following iteration, by freeing the current one.
306  */
307  if (unusedItem)
308  offset = OffsetNumberNext(offset);
309  else if (attno >= bdesc->bd_tupdesc->natts)
310  {
311  pfree(dtup);
312  dtup = NULL;
313  offset = OffsetNumberNext(offset);
314  }
315 
316  /*
317  * If we're beyond the end of the page, we're done.
318  */
319  if (offset > PageGetMaxOffsetNumber(page))
320  break;
321  }
322 
323  brin_free_desc(bdesc);
324  index_close(indexRel, AccessShareLock);
325 
326  return (Datum) 0;
327 }
int16 AttrNumber
Definition: attnum.h:21
void brin_free_desc(BrinDesc *bdesc)
Definition: brin.c:1327
BrinDesc * brin_build_desc(Relation rel)
Definition: brin.c:1272
#define BRIN_PAGETYPE_REGULAR
Definition: brin_page.h:53
BrinMemTuple * brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple, BrinMemTuple *dMemtuple)
Definition: brin_tuple.c:553
#define IS_BRIN(r)
Definition: brinfuncs.c:35
static Item PageGetItem(Page page, ItemId itemId)
Definition: bufpage.h:351
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
Definition: bufpage.h:240
static OffsetNumber PageGetMaxOffsetNumber(Page page)
Definition: bufpage.h:369
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1666
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
FILE * output
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:158
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:132
long val
Definition: informix.c:664
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
#define ItemIdIsUsed(itemId)
Definition: itemid.h:92
#define AccessShareLock
Definition: lockdefs.h:36
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2889
void pfree(void *pointer)
Definition: mcxt.c:1456
void * palloc(Size size)
Definition: mcxt.c:1226
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
static Datum UInt16GetDatum(uint16 X)
Definition: postgres.h:192
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum UInt32GetDatum(uint32 X)
Definition: postgres.h:232
unsigned int Oid
Definition: postgres_ext.h:31
#define RelationGetDescr(relation)
Definition: rel.h:530
#define RelationGetRelationName(relation)
Definition: rel.h:538
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
TypeCacheEntry * oi_typcache[FLEXIBLE_ARRAY_MEMBER]
Definition: brin_internal.h:37
uint16 oi_nstored
Definition: brin_internal.h:28
Datum * bv_values
Definition: brin_tuple.h:34
Definition: fmgr.h:57
TupleDesc setDesc
Definition: execnodes.h:333
Tuplestorestate * setResult
Definition: execnodes.h:332
FmgrInfo outputFn[FLEXIBLE_ARRAY_MEMBER]
Definition: brinfuncs.c:40
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:750

References AccessShareLock, appendStringInfoChar(), appendStringInfoString(), BoolGetDatum(), brin_build_desc(), brin_deform_tuple(), brin_free_desc(), BRIN_PAGETYPE_REGULAR, BrinValues::bv_values, CStringGetTextDatum, StringInfoData::data, elog(), ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, fmgr_info(), getTypeOutputInfo(), i, if(), index_close(), index_open(), InitMaterializedSRF(), initStringInfo(), Int64GetDatum(), IS_BRIN, ItemIdIsUsed, brin_column_state::nstored, OffsetNumberNext, BrinOpcInfo::oi_nstored, BrinOpcInfo::oi_typcache, output, brin_column_state::outputFn, OutputFunctionCall(), PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), PageIsNew(), palloc(), pfree(), PG_GETARG_BYTEA_P, PG_GETARG_OID, PG_RETURN_NULL, RelationGetDescr, RelationGetRelationName, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, superuser(), TupleDescAttr, tuplestore_putvalues(), TypeCacheEntry::type_id, UInt16GetDatum(), UInt32GetDatum(), val, values, and verify_brin_page().

◆ brin_page_type()

Datum brin_page_type ( PG_FUNCTION_ARGS  )

Definition at line 48 of file brinfuncs.c.

49 {
50  bytea *raw_page = PG_GETARG_BYTEA_P(0);
51  Page page;
52  char *type;
53 
54  if (!superuser())
55  ereport(ERROR,
56  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
57  errmsg("must be superuser to use raw page functions")));
58 
59  page = get_page_from_raw(raw_page);
60 
61  if (PageIsNew(page))
63 
64  /* verify the special space has the expected size */
65  if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace)))
66  ereport(ERROR,
67  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
68  errmsg("input page is not a valid %s page", "BRIN"),
69  errdetail("Expected special size %d, got %d.",
70  (int) MAXALIGN(sizeof(BrinSpecialSpace)),
71  (int) PageGetSpecialSize(page))));
72 
73  switch (BrinPageType(page))
74  {
75  case BRIN_PAGETYPE_META:
76  type = "meta";
77  break;
79  type = "revmap";
80  break;
82  type = "regular";
83  break;
84  default:
85  type = psprintf("unknown (%02x)", BrinPageType(page));
86  break;
87  }
88 
90 }
#define BRIN_PAGETYPE_REVMAP
Definition: brin_page.h:52
#define BrinPageType(page)
Definition: brin_page.h:42
static uint16 PageGetSpecialSize(Page page)
Definition: bufpage.h:313
#define MAXALIGN(LEN)
Definition: c.h:800
int errdetail(const char *fmt,...)
Definition: elog.c:1202
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
Page get_page_from_raw(bytea *raw_page)
Definition: rawpage.c:215
text * cstring_to_text(const char *s)
Definition: varlena.c:184
const char * type

References BRIN_PAGETYPE_META, BRIN_PAGETYPE_REGULAR, BRIN_PAGETYPE_REVMAP, BrinPageType, cstring_to_text(), ereport, errcode(), errdetail(), errmsg(), ERROR, get_page_from_raw(), MAXALIGN, PageGetSpecialSize(), PageIsNew(), PG_GETARG_BYTEA_P, PG_RETURN_NULL, PG_RETURN_TEXT_P, psprintf(), superuser(), and type.

◆ brin_revmap_data()

Datum brin_revmap_data ( PG_FUNCTION_ARGS  )

Definition at line 371 of file brinfuncs.c.

372 {
373  struct
374  {
375  ItemPointerData *tids;
376  int idx;
377  } *state;
378  FuncCallContext *fctx;
379 
380  if (!superuser())
381  ereport(ERROR,
382  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
383  errmsg("must be superuser to use raw page functions")));
384 
385  if (SRF_IS_FIRSTCALL())
386  {
387  bytea *raw_page = PG_GETARG_BYTEA_P(0);
388  MemoryContext mctx;
389  Page page;
390 
391  /* create a function context for cross-call persistence */
392  fctx = SRF_FIRSTCALL_INIT();
393 
394  /* switch to memory context appropriate for multiple function calls */
396 
397  /* minimally verify the page we got */
398  page = verify_brin_page(raw_page, BRIN_PAGETYPE_REVMAP, "revmap");
399 
400  if (PageIsNew(page))
401  {
402  MemoryContextSwitchTo(mctx);
403  PG_RETURN_NULL();
404  }
405 
406  state = palloc(sizeof(*state));
407  state->tids = ((RevmapContents *) PageGetContents(page))->rm_tids;
408  state->idx = 0;
409 
410  fctx->user_fctx = state;
411 
412  MemoryContextSwitchTo(mctx);
413  }
414 
415  fctx = SRF_PERCALL_SETUP();
416  state = fctx->user_fctx;
417 
418  if (state->idx < REVMAP_PAGE_MAXITEMS)
419  SRF_RETURN_NEXT(fctx, PointerGetDatum(&state->tids[state->idx++]));
420 
421  SRF_RETURN_DONE(fctx);
422 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define REVMAP_PAGE_MAXITEMS
Definition: brin_page.h:93
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
Definition: regguts.h:323

References BRIN_PAGETYPE_REVMAP, ereport, errcode(), errmsg(), ERROR, idx(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, PageGetContents(), PageIsNew(), palloc(), PG_GETARG_BYTEA_P, PG_RETURN_NULL, PointerGetDatum(), REVMAP_PAGE_MAXITEMS, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, superuser(), FuncCallContext::user_fctx, and verify_brin_page().

◆ PG_FUNCTION_INFO_V1() [1/4]

PG_FUNCTION_INFO_V1 ( brin_metapage_info  )

◆ PG_FUNCTION_INFO_V1() [2/4]

PG_FUNCTION_INFO_V1 ( brin_page_items  )

◆ PG_FUNCTION_INFO_V1() [3/4]

PG_FUNCTION_INFO_V1 ( brin_page_type  )

◆ PG_FUNCTION_INFO_V1() [4/4]

PG_FUNCTION_INFO_V1 ( brin_revmap_data  )

◆ verify_brin_page()

static Page verify_brin_page ( bytea raw_page,
uint16  type,
const char *  strtype 
)
static

Definition at line 97 of file brinfuncs.c.

98 {
99  Page page = get_page_from_raw(raw_page);
100 
101  if (PageIsNew(page))
102  return page;
103 
104  /* verify the special space has the expected size */
105  if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace)))
106  ereport(ERROR,
107  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
108  errmsg("input page is not a valid %s page", "BRIN"),
109  errdetail("Expected special size %d, got %d.",
110  (int) MAXALIGN(sizeof(BrinSpecialSpace)),
111  (int) PageGetSpecialSize(page))));
112 
113  /* verify the special space says this page is what we want */
114  if (BrinPageType(page) != type)
115  ereport(ERROR,
116  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
117  errmsg("page is not a BRIN page of type \"%s\"", strtype),
118  errdetail("Expected special type %08x, got %08x.",
119  type, BrinPageType(page))));
120 
121  return page;
122 }

References BrinPageType, ereport, errcode(), errdetail(), errmsg(), ERROR, get_page_from_raw(), MAXALIGN, PageGetSpecialSize(), PageIsNew(), and type.

Referenced by brin_metapage_info(), brin_page_items(), and brin_revmap_data().