diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/access/heap/htup_03.c pgsql_master_upgrade.13a47c410da7/src/backend/access/heap/htup_03.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/access/heap/htup_03.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/access/heap/htup_03.c	2008-10-31 21:45:33.281134312 +0100
***************
*** 0 ****
--- 1,223 ----
+ #include "postgres.h"
+ #include "access/htup_03.h"
+ #include "access/heapam.h"
+ #include "utils/rel.h"
+ 
+ #define VARATT_FLAG_EXTERNAL	0x80000000
+ #define VARATT_FLAG_COMPRESSED	0x40000000
+ #define VARATT_MASK_FLAGS		0xc0000000
+ #define VARATT_MASK_SIZE		0x3fffffff
+ #define VARATT_SIZEP(_PTR)	(((varattrib_03 *)(_PTR))->va_header)
+ #define VARATT_SIZE(PTR)		(VARATT_SIZEP(PTR) & VARATT_MASK_SIZE)
+ 
+ typedef struct varattrib_03
+ {
+ 	int32		va_header;		/* External/compressed storage */
+ 	/* flags and item size */
+ 	union
+ 	{
+ 		struct
+ 		{
+ 			int32		va_rawsize;		/* Plain data size */
+ 			char		va_data[1];		/* Compressed data */
+ 		}			va_compressed;		/* Compressed stored attribute */
+ 
+ 		struct
+ 		{
+ 			int32		va_rawsize;		/* Plain data size */
+ 			int32		va_extsize;		/* External saved size */
+ 			Oid			va_valueid;		/* Unique identifier of value */
+ 			Oid			va_toastrelid;	/* RelID where to find chunks */
+ 		}			va_external;	/* External stored attribute */
+ 
+ 		char		va_data[1]; /* Plain stored attribute */
+ 	}			va_content;
+ } varattrib_03;
+ 
+ /*
+  * att_align aligns the given offset as needed for a datum of alignment
+  * requirement attalign.  The cases are tested in what is hopefully something
+  * like their frequency of occurrence.
+  */
+ static
+ long att_align_03(long cur_offset, char attalign)
+ {
+ 	switch(attalign)
+ 	{
+ 		case 'i' : return INTALIGN(cur_offset);
+ 		case 'c' : return cur_offset;
+ 		case 'd' : return DOUBLEALIGN(cur_offset);
+ 		case 's' : return SHORTALIGN(cur_offset);
+ 		default: elog(ERROR, "unsupported alligment (%c).", attalign);
+ 	}
+ }
+ 
+ /*
+  * att_addlength increments the given offset by the length of the attribute.
+  * attval is only accessed if we are dealing with a variable-length attribute.
+  */
+ static
+ long att_addlength_03(long cur_offset, int attlen, Datum attval)
+ {
+ 	if(attlen > 0)
+ 		return cur_offset + attlen;
+ 
+ 	if(attlen == -1)
+ 		return cur_offset + (*((uint32*) DatumGetPointer(attval)) & 0x3fffffff);
+ 
+ 	if(attlen != -2)
+ 		elog(ERROR, "not supported attlen (%i).", attlen);
+ 
+ 	return cur_offset + strlen(DatumGetCString(attval)) + 1;
+ }
+ 
+ 
+ /* deform tuple from version 03 including varlena and
+  * composite type handling */
+ void
+ heap_deform_tuple_03(HeapTuple tuple, TupleDesc tupleDesc,
+ 				  Datum *values, bool *isnull)
+ {
+ 	HeapTupleHeader_03 tup = (HeapTupleHeader_03) tuple->t_data;
+ 	bool		hasnulls = (tup->t_infomask & 0x01); 
+ 	Form_pg_attribute *att = tupleDesc->attrs;
+ 	int			tdesc_natts = tupleDesc->natts;
+ 	int			natts;			/* number of atts to extract */
+ 	int			attnum;
+ 	Pointer		tp_data;
+ 	long		off;			/* offset in tuple data */
+ 	bits8	   *bp = tup->t_bits;		/* ptr to null bitmap in tuple */
+ 
+ 	natts = tup->t_natts;
+ 
+ 	/*
+ 	 * In inheritance situations, it is possible that the given tuple actually
+ 	 * has more fields than the caller is expecting.  Don't run off the end of
+ 	 * the caller's arrays.
+ 	 */
+ 	natts = Min(natts, tdesc_natts);
+ 
+ 	tp_data = ((Pointer)tup) + tup->t_hoff;
+ 
+ 	off = 0;
+ 
+ 	for (attnum = 0; attnum < natts; attnum++)
+ 	{
+ 		Form_pg_attribute thisatt = att[attnum];
+ 
+ 		if (hasnulls && att_isnull(attnum, bp))
+ 		{
+ 			values[attnum] = (Datum) 0;
+ 			isnull[attnum] = true;
+ 			continue;
+ 		}
+ 
+ 		isnull[attnum] = false;
+ 
+ 		off = att_align_03(off, thisatt->attalign);
+ 
+ 		values[attnum] = fetchatt(thisatt, tp_data + off); /* fetchatt looks compatible */
+ 
+ 		off = att_addlength_03(off, thisatt->attlen, (Datum)(tp_data + off));
+ 	}
+ 
+ 	/*
+ 	 * If tuple doesn't have all the atts indicated by tupleDesc, read the
+ 	 * rest as null
+ 	 */
+ 	for (; attnum < tdesc_natts; attnum++)
+ 	{
+ 		values[attnum] = (Datum) 0;
+ 		isnull[attnum] = true;
+ 	}
+ }
+ 
+ HeapTuple heap_tuple_upgrade_03(Relation rel, HeapTuple tuple)
+ {
+ 	TupleDesc	tupleDesc = RelationGetDescr(rel);
+ 	int			natts;
+ 	Datum		*values;
+ 	bool		*isnull;
+ 	bool		*isalloc;
+ 	HeapTuple	newTuple;
+ 	int			n;
+ 
+ 	/* Preallocate values/isnull arrays */
+ 	natts = tupleDesc->natts;
+ 	values = (Datum *) palloc0(natts * sizeof(Datum));
+ 	isnull = (bool *) palloc0(natts * sizeof(bool));
+ 	isalloc = (bool *) palloc0(natts * sizeof(bool));
+ 
+ 	heap_deform_tuple_03(tuple, tupleDesc, values, isnull); 
+ 
+ 	/* now we need to go through values and convert varlen and composite types */
+ 	for( n = 0; n < natts; n++)
+ 	{
+ 		if(isnull[n])
+ 			continue;
+ 
+ 		if(tupleDesc->attrs[n]->attlen == -1)
+ 		{
+ 			varattrib_03* varhdr_03;
+ 			varattrib_4b* varhdr_04; 
+ 			char *data;
+ 
+ //			elog(NOTICE,"attname %s", tupleDesc->attrs[n]->attname);
+ 
+ 			/* varlena conversion */
+ 			varhdr_03 = (varattrib_03*) DatumGetPointer(values[n]);
+ 			data = palloc(VARATT_SIZE(varhdr_03));
+ 			varhdr_04 = (varattrib_4b*) data;
+ 
+ 			if( (varhdr_03->va_header & VARATT_MASK_FLAGS) == 0 )
+ 			{ 	/* TODO short varlena - but form_tuple should convert it anyway */
+ 
+ 				SET_VARSIZE(varhdr_04, VARATT_SIZE(varhdr_03));
+ 				memcpy( VARDATA(varhdr_04), varhdr_03->va_content.va_data,
+ 					VARATT_SIZE(varhdr_03)- offsetof(varattrib_03, va_content.va_data) );
+ 			} else
+ 			if( (varhdr_03->va_header & VARATT_FLAG_EXTERNAL) != 0)
+ 			{
+ 				SET_VARSIZE_EXTERNAL(varhdr_04, 
+ 					VARHDRSZ_EXTERNAL + sizeof(struct varatt_external));
+ 				memcpy( VARDATA_EXTERNAL(varhdr_04), 
+ 						&(varhdr_03->va_content.va_external.va_rawsize), sizeof(struct varatt_external));
+ 			} else
+ 			if( (varhdr_03->va_header & VARATT_FLAG_COMPRESSED ) != 0)
+ 			{
+ 
+ 				SET_VARSIZE_COMPRESSED(varhdr_04, VARATT_SIZE(varhdr_03));
+ 				varhdr_04->va_compressed.va_rawsize = varhdr_03->va_content.va_compressed.va_rawsize;
+ 
+ 				memcpy( VARDATA_4B_C(varhdr_04), varhdr_03->va_content.va_compressed.va_data,
+ 					VARATT_SIZE(varhdr_03)- offsetof(varattrib_03, va_content.va_compressed.va_data) );
+ 			}
+ 
+ 			values[n] = PointerGetDatum(data);
+ 			isalloc[n] = true;								
+ 		}
+ 	}
+ 
+ 	newTuple = heap_form_tuple(tupleDesc, values, isnull);
+ 
+ 	/* free allocated memory */
+ 	for( n = 0; n < natts; n++)
+ 	{
+ 		if(isalloc[n])
+ 			pfree(DatumGetPointer(values[n]));
+ 	}
+ 
+ 	/* Preserve OID, if any */
+ 	if(rel->rd_rel->relhasoids)
+ 	{
+ 		Oid oid;
+ 		oid = *((Oid *) ((char *)(tuple->t_data) + ((HeapTupleHeader_03)(tuple->t_data))->t_hoff - sizeof(Oid)));
+ 		HeapTupleSetOid(newTuple, oid);
+ 	}
+ 	return newTuple;
+ }
+ 
+ 
+ 
+ 
+ 
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/access/heap/htup.c pgsql_master_upgrade.13a47c410da7/src/backend/access/heap/htup.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/access/heap/htup.c	2008-10-31 21:45:33.114200837 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/access/heap/htup.c	2008-10-31 21:45:33.218887161 +0100
***************
*** 2,10 ****
--- 2,15 ----
  
  #include "fmgr.h"
  #include "access/htup.h"
+ #include "access/htup_03.h"
  #include "access/transam.h"
  #include "storage/bufpage.h"
  
