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