Tatsuhito Kasahara wrote:
> Hello.
> 
> I found a bug in contrib/pgstatindex.c to reports a strange value of
> leaf_fragmentation with some cases.
> #Look the following test example.
> 
> In GetBTPageStatistics(),  stat->fragments is not initialized properly
> so that invalid leaf_fragments values are inserted in results.

Right.  Checking that code, it seems btpo.xact is also being incorrectly
handled, is it not?  Incidentally, the return value seems a bit useless.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
Index: pgstatindex.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/contrib/pgstattuple/pgstatindex.c,v
retrieving revision 1.2
diff -c -p -r1.2 pgstatindex.c
*** pgstatindex.c	4 Sep 2006 02:03:04 -0000	1.2
--- pgstatindex.c	9 Mar 2007 03:16:30 -0000
*************** typedef struct BTIndexStat
*** 139,145 ****
   * Collect statistics of single b-tree leaf page
   * -------------------------------------------------
   */
! static bool
  GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat * stat)
  {
  	Page		page = BufferGetPage(buffer);
--- 139,145 ----
   * Collect statistics of single b-tree leaf page
   * -------------------------------------------------
   */
! static void
  GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat * stat)
  {
  	Page		page = BufferGetPage(buffer);
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 154,159 ****
--- 154,160 ----
  	stat->max_avail = BLCKSZ - (BLCKSZ - phdr->pd_special + SizeOfPageHeaderData);
  
  	stat->dead_items = stat->live_items = 0;
+ 	stat->fragments = 0;
  
  	stat->page_size = PageGetPageSize(page);
  
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 161,167 ****
  	if (P_ISDELETED(opaque))
  	{
  		stat->type = 'd';
! 		return true;
  	}
  	else if (P_IGNORE(opaque))
  		stat->type = 'e';
--- 162,169 ----
  	if (P_ISDELETED(opaque))
  	{
  		stat->type = 'd';
! 		stat->btpo.xact = opaque->btpo.xact;
! 		return;
  	}
  	else if (P_IGNORE(opaque))
  		stat->type = 'e';
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 175,184 ****
  	/* btpage opaque data */
  	stat->btpo_prev = opaque->btpo_prev;
  	stat->btpo_next = opaque->btpo_next;
! 	if (P_ISDELETED(opaque))
! 		stat->btpo.xact = opaque->btpo.xact;
! 	else
! 		stat->btpo.level = opaque->btpo.level;
  	stat->btpo_flags = opaque->btpo_flags;
  	stat->btpo_cycleid = opaque->btpo_cycleid;
  
--- 177,183 ----
  	/* btpage opaque data */
  	stat->btpo_prev = opaque->btpo_prev;
  	stat->btpo_next = opaque->btpo_next;
! 	stat->btpo.level = opaque->btpo.level;
  	stat->btpo_flags = opaque->btpo_flags;
  	stat->btpo_cycleid = opaque->btpo_cycleid;
  
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 187,193 ****
  	 * it means a fragmentation.
  	 *----------------------------------------------
  	 */
- 	stat->fragments = 0;
  	if (stat->type == 'l')
  	{
  		if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno)
--- 186,191 ----
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 216,223 ****
  		stat->avg_item_size = item_size / (stat->live_items + stat->dead_items);
  	else
  		stat->avg_item_size = 0;
- 
- 	return true;
  }
  
  
--- 214,219 ----
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to