+ 
+ #define TPH03(tup) \
+ 	((HeapTupleHeader_03)tuple->t_data)
+ 
  /*
   * HeapTupleHeader accessor macros
   *
***************
*** 135,251 ****
   */
  bool HeapTupleIsHotUpdated(HeapTuple tuple)
  {
! 	return ((tuple->t_data->t_infomask2 & HEAP_HOT_UPDATED) != 0 && 
! 			(tuple->t_data->t_infomask & (HEAP_XMIN_INVALID | HEAP_XMAX_INVALID)) == 0);
  }
  void HeapTupleSetHotUpdated(HeapTuple tuple)
  {
! 	tuple->t_data->t_infomask2 |= HEAP_HOT_UPDATED;
  }
  
  void HeapTupleClearHotUpdated(HeapTuple tuple)
  {
! 	tuple->t_data->t_infomask2 &= ~HEAP_HOT_UPDATED;
  }
  
  bool HeapTupleIsHeapOnly(HeapTuple tuple)
  {
! 	return (tuple->t_data->t_infomask2 & HEAP_ONLY_TUPLE) != 0;
  }
  
  void HeapTupleSetHeapOnly(HeapTuple tuple)
  { 
! 	tuple->t_data->t_infomask2 |= HEAP_ONLY_TUPLE;
  }
  
  void HeapTupleClearHeapOnly(HeapTuple tuple)
  {
! 	tuple->t_data->t_infomask2 &= ~HEAP_ONLY_TUPLE;
  }
  
  
  Oid HeapTupleGetOid(HeapTuple tuple)
  {
  	if(!HeapTupleIs(tuple, HEAP_HASOID))
  		return InvalidOid;
  
! 	return  *((Oid *) ((char *)tuple->t_data + HeapTupleGetHoff(tuple) - sizeof(Oid)));
  }
  
  void HeapTupleSetOid(HeapTuple tuple, Oid oid)
  {
  	Assert(HeapTupleIs(tuple, HEAP_HASOID)); 
! 	*((Oid *) ((char *)(tuple->t_data) + HeapTupleGetHoff(tuple) - sizeof(Oid))) = oid; 
! }
! 
! bool HeapTupleHasOid(HeapTuple tuple)
! {
! 	return HeapTupleIs(tuple, HEAP_HASOID);
  }
  
  TransactionId HeapTupleGetXmax(HeapTuple tuple)
  {
! 	return tuple->t_data->t_choice.t_heap.t_xmax;
  }
  
  void HeapTupleSetXmax(HeapTuple tuple, TransactionId xmax)
  {
! 	tuple->t_data->t_choice.t_heap.t_xmax = xmax;
  }
  
  TransactionId HeapTupleGetXmin(HeapTuple tuple)
  {
! 	return tuple->t_data->t_choice.t_heap.t_xmin;
  }
  
  void HeapTupleSetXmin(HeapTuple tuple, TransactionId xmin)
  {
! 	tuple->t_data->t_choice.t_heap.t_xmin = xmin;
  }
  
  TransactionId HeapTupleGetXvac(HeapTuple tuple)
  {
! 	return (HeapTupleIs(tuple, HEAP_MOVED)) ?
! 			tuple->t_data->t_choice.t_heap.t_field3.t_xvac :
! 			InvalidTransactionId;
  }
  
  void HeapTupleSetXvac(HeapTuple tuple, TransactionId Xvac)
  {
! 	Assert(HeapTupleIs(tuple, HEAP_MOVED));
! 		 tuple->t_data->t_choice.t_heap.t_field3.t_xvac = Xvac;
  }
  
  void HeapTupleSetCmax(HeapTuple tuple, CommandId cid, bool iscombo)
  {
! 	Assert(!(HeapTupleIs(tuple, HEAP_MOVED)));
! 	tuple->t_data->t_choice.t_heap.t_field3.t_cid = cid;
! 	if(iscombo)
! 		HeapTupleSet(tuple, HEAP_COMBOCID);
! 	else
! 		HeapTupleClear(tuple, HEAP_COMBOCID);
  }
  
  void HeapTupleSetCmin(HeapTuple tuple, CommandId cid)
  {
! 	Assert(!(HeapTupleIs(tuple, HEAP_MOVED)));
! 	tuple->t_data->t_choice.t_heap.t_field3.t_cid = cid;
! 	HeapTupleClear(tuple, HEAP_COMBOCID);
  }
  
  uint16 HeapTupleGetInfoMask(HeapTuple tuple)
  {
! 	return ((tuple)->t_data->t_infomask);
  }
  
  void HeapTupleSetInfoMask(HeapTuple tuple, uint16 infomask)
  {
! 	((tuple)->t_data->t_infomask = (infomask));
  }
  
  uint16 HeapTupleGetInfoMask2(HeapTuple tuple)
  {
! 	return ((tuple)->t_data->t_infomask2);
  }
  
  bool HeapTupleIs(HeapTuple tuple, uint16 mask)
--- 140,361 ----
   */
  bool HeapTupleIsHotUpdated(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : return ((tuple->t_data->t_infomask2 & HEAP_HOT_UPDATED) != 0 && 
! 					(tuple->t_data->t_infomask & (HEAP_XMIN_INVALID | HEAP_XMAX_INVALID)) == 0);
! 		case 3 : return false;
! 	}
! 	Assert(false);
! 	return false;
  }
  void HeapTupleSetHotUpdated(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : tuple->t_data->t_infomask2 |= HEAP_HOT_UPDATED;
! 				 return; 
! 	}
! 	elog(PANIC,"Tuple cannot be HOT updated");
  }
  
  void HeapTupleClearHotUpdated(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : tuple->t_data->t_infomask2 &= ~HEAP_HOT_UPDATED;
! 				 return; 
! 	}
! 	elog(PANIC,"Tuple cannot be HOT updated");
  }
  
  bool HeapTupleIsHeapOnly(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : return (tuple->t_data->t_infomask2 & HEAP_ONLY_TUPLE) != 0;
! 		case 3 : return false;
! 	}
! 	Assert(false);
! 	return false;
  }
  
  void HeapTupleSetHeapOnly(HeapTuple tuple)
  { 
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : tuple->t_data->t_infomask2 |= HEAP_ONLY_TUPLE;
! 				 return;
! 	}
! 	elog(PANIC, "HeapOnly flag is not supported.");
  }
  
  void HeapTupleClearHeapOnly(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{ 
! 		case 4 : tuple->t_data->t_infomask2 &= ~HEAP_ONLY_TUPLE;
! 				 return;
! 	}
! 	elog(PANIC, "HeapOnly flag is not supported.");
  }
  
+ bool HeapTupleHasOid(HeapTuple tuple)
+ {
+ 	return HeapTupleIs(tuple, HEAP_HASOID);
+ }
  
  Oid HeapTupleGetOid(HeapTuple tuple)
  {
  	if(!HeapTupleIs(tuple, HEAP_HASOID))
  		return InvalidOid;
  
! 	switch(tuple->t_ver)
! 	{ 
! 		case 4 : return  *((Oid *) ((char *)tuple->t_data + HeapTupleGetHoff(tuple) - sizeof(Oid)));
! 		case 3 : return  *((Oid *) ((char *)TPH03(tuple) + HeapTupleGetHoff(tuple) - sizeof(Oid)));
! 	}
! 	elog(PANIC, "HeapTupleGetOid is not supported.");
  }
  
  void HeapTupleSetOid(HeapTuple tuple, Oid oid)
  {
  	Assert(HeapTupleIs(tuple, HEAP_HASOID)); 
! 	switch(tuple->t_ver)
! 	{ 
! 		case 4 : *((Oid *) ((char *)(tuple->t_data) + HeapTupleGetHoff(tuple) - sizeof(Oid))) = oid;
! 				 break;
! 		case 3 : *((Oid *) ((char *)TPH03(tuple) + HeapTupleGetHoff(tuple) - sizeof(Oid))) = oid;
! 				 break;
! 		default: elog(PANIC, "HeapTupleSetOid is not supported.");
! 	}
  }
  
  TransactionId HeapTupleGetXmax(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : return tuple->t_data->t_choice.t_heap.t_xmax;
! 		case 3 : return TPH03(tuple)->t_choice.t_heap.t_xmax;
! 	}
! 	elog(PANIC, "HeapTupleGetXmax is not supported.");
! 	return 0;
  }
  
  void HeapTupleSetXmax(HeapTuple tuple, TransactionId xmax)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : tuple->t_data->t_choice.t_heap.t_xmax = xmax;
! 				 break;
! 		case 3 : TPH03(tuple)->t_choice.t_heap.t_xmax = xmax;
! 				 break;
! 		default: elog(PANIC, "HeapTupleSetXmax is not supported.");
! 	}
  }
  
  TransactionId HeapTupleGetXmin(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : return tuple->t_data->t_choice.t_heap.t_xmin;
! 		case 3 : return TPH03(tuple)->t_choice.t_heap.t_xmin;
! 	}
! 	elog(PANIC, "HeapTupleSetXmin is not supported.");
! 	return 0;
  }
  
  void HeapTupleSetXmin(HeapTuple tuple, TransactionId xmin)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : tuple->t_data->t_choice.t_heap.t_xmin = xmin;
! 				 break;
! 		case 3 : TPH03(tuple)->t_choice.t_heap.t_xmin = xmin;
! 		default: elog(PANIC, "HeapTupleSetXmin is not supported.");
! 	}
  }
  
  TransactionId HeapTupleGetXvac(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : return (HeapTupleIs(tuple, HEAP_MOVED)) ?
! 						tuple->t_data->t_choice.t_heap.t_field3.t_xvac :
! 						InvalidTransactionId;
! 	}
! 	Assert(false);
! 	return InvalidTransactionId;
  }
  
  void HeapTupleSetXvac(HeapTuple tuple, TransactionId Xvac)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : Assert(HeapTupleIs(tuple, HEAP_MOVED));
! 				 tuple->t_data->t_choice.t_heap.t_field3.t_xvac = Xvac;
! 				 break;
! 		default: Assert(false);
! 	}
  }
  
  void HeapTupleSetCmax(HeapTuple tuple, CommandId cid, bool iscombo)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : Assert(!(HeapTupleIs(tuple, HEAP_MOVED)));
! 				 tuple->t_data->t_choice.t_heap.t_field3.t_cid = cid;
! 				 if(iscombo)
! 					HeapTupleSet(tuple, HEAP_COMBOCID);
! 				 else
! 					HeapTupleClear(tuple, HEAP_COMBOCID);
! 				 break;
! 		default: Assert(false);
! 	} 
  }
  
  void HeapTupleSetCmin(HeapTuple tuple, CommandId cid)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 : Assert(!(HeapTupleIs(tuple, HEAP_MOVED)));
! 				 tuple->t_data->t_choice.t_heap.t_field3.t_cid = cid;
! 				 HeapTupleClear(tuple, HEAP_COMBOCID);
! 				 break;
! 		default: Assert(false);
! 	}
  }
  
  uint16 HeapTupleGetInfoMask(HeapTuple tuple)
  {
! 	uint16 infomask;
! 	switch(tuple->t_ver)
! 	{
! 		case 4: return ((tuple)->t_data->t_infomask);
! 		case 3: infomask = TPH03(tuple)->t_infomask & 0xFFB7; /* reset 3 (HASOID), 4 (UNUSED), 5 (COMBOCID) bit */
! 				infomask |= ((TPH03(tuple)->t_infomask& 0x0010) << 1 ); /* copy HASOID */ 
! 				return infomask;	
! 	}
! 	elog(PANIC, "HeapTupleGetInfoMask is not supported.");	
  }
  
  void HeapTupleSetInfoMask(HeapTuple tuple, uint16 infomask)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4:	((tuple)->t_data->t_infomask = (infomask));
! 				break;
! 		default: Assert(false);
! 	}
  }
  
  uint16 HeapTupleGetInfoMask2(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4 :return ((tuple)->t_data->t_infomask2);
! 		default: return 0;
! 	}
  }
  
  bool HeapTupleIs(HeapTuple tuple, uint16 mask)
***************
*** 265,271 ****
  
  void HeapTupleClear2(HeapTuple tuple, uint16 mask)
  {
! 	((tuple)->t_data->t_infomask2 &= ~(mask));
  }
  
  CommandId HeapTupleGetRawCommandId(HeapTuple tuple)
--- 375,386 ----
  
  void HeapTupleClear2(HeapTuple tuple, uint16 mask)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4:	((tuple)->t_data->t_infomask2 &= ~(mask));
! 				break;
! 	}
! 	/* silently ignore on older versions */
  }
  
  CommandId HeapTupleGetRawCommandId(HeapTuple tuple)
***************
*** 275,281 ****
  
  int HeapTupleGetNatts(HeapTuple tuple)
  {
! 	return (tuple->t_data->t_infomask2 & HEAP_NATTS_MASK);
  }
  
  ItemPointer HeapTupleGetCtid(HeapTuple tuple)
--- 390,401 ----
  
  int HeapTupleGetNatts(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4: return (tuple->t_data->t_infomask2 & HEAP_NATTS_MASK);
! 		case 3: return TPH03(tuple)->t_natts;
! 	}
! 	elog(PANIC, "HeapTupleGetNatts is not supported.");
  }
  
  ItemPointer HeapTupleGetCtid(HeapTuple tuple)
