{
/* save old rightlink and NSN */
oldrlink = GistPageGetOpaque(page)->rightlink;
- oldnsn = GistPageGetOpaque(page)->nsn;
+ oldnsn = GistPageGetNSN(page);
dist->buffer = buffer;
dist->block.blkno = BufferGetBlockNumber(buffer);
* F_FOLLOW_RIGHT flags ensure that scans will follow the
* rightlinks until the downlinks are inserted.
*/
- GistPageGetOpaque(ptr->page)->nsn = oldnsn;
+ GistPageSetNSN(ptr->page, oldnsn);
}
START_CRIT_SECTION();
{
Page leftpg = BufferGetPage(leftchildbuf);
- GistPageGetOpaque(leftpg)->nsn = recptr;
+ GistPageSetNSN(leftpg, recptr);
GistClearFollowRight(leftpg);
PageSetLSN(leftpg, recptr);
}
if (stack->blkno != GIST_ROOT_BLKNO &&
- stack->parent->lsn < GistPageGetOpaque(stack->page)->nsn)
+ stack->parent->lsn < GistPageGetNSN(stack->page))
{
/*
* Concurrent split detected. There's no guarantee that the
*/
}
else if (GistFollowRight(stack->page) ||
- stack->parent->lsn <
- GistPageGetOpaque(stack->page)->nsn)
+ stack->parent->lsn < GistPageGetNSN(stack->page))
{
/*
* The page was split while we momentarily unlocked the
if (GistFollowRight(page))
elog(ERROR, "concurrent GiST page split was incomplete");
- if (top->parent && top->parent->lsn < GistPageGetOpaque(page)->nsn &&
+ if (top->parent && top->parent->lsn < GistPageGetNSN(page) &&
GistPageGetOpaque(page)->rightlink != InvalidBlockNumber /* sanity check */ )
{
/*
*/
if (!XLogRecPtrIsInvalid(pageItem->data.parentlsn) &&
(GistFollowRight(page) ||
- pageItem->data.parentlsn < opaque->nsn) &&
+ pageItem->data.parentlsn < GistPageGetNSN(page)) &&
opaque->rightlink != InvalidBlockNumber /* sanity check */ )
{
/* There was a page split, follow right link to add pages */
GISTPageOpaque opaque = GistPageGetOpaque(page);
if (stack->blkno != GIST_ROOT_BLKNO && !XLogRecPtrIsInvalid(stack->parentlsn) &&
- (GistFollowRight(page) || stack->parentlsn < opaque->nsn) &&
+ (GistFollowRight(page) || stack->parentlsn < GistPageGetNSN(page)) &&
opaque->rightlink != InvalidBlockNumber /* sanity check */ )
{
/* split page detected, install right link to the stack */
*/
if (lsn >= PageGetLSN(page))
{
- GistPageGetOpaque(page)->nsn = lsn;
+ GistPageSetNSN(page, lsn);
GistClearFollowRight(page);
PageSetLSN(page, lsn);
if (newpage->header->blkno == GIST_ROOT_BLKNO)
{
GistPageGetOpaque(page)->rightlink = InvalidBlockNumber;
- GistPageGetOpaque(page)->nsn = xldata->orignsn;
+ GistPageSetNSN(page, xldata->orignsn);
GistClearFollowRight(page);
}
else
GistPageGetOpaque(page)->rightlink = xlrec.page[i + 1].header->blkno;
else
GistPageGetOpaque(page)->rightlink = xldata->origrlink;
- GistPageGetOpaque(page)->nsn = xldata->orignsn;
+ GistPageSetNSN(page, xldata->orignsn);
if (i < xlrec.data->npage - 1 && !isrootsplit &&
xldata->markfollowright)
GistMarkFollowRight(page);
#define F_FOLLOW_RIGHT (1 << 3) /* page to the right has no downlink */
typedef XLogRecPtr GistNSN;
+/*
+ * For on-disk compatibility with pre-9.3 servers, NSN is stored as two
+ * 32-bit fields on disk, same as LSNs.
+ */
+typedef PageXLogRecPtr PageGistNSN;
typedef struct GISTPageOpaqueData
{
- GistNSN nsn; /* this value must change on page split */
+ PageGistNSN nsn; /* this value must change on page split */
BlockNumber rightlink; /* next page if any */
uint16 flags; /* see bit definitions above */
uint16 gist_page_id; /* for identification of GiST indexes */
#define GistMarkFollowRight(page) ( GistPageGetOpaque(page)->flags |= F_FOLLOW_RIGHT)
#define GistClearFollowRight(page) ( GistPageGetOpaque(page)->flags &= ~F_FOLLOW_RIGHT)
+#define GistPageGetNSN(page) ( PageXLogRecPtrGet(GistPageGetOpaque(page)->nsn))
+#define GistPageSetNSN(page, val) ( PageXLogRecPtrSet(GistPageGetOpaque(page)->nsn, val))
+
/*
* Vector of GISTENTRY structs; user-defined methods union and picksplit
* take it as one of their arguments
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201212081
+#define CATALOG_VERSION_NO 201301171
#endif
typedef uint16 LocationIndex;
+/*
+ * For historical reasons, the 64-bit LSN value is stored as two 32-bit
+ * values.
+ */
+typedef struct
+{
+ uint32 xlogid; /* high bits */
+ uint32 xrecoff; /* low bits */
+} PageXLogRecPtr;
+
+#define PageXLogRecPtrGet(val) \
+ ((uint64) (val).xlogid << 32 | (val).xrecoff)
+#define PageXLogRecPtrSet(ptr, lsn) \
+ ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn))
+
/*
* disk page organization
*
* are 15 bits.
*/
-/* for historical reasons, the LSN is stored as two 32-bit values. */
-typedef struct
-{
- uint32 xlogid; /* high bits */
- uint32 xrecoff; /* low bits */
-} PageXLogRecPtr;
-
typedef struct PageHeaderData
{
/* XXX LSN is member of *any* block, not only page-organized ones */
/ sizeof(ItemIdData)))
/*
- * Additional macros for access to page headers
+ * Additional macros for access to page headers. (Beware multiple evaluation
+ * of the arguments!)
*/
#define PageGetLSN(page) \
- ((uint64) ((PageHeader) (page))->pd_lsn.xlogid << 32 | ((PageHeader) (page))->pd_lsn.xrecoff)
+ PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn)
#define PageSetLSN(page, lsn) \
- (((PageHeader) (page))->pd_lsn.xlogid = (uint32) ((lsn) >> 32), \
- ((PageHeader) (page))->pd_lsn.xrecoff = (uint32) (lsn))
+ PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn)
/* NOTE: only the 16 least significant bits are stored */
#define PageGetTLI(page) \