Пример #1
0
/*  Like PageInit() in the backend */
static void
page_init(Page page)
{
	PageHeader	p = (PageHeader) page;

	/* Make sure all fields of page are zero, as well as unused space */
	MemSet(p, 0, BLCKSZ);

	/* p->pd_flags = 0;								done by above MemSet */
	p->pd_lower = SizeOfPageHeaderData;
	p->pd_upper = BLCKSZ;
	p->pd_special = BLCKSZ; /* no special area on heap pages */
	PageSetPageSizeAndVersion(page, BLCKSZ, TARGET_PAGE_VERSION);
	/* p->pd_prune_xid = InvalidTransactionId;		done by above MemSet */
}
Пример #2
0
/*
 * PageInit
 *		Initializes the contents of a page.
 */
void
PageInit(Page page, Size pageSize, Size specialSize)
{
	PageHeader	p = (PageHeader) page;

	specialSize = MAXALIGN(specialSize);

	Assert(pageSize == BLCKSZ);
	Assert(pageSize > specialSize + SizeOfPageHeaderData);

	/* Make sure all fields of page are zero, as well as unused space */
	MemSet(p, 0, pageSize);

	/* p->pd_flags = 0;								done by above MemSet */
	p->pd_lower = SizeOfPageHeaderData;
	p->pd_upper = pageSize - specialSize;
	p->pd_special = pageSize - specialSize;
	PageSetPageSizeAndVersion(page, pageSize, PG_PAGE_LAYOUT_VERSION);
}
Пример #3
0
static const char *
convert_gpdb4_heap_page(char *page)
{
	VERSION4_PageHeaderData *oldhdr;
	PageHeader	newhdr;
	OffsetNumber off;
	OffsetNumber maxoff;

	if (PageGetPageSize(page) != BLCKSZ)
		return "invalid block size on page";

	/* Can only convert from GPDB4 format */
	if (PageGetPageLayoutVersion(page) != 4)
		return "invalid page version";

	oldhdr = (VERSION4_PageHeaderData *) page;

	/* Other checks that PageHeaderIsValid() normally performs */
	if (!((oldhdr->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
		  oldhdr->pd_lower >= SizeOfPageHeaderData &&
		  oldhdr->pd_lower <= oldhdr->pd_upper &&
		  oldhdr->pd_upper <= oldhdr->pd_special &&
		  oldhdr->pd_special <= BLCKSZ &&
		  oldhdr->pd_special == MAXALIGN(oldhdr->pd_special)))
		return "invalid header";

	/*
	 * Ok, it's a valid heap page, from GPDB4. We know how to convert that!
	 */

	/* 1. pd_prune_xid was added to page header */

	/* 2. Line pointer flags were changed */

	/* 3. HEAP_COMPRESSED flag was removed */

	/* 4. On-disk representation of numerics was changed */

	/*
	 * Also, money datatype was widened from 32 to 64 bits. (pg_upgrade
	 * should've refused the upgrade)
	 */

	/*
	 * First, check if there is enough space on the page, after we expand the header.
	 */
	oldhdr = (VERSION4_PageHeaderData *) page;
	newhdr = (PageHeader) page;

	/*
	 * If there isn't enough space on this page for the new header field, relocate a tuple
	 */
	make_room(page);

	/*
	 * There is space. Move the line pointers. We also convert the line pointer flags
	 * while we're at it. Begin from end to beginning, so that we don't overwrite items
	 * we haven't processed yet.
	 */
	maxoff = (oldhdr->pd_lower - VERSION4_SizeOfPageHeaderData) / sizeof(ItemIdData); /* PageGetMaxOffsetNumber */
	for (off = maxoff; off >= 1; off--)
	{
		ItemIdData iid = oldhdr->pd_linp[off - 1];	/* PageGetItemId */

		if (iid.lp_flags == VERSION4_LP_UNUSED)
			iid.lp_flags = LP_UNUSED;
		else if (iid.lp_flags == VERSION4_LP_USED)
			iid.lp_flags = LP_NORMAL;
		else
		{
			/* LP_DELETE and  LP_USED were never used on heap pages. */
			return "unexpected LP_DELETE or LP_DEAD line pointer on old-format heap page";
		}

		newhdr->pd_linp[off - 1] = iid;
	}
	newhdr->pd_lower = (char *) &newhdr->pd_linp[maxoff] - (char *) page;

	/* Initialize the field that was added after version 4 format */
	newhdr->pd_prune_xid = 0;

	/*
	 * Ok, the page header and line pointers are in the new format now. Mangle
	 * the tuples themselves
	 */
	for (off = 1; off <= maxoff; off++)
	{
		ItemId iid = PageGetItemId(page, off);	/* we can use PageGetItemId now */
		HeapTupleHeader htup;

		if (!ItemIdIsNormal(iid))
			continue;

		htup = (HeapTupleHeader) PageGetItem(page, iid);

		convert_heaptuple(htup);
	}

	/*
	 * Finally, change the version number.
	 */
	PageSetPageSizeAndVersion(page, BLCKSZ, TARGET_PAGE_VERSION);

	return NULL;
}