***************
*** 290,306 ****
  
  uint8 HeapTupleGetHoff(HeapTuple tuple)
  {
! 	return (tuple->t_data->t_hoff);
  }
  
  Pointer HeapTupleGetBits(HeapTuple tuple)
  {
! 	return (Pointer)(tuple->t_data->t_bits);
  }
  
  Pointer HeapTupleGetData(HeapTuple tuple)
  {
! 	return (((Pointer)tuple->t_data) + tuple->t_data->t_hoff);
  }
  
  void HeapTupleInit(HeapTuple tuple, int32 len, Oid typid, int32 typmod,
--- 410,438 ----
  
  uint8 HeapTupleGetHoff(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4: return (tuple->t_data->t_hoff);
! 	}
! 	elog(PANIC, "HeapTupleGetHoff is not supported.");
  }
  
  Pointer HeapTupleGetBits(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4: return (Pointer)(tuple->t_data->t_bits);
! 	}
! 	elog(PANIC, "HeapTupleGetBits is not supported.");
  }
  
  Pointer HeapTupleGetData(HeapTuple tuple)
  {
! 	switch(tuple->t_ver)
! 	{
! 		case 4: return (((Pointer)tuple->t_data) + tuple->t_data->t_hoff);
! 	}
! 	elog(PANIC, "HeapTupleGetData is not supported.");
  }
  
  void HeapTupleInit(HeapTuple tuple, int32 len, Oid typid, int32 typmod,
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/access/heap/Makefile pgsql_master_upgrade.13a47c410da7/src/backend/access/heap/Makefile
*** pgsql_master_upgrade.751eb7c6969f/src/backend/access/heap/Makefile	2008-10-31 21:45:33.112796571 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/access/heap/Makefile	2008-10-31 21:45:33.217276252 +0100
***************
*** 12,17 ****
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o htup.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 12,17 ----
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o htup.o htup_03.o
  
  include $(top_srcdir)/src/backend/common.mk
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/access/nbtree/nbtinsert.c pgsql_master_upgrade.13a47c410da7/src/backend/access/nbtree/nbtinsert.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/access/nbtree/nbtinsert.c	2008-10-31 21:45:33.136480748 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/access/nbtree/nbtinsert.c	2008-10-31 21:45:33.231075233 +0100
***************
*** 1203,1209 ****
  
  	/* Total free space available on a btree page, after fixed overhead */
  	leftspace = rightspace =
! 		PageGetPageSize(page) - SizeOfPageHeaderData -
  		MAXALIGN(sizeof(BTPageOpaqueData));
  
  	/* The right page will have the same high key as the old page */
--- 1203,1209 ----
  
  	/* Total free space available on a btree page, after fixed overhead */
  	leftspace = rightspace =
! 		PageGetPageSize(page) - SizeOfPageHeaderData04 -
  		MAXALIGN(sizeof(BTPageOpaqueData));
  
  	/* The right page will have the same high key as the old page */
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/executor/nodeIndexscan.c pgsql_master_upgrade.13a47c410da7/src/backend/executor/nodeIndexscan.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/executor/nodeIndexscan.c	2008-10-31 21:45:33.144606136 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/executor/nodeIndexscan.c	2008-10-31 21:45:33.238969129 +0100
***************
*** 27,32 ****
--- 27,33 ----
  #include "access/genam.h"
  #include "access/nbtree.h"
  #include "access/relscan.h"
+ #include "access/htup_03.h"
  #include "executor/execdebug.h"
  #include "executor/nodeIndexscan.h"
  #include "optimizer/clauses.h"
***************
*** 113,122 ****
  		 * Note: we pass 'false' because tuples returned by amgetnext are
  		 * pointers onto disk pages and must not be pfree()'d.
  		 */
! 		ExecStoreTuple(tuple,	/* tuple to store */
! 					   slot,	/* slot to store in */
! 					   scandesc->xs_cbuf,		/* buffer containing tuple */
! 					   false);	/* don't pfree */
  
  		/*
  		 * If the index was lossy, we have to recheck the index quals using
--- 114,138 ----
  		 * Note: we pass 'false' because tuples returned by amgetnext are
  		 * pointers onto disk pages and must not be pfree()'d.
  		 */
! 		if(tuple->t_ver == 4)
! 		{
! 			ExecStoreTuple(tuple,	/* tuple to store */
! 						   slot,	/* slot to store in */
! 						   scandesc->xs_cbuf,		/* buffer containing tuple */
! 						   false);	/* don't pfree */
! 		} else
! 		if(tuple->t_ver == 3)
! 		{
! 			HeapTuple newtup;
! 			newtup = heap_tuple_upgrade_03(scandesc->heapRelation, tuple);
! 			ExecStoreTuple(newtup,	/* tuple to store */
! 						   slot,	/* slot to store in */
! 						   InvalidBuffer,		/* buffer associated with this
! 													 * tuple */
! 						   true);	/* pfree this pointer */
! 		}
! 		else
! 			elog(ERROR,"Unsupported tuple version (%i).",tuple->t_ver);
  
  		/*
  		 * If the index was lossy, we have to recheck the index quals using
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/executor/nodeSeqscan.c pgsql_master_upgrade.13a47c410da7/src/backend/executor/nodeSeqscan.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/executor/nodeSeqscan.c	2008-10-31 21:45:33.148191833 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/executor/nodeSeqscan.c	2008-10-31 21:45:33.242644971 +0100
***************
*** 25,30 ****
--- 25,31 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "access/htup_03.h"
  #include "access/relscan.h"
  #include "executor/execdebug.h"
  #include "executor/nodeSeqscan.h"
***************
*** 101,111 ****
  	 * refcount will not be dropped until the tuple table slot is cleared.
  	 */
  	if (tuple)
! 		ExecStoreTuple(tuple,	/* tuple to store */
! 					   slot,	/* slot to store in */
! 					   scandesc->rs_cbuf,		/* buffer associated with this
! 												 * tuple */
! 					   false);	/* don't pfree this pointer */
  	else
  		ExecClearTuple(slot);
  
--- 102,129 ----
  	 * refcount will not be dropped until the tuple table slot is cleared.
  	 */
  	if (tuple)
! 	{
! 		if(tuple->t_ver == 4)
! 		{
! 			ExecStoreTuple(tuple,	/* tuple to store */
! 						   slot,	/* slot to store in */
! 						   scandesc->rs_cbuf,		/* buffer associated with this
! 													 * tuple */
! 						   false);	/* don't pfree this pointer */
! 		} else
! 		if(tuple->t_ver == 3)
! 		{
! 			HeapTuple newtup;
! 			newtup = heap_tuple_upgrade_03(scandesc->rs_rd, tuple);
! 			ExecStoreTuple(newtup,	/* tuple to store */
! 						   slot,	/* slot to store in */
! 						   InvalidBuffer,		/* buffer associated with this
! 													 * tuple */
! 						   true);	/* pfree this pointer */
! 		}
! 		else
! 			elog(ERROR,"Unsupported tuple version (%i).",tuple->t_ver);
! 	}
  	else
  		ExecClearTuple(slot);
  
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/optimizer/util/plancat.c pgsql_master_upgrade.13a47c410da7/src/backend/optimizer/util/plancat.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/optimizer/util/plancat.c	2008-10-31 21:45:33.157104094 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/optimizer/util/plancat.c	2008-10-31 21:45:33.251184277 +0100
***************
*** 429,435 ****
  				tuple_width += sizeof(HeapTupleHeaderData);
  				tuple_width += sizeof(ItemPointerData);
  				/* note: integer division is intentional here */
! 				density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
  			}
  			*tuples = rint(density * (double) curpages);
  			break;
--- 429,435 ----
  				tuple_width += sizeof(HeapTupleHeaderData);
  				tuple_width += sizeof(ItemPointerData);
  				/* note: integer division is intentional here */
! 				density = (BLCKSZ - SizeOfPageHeaderData04) / tuple_width;
  			}
  			*tuples = rint(density * (double) curpages);
  			break;
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/backend/storage/page/bufpage.c pgsql_master_upgrade.13a47c410da7/src/backend/storage/page/bufpage.c
*** pgsql_master_upgrade.751eb7c6969f/src/backend/storage/page/bufpage.c	2008-10-31 21:45:33.168097249 +0100
--- pgsql_master_upgrade.13a47c410da7/src/backend/storage/page/bufpage.c	2008-10-31 21:45:33.262190876 +0100
***************
*** 19,24 ****
--- 19,28 ----
  #include "access/transam.h"
  #include "storage/bufpage.h"
  
