From 3b23e3a97b445aba7b4fe2561ad44cf67e254bae Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Mon, 19 May 2014 23:41:55 +0400 Subject: [PATCH] 9.4 + gin_statpage. gin_statpage author is Alexander Korotkov --- Makefile | 4 +- README.gevel | 25 ++ expected/gevel.out.9.4 | 524 +++++++++++++++++++++++++++++++++++++++++ gevel.c | 183 +++++++++++++- gevel.sql.in | 6 + 5 files changed, 736 insertions(+), 6 deletions(-) create mode 100644 expected/gevel.out.9.4 diff --git a/Makefile b/Makefile index 2c72557..e15bc01 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ pg_version.txt: echo PG_MAJORVERSION | $(CPP) -undef -x c -w -P $(CPPFLAGS) -include pg_config.h -o - - | grep -v '^$$' | sed -e 's/"//g' > $@ if [ -f expected/gevel.out.`cat pg_version.txt` ] ; \ then \ - cp $(top_srcdir)/$(subdir)/expected/gevel.out.`cat pg_version.txt` expected/gevel.out ; \ + cp expected/gevel.out.`cat pg_version.txt` expected/gevel.out ; \ else \ - cp $(top_srcdir)/$(subdir)/expected/gevel.out.st expected/gevel.out ; \ + cp expected/gevel.out.st expected/gevel.out ; \ fi diff --git a/README.gevel b/README.gevel index 35b81d1..2292c7a 100644 --- a/README.gevel +++ b/README.gevel @@ -195,3 +195,28 @@ regression=# select gist_tree('pix'); 790 (1 row) + * text gin_statpage(INDEXNAME) + Prints various stat about index internals. + +# select gin_statpage('gin_idx'); + gin_statpage +------------------------------ + totalPages: 32 + + dataPages: 1 + + dataInnerPages: 0 + + dataLeafPages: 1 + + dataInnerFreeSpace: 0 + + dataLeafFreeSpace: 4454 + + dataInnerTuplesCount: 0 + + dataLeafIptrsCount: 3600 + + entryPages: 31 + + entryInnerPages: 21 + + entryLeafPages: 10 + + entryInnerFreeSpace: 15160+ + entryLeafFreeSpace: 32788+ + entryInnerTuplesCount: 7810 + + entryLeafTuplesCount: 305 + + entryPostingSize: 42122+ + entryPostingCount: 96759+ + entryAttrSize: 64924+ + diff --git a/expected/gevel.out.9.4 b/expected/gevel.out.9.4 new file mode 100644 index 0000000..22fa271 --- /dev/null +++ b/expected/gevel.out.9.4 @@ -0,0 +1,524 @@ +SET client_min_messages = warning; +\set ECHO none +RESET client_min_messages; +CREATE TABLE gevelt ( t box ); +\copy gevelt from 'data/rect.data' +SELECT center(t) AS p INTO gevelp FROM gevelt; +CREATE INDEX gist_idx ON gevelt USING gist ( t ); +CREATE INDEX spgist_idx ON gevelp USING spgist ( p ); +CREATE INDEX kdspgist_idx ON gevelp USING spgist ( p kd_point_ops); +--GiST +SELECT gist_stat('gist_idx'); + gist_stat +----------------------------------------- + Number of levels: 2 + + Number of pages: 29 + + Number of leaf pages: 28 + + Number of tuples: 3406 + + Number of invalid tuples: 0 + + Number of leaf tuples: 3378 + + Total size of tuples: 143516 bytes+ + Total size of leaf tuples: 142296 bytes+ + Total size of index: 237568 bytes+ + +(1 row) + +SELECT gist_tree('gist_idx'); + gist_tree +----------------------------------------------------------------------------------------------- + 0(l:0) blk: 0 numTuple: 28 free: 6940b(14.95%) rightlink:4294967295 (InvalidBlockNumber) + + 1(l:1) blk: 2 numTuple: 278 free: 2588b(68.28%) rightlink:4294967295 (InvalidBlockNumber)+ + 2(l:1) blk: 18 numTuple: 123 free: 2736b(66.47%) rightlink:3 (OK) + + 3(l:1) blk: 8 numTuple: 128 free: 2516b(69.17%) rightlink:21 (OK) + + 4(l:1) blk: 4 numTuple: 92 free: 4100b(49.75%) rightlink:23 (OK) + + 5(l:1) blk: 19 numTuple: 122 free: 2780b(65.93%) rightlink:7 (OK) + + 6(l:1) blk: 15 numTuple: 135 free: 2208b(72.94%) rightlink:11 (OK) + + 7(l:1) blk: 23 numTuple: 126 free: 2604b(68.09%) rightlink:8 (OK) + + 8(l:1) blk: 10 numTuple: 156 free: 1284b(84.26%) rightlink:18 (OK) + + 9(l:1) blk: 13 numTuple: 130 free: 2428b(70.25%) rightlink:19 (OK) + + 10(l:1) blk: 9 numTuple: 124 free: 2692b(67.01%) rightlink:24 (OK) + + 11(l:1) blk: 12 numTuple: 70 free: 5068b(37.89%) rightlink:25 (OK) + + 12(l:1) blk: 21 numTuple: 112 free: 3220b(60.54%) rightlink:10 (OK) + + 13(l:1) blk: 16 numTuple: 89 free: 4232b(48.14%) rightlink:26 (OK) + + 14(l:1) blk: 26 numTuple: 108 free: 3396b(58.38%) rightlink:5 (OK) + + 15(l:1) blk: 7 numTuple: 99 free: 3792b(53.53%) rightlink:16 (OK) + + 16(l:1) blk: 6 numTuple: 85 free: 4408b(45.98%) rightlink:22 (OK) + + 17(l:1) blk: 14 numTuple: 163 free: 976b(88.04%) rightlink:6 (OK) + + 18(l:1) blk: 28 numTuple: 122 free: 2780b(65.93%) rightlink:12 (OK) + + 19(l:1) blk: 3 numTuple: 57 free: 5640b(30.88%) rightlink:27 (OK) + + 20(l:1) blk: 24 numTuple: 80 free: 4628b(43.28%) rightlink:15 (OK) + + 21(l:1) blk: 17 numTuple: 89 free: 4232b(48.14%) rightlink:4 (OK) + + 22(l:1) blk: 20 numTuple: 166 free: 844b(89.66%) rightlink:13 (OK) + + 23(l:1) blk: 27 numTuple: 122 free: 2780b(65.93%) rightlink:14 (OK) + + 24(l:1) blk: 22 numTuple: 147 free: 1680b(79.41%) rightlink:9 (OK) + + 25(l:1) blk: 11 numTuple: 146 free: 1724b(78.87%) rightlink:2 (OK) + + 26(l:1) blk: 5 numTuple: 61 free: 5464b(33.04%) rightlink:28 (OK) + + 27(l:1) blk: 1 numTuple: 92 free: 4100b(49.75%) rightlink:20 (OK) + + 28(l:1) blk: 25 numTuple: 156 free: 1284b(84.26%) rightlink:17 (OK) + + +(1 row) + +SELECT * FROM gist_print('gist_idx') as t(level int, valid bool, a box) where level=1; + level | valid | a +-------+-------+----------------------------- + 1 | t | + 1 | t | (32261,50040),(20397,42779) + 1 | t | (20400,41715),(9175,31485) + 1 | t | (8924,39250),(3,31083) + 1 | t | (20594,19151),(10869,10535) + 1 | t | (49999,42533),(43290,27088) + 1 | t | (8993,50012),(64,39781) + 1 | t | (32394,42395),(20513,31557) + 1 | t | (20715,10161),(10407,51) + 1 | t | (42941,36244),(32606,27088) + 1 | t | (32512,16364),(20947,11843) + 1 | t | (20327,49975),(9216,42130) + 1 | t | (13397,31188),(7334,19288) + 1 | t | (20856,31294),(13642,19263) + 1 | t | (6986,30859),(107,19466) + 1 | t | (39187,26879),(32770,15690) + 1 | t | (49985,15380),(42047,43) + 1 | t | (32715,11509),(24675,6) + 1 | t | (41916,5154),(32914,357) + 1 | t | (43056,42360),(32661,36457) + 1 | t | (32544,31262),(21146,25161) + 1 | t | (10104,18999),(15,7761) + 1 | t | (41835,15495),(32828,5360) + 1 | t | (49944,26858),(39348,15728) + 1 | t | (50027,50073),(32453,42694) + 1 | t | (24423,11473),(20828,181) + 1 | t | (10146,7495),(138,81) + 1 | t | (32705,25105),(20838,16626) +(28 rows) + +--SPGiST +SELECT spgist_stat('spgist_idx'); + spgist_stat +---------------------------------- + totalPages: 21 + + deletedPages: 0 + + innerPages: 2 + + leafPages: 19 + + emptyPages: 0 + + usedSpace: 126.70 kbytes+ + freeSpace: 40.64 kbytes + + fillRatio: 75.71% + + leafTuples: 3947 + + innerTuples: 20 + + innerAllTheSame: 0 + + leafPlaceholders: 569 + + innerPlaceholders: 0 + + leafRedirects: 0 + + innerRedirects: 0 +(1 row) + +SELECT * FROM spgist_print('kdspgist_idx') as t(tid tid, node_n int, level int, tid_pointer tid, prefix float8, node_label int, leaf_value point); + tid | node_n | level | tid_pointer | prefix | node_label | leaf_value +----------+--------+-------+-------------+--------+------------+------------------- + (1,1) | 0 | 1 | (5,1) | | | + (1,1) | 1 | 1 | (5,2) | | | + (5,2) | 0 | 2 | (5,6) | | | + (5,2) | 1 | 2 | (5,3) | | | + (5,3) | 0 | 3 | (5,5) | | | + (5,3) | 1 | 3 | (5,12) | | | + (5,12) | 0 | 4 | (5,13) | | | + (5,12) | 1 | 4 | (14,226) | | | + (14,226) | | 5 | | | | (43240,47256.5) + (5,13) | 0 | 5 | (3,112) | | | + (5,13) | 1 | 5 | (5,25) | | | + (5,25) | 0 | 6 | (22,116) | | | + (5,25) | 1 | 6 | (22,115) | | | + (22,115) | | 7 | | | | (30902,44532) + (22,116) | | 7 | | | | (23048,47416) + (3,112) | | 6 | | | | (35218.5,42124) + (5,5) | 0 | 4 | (5,11) | | | + (5,5) | 1 | 4 | (5,22) | | | + (5,22) | 0 | 5 | (20,225) | | | + (5,22) | 1 | 5 | (5,23) | | | + (5,23) | 0 | 6 | (9,112) | | | + (5,23) | 1 | 6 | (9,114) | | | + (9,114) | | 7 | | | | (44732,32182) + (9,112) | | 7 | | | | (35580,33526.5) + (20,225) | | 6 | | | | (47724.5,27185.5) + (5,11) | 0 | 5 | (13,101) | | | + (5,11) | 1 | 5 | (13,100) | | | + (13,100) | | 6 | | | | (24069,30850.5) + (13,101) | | 6 | | | | (29539,25566) + (5,6) | 0 | 3 | (5,7) | | | + (5,6) | 1 | 3 | (5,19) | | | + (5,19) | 0 | 4 | (5,20) | | | + (5,19) | 1 | 4 | (18,225) | | | + (18,225) | | 5 | | | | (20920.5,49105.5) + (5,20) | 0 | 5 | (10,110) | | | + (5,20) | 1 | 5 | (10,113) | | | + (10,113) | | 6 | | | | (93,46797) + (10,110) | | 6 | | | | (28.5,38640.5) + (5,7) | 0 | 4 | (7,113) | | | + (5,7) | 1 | 4 | (5,21) | | | + (5,21) | 0 | 5 | (19,115) | | | + (5,21) | 1 | 5 | (19,112) | | | + (19,112) | | 6 | | | | (11916.5,31668) + (19,115) | | 6 | | | | (20622.5,27462.5) + (7,113) | | 5 | | | | (9296,35157) + (5,1) | 0 | 2 | (5,8) | | | + (5,1) | 1 | 2 | (5,4) | | | + (5,4) | 0 | 3 | (5,10) | | | + (5,4) | 1 | 3 | (5,14) | | | + (5,14) | 0 | 4 | (5,15) | | | + (5,14) | 1 | 4 | (15,222) | | | + (15,222) | | 5 | | | | (41926.5,17934.5) + (5,15) | 0 | 5 | (8,113) | | | + (5,15) | 1 | 5 | (8,112) | | | + (8,112) | | 6 | | | | (32425,20702.5) + (8,113) | | 6 | | | | (29134,15559.5) + (5,10) | 0 | 4 | (12,94) | | | + (5,10) | 1 | 4 | (5,24) | | | + (5,24) | 0 | 5 | (21,108) | | | + (5,24) | 1 | 5 | (21,107) | | | + (21,107) | | 6 | | | | (49822.5,7097.5) + (21,108) | | 6 | | | | (40315.5,1689.5) + (12,94) | | 5 | | | | (30295.5,5090) + (5,8) | 0 | 3 | (5,17) | | | + (5,8) | 1 | 3 | (5,9) | | | + (5,9) | 0 | 4 | (6,114) | | | + (5,9) | 1 | 4 | (5,16) | | | + (5,16) | 0 | 5 | (16,123) | | | + (5,16) | 1 | 5 | (16,127) | | | + (16,127) | | 6 | | | | (18352.5,19366) + (16,123) | | 6 | | | | (24795,14921) + (6,114) | | 5 | | | | (6706,16676) + (5,17) | 0 | 4 | (5,18) | | | + (5,17) | 1 | 4 | (17,226) | | | + (17,226) | | 5 | | | | (23690,10214.5) + (5,18) | 0 | 5 | (11,113) | | | + (5,18) | 1 | 5 | (11,109) | | | + (11,109) | | 6 | | | | (5501.5,9916) + (11,113) | | 6 | | | | (1072.5,4752) +(79 rows) + +SELECT * FROM spgist_print('spgist_idx') as t(tid tid, node_n int, level int, tid_pointer tid, prefix point, node_label int, leaf_value point) WHERE level = 1; + tid | node_n | level | tid_pointer | prefix | node_label | leaf_value +-------+--------+-------+-------------+-------------------------------------+------------+------------ + (1,1) | 0 | 1 | (5,4) | (24530.2070484581,23595.7092511013) | | + (1,1) | 1 | 1 | (5,3) | (24530.2070484581,23595.7092511013) | | + (1,1) | 2 | 1 | (5,2) | (24530.2070484581,23595.7092511013) | | + (1,1) | 3 | 1 | (5,1) | (24530.2070484581,23595.7092511013) | | +(4 rows) + +--GIN +CREATE TABLE test__int( a int[] ); +\copy test__int from 'data/test__int.data' +CREATE INDEX gin_idx ON test__int USING gin ( a ); +INSERT INTO test__int ( SELECT ARRAY[t] || '{1000}'::_int4 FROM generate_series (1,300) as t ); +INSERT INTO test__int ( SELECT ARRAY[t] || '{1001}'::_int4 FROM generate_series (1,300) as t, generate_series(1,12) ); +VACUUM ANALYZE test__int; +SELECT * FROM gin_stat('gin_idx') as t(value int, nrow int); + value | nrow +-------+------ + 0 | 38 + 1 | 257 + 2 | 244 + 3 | 222 + 4 | 228 + 5 | 227 + 6 | 243 + 7 | 238 + 8 | 236 + 9 | 224 + 10 | 236 + 11 | 248 + 12 | 224 + 13 | 235 + 14 | 237 + 15 | 253 + 16 | 234 + 17 | 245 + 18 | 246 + 19 | 234 + 20 | 236 + 21 | 213 + 22 | 235 + 23 | 222 + 24 | 197 + 25 | 253 + 26 | 218 + 27 | 239 + 28 | 198 + 29 | 244 + 30 | 247 + 31 | 267 + 32 | 234 + 33 | 209 + 34 | 231 + 35 | 218 + 36 | 242 + 37 | 232 + 38 | 221 + 39 | 232 + 40 | 241 + 41 | 239 + 42 | 221 + 43 | 211 + 44 | 231 + 45 | 213 + 46 | 236 + 47 | 264 + 48 | 221 + 49 | 235 + 50 | 219 + 51 | 250 + 52 | 270 + 53 | 222 + 54 | 242 + 55 | 237 + 56 | 237 + 57 | 251 + 58 | 231 + 59 | 272 + 60 | 219 + 61 | 233 + 62 | 235 + 63 | 260 + 64 | 252 + 65 | 221 + 66 | 228 + 67 | 253 + 68 | 196 + 69 | 232 + 70 | 232 + 71 | 223 + 72 | 247 + 73 | 214 + 74 | 232 + 75 | 229 + 76 | 233 + 77 | 221 + 78 | 227 + 79 | 233 + 80 | 216 + 81 | 244 + 82 | 223 + 83 | 254 + 84 | 227 + 85 | 247 + 86 | 255 + 87 | 239 + 88 | 258 + 89 | 249 + 90 | 244 + 91 | 226 + 92 | 225 + 93 | 230 + 94 | 218 + 95 | 232 + 96 | 239 + 97 | 226 + 98 | 209 + 99 | 211 + 100 | 216 + 101 | 49 + 102 | 47 + 103 | 59 + 104 | 55 + 105 | 48 + 106 | 49 + 107 | 49 + 108 | 51 + 109 | 47 + 110 | 51 + 111 | 45 + 112 | 46 + 113 | 48 + 114 | 38 + 115 | 39 + 116 | 43 + 117 | 44 + 118 | 46 + 119 | 45 + 120 | 52 + 121 | 41 + 122 | 64 + 123 | 50 + 124 | 41 + 125 | 55 + 126 | 41 + 127 | 50 + 128 | 54 + 129 | 43 + 130 | 44 + 131 | 50 + 132 | 57 + 133 | 40 + 134 | 41 + 135 | 44 + 136 | 58 + 137 | 48 + 138 | 44 + 139 | 50 + 140 | 49 + 141 | 48 + 142 | 43 + 143 | 36 + 144 | 43 + 145 | 49 + 146 | 46 + 147 | 40 + 148 | 52 + 149 | 46 + 150 | 49 + 151 | 42 + 152 | 58 + 153 | 49 + 154 | 51 + 155 | 49 + 156 | 45 + 157 | 53 + 158 | 59 + 159 | 38 + 160 | 53 + 161 | 48 + 162 | 41 + 163 | 40 + 164 | 52 + 165 | 50 + 166 | 40 + 167 | 48 + 168 | 45 + 169 | 49 + 170 | 50 + 171 | 45 + 172 | 46 + 173 | 47 + 174 | 41 + 175 | 51 + 176 | 50 + 177 | 41 + 178 | 42 + 179 | 48 + 180 | 47 + 181 | 49 + 182 | 40 + 183 | 46 + 184 | 52 + 185 | 36 + 186 | 45 + 187 | 41 + 188 | 47 + 189 | 49 + 190 | 46 + 191 | 45 + 192 | 39 + 193 | 50 + 194 | 39 + 195 | 54 + 196 | 43 + 197 | 50 + 198 | 46 + 199 | 42 + 200 | 31 + 201 | 28 + 202 | 28 + 203 | 28 + 204 | 30 + 205 | 22 + 206 | 25 + 207 | 27 + 208 | 32 + 209 | 22 + 210 | 21 + 211 | 31 + 212 | 22 + 213 | 37 + 214 | 19 + 215 | 25 + 216 | 27 + 217 | 26 + 218 | 24 + 219 | 25 + 220 | 26 + 221 | 21 + 222 | 23 + 223 | 20 + 224 | 26 + 225 | 25 + 226 | 25 + 227 | 23 + 228 | 30 + 229 | 30 + 230 | 24 + 231 | 22 + 232 | 27 + 233 | 27 + 234 | 21 + 235 | 27 + 236 | 24 + 237 | 24 + 238 | 29 + 239 | 32 + 240 | 31 + 241 | 24 + 242 | 36 + 243 | 21 + 244 | 29 + 245 | 22 + 246 | 23 + 247 | 21 + 248 | 26 + 249 | 29 + 250 | 24 + 251 | 29 + 252 | 25 + 253 | 28 + 254 | 25 + 255 | 19 + 256 | 23 + 257 | 20 + 258 | 24 + 259 | 31 + 260 | 29 + 261 | 20 + 262 | 25 + 263 | 23 + 264 | 25 + 265 | 23 + 266 | 31 + 267 | 22 + 268 | 26 + 269 | 33 + 270 | 25 + 271 | 27 + 272 | 29 + 273 | 29 + 274 | 26 + 275 | 28 + 276 | 30 + 277 | 28 + 278 | 29 + 279 | 22 + 280 | 29 + 281 | 23 + 282 | 30 + 283 | 29 + 284 | 23 + 285 | 37 + 286 | 27 + 287 | 31 + 288 | 28 + 289 | 26 + 290 | 25 + 291 | 29 + 292 | 22 + 293 | 26 + 294 | 29 + 295 | 24 + 296 | 27 + 297 | 30 + 298 | 29 + 299 | 26 + 300 | 13 + 1000 | 300 + 1001 | 0 + | 9 + | 244 +(305 rows) + diff --git a/gevel.c b/gevel.c index d95fbdf..b4e66f4 100644 --- a/gevel.c +++ b/gevel.c @@ -695,8 +695,11 @@ processTuple( FuncCallContext *funcctx, GinStatState *st, IndexTuple itup ) { if ( GinIsPostingTree(itup) ) { BlockNumber rootblkno = GinGetPostingTree(itup); #if PG_VERSION_NUM >= 90400 - GinBtreeData btree, *gdi = &btree; + GinBtreeData btree; GinBtreeStack *stack; + ItemPointerData minItem; + int nlist; + ItemPointer list; #else GinPostingTreeScan *gdi; Buffer entrybuffer; @@ -706,9 +709,11 @@ processTuple( FuncCallContext *funcctx, GinStatState *st, IndexTuple itup ) { LockBuffer(st->buffer, GIN_UNLOCK); #if PG_VERSION_NUM >= 90400 - ginPrepareDataScan(gdi, st->index, rootblkno); - stack = ginScanBeginPostingTree(gdi, st->index, rootblkno); + stack = ginScanBeginPostingTree(&btree, st->index, rootblkno); page = BufferGetPage(stack->buffer); + ItemPointerSetMin(&minItem); + list = GinDataLeafPageGetItems(page, &nlist, minItem); + pfree(list); predictNumber = stack->predictNumber; #elif PG_VERSION_NUM >= 90100 gdi = ginPrepareScanPostingTree(st->index, rootblkno, TRUE); @@ -729,6 +734,7 @@ processTuple( FuncCallContext *funcctx, GinStatState *st, IndexTuple itup ) { freeGinBtreeStack(gdi->stack); pfree(gdi); #else + LockBuffer(stack->buffer, GIN_UNLOCK); freeGinBtreeStack(stack); #endif } else { @@ -830,7 +836,7 @@ gin_count_estimate(PG_FUNCTION_ARGS) { #if PG_VERSION_NUM >= 90100 #if PG_VERSION_NUM >= 90400 - scan = index_beginscan_bitmap(index, GetTransactionSnapshot(), 1); + scan = index_beginscan_bitmap(index, SnapshotSelf, 1); #else scan = index_beginscan_bitmap(index, SnapshotNow, 1); #endif @@ -1227,3 +1233,172 @@ next: #endif } + +PG_FUNCTION_INFO_V1(gin_statpage); +Datum gin_statpage(PG_FUNCTION_ARGS); +Datum +gin_statpage(PG_FUNCTION_ARGS) +{ +#if PG_VERSION_NUM < 90400 + elog(NOTICE, "Function is not working under PgSQL < 9.4"); + + PG_RETURN_TEXT_P(CStringGetTextDatum("???")); +#else + text *name = PG_GETARG_TEXT_P(0); + RangeVar *relvar; + Relation index; + BlockNumber blkno; + char res[1024]; + uint32 totalPages, + entryPages = 0, + dataPages = 0, + dataInnerPages = 0, + dataLeafPages = 0, + entryInnerPages = 0, + entryLeafPages = 0 + ; + uint64 dataInnerFreeSpace = 0, + dataLeafFreeSpace = 0, + dataInnerTuplesCount = 0, + dataLeafIptrsCount = 0, + entryInnerFreeSpace = 0, + entryLeafFreeSpace = 0, + entryInnerTuplesCount = 0, + entryLeafTuplesCount = 0, + entryPostingSize = 0, + entryPostingCount = 0, + entryAttrSize = 0 + ; + + relvar = makeRangeVarFromNameList(textToQualifiedNameList(name)); + index = relation_openrv(relvar, AccessExclusiveLock); + + if (index->rd_rel->relkind != RELKIND_INDEX || + index->rd_rel->relam != GIN_AM_OID) + elog(ERROR, "relation \"%s\" is not an SPGiST index", + RelationGetRelationName(index)); + + totalPages = RelationGetNumberOfBlocks(index); + + for (blkno = GIN_ROOT_BLKNO; blkno < totalPages; blkno++) + { + Buffer buffer; + Page page; + PageHeader header; + + buffer = ReadBuffer(index, blkno); + LockBuffer(buffer, BUFFER_LOCK_SHARE); + + page = BufferGetPage(buffer); + header = (PageHeader)page; + + if (GinPageIsData(page)) + { + dataPages++; + if (GinPageIsLeaf(page)) + { + ItemPointerData minItem; + int nlist; + + dataLeafPages++; + dataLeafFreeSpace += header->pd_upper - header->pd_lower; + ItemPointerSetMin(&minItem); + pfree(GinDataLeafPageGetItems(page, &nlist, minItem)); + dataLeafIptrsCount += nlist; + } + else + { + dataInnerPages++; + dataInnerFreeSpace += header->pd_upper - header->pd_lower; + dataInnerTuplesCount += GinPageGetOpaque(page)->maxoff; + } + } + else + { + IndexTuple itup; + OffsetNumber i, maxoff; + + maxoff = PageGetMaxOffsetNumber(page); + + entryPages++; + if (GinPageIsLeaf(page)) + { + entryLeafPages++; + entryLeafFreeSpace += header->pd_upper - header->pd_lower; + entryLeafTuplesCount += maxoff; + } + else + { + entryInnerPages++; + entryInnerFreeSpace += header->pd_upper - header->pd_lower; + entryInnerTuplesCount += maxoff; + } + + for (i = 1; i <= maxoff; i++) + { + itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, i)); + + if (GinPageIsLeaf(page)) + { + GinPostingList *list = (GinPostingList *)GinGetPosting(itup); + entryPostingCount += GinGetNPosting(itup); + entryPostingSize += SizeOfGinPostingList(list); + entryAttrSize += GinGetPostingOffset(itup) - IndexInfoFindDataOffset((itup)->t_info); + } + else + { + entryAttrSize += IndexTupleSize(itup) - IndexInfoFindDataOffset((itup)->t_info); + } + } + } + + UnlockReleaseBuffer(buffer); + } + + index_close(index, AccessExclusiveLock); + totalPages--; + + snprintf(res, sizeof(res), + "totalPages: %u\n" + "dataPages: %u\n" + "dataInnerPages: %u\n" + "dataLeafPages: %u\n" + "dataInnerFreeSpace: " INT64_FORMAT "\n" + "dataLeafFreeSpace: " INT64_FORMAT "\n" + "dataInnerTuplesCount: " INT64_FORMAT "\n" + "dataLeafIptrsCount: " INT64_FORMAT "\n" + "entryPages: %u\n" + "entryInnerPages: %u\n" + "entryLeafPages: %u\n" + "entryInnerFreeSpace: " INT64_FORMAT "\n" + "entryLeafFreeSpace: " INT64_FORMAT "\n" + "entryInnerTuplesCount: " INT64_FORMAT "\n" + "entryLeafTuplesCount: " INT64_FORMAT "\n" + "entryPostingSize: " INT64_FORMAT "\n" + "entryPostingCount: " INT64_FORMAT "\n" + "entryAttrSize: " INT64_FORMAT "\n" + , + totalPages, + dataPages, + dataInnerPages, + dataLeafPages, + dataInnerFreeSpace, + dataLeafFreeSpace, + dataInnerTuplesCount, + dataLeafIptrsCount, + entryPages, + entryInnerPages, + entryLeafPages, + entryInnerFreeSpace, + entryLeafFreeSpace, + entryInnerTuplesCount, + entryLeafTuplesCount, + entryPostingSize, + entryPostingCount, + entryAttrSize + ); + + PG_RETURN_TEXT_P(CStringGetTextDatum(res)); +#endif +} + diff --git a/gevel.sql.in b/gevel.sql.in index 1f031ed..a2310bf 100644 --- a/gevel.sql.in +++ b/gevel.sql.in @@ -37,6 +37,12 @@ create or replace function gin_stat(text, int) language C with (isstrict); +create or replace function gin_statpage(text) + returns text + as 'MODULE_PATHNAME' + language C + with (isstrict); + create or replace function gin_count_estimate(text, tsquery) returns bigint as 'MODULE_PATHNAME' -- 2.46.1