@@ -54,6 +54,14 @@ PG_FUNCTION_INFO_V1(pg_relpages);
54
54
PG_FUNCTION_INFO_V1 (pg_relpagesbyid );
55
55
PG_FUNCTION_INFO_V1 (pgstatginindex );
56
56
57
+ PG_FUNCTION_INFO_V1 (pgstatindex_v1_5 );
58
+ PG_FUNCTION_INFO_V1 (pgstatindexbyid_v1_5 );
59
+ PG_FUNCTION_INFO_V1 (pg_relpages_v1_5 );
60
+ PG_FUNCTION_INFO_V1 (pg_relpagesbyid_v1_5 );
61
+ PG_FUNCTION_INFO_V1 (pgstatginindex_v1_5 );
62
+
63
+ Datum pgstatginindex_internal (Oid relid , FunctionCallInfo fcinfo );
64
+
57
65
#define IS_INDEX (r ) ((r)->rd_rel->relkind == RELKIND_INDEX)
58
66
#define IS_BTREE (r ) ((r)->rd_rel->relam == BTREE_AM_OID)
59
67
#define IS_GIN (r ) ((r)->rd_rel->relam == GIN_AM_OID)
@@ -99,6 +107,10 @@ static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo);
99
107
* pgstatindex()
100
108
*
101
109
* Usage: SELECT * FROM pgstatindex('t1_pkey');
110
+ *
111
+ * The superuser() check here must be kept as the library might be upgraded
112
+ * without the extension being upgraded, meaning that in pre-1.5 installations
113
+ * these functions could be called by any user.
102
114
* ------------------------------------------------------
103
115
*/
104
116
Datum
@@ -119,6 +131,31 @@ pgstatindex(PG_FUNCTION_ARGS)
119
131
PG_RETURN_DATUM (pgstatindex_impl (rel , fcinfo ));
120
132
}
121
133
134
+ /*
135
+ * As of pgstattuple version 1.5, we no longer need to check if the user
136
+ * is a superuser because we REVOKE EXECUTE on the function from PUBLIC.
137
+ * Users can then grant access to it based on their policies.
138
+ *
139
+ * Otherwise identical to pgstatindex (above).
140
+ */
141
+ Datum
142
+ pgstatindex_v1_5 (PG_FUNCTION_ARGS )
143
+ {
144
+ text * relname = PG_GETARG_TEXT_P (0 );
145
+ Relation rel ;
146
+ RangeVar * relrv ;
147
+
148
+ relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ));
149
+ rel = relation_openrv (relrv , AccessShareLock );
150
+
151
+ PG_RETURN_DATUM (pgstatindex_impl (rel , fcinfo ));
152
+ }
153
+
154
+ /*
155
+ * The superuser() check here must be kept as the library might be upgraded
156
+ * without the extension being upgraded, meaning that in pre-1.5 installations
157
+ * these functions could be called by any user.
158
+ */
122
159
Datum
123
160
pgstatindexbyid (PG_FUNCTION_ARGS )
124
161
{
@@ -135,6 +172,18 @@ pgstatindexbyid(PG_FUNCTION_ARGS)
135
172
PG_RETURN_DATUM (pgstatindex_impl (rel , fcinfo ));
136
173
}
137
174
175
+ /* No need for superuser checks in v1.5, see above */
176
+ Datum
177
+ pgstatindexbyid_v1_5 (PG_FUNCTION_ARGS )
178
+ {
179
+ Oid relid = PG_GETARG_OID (0 );
180
+ Relation rel ;
181
+
182
+ rel = relation_open (relid , AccessShareLock );
183
+
184
+ PG_RETURN_DATUM (pgstatindex_impl (rel , fcinfo ));
185
+ }
186
+
138
187
static Datum
139
188
pgstatindex_impl (Relation rel , FunctionCallInfo fcinfo )
140
189
{
@@ -292,6 +341,8 @@ pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
292
341
*
293
342
* Usage: SELECT pg_relpages('t1');
294
343
* SELECT pg_relpages('t1_pkey');
344
+ *
345
+ * Must keep superuser() check, see above.
295
346
* --------------------------------------------------------
296
347
*/
297
348
Datum
@@ -319,6 +370,28 @@ pg_relpages(PG_FUNCTION_ARGS)
319
370
PG_RETURN_INT64 (relpages );
320
371
}
321
372
373
+ /* No need for superuser checks in v1.5, see above */
374
+ Datum
375
+ pg_relpages_v1_5 (PG_FUNCTION_ARGS )
376
+ {
377
+ text * relname = PG_GETARG_TEXT_P (0 );
378
+ int64 relpages ;
379
+ Relation rel ;
380
+ RangeVar * relrv ;
381
+
382
+ relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ));
383
+ rel = relation_openrv (relrv , AccessShareLock );
384
+
385
+ /* note: this will work OK on non-local temp tables */
386
+
387
+ relpages = RelationGetNumberOfBlocks (rel );
388
+
389
+ relation_close (rel , AccessShareLock );
390
+
391
+ PG_RETURN_INT64 (relpages );
392
+ }
393
+
394
+ /* Must keep superuser() check, see above. */
322
395
Datum
323
396
pg_relpagesbyid (PG_FUNCTION_ARGS )
324
397
{
@@ -342,16 +415,58 @@ pg_relpagesbyid(PG_FUNCTION_ARGS)
342
415
PG_RETURN_INT64 (relpages );
343
416
}
344
417
418
+ /* No need for superuser checks in v1.5, see above */
419
+ Datum
420
+ pg_relpagesbyid_v1_5 (PG_FUNCTION_ARGS )
421
+ {
422
+ Oid relid = PG_GETARG_OID (0 );
423
+ int64 relpages ;
424
+ Relation rel ;
425
+
426
+ rel = relation_open (relid , AccessShareLock );
427
+
428
+ /* note: this will work OK on non-local temp tables */
429
+
430
+ relpages = RelationGetNumberOfBlocks (rel );
431
+
432
+ relation_close (rel , AccessShareLock );
433
+
434
+ PG_RETURN_INT64 (relpages );
435
+ }
436
+
345
437
/* ------------------------------------------------------
346
438
* pgstatginindex()
347
439
*
348
440
* Usage: SELECT * FROM pgstatginindex('ginindex');
441
+ *
442
+ * Must keep superuser() check, see above.
349
443
* ------------------------------------------------------
350
444
*/
351
445
Datum
352
446
pgstatginindex (PG_FUNCTION_ARGS )
353
447
{
354
448
Oid relid = PG_GETARG_OID (0 );
449
+
450
+ if (!superuser ())
451
+ ereport (ERROR ,
452
+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
453
+ (errmsg ("must be superuser to use pgstattuple functions" ))));
454
+
455
+ PG_RETURN_DATUM (pgstatginindex_internal (relid , fcinfo ));
456
+ }
457
+
458
+ /* No need for superuser checks in v1.5, see above */
459
+ Datum
460
+ pgstatginindex_v1_5 (PG_FUNCTION_ARGS )
461
+ {
462
+ Oid relid = PG_GETARG_OID (0 );
463
+
464
+ PG_RETURN_DATUM (pgstatginindex_internal (relid , fcinfo ));
465
+ }
466
+
467
+ Datum
468
+ pgstatginindex_internal (Oid relid , FunctionCallInfo fcinfo )
469
+ {
355
470
Relation rel ;
356
471
Buffer buffer ;
357
472
Page page ;
@@ -363,11 +478,6 @@ pgstatginindex(PG_FUNCTION_ARGS)
363
478
bool nulls [3 ] = {false, false, false};
364
479
Datum result ;
365
480
366
- if (!superuser ())
367
- ereport (ERROR ,
368
- (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
369
- (errmsg ("must be superuser to use pgstattuple functions" ))));
370
-
371
481
rel = relation_open (relid , AccessShareLock );
372
482
373
483
if (!IS_INDEX (rel ) || !IS_GIN (rel ))
@@ -415,5 +525,5 @@ pgstatginindex(PG_FUNCTION_ARGS)
415
525
tuple = heap_form_tuple (tupleDesc , values , nulls );
416
526
result = HeapTupleGetDatum (tuple );
417
527
418
- PG_RETURN_DATUM (result );
528
+ return (result );
419
529
}
0 commit comments