+ 
+ static bool PageLayoutIsValid_04(Page page);
+ static bool PageLayoutIsValid_03(Page page);
+ static bool PageIsZeroed(Page page);
  static Item PageGetItem(Page page, OffsetNumber offsetNumber);
  
  /* ----------------------------------------------------------------
***************
*** 28,50 ****
  
  /*
   * 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);
--- 32,55 ----
  
  /*
   * PageInit
!  *		Initializes the contents of a page. We allow to initialize page only
!  *      in latest Page Layout Version.
   */
  void
  PageInit(Page page, Size pageSize, Size specialSize)
  {
! 	PageHeader_04	p = (PageHeader_04) page;
  
  	specialSize = MAXALIGN(specialSize);
  
  	Assert(pageSize == BLCKSZ);
! 	Assert(pageSize > specialSize + SizeOfPageHeaderData04);
  
  	/* 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 = SizeOfPageHeaderData04;
  	p->pd_upper = pageSize - specialSize;
  	p->pd_special = pageSize - specialSize;
  	PageSetPageSizeAndVersion(page, pageSize, PG_PAGE_LAYOUT_VERSION);
***************
*** 53,59 ****
  
  
  /*
!  * PageHeaderIsValid
   *		Check that the header fields of a page appear valid.
   *
   * This is called when a page has just been read in from disk.	The idea is
--- 58,64 ----
  
  
  /*
!  * PageLayoutIsValid
   *		Check that the header fields of a page appear valid.
   *
   * This is called when a page has just been read in from disk.	The idea is
***************
*** 73,94 ****
  bool
  PageLayoutIsValid(Page page)
  {
  	char	   *pagebytes;
  	int			i;
- 	PageHeader	ph = (PageHeader)page;
- 
- 	/* Check normal case */
- 	if (PageGetPageSize(page) == BLCKSZ &&
- 		PageGetPageLayoutVersion(page) == PG_PAGE_LAYOUT_VERSION &&
- 		(ph->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
- 		ph->pd_lower >= SizeOfPageHeaderData &&
- 		ph->pd_lower <= ph->pd_upper &&
- 		ph->pd_upper <= ph->pd_special &&
- 		ph->pd_special <= BLCKSZ &&
- 		ph->pd_special == MAXALIGN(ph->pd_special))
- 		return true;
  
- 	/* Check all-zeroes case */
  	pagebytes = (char *) page;
  	for (i = 0; i < BLCKSZ; i++)
  	{
--- 78,102 ----
  bool
  PageLayoutIsValid(Page page)
  {
+ 	/* Check normal case */
+ 	switch(PageGetPageLayoutVersion(page))
+ 	{
+ 		case 4 : return(PageLayoutIsValid_04(page));
+ 		case 3 : return(PageLayoutIsValid_03(page));
+ 		case 0 : return(PageIsZeroed(page));
+ 	}
+ 	return false;
+ }
+ 
+ /* 
+  * Check all-zeroes case 
+  */
+ bool
+ PageIsZeroed(Page page)
+ {
  	char	   *pagebytes;
  	int			i;
  
  	pagebytes = (char *) page;
  	for (i = 0; i < BLCKSZ; i++)
  	{
***************
*** 98,103 ****
--- 106,141 ----
  	return true;
  }
  
+ bool PageLayoutIsValid_04(Page page)
+ {
+ 	PageHeader_04 phdr = (PageHeader_04)page;
+  	if(
+ 		 PageGetPageSize(page) == BLCKSZ &&
+ 		(phdr->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
+ 		phdr->pd_lower >= SizeOfPageHeaderData04 &&
+ 		phdr->pd_lower <= phdr->pd_upper &&
+ 		phdr->pd_upper <= phdr->pd_special &&
+ 		phdr->pd_special <= BLCKSZ &&
+ 		phdr->pd_special == MAXALIGN(phdr->pd_special))
+ 		return true;
+ 	return false;
+ }
+ 
+ bool PageLayoutIsValid_03(Page page)
+ {
+ 	PageHeader_03 phdr = (PageHeader_03)page;
+  	if(
+ 		 PageGetPageSize(page) == BLCKSZ &&
+ 		phdr->pd_lower >= SizeOfPageHeaderData03 &&
+ 		phdr->pd_lower <= phdr->pd_upper &&
+ 		phdr->pd_upper <= phdr->pd_special &&
+ 		phdr->pd_special <= BLCKSZ &&
+ 		phdr->pd_special == MAXALIGN(phdr->pd_special))
+ 		return true;
+ 	return false;
+ }
+ 
+ 
  
  /*
   *	PageAddItem
***************
*** 127,133 ****
  			bool overwrite,
  			bool is_heap)
  {
! 	PageHeader	phdr = (PageHeader) page;
  	Size		alignedSize;
  	int			lower;
  	int			upper;
--- 165,171 ----
  			bool overwrite,
  			bool is_heap)
  {
! 	PageHeader_04	phdr = (PageHeader_04) page;
  	Size		alignedSize;
  	int			lower;
  	int			upper;
***************
*** 135,144 ****
  	OffsetNumber limit;
  	bool		needshuffle = false;
  
  	/*
  	 * Be wary about corrupted page pointers
  	 */
! 	if (phdr->pd_lower < SizeOfPageHeaderData ||
  		phdr->pd_lower > phdr->pd_upper ||
  		phdr->pd_upper > phdr->pd_special ||
  		phdr->pd_special > BLCKSZ)
--- 173,185 ----
  	OffsetNumber limit;
  	bool		needshuffle = false;
  
+ 	/* We allow add new items only on the new page layout - TODO indexes? */
+ 	if( PageGetPageLayoutVersion(page) != PG_PAGE_LAYOUT_VERSION )
+ 		elog(PANIC, "Add item on old page layout version is forbidden.");
  	/*
  	 * Be wary about corrupted page pointers
  	 */
! 	if (phdr->pd_lower < SizeOfPageHeaderData04 ||
  		phdr->pd_lower > phdr->pd_upper ||
  		phdr->pd_upper > phdr->pd_special ||
  		phdr->pd_special > BLCKSZ)
***************
*** 265,281 ****
  {
  	Size		pageSize;
  	Page		temp;
! 	PageHeader	thdr;
  
  	pageSize = PageGetPageSize(page);
  	temp = (Page) palloc(pageSize);
! 	thdr = (PageHeader) temp;
  
  	/* copy old page in */
  	memcpy(temp, page, pageSize);
  
  	/* set high, low water marks */
! 	thdr->pd_lower = SizeOfPageHeaderData;
  	thdr->pd_upper = pageSize - MAXALIGN(specialSize);
  
  	/* clear out the middle */
--- 306,322 ----
  {
  	Size		pageSize;
  	Page		temp;
! 	PageHeader_04	thdr;
  
  	pageSize = PageGetPageSize(page);
  	temp = (Page) palloc(pageSize);
! 	thdr = (PageHeader_04) temp;
  
  	/* copy old page in */
  	memcpy(temp, page, pageSize);
  
  	/* set high, low water marks */
! 	thdr->pd_lower = SizeOfPageHeaderData04;
  	thdr->pd_upper = pageSize - MAXALIGN(specialSize);
  
  	/* clear out the middle */
***************
*** 333,341 ****
  void
  PageRepairFragmentation(Page page)
  {
! 	Offset		pd_lower = ((PageHeader) page)->pd_lower;
! 	Offset		pd_upper = ((PageHeader) page)->pd_upper;
! 	Offset		pd_special = ((PageHeader) page)->pd_special;
  	itemIdSort	itemidbase,
  				itemidptr;
  	ItemId		lp;
--- 374,382 ----
  void
  PageRepairFragmentation(Page page)
  {
! 	Offset		pd_lower = PageGetLower(page);
! 	Offset		pd_upper = PageGetUpper(page);
! 	Offset		pd_special = PageGetSpecial(page);
  	itemIdSort	itemidbase,
  				itemidptr;
  	ItemId		lp;
***************
*** 353,359 ****
  	 * etc could cause us to clobber adjacent disk buffers, spreading the data
  	 * loss further.  So, check everything.
  	 */
! 	if (pd_lower < SizeOfPageHeaderData ||
  		pd_lower > pd_upper ||
  		pd_upper > pd_special ||
  		pd_special > BLCKSZ ||
--- 394,400 ----
  	 * etc could cause us to clobber adjacent disk buffers, spreading the data
  	 * loss further.  So, check everything.
  	 */
! 	if (pd_lower < SizeOfPageHeaderData04 ||
  		pd_lower > pd_upper ||
  		pd_upper > pd_special ||
  		pd_special > BLCKSZ ||
***************
*** 384,390 ****
  	if (nstorage == 0)
  	{
  		/* Page is completely empty, so just reset it quickly */
! 		((PageHeader) page)->pd_upper = pd_special;
  	}
  	else
  	{							/* nstorage != 0 */
--- 425,431 ----
  	if (nstorage == 0)
  	{
  		/* Page is completely empty, so just reset it quickly */
! 		PageSetUpper(page, pd_special);
  	}
  	else
  	{							/* nstorage != 0 */
***************
*** 434,440 ****
  			lp->lp_off = upper;
  		}
  
! 		((PageHeader) page)->pd_upper = upper;
  
  		pfree(itemidbase);
  	}
--- 475,481 ----
  			lp->lp_off = upper;
  		}
  
! 		PageSetUpper(page, upper);
  
  		pfree(itemidbase);
  	}
***************
*** 463,470 ****
  	 * Use signed arithmetic here so that we behave sensibly if pd_lower >
  	 * pd_upper.
  	 */
! 	space = (int) ((PageHeader) page)->pd_upper -
! 		(int) ((PageHeader) page)->pd_lower;
  
  	if (space < (int) sizeof(ItemIdData))
  		return 0;
--- 504,510 ----
  	 * Use signed arithmetic here so that we behave sensibly if pd_lower >
  	 * pd_upper.
  	 */
! 	space = PageGetExactFreeSpace(page);
  
  	if (space < (int) sizeof(ItemIdData))
  		return 0;
***************
*** 487,494 ****
  	 * Use signed arithmetic here so that we behave sensibly if pd_lower >
  	 * pd_upper.
  	 */
! 	space = (int) ((PageHeader) page)->pd_upper -
! 		(int) ((PageHeader) page)->pd_lower;
  
  	if (space < 0)
  		return 0;
--- 527,533 ----
  	 * Use signed arithmetic here so that we behave sensibly if pd_lower >
  	 * pd_upper.
  	 */
! 	space = (int)PageGetUpper(page) - (int)PageGetLower(page);
  
  	if (space < 0)
  		return 0;
***************
*** 575,581 ****
  void
  PageIndexTupleDelete(Page page, OffsetNumber offnum)
  {
! 	PageHeader	phdr = (PageHeader) page;
  	char	   *addr;
  	ItemId		tup;
  	Size		size;
--- 614,620 ----
  void
  PageIndexTupleDelete(Page page, OffsetNumber offnum)
  {
! 	PageHeader_04	phdr = (PageHeader_04) page; /* TODO PGU */
  	char	   *addr;
  	ItemId		tup;
  	Size		size;
***************
*** 587,593 ****
  	/*
  	 * As with PageRepairFragmentation, paranoia seems justified.
  	 */
! 	if (phdr->pd_lower < SizeOfPageHeaderData ||
  		phdr->pd_lower > phdr->pd_upper ||
  		phdr->pd_upper > phdr->pd_special ||
  		phdr->pd_special > BLCKSZ)
--- 626,632 ----
  	/*
  	 * As with PageRepairFragmentation, paranoia seems justified.
  	 */
! 	if (phdr->pd_lower < SizeOfPageHeaderData04 ||
  		phdr->pd_lower > phdr->pd_upper ||
  		phdr->pd_upper > phdr->pd_special ||
  		phdr->pd_special > BLCKSZ)
***************
*** 681,687 ****
  void
  PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
  {
! 	PageHeader	phdr = (PageHeader) page;
  	Offset		pd_lower = phdr->pd_lower;
  	Offset		pd_upper = phdr->pd_upper;
  	Offset		pd_special = phdr->pd_special;
--- 720,726 ----
  void
  PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
  {
! 	PageHeader_04	phdr = (PageHeader_04) page; /* TODO PGU */
  	Offset		pd_lower = phdr->pd_lower;
  	Offset		pd_upper = phdr->pd_upper;
  	Offset		pd_special = phdr->pd_special;
***************
*** 716,722 ****
  	/*
  	 * As with PageRepairFragmentation, paranoia seems justified.
  	 */
! 	if (pd_lower < SizeOfPageHeaderData ||
  		pd_lower > pd_upper ||
  		pd_upper > pd_special ||
  		pd_special > BLCKSZ ||
--- 755,761 ----
  	/*
  	 * As with PageRepairFragmentation, paranoia seems justified.
  	 */
! 	if (pd_lower < SizeOfPageHeaderData04 ||
  		pd_lower > pd_upper ||
  		pd_upper > pd_special ||
  		pd_special > BLCKSZ ||
***************
*** 796,815 ****
  		lp->lp_off = upper;
  	}
  
! 	phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
  	phdr->pd_upper = upper;
  
  	pfree(itemidbase);
  }
  
  /*
   * PageGetItemId
   *		Returns an item identifier of a page.
   */
! static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber) 
  {
  	AssertMacro(offsetNumber > 0);
! 	return (ItemId) (& ((PageHeader) page)->pd_linp[(offsetNumber) - 1]) ;
  }
  
  /*
--- 835,861 ----
  		lp->lp_off = upper;
  	}
  
! 	phdr->pd_lower = SizeOfPageHeaderData04 + nused * sizeof(ItemIdData);
  	phdr->pd_upper = upper;
  
  	pfree(itemidbase);
  }
  
+ 
+ 
  /*
   * PageGetItemId
   *		Returns an item identifier of a page.
   */
! ItemId PageGetItemId(Page page, OffsetNumber offsetNumber) 
  {
  	AssertMacro(offsetNumber > 0);
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (ItemId) (& ((PageHeader_04) page)->pd_linp[(offsetNumber) - 1]) ;
! 		case 3 : return (ItemId) (& ((PageHeader_03) page)->pd_linp[(offsetNumber) - 1]) ;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetItemId.");
  }
  
  /*
***************
*** 824,836 ****
  Item PageGetItem(Page page, OffsetNumber offsetNumber) 
  {
  	AssertMacro(PageIsValid(page));
! 	return (Item) (page + ((PageHeader) page)->pd_linp[(offsetNumber) - 1].lp_off);
  }
  
  ItemLength PageItemGetSize(Page page, OffsetNumber offsetNumber)
  {
! 	return (ItemLength)
! 			((PageHeader) page)->pd_linp[(offsetNumber) - 1].lp_len;
  }
  
  IndexTuple PageGetIndexTuple(Page page, OffsetNumber offsetNumber)
--- 870,896 ----
  Item PageGetItem(Page page, OffsetNumber offsetNumber) 
  {
  	AssertMacro(PageIsValid(page));
! //	AssertMacro(ItemIdHasStorage(itemId));
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (Item) (page + 
! 				   ((PageHeader_04) page)->pd_linp[(offsetNumber) - 1].lp_off);
! 		case 3 : return (Item) (page + 
! 				   ((PageHeader_03) page)->pd_linp[(offsetNumber) - 1].lp_off);
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetItem.");
  }
  
  ItemLength PageItemGetSize(Page page, OffsetNumber offsetNumber)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (ItemLength) 
! 					((PageHeader_04) page)->pd_linp[(offsetNumber) - 1].lp_len;
! 		case 3 : return (ItemLength) 
! 					((PageHeader_03) page)->pd_linp[(offsetNumber) - 1].lp_len;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageItemGetSize.");
  }
  
  IndexTuple PageGetIndexTuple(Page page, OffsetNumber offsetNumber)
***************
*** 848,889 ****
  
  bool PageItemIsDead(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsDead(PageGetItemId(page, offsetNumber));
  }
  
  void PageItemMarkDead(Page page, OffsetNumber offsetNumber)
  {
! 	ItemIdMarkDead(PageGetItemId(page, offsetNumber));
  }
  
  bool PageItemIsNormal(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsNormal(PageGetItemId(page, offsetNumber));
  }
  
  bool PageItemIsUsed(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsUsed(PageGetItemId(page, offsetNumber));
  }
  
  void PageItemSetUnused(Page page, OffsetNumber offsetNumber)
  {
! 	ItemIdSetUnused(PageGetItemId(page, offsetNumber));
  }
  
  bool PageItemIsRedirected(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsRedirected(PageGetItemId(page, offsetNumber));
  }
  
  OffsetNumber PageItemGetRedirect(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdGetRedirect(PageGetItemId(page, offsetNumber));
  }
  
  void PageItemSetRedirect(Page page, OffsetNumber fromoff, OffsetNumber tooff)
  {
! 	ItemIdSetRedirect( PageGetItemId(page, fromoff), tooff);
  }
  
  void PageItemMove(Page page, OffsetNumber dstoff, OffsetNumber srcoff)
--- 908,949 ----
  
  bool PageItemIsDead(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsDead(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  void PageItemMarkDead(Page page, OffsetNumber offsetNumber)
  {
! 	ItemIdMarkDead(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  bool PageItemIsNormal(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsNormal(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  bool PageItemIsUsed(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsUsed(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  void PageItemSetUnused(Page page, OffsetNumber offsetNumber)
  {
! 	ItemIdSetUnused(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  bool PageItemIsRedirected(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdIsRedirected(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  OffsetNumber PageItemGetRedirect(Page page, OffsetNumber offsetNumber)
  {
!   return ItemIdGetRedirect(PageGetItemId(page, offsetNumber)); // TODO multi version
  }
  
  void PageItemSetRedirect(Page page, OffsetNumber fromoff, OffsetNumber tooff)
  {
! 	ItemIdSetRedirect(PageGetItemId(page, fromoff), tooff); // TODO multi version
  }
  
  void PageItemMove(Page page, OffsetNumber dstoff, OffsetNumber srcoff)
***************
*** 900,906 ****
   */
  Pointer PageGetContents(Page page)
  {
! 	return (Pointer) (&((PageHeader) (page))->pd_linp[0]);
  }
  
  /* ----------------
--- 960,971 ----
   */
  Pointer PageGetContents(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (Pointer) (&((PageHeader_04) (page))->pd_linp[0]);
! 		case 3 : return (Pointer) (&((PageHeader_03) (page))->pd_linp[0]);
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetContents.");
  }
  
  /* ----------------
***************
*** 913,924 ****
   */
  Size PageGetSpecialSize(Page page)
  {
! 	return (Size) PageGetPageSize(page) - ((PageHeader)(page))->pd_special;
  }
  
  Size PageGetDataSize(Page page)
  {
! 	return (Size) ((PageHeader)(page))->pd_special - ((PageHeader)(page))->pd_upper;
  }
  
  /*
--- 978,1000 ----
   */
  Size PageGetSpecialSize(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (Size) PageGetPageSize(page) - ((PageHeader_04)(page))->pd_special;
! 		case 3 : return (Size) PageGetPageSize(page) - ((PageHeader_03)(page))->pd_special;
! 
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetSpecialSize.");
  }
  
  Size PageGetDataSize(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (Size) ((PageHeader_04)(page))->pd_special - ((PageHeader_04)(page))->pd_upper;
! 		case 3 : return (Size) ((PageHeader_03)(page))->pd_special - ((PageHeader_03)(page))->pd_upper;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetDataSize.");
  }
  
  /*
***************
*** 928,934 ****
  Pointer PageGetSpecialPointer(Page page)
  { 
  	AssertMacro(PageIsValid(page));
! 	return page + ((PageHeader)(page))->pd_special;
  }
  
  /*
--- 1004,1015 ----
  Pointer PageGetSpecialPointer(Page page)
  { 
  	AssertMacro(PageIsValid(page));
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return page + ((PageHeader_04)(page))->pd_special;
! 		case 3 : return page + ((PageHeader_03)(page))->pd_special;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetSpecialPointer.");
  }
  
  /*
***************
*** 938,970 ****
  Pointer PageGetUpperPointer(Page page)
  {
  	AssertMacro(PageIsValid(page));
! 	return page + ((PageHeader)(page))->pd_upper;
  }
  
  void PageSetLower(Page page, LocationIndex lower)
  {
! 	((PageHeader) page)->pd_lower = lower;
  }
  
  void PageSetUpper(Page page, LocationIndex upper)
  {
! 	((PageHeader) page)->pd_upper = upper;
  }
  
  void PageReserveLinp(Page page)
  {
  	AssertMacro(PageIsValid(page));
! 	((PageHeader) page)->pd_lower += sizeof(ItemIdData);
! 	AssertMacro(((PageHeader) page)->pd_lower <= ((PageHeader) page)->pd_upper );
  }
  
  void PageReleaseLinp(Page page)
  {
  	AssertMacro(PageIsValid(page));
! 	((PageHeader) page)->pd_lower -= sizeof(ItemIdData);
! 	AssertMacro(((PageHeader) page)->pd_lower >= SizeOfPageHeaderData);
  }
  
  /*
   * PageGetMaxOffsetNumber
   *		Returns the maximum offset number used by the given page.
--- 1019,1087 ----
  Pointer PageGetUpperPointer(Page page)
  {
  	AssertMacro(PageIsValid(page));
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return page + ((PageHeader_04)(page))->pd_upper;
! 		case 3 : return page + ((PageHeader_03)(page))->pd_upper;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetUpperPointer.");
  }
  
  void PageSetLower(Page page, LocationIndex lower)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) page)->pd_lower = lower;
! 				break;
! 		case 3 : ((PageHeader_03) page)->pd_lower = lower;
! 				break;
! 		default:  elog(PANIC, "Unsupported page layout in function PageSetLower.");
! 	}		  
  }
  
  void PageSetUpper(Page page, LocationIndex upper)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) page)->pd_upper = upper;
! 				break;
! 		case 3 : ((PageHeader_03) page)->pd_upper = upper;
! 				break;
! 		default:  elog(PANIC, "Unsupported page layout in function PageSetLower.");
! 	}		  
  }
  
  void PageReserveLinp(Page page)
  {
  	AssertMacro(PageIsValid(page));
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) page)->pd_lower += sizeof(ItemIdData);
! 				AssertMacro(((PageHeader_04) page)->pd_lower <= ((PageHeader_04) page)->pd_upper );
! 				break;
! 		case 3 : ((PageHeader_03) page)->pd_lower += sizeof(ItemIdData);
! 				AssertMacro(((PageHeader_03) page)->pd_lower <= ((PageHeader_03) page)->pd_upper );
! 				break;
! 		default: elog(PANIC, "Unsupported page layout in function PageReserveLinp.");
! 	}
  }
  
  void PageReleaseLinp(Page page)
  {
  	AssertMacro(PageIsValid(page));
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) page)->pd_lower -= sizeof(ItemIdData);
! 				AssertMacro(((PageHeader_04) page)->pd_lower >= SizeOfPageHeaderData04);
! 				break;
! 		case 3 : ((PageHeader_03) page)->pd_lower -= sizeof(ItemIdData);
! 				AssertMacro(((PageHeader_03) page)->pd_lower >= SizeOfPageHeaderData03);
! 				break;
! 		default: elog(PANIC, "Unsupported page layout in function PageReleaseLinp.");
! 	}
  }
  
+ 
  /*
   * PageGetMaxOffsetNumber
   *		Returns the maximum offset number used by the given page.
***************
*** 977,985 ****
   */
  int PageGetMaxOffsetNumber(Page page)
  {
! 	PageHeader header = (PageHeader) (page);
! 	return header->pd_lower <= SizeOfPageHeaderData ? 0 :
! 		 	(header->pd_lower - SizeOfPageHeaderData) / sizeof(ItemIdData);
  }
  
  /*
--- 1094,1115 ----
   */
  int PageGetMaxOffsetNumber(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : {
! 					PageHeader_04 header = (PageHeader_04) (page);
! 				 	return header->pd_lower <= SizeOfPageHeaderData04 ? 0 :
! 				 	(header->pd_lower - SizeOfPageHeaderData04) / sizeof(ItemIdData);
! 				 }
! 		case 3 : {
! 					PageHeader_03 header = (PageHeader_03) (page);
! 				 	return header->pd_lower <= SizeOfPageHeaderData03 ? 0 :
! 				 	(header->pd_lower - SizeOfPageHeaderData03) / sizeof(ItemIdData);
! 				 }
! 
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetMaxOffsetNumber. (%i)", PageGetPageLayoutVersion(page) );
! 	return 0;
  }
  
  /*
***************
*** 987,1089 ****
   */
  XLogRecPtr PageGetLSN(Page page) 
  {
! 	return ((PageHeader) page)->pd_lsn;
  }
  
  LocationIndex PageGetLower(Page page)
  {
! 	return ((PageHeader) page)->pd_lower;
  }
  
  LocationIndex PageGetUpper(Page page)
  {
! 	return ((PageHeader) page)->pd_upper;
  }
  
  LocationIndex PageGetSpecial(Page page)
  {
! 	return ((PageHeader) page)->pd_special;
  }
  
  void PageSetLSN(Page page, XLogRecPtr lsn)
  {
! 	((PageHeader) page)->pd_lsn = lsn;
  }
  
  /* NOTE: only the 16 least significant bits are stored */
  TimeLineID PageGetTLI(Page page)
  {
! 	return ((PageHeader) (page))->pd_tli;
  }
  
  void PageSetTLI(Page page, TimeLineID tli)
  {
! 	((PageHeader) (page))->pd_tli = (uint16) (tli);
  }
  
  bool PageHasFreeLinePointers(Page page)
  {
! 	return ((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES;
  }
  
  void PageSetHasFreeLinePointers(Page page)
  {
! 	((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES;
  }
  
  void PageClearHasFreeLinePointers(Page page)
  {
! 	((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES;
  }
  
  bool PageIsFull(Page page)
  {
! 	return ((PageHeader) (page))->pd_flags & PD_PAGE_FULL;
  }
  
  void PageSetFull(Page page)
  {
! 	((PageHeader) (page))->pd_flags |= PD_PAGE_FULL;
  }
  
  
  void PageClearFull(Page page)
  {
! 	((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL;
  }		
  
  bool PageIsPrunable(Page page, TransactionId oldestxmin)
  {
  	AssertMacro(TransactionIdIsNormal(oldestxmin));
! 	return ( 
! 			TransactionIdIsValid(((PageHeader) page)->pd_prune_xid) && 
! 			TransactionIdPrecedes(((PageHeader) page)->pd_prune_xid, oldestxmin) );
  }
  
  TransactionId PageGetPrunable(Page page)
  {
! 	return ((PageHeader) page)->pd_prune_xid;
  }
  
  void PageSetPrunable(Page page, TransactionId xid)
  {
  	Assert(TransactionIdIsNormal(xid));
! 	if (!TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) ||
! 				TransactionIdPrecedes(xid, ((PageHeader) (page))->pd_prune_xid)) 
! 				((PageHeader) (page))->pd_prune_xid = (xid); 
  }
  
  void PageClearPrunable(Page page)
  {
! 	((PageHeader) page)->pd_prune_xid = InvalidTransactionId;
  }
  
  bool PageIsComprimable(Page page)
  {
! 	PageHeader ph = (PageHeader) page;
! 	return(ph->pd_lower >= SizeOfPageHeaderData &&
! 			ph->pd_upper > ph->pd_lower &&
! 			ph->pd_upper <= BLCKSZ);
  }
  
  /*
--- 1117,1335 ----
   */
  XLogRecPtr PageGetLSN(Page page) 
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) page)->pd_lsn;
! 		case 3 : return ((PageHeader_03) page)->pd_lsn;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetLSN.");
  }
  
  LocationIndex PageGetLower(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) page)->pd_lower;
! 		case 3 : return ((PageHeader_03) page)->pd_lower;
! 		case 0 : return 0;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetLower.");
! 	return 0;
  }
  
  LocationIndex PageGetUpper(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) page)->pd_upper;
! 		case 3 : return ((PageHeader_03) page)->pd_upper;
! 		case 0 : return 0;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetUpper.");
! 	return 0;
  }
  
  LocationIndex PageGetSpecial(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) page)->pd_special;
! 		case 3 : return ((PageHeader_03) page)->pd_special;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetUpper.");
! 	return 0;
  }
  
+ 
  void PageSetLSN(Page page, XLogRecPtr lsn)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{	
! 		case 4 : ((PageHeader_04) page)->pd_lsn = lsn;
! 				break;
! 		case 3 : ((PageHeader_03) page)->pd_lsn = lsn;
! 				break;
! 		default: elog(PANIC, "Unsupported page layout in function PageSetLSN.");
! 	}	
  }
  
  /* NOTE: only the 16 least significant bits are stored */
  TimeLineID PageGetTLI(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) (page))->pd_tli;
! 		case 3 : return ((PageHeader_03) (page))->pd_tli;
! 	}
! 	elog(PANIC, "Unsupported page layout in function PageGetTLI.");
  }
  
  void PageSetTLI(Page page, TimeLineID tli)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) (page))->pd_tli = (uint16) (tli);
! 				break;
! 		case 3 : ((PageHeader_03) (page))->pd_tli = tli;
! 				break;
! 		default: elog(PANIC, "Unsupported page layout in function PageSetTLI.");
! 	}	
  }
  
  bool PageHasFreeLinePointers(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) (page))->pd_flags & PD_HAS_FREE_LINES;
! 		default: return false;
! 	}
  }
  
  void PageSetHasFreeLinePointers(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) (page))->pd_flags |= PD_HAS_FREE_LINES;
