Tom Lane wrote:
> Alvaro Herrera writes:
> > typedef struct BrinSpecialSpace
> > {
> > charpadding[MAXALIGN(1) - 2 * sizeof(uint16)];
> > uint16 flags;
> > uint16 type;
> > } BrinSpecialSpace;
>
> I should expect that to fail altogether on 32-bit machines, because
> the declared array size will be zero.
Hah, of course.
> You could try something like
>
> typedef struct BrinSpecialSpace
> {
> uint16 vector[MAXALIGN(1) / sizeof(uint16)];
> } BrinSpecialSpace;
>
> and then some access macros to use the last and next-to-last
> elements of that array.
Ah, thanks, that works fine on x86-64. Here's a patch I intend to push
tomorrow.
Heikki suggested that the comment above GinPageOpaqueData be moved to
some better place, but I couldn't find any such. If there are other
ideas, I'm all ears.
--
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
commit 8532bfeffdaeffa1d49c390ba6b7b0b46a20afb7
Author: Alvaro Herrera
Date: Mon Mar 9 23:18:16 2015 -0300
Move BRIN page type to page's last two bytes
... which is the usual convention, so that pg_filedump and similar
utilities can tell apart pages of different AMs.
Per note from Heikki at
http://www.postgresql.org/message-id/546a16ef.9070...@vmware.com
diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c
index 630dda4..1b15a7b 100644
--- a/contrib/pageinspect/brinfuncs.c
+++ b/contrib/pageinspect/brinfuncs.c
@@ -58,12 +58,9 @@ brin_page_type(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
Page page = VARDATA(raw_page);
- BrinSpecialSpace *special;
char *type;
- special = (BrinSpecialSpace *) PageGetSpecialPointer(page);
-
- switch (special->type)
+ switch (BrinPageType(page))
{
case BRIN_PAGETYPE_META:
type = "meta";
@@ -75,7 +72,7 @@ brin_page_type(PG_FUNCTION_ARGS)
type = "regular";
break;
default:
- type = psprintf("unknown (%02x)", special->type);
+ type = psprintf("unknown (%02x)", BrinPageType(page));
break;
}
@@ -91,7 +88,6 @@ verify_brin_page(bytea *raw_page, uint16 type, const char *strtype)
{
Page page;
int raw_page_size;
- BrinSpecialSpace *special;
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
@@ -104,13 +100,12 @@ verify_brin_page(bytea *raw_page, uint16 type, const char *strtype)
page = VARDATA(raw_page);
/* verify the special space says this page is what we want */
- special = (BrinSpecialSpace *) PageGetSpecialPointer(page);
- if (special->type != type)
+ if (BrinPageType(page) != type)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("page is not a BRIN page of type \"%s\"", strtype),
errdetail("Expected special type %08x, got %08x.",
- type, special->type)));
+ type, BrinPageType(page;
return page;
}
diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c
index 4e9392b..acb64bd 100644
--- a/src/backend/access/brin/brin_pageops.c
+++ b/src/backend/access/brin/brin_pageops.c
@@ -53,7 +53,6 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
BrinTuple *oldtup;
Size oldsz;
Buffer newbuf;
- BrinSpecialSpace *special;
bool extended = false;
newsz = MAXALIGN(newsz);
@@ -113,8 +112,6 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
return false;
}
- special = (BrinSpecialSpace *) PageGetSpecialPointer(oldpage);
-
/*
* Great, the old tuple is intact. We can proceed with the update.
*
@@ -124,7 +121,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
* caller told us there isn't, if a concurrent update moved another tuple
* elsewhere or replaced a tuple with a smaller one.
*/
- if (((special->flags & BRIN_EVACUATE_PAGE) == 0) &&
+ if (((BrinPageFlags(oldpage) & BRIN_EVACUATE_PAGE) == 0) &&
brin_can_do_samepage_update(oldbuf, origsz, newsz))
{
if (BufferIsValid(newbuf))
@@ -374,12 +371,9 @@ brin_doinsert(Relation idxrel, BlockNumber pagesPerRange,
void
brin_page_init(Page page, uint16 type)
{
- BrinSpecialSpace *special;
-
PageInit(page, BLCKSZ, sizeof(BrinSpecialSpace));
- special = (BrinSpecialSpace *) PageGetSpecialPointer(page);
- special->type = type;
+ BrinPageType(page) = type;
}
/*
@@ -420,7 +414,6 @@ brin_start_evacuating_page(Relation idxRel, Buffer buf)
{
OffsetNumber off;
OffsetNumber maxoff;
- BrinSpecialSpace *special;
Page page;
page = BufferGetPage(buf);
@@ -428,8 +421,6 @@ brin_start_evacuating_page(Relation idxRel, Buffer buf)
if (PageIsNew(page))
return false;
- special = (BrinSpecialSpace *) PageGetSpecialPointer(page);
-
maxoff = PageGetMaxOffsetNumber(page);
for (off = FirstOffsetNumber; off <= maxoff; off++)
{
@@ -439,7 +430,7 @@ brin_start_evacuating_page(Relation idxRel, Buffer buf)
if (ItemIdIsUsed(lp))
{
/* prevent other backends from adding m