3
3
* pg_freespacemap.c
4
4
* display some contents of the free space map.
5
5
*
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 $
7
7
*-------------------------------------------------------------------------
8
8
*/
9
9
#include "postgres.h"
12
12
#include "storage/freespace.h"
13
13
#include "utils/relcache.h"
14
14
15
- #define NUM_FREESPACE_PAGES_ELEM 6
15
+ #define NUM_FREESPACE_PAGES_ELEM 5
16
16
17
17
#if defined(WIN32 ) || defined(__CYGWIN__ )
18
18
/* Need DLLIMPORT for some things that are not so marked in main headers */
@@ -29,12 +29,12 @@ Datum pg_freespacemap(PG_FUNCTION_ARGS);
29
29
typedef struct
30
30
{
31
31
32
- uint32 blockid ;
33
- uint32 relfilenode ;
34
32
uint32 reltablespace ;
35
33
uint32 reldatabase ;
34
+ uint32 relfilenode ;
36
35
uint32 relblocknumber ;
37
- uint32 blockfreebytes ;
36
+ uint32 bytes ;
37
+ bool isindex ;
38
38
39
39
} FreeSpacePagesRec ;
40
40
@@ -91,17 +91,15 @@ pg_freespacemap(PG_FUNCTION_ARGS)
91
91
92
92
/* Construct a tuple to return. */
93
93
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" ,
97
95
OIDOID , -1 , 0 );
98
- TupleDescInitEntry (tupledesc , (AttrNumber ) 3 , "reltablespace " ,
96
+ TupleDescInitEntry (tupledesc , (AttrNumber ) 2 , "reldatabase " ,
99
97
OIDOID , -1 , 0 );
100
- TupleDescInitEntry (tupledesc , (AttrNumber ) 4 , "reldatabase " ,
98
+ TupleDescInitEntry (tupledesc , (AttrNumber ) 3 , "relfilenode " ,
101
99
OIDOID , -1 , 0 );
102
- TupleDescInitEntry (tupledesc , (AttrNumber ) 5 , "relblocknumber" ,
100
+ TupleDescInitEntry (tupledesc , (AttrNumber ) 4 , "relblocknumber" ,
103
101
INT8OID , -1 , 0 );
104
- TupleDescInitEntry (tupledesc , (AttrNumber ) 6 , "blockfreebytes " ,
102
+ TupleDescInitEntry (tupledesc , (AttrNumber ) 5 , "bytes " ,
105
103
INT4OID , -1 , 0 );
106
104
107
105
/* Generate attribute metadata needed later to produce tuples */
@@ -129,7 +127,6 @@ pg_freespacemap(PG_FUNCTION_ARGS)
129
127
fctx -> values [2 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
130
128
fctx -> values [3 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
131
129
fctx -> values [4 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
132
- fctx -> values [5 ] = (char * ) palloc (3 * sizeof (uint32 ) + 1 );
133
130
134
131
135
132
/* Return to original context when allocating transient memory */
@@ -158,12 +155,12 @@ pg_freespacemap(PG_FUNCTION_ARGS)
158
155
for (nPages = 0 ; nPages < fsmrel -> storedPages ; nPages ++ )
159
156
{
160
157
161
- fctx -> record [i ].blockid = i ;
162
- fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
163
158
fctx -> record [i ].reltablespace = fsmrel -> key .spcNode ;
164
159
fctx -> record [i ].reldatabase = fsmrel -> key .dbNode ;
160
+ fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
165
161
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;
167
164
168
165
page ++ ;
169
166
i ++ ;
@@ -178,12 +175,12 @@ pg_freespacemap(PG_FUNCTION_ARGS)
178
175
179
176
for (nPages = 0 ; nPages < fsmrel -> storedPages ; nPages ++ )
180
177
{
181
- fctx -> record [i ].blockid = i ;
182
- fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
183
178
fctx -> record [i ].reltablespace = fsmrel -> key .spcNode ;
184
179
fctx -> record [i ].reldatabase = fsmrel -> key .dbNode ;
180
+ fctx -> record [i ].relfilenode = fsmrel -> key .relNode ;
185
181
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;
187
184
188
185
page ++ ;
189
186
i ++ ;
@@ -209,19 +206,41 @@ pg_freespacemap(PG_FUNCTION_ARGS)
209
206
if (funcctx -> call_cntr < funcctx -> max_calls )
210
207
{
211
208
uint32 i = funcctx -> call_cntr ;
209
+ char * values [NUM_FREESPACE_PAGES_ELEM ];
210
+ int j ;
212
211
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 );
213
227
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 );
220
228
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
+ }
221
240
222
241
223
242
/* Build and return the tuple. */
224
- tuple = BuildTupleFromCStrings (funcctx -> attinmeta , fctx -> values );
243
+ tuple = BuildTupleFromCStrings (funcctx -> attinmeta , values );
225
244
result = HeapTupleGetDatum (tuple );
226
245
227
246
0 commit comments