! 				 break;
! 		default: elog(PANIC, "HasFreeLinePointers is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));
! 	}
  }
  
  void PageClearHasFreeLinePointers(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) (page))->pd_flags &= ~PD_HAS_FREE_LINES;
! 				  break;
! 		default: elog(PANIC, "HasFreeLinePointers is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));
! 	}	
  }
  
  bool PageIsFull(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) (page))->pd_flags & PD_PAGE_FULL;
! 		default : return true;
! 	}
! 	return true; /* no space on old data page */
  }
  
  void PageSetFull(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) (page))->pd_flags |= PD_PAGE_FULL;
! 				  break;
! 		default: elog(PANIC, "PageSetFull is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));
! 	}
  }
  
  
  void PageClearFull(Page page)
  {
! 	switch( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) (page))->pd_flags &= ~PD_PAGE_FULL;
! 				  break;
! 		default: elog(PANIC, "PageClearFull is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));
! 	}
  }		
  
  bool PageIsPrunable(Page page, TransactionId oldestxmin)
  {
  	AssertMacro(TransactionIdIsNormal(oldestxmin));
! 	switch( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ( 
! 			TransactionIdIsValid(((PageHeader_04) page)->pd_prune_xid) && 
! 			TransactionIdPrecedes(((PageHeader_04) page)->pd_prune_xid, oldestxmin) );
! 		case 3 : return false;
! 	}
! 	elog(PANIC, "PageIsPrunable is not supported on page layout version %i",
! 		PageGetPageLayoutVersion(page));	
  }
  
  TransactionId PageGetPrunable(Page page)
  {
! 	switch( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return ((PageHeader_04) page)->pd_prune_xid;
! 		case 3 : return 0;
! 	}
! 	elog(PANIC, "PageGetPrunable is not supported on page layout version %i",
! 		PageGetPageLayoutVersion(page));	
  }
  
  void PageSetPrunable(Page page, TransactionId xid)
  {
  	Assert(TransactionIdIsNormal(xid));
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : if (!TransactionIdIsValid(((PageHeader_04) (page))->pd_prune_xid) ||
! 				TransactionIdPrecedes(xid, ((PageHeader_04) (page))->pd_prune_xid)) 
! 				((PageHeader_04) (page))->pd_prune_xid = (xid); 
! 				break;
! 		default: elog(PANIC, "PageSetPrunable is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));
! 	}
  }
  
  void PageClearPrunable(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : ((PageHeader_04) page)->pd_prune_xid = InvalidTransactionId;
! 				break;
! //		default: elog(PANIC, "PageClearPrunable is not supported on page layout version %i",
! //				PageGetPageLayoutVersion(page));		
! //	Silently ignore this request
! 	}
  }
  
  bool PageIsComprimable(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : { 
! 					PageHeader_04 ph = (PageHeader_04) page;
! 					return(ph->pd_lower >= SizeOfPageHeaderData04 &&
! 						ph->pd_upper > ph->pd_lower &&
! 						ph->pd_upper <= BLCKSZ);
! 				  }
! 		case 3 : { 
! 					PageHeader_03 ph = (PageHeader_03) page;
! 					return(ph->pd_lower >= SizeOfPageHeaderData03 &&
! 						ph->pd_upper > ph->pd_lower &&
! 						ph->pd_upper <= BLCKSZ);
! 				  }
! 		default: elog(PANIC, "PageIsComprimable is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));		
! 	}
  }
  
  /*
***************
*** 1092,1097 ****
   */
  bool PageIsEmpty(Page page)
  {
! 	return (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData);
  }
  
