33 * pg_freespacemap.c
44 * display some contents of the free space map.
55 *
6- * $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.2 2006/02/14 15:03:59 tgl Exp $
6+ * $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.3 2006/04/26 22:41:18 momjian Exp $
77 *-------------------------------------------------------------------------
88 */
99#include "postgres.h"
1212#include "storage/freespace.h"
1313#include "utils/relcache.h"
1414
15- #define NUM_FREESPACE_PAGES_ELEM 6
15+ #define NUM_FREESPACE_PAGES_ELEM 5
1616
1717#if defined(WIN32 ) || defined(__CYGWIN__ )
1818/* Need DLLIMPORT for some things that are not so marked in main headers */
@@ -29,12 +29,12 @@ Datum pg_freespacemap(PG_FUNCTION_ARGS);
2929typedef struct
3030{
3131
32- uint32 blockid ;
33- uint32 relfilenode ;
3432 uint32 reltablespace ;
3533 uint32 reldatabase ;
34+ uint32 relfilenode ;
3635 uint32 relblocknumber ;
37- uint32 blockfreebytes ;
36+ uint32 bytes ;
37+ bool isindex ;
3838
3939} FreeSpacePagesRec ;
4040
@@ -91,17 +91,15 @@ pg_freespacemap(PG_FUNCTION_ARGS)
9191
9292 /* Construct a tuple to return. */
9393 tupledesc = CreateTemplateTupleDesc (NUM_FREESPACE_PAGES_ELEM , false);
94- TupleDescInitEntry (tupledesc , (AttrNumber ) 1 , "blockid" ,
95- INT4OID , -1 , 0 );
96- TupleDescInitEntry (tupledesc , (AttrNumber ) 2 , "relfilenode" ,
94+ TupleDescInitEntry (tupledesc , (AttrNumber ) 1 , "reltablespace" ,
9795 OIDOID , -1 , 0 );
98- TupleDescInitEntry (tupledesc , (AttrNumber ) 3 , "reltablespace " ,
96+ TupleDescInitEntry (tupledesc , (AttrNumber ) 2 , "reldatabase " ,
9997 OIDOID , -1 , 0 );
100- TupleDescInitEntry (tupledesc , (AttrNumber ) 4 , "reldatabase " ,
98+ TupleDescInitEntry (tupledesc , (AttrNumber ) 3 , "relfilenode " ,
10199 OIDOID , -1 , 0 );
102- TupleDescInitEntry (tupledesc , (AttrNumber ) 5 , "relblocknumber" ,
100+ TupleDescInitEntry (tupledesc , (AttrNumber ) 4 , "relblocknumber" ,
103101 INT8OID , -1 , 0 );
104- TupleDescInitEntry (tupledesc , (AttrNumber ) 6 , "blockfreebytes " ,
102+ TupleDescInitEntry (tupledesc , (AttrNumber ) 5 , "bytes " ,
105103 INT4OID , -1 , 0 );
106104
107105 /* Generate attribute metadata needed later to produce tuples */
@@ -129,7 +127,6 @@ pg_freespacemap(PG_FUNCTION_ARGS)
129127 fctx -> values [2 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
130128 fctx -> values [3 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
131129 fctx -> values [4 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
132- fctx -> values [5 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
133130
134131
135132 /* Return to original context when allocating transient memory */
@@ -158,12 +155,12 @@ pg_freespacemap(PG_FUNCTION_ARGS)
158155 for (nPages = 0 ; nPages < fsmrel -> storedPages ; nPages ++ )
159156 {
160157
161- fctx -> record [i ].blockid = i ;
162- fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
163158 fctx -> record [i ].reltablespace = fsmrel -> key .spcNode ;
164159 fctx -> record [i ].reldatabase = fsmrel -> key .dbNode ;
160+ fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
165161 fctx -> record [i ].relblocknumber = IndexFSMPageGetPageNum (page );
166- fctx -> record [i ].blockfreebytes = 0 ; /* index.*/
162+ fctx -> record [i ].bytes = 0 ;
163+ fctx -> record [i ].isindex = true;
167164
168165 page ++ ;
169166 i ++ ;
@@ -178,12 +175,12 @@ pg_freespacemap(PG_FUNCTION_ARGS)
178175
179176 for (nPages = 0 ; nPages < fsmrel -> storedPages ; nPages ++ )
180177 {
181- fctx -> record [i ].blockid = i ;
182- fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
183178 fctx -> record [i ].reltablespace = fsmrel -> key .spcNode ;
184179 fctx -> record [i ].reldatabase = fsmrel -> key .dbNode ;
180+ fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
185181 fctx -> record [i ].relblocknumber = FSMPageGetPageNum (page );
186- fctx -> record [i ].blockfreebytes = FSMPageGetSpace (page );
182+ fctx -> record [i ].bytes = FSMPageGetSpace (page );
183+ fctx -> record [i ].isindex = false;
187184
188185 page ++ ;
189186 i ++ ;
@@ -209,19 +206,41 @@ pg_freespacemap(PG_FUNCTION_ARGS)
209206 if (funcctx -> call_cntr < funcctx -> max_calls )
210207 {
211208 uint32 i = funcctx -> call_cntr ;
209+ char * values [NUM_FREESPACE_PAGES_ELEM ];
210+ int j ;
212211
212+ /*
213+ * Use a temporary values array, initially pointing to fctx->values,
214+ * so it can be reassigned w/o losing the storage for subsequent
215+ * calls.
216+ */
217+ for (j = 0 ; j < NUM_FREESPACE_PAGES_ELEM ; j ++ )
218+ {
219+ values [j ] = fctx -> values [j ];
220+ }
221+
222+
223+ sprintf (values [0 ], "%u" , fctx -> record [i ].reltablespace );
224+ sprintf (values [1 ], "%u" , fctx -> record [i ].reldatabase );
225+ sprintf (values [2 ], "%u" , fctx -> record [i ].relfilenode );
226+ sprintf (values [3 ], "%u" , fctx -> record [i ].relblocknumber );
213227
214- sprintf (fctx -> values [0 ], "%u" , fctx -> record [i ].blockid );
215- sprintf (fctx -> values [1 ], "%u" , fctx -> record [i ].relfilenode );
216- sprintf (fctx -> values [2 ], "%u" , fctx -> record [i ].reltablespace );
217- sprintf (fctx -> values [3 ], "%u" , fctx -> record [i ].reldatabase );
218- sprintf (fctx -> values [4 ], "%u" , fctx -> record [i ].relblocknumber );
219- sprintf (fctx -> values [5 ], "%u" , fctx -> record [i ].blockfreebytes );
220228
229+ /*
230+ * Set (free) bytes to NULL for an index relation.
231+ */
232+ if (fctx -> record [i ].isindex == true)
233+ {
234+ values [4 ] = NULL ;
235+ }
236+ else
237+ {
238+ sprintf (values [4 ], "%u" , fctx -> record [i ].bytes );
239+ }
221240
222241
223242 /* Build and return the tuple. */
224- tuple = BuildTupleFromCStrings (funcctx -> attinmeta , fctx -> values );
243+ tuple = BuildTupleFromCStrings (funcctx -> attinmeta , values );
225244 result = HeapTupleGetDatum (tuple );
226245
227246
0 commit comments