? toast-main-out-of-line-reluctantly.diff
Index: src/backend/access/heap/tuptoaster.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v
retrieving revision 1.93
diff -c -r1.93 tuptoaster.c
*** src/backend/access/heap/tuptoaster.c	11 Jun 2009 14:48:54 -0000	1.93
--- src/backend/access/heap/tuptoaster.c	11 Jun 2009 23:47:09 -0000
***************
*** 798,803 ****
--- 798,804 ----
  	/*
  	 * Finally we store attributes of type 'm' external, if possible.
  	 */
+ 	maxDataLen = TOAST_TUPLE_TARGET_MAIN - hoff;
  	while (heap_compute_data_size(tupleDesc,
  								  toast_values, toast_isnull) > maxDataLen &&
  		   rel->rd_rel->reltoastrelid != InvalidOid)
Index: src/include/access/tuptoaster.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/tuptoaster.h,v
retrieving revision 1.43
diff -c -r1.43 tuptoaster.h
*** src/include/access/tuptoaster.h	1 Jan 2009 17:23:56 -0000	1.43
--- src/include/access/tuptoaster.h	11 Jun 2009 23:47:09 -0000
***************
*** 27,33 ****
  /*
   * These symbols control toaster activation.  If a tuple is larger than
   * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
!  * TOAST_TUPLE_TARGET bytes.  Both numbers include all tuple header overhead
   * and between-fields alignment padding, but we do *not* consider any
   * end-of-tuple alignment padding; hence the values can be compared directly
   * to a tuple's t_len field.
--- 27,35 ----
  /*
   * These symbols control toaster activation.  If a tuple is larger than
   * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
!  * TOAST_TUPLE_TARGET bytes through compressing compressible fields and
!  * moving moving EXTENDED and EXTERNAL data out-of-line.
!  * Both numbers include all tuple header overhead
   * and between-fields alignment padding, but we do *not* consider any
   * end-of-tuple alignment padding; hence the values can be compared directly
   * to a tuple's t_len field.
***************
*** 39,44 ****
--- 41,52 ----
   * Currently we choose both values to match the largest tuple size for which
   * TOAST_TUPLES_PER_PAGE tuples can fit on a disk page.
   *
+  * We set a separate target for MAIN fields, which we will try to reach by
+  * moving MAIN fields out-of-line only if the above has not already done so.
+  * Since the user is trying to keep the data in-line, it makes sense to set
+  * TOAST_TUPLES_PER_PAGE_MAIN to a lower number (currently 1), which will
+  * result in a larger TOAST_TUPLE_TARGET_MAIN value.
+  *
   * XXX while these can be modified without initdb, some thought needs to be
   * given to needs_toast_table() in toasting.c before unleashing random
   * changes.  Also see LOBLKSIZE in large_object.h, which can *not* be
***************
*** 53,58 ****
--- 61,73 ----
  
  #define TOAST_TUPLE_TARGET		TOAST_TUPLE_THRESHOLD
  
+ #define TOAST_TUPLES_PER_PAGE_MAIN	1
+ 
+ #define TOAST_TUPLE_TARGET_MAIN	\
+ 	MAXALIGN_DOWN((BLCKSZ - \
+ 				   MAXALIGN(SizeOfPageHeaderData + TOAST_TUPLES_PER_PAGE_MAIN * sizeof(ItemIdData))) \
+ 				  / TOAST_TUPLES_PER_PAGE_MAIN)
+ 
  /*
   * If an index value is larger than TOAST_INDEX_TARGET, we will try to
   * compress it (we can't move it out-of-line, however).  Note that this