--- 1338,1349 ----
   */
  bool PageIsEmpty(Page page)
  {
! 	switch ( PageGetPageLayoutVersion(page) )
! 	{
! 		case 4 : return (((PageHeader_04) (page))->pd_lower <= SizeOfPageHeaderData04);
! 		case 3 : return (((PageHeader_04) (page))->pd_lower <= SizeOfPageHeaderData03);
! 		default: elog(PANIC, "PageIsEmpty is not supported on page layout version %i",
! 				PageGetPageLayoutVersion(page));		
! 	}
  }
  
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/access/gin.h pgsql_master_upgrade.13a47c410da7/src/include/access/gin.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/access/gin.h	2008-10-31 21:45:33.172329319 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/access/gin.h	2008-10-31 21:45:33.265898951 +0100
***************
*** 115,121 ****
  #define GinGetPosting(itup)			( (ItemPointer)(( ((char*)(itup)) + SHORTALIGN(GinGetOrigSizePosting(itup)) )) )
  
  #define GinMaxItemSize \
! 	((BLCKSZ - SizeOfPageHeaderData - \
  		MAXALIGN(sizeof(GinPageOpaqueData))) / 3 - sizeof(ItemIdData))
  
  
--- 115,121 ----
  #define GinGetPosting(itup)			( (ItemPointer)(( ((char*)(itup)) + SHORTALIGN(GinGetOrigSizePosting(itup)) )) )
  
  #define GinMaxItemSize \
! 	((BLCKSZ - SizeOfPageHeaderData04 - \
  		MAXALIGN(sizeof(GinPageOpaqueData))) / 3 - sizeof(ItemIdData))
  
  
***************
*** 131,137 ****
  	(GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page))
  
  #define GinDataPageGetFreeSpace(page)	\
! 	(BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \
  	 - MAXALIGN(sizeof(ItemPointerData)) \
  	 - GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) \
  	 - MAXALIGN(sizeof(GinPageOpaqueData)))
--- 131,137 ----
  	(GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page))
  
  #define GinDataPageGetFreeSpace(page)	\
! 	(BLCKSZ - MAXALIGN(SizeOfPageHeaderData04) \
  	 - MAXALIGN(sizeof(ItemPointerData)) \
  	 - GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) \
  	 - MAXALIGN(sizeof(GinPageOpaqueData)))
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/access/gist_private.h pgsql_master_upgrade.13a47c410da7/src/include/access/gist_private.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/access/gist_private.h	2008-10-31 21:45:33.176541012 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/access/gist_private.h	2008-10-31 21:45:33.270105878 +0100
***************
*** 272,278 ****
  /* gistutil.c */
  
  #define GiSTPageSize   \
! 	( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GISTPageOpaqueData)) )
  
  #define GIST_MIN_FILLFACTOR			10
  #define GIST_DEFAULT_FILLFACTOR		90
--- 272,278 ----
  /* gistutil.c */
  
  #define GiSTPageSize   \
! 	( BLCKSZ - SizeOfPageHeaderData04 - MAXALIGN(sizeof(GISTPageOpaqueData)) )
  
  #define GIST_MIN_FILLFACTOR			10
  #define GIST_DEFAULT_FILLFACTOR		90
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/access/hash.h pgsql_master_upgrade.13a47c410da7/src/include/access/hash.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/access/hash.h	2008-10-31 21:45:33.180773015 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/access/hash.h	2008-10-31 21:45:33.274260668 +0100
***************
*** 168,174 ****
   */
  #define HashMaxItemSize(page) \
  	MAXALIGN_DOWN(PageGetPageSize(page) - \
! 				  SizeOfPageHeaderData - \
  				  sizeof(ItemIdData) - \
  				  MAXALIGN(sizeof(HashPageOpaqueData)))
  
--- 168,174 ----
   */
  #define HashMaxItemSize(page) \
  	MAXALIGN_DOWN(PageGetPageSize(page) - \
! 				  SizeOfPageHeaderData04 - \
  				  sizeof(ItemIdData) - \
  				  MAXALIGN(sizeof(HashPageOpaqueData)))
  
***************
*** 198,204 ****
  
  #define HashGetMaxBitmapSize(page) \
  	(PageGetPageSize((Page) page) - \
! 	 (MAXALIGN(SizeOfPageHeaderData) + MAXALIGN(sizeof(HashPageOpaqueData))))
  
  #define HashPageGetMeta(page) \
  	((HashMetaPage) PageGetContents(page))
--- 198,204 ----
  
  #define HashGetMaxBitmapSize(page) \
  	(PageGetPageSize((Page) page) - \
! 	 (MAXALIGN(SizeOfPageHeaderData04) + MAXALIGN(sizeof(HashPageOpaqueData))))
  
  #define HashPageGetMeta(page) \
  	((HashMetaPage) PageGetContents(page))
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/access/htup_03.h pgsql_master_upgrade.13a47c410da7/src/include/access/htup_03.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/access/htup_03.h	1970-01-01 01:00:00.000000000 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/access/htup_03.h	2008-10-31 21:45:33.282414095 +0100
***************
*** 0 ****
--- 1,311 ----
+ /*-------------------------------------------------------------------------
+  *
+  * htup.h
+  *	  POSTGRES heap tuple definitions.
+  *
+  *
+  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.87 2006/11/05 22:42:10 tgl Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef HTUP_03_H
+ #define HTUP_03_H
+ 
+ #include "access/htup.h"
+ #include "storage/itemptr.h"
+ #include "storage/relfilenode.h"
+ #include "utils/rel.h"
+ 
+ /*
+  * Heap tuple header.  To avoid wasting space, the fields should be
+  * layed out in such a way to avoid structure padding.
+  *
+  * Datums of composite types (row types) share the same general structure
+  * as on-disk tuples, so that the same routines can be used to build and
+  * examine them.  However the requirements are slightly different: a Datum
+  * does not need any transaction visibility information, and it does need
+  * a length word and some embedded type information.  We can achieve this
+  * by overlaying the xmin/cmin/xmax/cmax/xvac fields of a heap tuple
+  * with the fields needed in the Datum case.  Typically, all tuples built
+  * in-memory will be initialized with the Datum fields; but when a tuple is
+  * about to be inserted in a table, the transaction fields will be filled,
+  * overwriting the datum fields.
+  *
+  * The overall structure of a heap tuple looks like:
+  *			fixed fields (HeapTupleHeaderData struct)
+  *			nulls bitmap (if HEAP_HASNULL is set in t_infomask)
+  *			alignment padding (as needed to make user data MAXALIGN'd)
+  *			object ID (if HEAP_HASOID is set in t_infomask)
+  *			user data fields
+  *
+  * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in four
+  * physical fields.  Xmin, Cmin and Xmax are always really stored, but
+  * Cmax and Xvac share a field.  This works because we know that there are
+  * only a limited number of states that a tuple can be in, and that Cmax
+  * is only interesting for the lifetime of the deleting transaction.
+  * This assumes that VACUUM FULL never tries to move a tuple whose Cmax
+  * is still interesting (ie, delete-in-progress).
+  *
+  * Note that in 7.3 and 7.4 a similar idea was applied to Xmax and Cmin.
+  * However, with the advent of subtransactions, a tuple may need both Xmax
+  * and Cmin simultaneously, so this is no longer possible.
+  *
+  * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid
+  * is initialized with its own TID (location).	If the tuple is ever updated,
+  * its t_ctid is changed to point to the replacement version of the tuple.
+  * Thus, a tuple is the latest version of its row iff XMAX is invalid or
+  * t_ctid points to itself (in which case, if XMAX is valid, the tuple is
+  * either locked or deleted).  One can follow the chain of t_ctid links
+  * to find the newest version of the row.  Beware however that VACUUM might
+  * erase the pointed-to (newer) tuple before erasing the pointing (older)
+  * tuple.  Hence, when following a t_ctid link, it is necessary to check
+  * to see if the referenced slot is empty or contains an unrelated tuple.
+  * Check that the referenced tuple has XMIN equal to the referencing tuple's
+  * XMAX to verify that it is actually the descendant version and not an
+  * unrelated tuple stored into a slot recently freed by VACUUM.  If either
+  * check fails, one may assume that there is no live descendant version.
+  *
+  * Following the fixed header fields, the nulls bitmap is stored (beginning
+  * at t_bits).	The bitmap is *not* stored if t_infomask shows that there
+  * are no nulls in the tuple.  If an OID field is present (as indicated by
+  * t_infomask), then it is stored just before the user data, which begins at
+  * the offset shown by t_hoff.	Note that t_hoff must be a multiple of
+  * MAXALIGN.
+  */
+ 
+ typedef struct HeapTupleFields_03
+ {
+ 	TransactionId t_xmin;		/* inserting xact ID */
+ 	CommandId	t_cmin;			/* inserting command ID */
+ 	TransactionId t_xmax;		/* deleting or locking xact ID */
+ 
+ 	union
+ 	{
+ 		CommandId	t_cmax;		/* deleting or locking command ID */
+ 		TransactionId t_xvac;	/* VACUUM FULL xact ID */
+ 	}			t_field4;
+ } HeapTupleFields_03;
+ 
+ typedef struct DatumTupleFields_03
+ {
+ 	int32		datum_len;		/* required to be a varlena type */
+ 
+ 	int32		datum_typmod;	/* -1, or identifier of a record type */
+ 
+ 	Oid			datum_typeid;	/* composite type OID, or RECORDOID */
+ 
+ 	/*
+ 	 * Note: field ordering is chosen with thought that Oid might someday
+ 	 * widen to 64 bits.
+ 	 */
+ } DatumTupleFields_03;
+ 
+ typedef struct HeapTupleHeaderData_03
+ {
+ 	union
+ 	{
+ 		HeapTupleFields_03 t_heap;
+ 		DatumTupleFields_03 t_datum;
+ 	}			t_choice;
+ 
+ 	ItemPointerData t_ctid;		/* current TID of this or newer tuple */
+ 
+ 	/* Fields below here must match MinimalTupleData! */
+ 
+ 	int16		t_natts;		/* number of attributes */
+ 
+ 	uint16		t_infomask;		/* various flag bits, see below */
+ 
+ 	uint8		t_hoff;			/* sizeof header incl. bitmap, padding */
+ 
+ 	/* ^ - 27 bytes - ^ */
+ 
+ 	bits8		t_bits[1];		/* bitmap of NULLs -- VARIABLE LENGTH */
+ 
+ 	/* MORE DATA FOLLOWS AT END OF STRUCT */
+ } HeapTupleHeaderData_03;
+ 
+ typedef HeapTupleHeaderData_03 *HeapTupleHeader_03;
+ 
+ /*
+  * information stored in t_infomask:
+  */
+ #define HEAP03_HASNULL			0x0001	/* has null attribute(s) */
+ #define HEAP03_HASVARWIDTH		0x0002	/* has variable-width attribute(s) */
+ #define HEAP03_HASEXTERNAL		0x0004	/* has external stored attribute(s) */
+ #define HEAP03_HASCOMPRESSED	0x0008	/* has compressed stored attribute(s) */
+ #define HEAP03_HASEXTENDED		0x000C	/* the two above combined */
+ #define HEAP03_HASOID			0x0010	/* has an object-id field */
+ /* 0x0020 is presently unused */
+ #define HEAP03_XMAX_EXCL_LOCK	0x0040	/* xmax is exclusive locker */
+ #define HEAP03_XMAX_SHARED_LOCK	0x0080	/* xmax is shared locker */
+ /* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */
+ #define HEAP03_IS_LOCKED	(HEAP03_XMAX_EXCL_LOCK | HEAP03_XMAX_SHARED_LOCK)
+ #define HEAP03_XMIN_COMMITTED	0x0100	/* t_xmin committed */
+ #define HEAP03_XMIN_INVALID		0x0200	/* t_xmin invalid/aborted */
+ #define HEAP03_XMAX_COMMITTED	0x0400	/* t_xmax committed */
+ #define HEAP03_XMAX_INVALID		0x0800	/* t_xmax invalid/aborted */
+ #define HEAP03_XMAX_IS_MULTI	0x1000	/* t_xmax is a MultiXactId */
+ #define HEAP03_UPDATED			0x2000	/* this is UPDATEd version of row */
+ #define HEAP03_MOVED_OFF		0x4000	/* moved to another place by VACUUM
+ 										 * FULL */
+ #define HEAP03_MOVED_IN			0x8000	/* moved from another place by VACUUM
+ 										 * FULL */
+ #define HEAP03_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)
+ 
+ #define HEAP03_XACT_MASK			0xFFC0	/* visibility-related bits */
+ 
+ 
+ /*
+  * HeapTupleHeader accessor macros
+  *
+  * Note: beware of multiple evaluations of "tup" argument.	But the Set
+  * macros evaluate their other argument only once.
+  */
+ /*
+ #define HeapTupleHeaderGetXmin(tup) \
+ ( \
+ 	(tup)->t_choice.t_heap.t_xmin \
+ )
+ 
+ #define HeapTupleHeaderSetXmin(tup, xid) \
+ ( \
+ 	TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_xmin) \
+ )
+ 
+ #define HeapTupleHeaderGetXmax(tup) \
+ ( \
+ 	(tup)->t_choice.t_heap.t_xmax \
+ )
+ 
+ #define HeapTupleHeaderSetXmax(tup, xid) \
+ ( \
+ 	TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_xmax) \
+ )
+ 
+ #define HeapTupleHeaderGetCmin(tup) \
+ ( \
+ 	(tup)->t_choice.t_heap.t_cmin \
+ )
+ 
+ #define HeapTupleHeaderSetCmin(tup, cid) \
+ ( \
+ 	(tup)->t_choice.t_heap.t_cmin = (cid) \
+ )
+ */
+ /*
+  * Note: GetCmax will produce wrong answers after SetXvac has been executed
+  * by a transaction other than the inserting one.  We could check
+  * HEAP_XMAX_INVALID and return FirstCommandId if it's clear, but since that
+  * bit will be set again if the deleting transaction aborts, there'd be no
+  * real gain in safety from the extra test.  So, just rely on the caller not
+  * to trust the value unless it's meaningful.
+  */
+ /*
+ #define HeapTupleHeaderGetCmax(tup) \
+ ( \
+ 	(tup)->t_choice.t_heap.t_field4.t_cmax \
+ )
+ 
+ #define HeapTupleHeaderSetCmax(tup, cid) \
+ do { \
+ 	Assert(!((tup)->t_infomask & HEAP_MOVED)); \
+ 	(tup)->t_choice.t_heap.t_field4.t_cmax = (cid); \
+ } while (0)
+ 
+ #define HeapTupleHeaderGetXvac(tup) \
+ ( \
+ 	((tup)->t_infomask & HEAP_MOVED) ? \
+ 		(tup)->t_choice.t_heap.t_field4.t_xvac \
+ 	: \
+ 		InvalidTransactionId \
+ )
+ 
+ #define HeapTupleHeaderSetXvac(tup, xid) \
+ do { \
+ 	Assert((tup)->t_infomask & HEAP_MOVED); \
+ 	TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_field4.t_xvac); \
+ } while (0)
+ 
+ #define HeapTupleHeaderGetDatumLength(tup) \
+ ( \
+ 	(tup)->t_choice.t_datum.datum_len \
+ )
+ 
+ #define HeapTupleHeaderSetDatumLength(tup, len) \
+ ( \
+ 	(tup)->t_choice.t_datum.datum_len = (len) \
+ )
+ 
+ #define HeapTupleHeaderGetTypeId(tup) \
+ ( \
+ 	(tup)->t_choice.t_datum.datum_typeid \
+ )
+ 
+ #define HeapTupleHeaderSetTypeId(tup, typeid) \
+ ( \
+ 	(tup)->t_choice.t_datum.datum_typeid = (typeid) \
+ )
+ 
+ #define HeapTupleHeaderGetTypMod(tup) \
+ ( \
+ 	(tup)->t_choice.t_datum.datum_typmod \
+ )
+ 
+ #define HeapTupleHeaderSetTypMod(tup, typmod) \
+ ( \
+ 	(tup)->t_choice.t_datum.datum_typmod = (typmod) \
+ )
+ 
+ #define HeapTupleHeaderGetOid(tup) \
+ ( \
+ 	((tup)->t_infomask & HEAP_HASOID) ? \
+ 		*((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \
+ 	: \
+ 		InvalidOid \
+ )
+ 
+ #define HeapTupleHeaderSetOid(tup, oid) \
+ do { \
+ 	Assert((tup)->t_infomask & HEAP_HASOID); \
+ 	*((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \
+ } while (0)
+ 
+ */
+ /*
+  * BITMAPLEN(NATTS) -
+  *		Computes size of null bitmap given number of data columns.
+  */
+ //#define BITMAPLEN(NATTS)	(((int)(NATTS) + 7) / 8)
+ 
+ /*
+  * MaxTupleSize is the maximum allowed size of a tuple, including header and
+  * MAXALIGN alignment padding.	Basically it's BLCKSZ minus the other stuff
+  * that has to be on a disk page.  The "other stuff" includes access-method-
+  * dependent "special space", which we assume will be no more than
+  * MaxSpecialSpace bytes (currently, on heap pages it's actually zero).
+  *
+  * NOTE: we do not need to count an ItemId for the tuple because
+  * sizeof(PageHeaderData) includes the first ItemId on the page.
+  */
+ //#define MaxSpecialSpace  32
+ 
+ //#define MaxTupleSize	\
+ //	(BLCKSZ - MAXALIGN(sizeof(PageHeaderData) + MaxSpecialSpace))
+ 
+ /*
+  * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
+  * fit on one heap page.  (Note that indexes could have more, because they
+  * use a smaller tuple header.)  We arrive at the divisor because each tuple
+  * must be maxaligned, and it must have an associated item pointer.
+  */
+ //#define MaxHeapTuplesPerPage	\
+ //	((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
+ //			(MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
+ 
+ extern HeapTuple heap_tuple_upgrade_03(Relation rel, HeapTuple tuple);
+ 
+ #endif   /* HTUP_H */
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/access/tuplimits.h pgsql_master_upgrade.13a47c410da7/src/include/access/tuplimits.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/access/tuplimits.h	2008-10-31 21:45:33.181679309 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/access/tuplimits.h	2008-10-31 21:45:33.275179286 +0100
***************
*** 29,35 ****
   * ItemIds and tuples have different alignment requirements, don't assume that
   * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData)))
  
  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 29,35 ----
   * ItemIds and tuples have different alignment requirements, don't assume that
   * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(SizeOfPageHeaderData04 + sizeof(ItemIdData)))
  
  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 43,49 ****
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage	\
! 	((int) ((BLCKSZ - SizeOfPageHeaderData) / \
  			(MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
  
  
--- 43,49 ----
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage	\
! 	((int) ((BLCKSZ - SizeOfPageHeaderData04) / \
  			(MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
  
  
***************
*** 55,61 ****
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage	\
! 	((int) ((BLCKSZ - SizeOfPageHeaderData) / \
  			(MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
  
  /*
--- 55,61 ----
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage	\
! 	((int) ((BLCKSZ - SizeOfPageHeaderData04) / \
  			(MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
  
  /*
***************
*** 66,72 ****
   */
  #define BTMaxItemSize(page) \
  	MAXALIGN_DOWN((PageGetPageSize(page) - \
! 				   MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
  				   MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
  
  
--- 66,72 ----
   */
  #define BTMaxItemSize(page) \
  	MAXALIGN_DOWN((PageGetPageSize(page) - \
! 				   MAXALIGN(SizeOfPageHeaderData04 + 3*sizeof(ItemIdData)) - \
  				   MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
  
  
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/access/tuptoaster.h pgsql_master_upgrade.13a47c410da7/src/include/access/tuptoaster.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/access/tuptoaster.h	2008-10-31 21:45:33.183208112 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/access/tuptoaster.h	2008-10-31 21:45:33.276709073 +0100
***************
*** 49,55 ****
  
  #define TOAST_TUPLE_THRESHOLD	\
  	MAXALIGN_DOWN((BLCKSZ - \
! 				   MAXALIGN(SizeOfPageHeaderData + TOAST_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
  				  / TOAST_TUPLES_PER_PAGE)
  
  #define TOAST_TUPLE_TARGET		TOAST_TUPLE_THRESHOLD
--- 49,55 ----
  
  #define TOAST_TUPLE_THRESHOLD	\
  	MAXALIGN_DOWN((BLCKSZ - \
! 				   MAXALIGN(SizeOfPageHeaderData04 + TOAST_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
  				  / TOAST_TUPLES_PER_PAGE)
  
  #define TOAST_TUPLE_TARGET		TOAST_TUPLE_THRESHOLD
***************
*** 75,81 ****
  
  #define EXTERN_TUPLE_MAX_SIZE	\
  	MAXALIGN_DOWN((BLCKSZ - \
! 				   MAXALIGN(SizeOfPageHeaderData + EXTERN_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
  				  / EXTERN_TUPLES_PER_PAGE)
  
  #define TOAST_MAX_CHUNK_SIZE	\
--- 75,81 ----
  
  #define EXTERN_TUPLE_MAX_SIZE	\
  	MAXALIGN_DOWN((BLCKSZ - \
! 				   MAXALIGN(SizeOfPageHeaderData04 + EXTERN_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
  				  / EXTERN_TUPLES_PER_PAGE)
  
  #define TOAST_MAX_CHUNK_SIZE	\
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/storage/bufpage.h pgsql_master_upgrade.13a47c410da7/src/include/storage/bufpage.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/storage/bufpage.h	2008-10-31 21:45:33.185832325 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/storage/bufpage.h	2008-10-31 21:45:33.279178878 +0100
***************
*** 121,127 ****
   * On the high end, we can only support pages up to 32KB because lp_off/lp_len
   * are 15 bits.
   */
! typedef struct PageHeaderData
  {
  	/* XXX LSN is member of *any* block, not only page-organized ones */
  	XLogRecPtr	pd_lsn;			/* LSN: next byte after last byte of xlog
--- 121,127 ----
   * On the high end, we can only support pages up to 32KB because lp_off/lp_len
   * are 15 bits.
   */
! typedef struct PageHeaderData_04
  {
  	/* XXX LSN is member of *any* block, not only page-organized ones */
  	XLogRecPtr	pd_lsn;			/* LSN: next byte after last byte of xlog
***************
*** 135,143 ****
  	uint16		pd_pagesize_version;
  	TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */
  	ItemIdData	pd_linp[1];		/* beginning of line pointer array */
! } PageHeaderData;
  
- typedef PageHeaderData *PageHeader;
  
  /*
   * pd_flags contains the following flag bits.  Undefined bits are initialized
--- 135,160 ----
  	uint16		pd_pagesize_version;
  	TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */
  	ItemIdData	pd_linp[1];		/* beginning of line pointer array */
! } PageHeaderData_04;
! 
! typedef PageHeaderData_04 *PageHeader_04;
! 
! typedef struct PageHeaderData_03
! {
! 	/* XXX LSN is member of *any* block, not only page-organized ones */
! 	XLogRecPtr	pd_lsn;			/* LSN: next byte after last byte of xlog
! 								 * record for last change to this page */
! 	TimeLineID	pd_tli;			/* TLI of last change */
! 	LocationIndex pd_lower;		/* offset to start of free space */
! 	LocationIndex pd_upper;		/* offset to end of free space */
! 	LocationIndex pd_special;	/* offset to start of special space */
! 	uint16		pd_pagesize_version;
! 	ItemIdData	pd_linp[1];		/* beginning of line pointer array */
! } PageHeaderData_03;
! 
! typedef PageHeaderData_03 *PageHeader_03;
! 
  
  
  /*
   * pd_flags contains the following flag bits.  Undefined bits are initialized
***************
*** 181,195 ****
  #define PageIsValid(page) PointerIsValid(page)
  
  /*
!  * line pointer(s) do not count as part of header
   */
! #define SizeOfPageHeaderData (offsetof(PageHeaderData, pd_linp))
  
  /*
   * PageIsNew
   *		returns true iff page has not been initialized (by PageInit)
   */
! #define PageIsNew(page) (((PageHeader) (page))->pd_upper == 0)
  
  /* ----------------
   *		macros to access page size info
--- 198,213 ----
  #define PageIsValid(page) PointerIsValid(page)
  
  /*
!  * line pointer does not count as part of header
   */
! #define SizeOfPageHeaderData04 offsetof(PageHeaderData_04, pd_linp[0])
! #define SizeOfPageHeaderData03 offsetof(PageHeaderData_03, pd_linp[0])
  
  /*
   * PageIsNew
   *		returns true iff page has not been initialized (by PageInit)
   */
! #define PageIsNew(page) (((PageHeader_04) (page))->pd_upper == 0)
  
  /* ----------------
   *		macros to access page size info
***************
*** 211,224 ****
   * however, it can be called on a page that is not stored in a buffer.
   */
  #define PageGetPageSize(page) \
! 	((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00))
  
  /*
   * PageGetPageLayoutVersion
   *		Returns the page layout version of a page.
   */
  #define PageGetPageLayoutVersion(page) \
! 	(((PageHeader) (page))->pd_pagesize_version & 0x00FF)
  
  /*
   * PageSetPageSizeAndVersion
--- 229,242 ----
   * however, it can be called on a page that is not stored in a buffer.
   */
  #define PageGetPageSize(page) \
! 	((Size) (((PageHeader_04) (page))->pd_pagesize_version & (uint16) 0xFF00))
  
  /*
   * PageGetPageLayoutVersion
   *		Returns the page layout version of a page.
   */
  #define PageGetPageLayoutVersion(page) \
! 	(((PageHeader_04) (page))->pd_pagesize_version & 0x00FF)
  
  /*
   * PageSetPageSizeAndVersion
***************
*** 231,239 ****
  ( \
  	AssertMacro(((size) & 0xFF00) == (size)), \
  	AssertMacro(((version) & 0x00FF) == (version)), \
! 	((PageHeader) (page))->pd_pagesize_version = (size) | (version) \
  )
  
  /* ----------------------------------------------------------------
   *		extern declarations
   * ----------------------------------------------------------------
--- 249,259 ----
  ( \
  	AssertMacro(((size) & 0xFF00) == (size)), \
  	AssertMacro(((version) & 0x00FF) == (version)), \
! 	((PageHeader_04) (page))->pd_pagesize_version = (size) | (version) \
  )
  
+ 
+ 
  /* ----------------------------------------------------------------
   *		extern declarations
   * ----------------------------------------------------------------
***************
*** 303,307 ****
--- 323,328 ----
  extern OffsetNumber	PageItemGetRedirect(Page, OffsetNumber offsetNumber);
  
  extern ItemId PageGetItemId(Page page, OffsetNumber offsetNumber);/* do not use it - only for pg_inspect contrib modul */
+   
  
  #endif   /* BUFPAGE_H */
diff -Nrc pgsql_master_upgrade.751eb7c6969f/src/include/storage/fsm_internals.h pgsql_master_upgrade.13a47c410da7/src/include/storage/fsm_internals.h
*** pgsql_master_upgrade.751eb7c6969f/src/include/storage/fsm_internals.h	2008-10-31 21:45:33.186717311 +0100
--- pgsql_master_upgrade.13a47c410da7/src/include/storage/fsm_internals.h	2008-10-31 21:45:33.280068969 +0100
***************
*** 49,55 ****
   * Number of non-leaf and leaf nodes, and nodes in total, on an FSM page.
   * These definitions are internal to fsmpage.c.
   */
! #define NodesPerPage (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - \
  					  offsetof(FSMPageData, fp_nodes))
  
  #define NonLeafNodesPerPage (BLCKSZ / 2 - 1)
--- 49,55 ----
   * Number of non-leaf and leaf nodes, and nodes in total, on an FSM page.
   * These definitions are internal to fsmpage.c.
   */
! #define NodesPerPage (BLCKSZ - MAXALIGN(SizeOfPageHeaderData04) - \
  					  offsetof(FSMPageData, fp_nodes))
  
  #define NonLeafNodesPerPage (BLCKSZ / 2 - 1)
