summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2007-08-26 23:59:50 +0000
committerTom Lane2007-08-26 23:59:50 +0000
commit38c75ecf8345bd338112ad2a3221dfc47929fb7e (patch)
tree0f276f68263c40607ba2eb14d8612e8c6066cea4
parent0effa088f5a5b55ab5b963159d18cc26dc7ccc4e (diff)
Restrict pgstattuple functions to superusers. (This might be too strict,
but no permissions check at all is certainly no good.) Clean up usage of some deprecated APIs.
-rw-r--r--contrib/pgstattuple/pgstatindex.c46
-rw-r--r--contrib/pgstattuple/pgstattuple.c20
-rw-r--r--contrib/pgstattuple/pgstattuple.sql.in66
-rw-r--r--contrib/pgstattuple/uninstall_pgstattuple.sql6
4 files changed, 72 insertions, 66 deletions
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index 0c2c9a1448..3018b6aedd 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -24,27 +24,21 @@
#include "postgres.h"
-#include "fmgr.h"
-#include "funcapi.h"
#include "access/heapam.h"
-#include "access/itup.h"
#include "access/nbtree.h"
-#include "access/transam.h"
#include "catalog/namespace.h"
-#include "catalog/pg_type.h"
+#include "funcapi.h"
+#include "miscadmin.h"
#include "utils/builtins.h"
-#include "utils/inval.h"
-PG_FUNCTION_INFO_V1(pgstatindex);
-PG_FUNCTION_INFO_V1(pg_relpages);
extern Datum pgstatindex(PG_FUNCTION_ARGS);
extern Datum pg_relpages(PG_FUNCTION_ARGS);
-#define PGSTATINDEX_TYPE "public.pgstatindex_type"
-#define PGSTATINDEX_NCOLUMNS 10
+PG_FUNCTION_INFO_V1(pgstatindex);
+PG_FUNCTION_INFO_V1(pg_relpages);
-#define IS_INDEX(r) ((r)->rd_rel->relkind == 'i')
+#define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
#define IS_BTREE(r) ((r)->rd_rel->relam == BTREE_AM_OID)
#define CHECK_PAGE_OFFSET_RANGE(pg, offnum) { \
@@ -97,15 +91,20 @@ pgstatindex(PG_FUNCTION_ARGS)
uint32 blkno;
BTIndexStat indexStat;
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ (errmsg("must be superuser to use pgstattuple functions"))));
+
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
if (!IS_INDEX(rel) || !IS_BTREE(rel))
- elog(ERROR, "pgstatindex() can only be used on b-tree index");
+ elog(ERROR, "relation \"%s\" is not a btree index",
+ RelationGetRelationName(rel));
- /*-------------------
- * Read a metapage
- *-------------------
+ /*
+ * Read metapage
*/
{
Buffer buffer = ReadBuffer(rel, 0);
@@ -194,11 +193,12 @@ pgstatindex(PG_FUNCTION_ARGS)
{
TupleDesc tupleDesc;
int j;
- char *values[PGSTATINDEX_NCOLUMNS];
-
+ char *values[10];
HeapTuple tuple;
- tupleDesc = RelationNameGetTupleDesc(PGSTATINDEX_TYPE);
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
j = 0;
values[j] = palloc(32);
@@ -229,7 +229,7 @@ pgstatindex(PG_FUNCTION_ARGS)
tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc),
values);
- result = TupleGetDatum(TupleDescGetSlot(tupleDesc), tuple);
+ result = HeapTupleGetDatum(tuple);
}
PG_RETURN_DATUM(result);
@@ -238,7 +238,7 @@ pgstatindex(PG_FUNCTION_ARGS)
/* --------------------------------------------------------
* pg_relpages()
*
- * Get a number of pages of the table/index.
+ * Get the number of pages of the table/index.
*
* Usage: SELECT pg_relpages('t1');
* SELECT pg_relpages('t1_pkey');
@@ -248,11 +248,15 @@ Datum
pg_relpages(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_P(0);
-
Relation rel;
RangeVar *relrv;
int4 relpages;
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ (errmsg("must be superuser to use pgstattuple functions"))));
+
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index 64e7f982fb..9072a37aa9 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -1,5 +1,5 @@
/*
- * $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.27 2007/05/03 16:45:58 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.28 2007/08/26 23:59:50 tgl Exp $
*
* Copyright (c) 2001,2002 Tatsuo Ishii
*
@@ -24,14 +24,13 @@
#include "postgres.h"
-#include "fmgr.h"
-#include "funcapi.h"
#include "access/gist_private.h"
#include "access/hash.h"
#include "access/heapam.h"
#include "access/nbtree.h"
-#include "access/transam.h"
#include "catalog/namespace.h"
+#include "funcapi.h"
+#include "miscadmin.h"
#include "utils/builtins.h"
@@ -99,9 +98,6 @@ build_pgstattuple_type(pgstattuple_type * stat, FunctionCallInfo fcinfo)
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
- /* make sure we have a persistent copy of the tupdesc */
- tupdesc = CreateTupleDescCopy(tupdesc);
-
/*
* Generate attribute metadata needed later to produce tuples from raw C
* strings
@@ -163,6 +159,11 @@ pgstattuple(PG_FUNCTION_ARGS)
RangeVar *relrv;
Relation rel;
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ (errmsg("must be superuser to use pgstattuple functions"))));
+
/* open relation */
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
@@ -176,6 +177,11 @@ pgstattuplebyid(PG_FUNCTION_ARGS)
Oid relid = PG_GETARG_OID(0);
Relation rel;
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ (errmsg("must be superuser to use pgstattuple functions"))));
+
/* open relation */
rel = relation_open(relid, AccessShareLock);
diff --git a/contrib/pgstattuple/pgstattuple.sql.in b/contrib/pgstattuple/pgstattuple.sql.in
index 77a5e2d4b2..ec8f8b1bbe 100644
--- a/contrib/pgstattuple/pgstattuple.sql.in
+++ b/contrib/pgstattuple/pgstattuple.sql.in
@@ -1,48 +1,48 @@
-- Adjust this setting to control where the objects get created.
SET search_path = public;
-CREATE TYPE pgstattuple_type AS (
- table_len BIGINT, -- physical table length in bytes
- tuple_count BIGINT, -- number of live tuples
- tuple_len BIGINT, -- total tuples length in bytes
- tuple_percent FLOAT, -- live tuples in %
- dead_tuple_count BIGINT, -- number of dead tuples
- dead_tuple_len BIGINT, -- total dead tuples length in bytes
- dead_tuple_percent FLOAT, -- dead tuples in %
- free_space BIGINT, -- free space in bytes
- free_percent FLOAT -- free space in %
-);
-
-CREATE OR REPLACE FUNCTION pgstattuple(text)
-RETURNS pgstattuple_type
+CREATE OR REPLACE FUNCTION pgstattuple(IN relname text,
+ OUT table_len BIGINT, -- physical table length in bytes
+ OUT tuple_count BIGINT, -- number of live tuples
+ OUT tuple_len BIGINT, -- total tuples length in bytes
+ OUT tuple_percent FLOAT, -- live tuples in %
+ OUT dead_tuple_count BIGINT, -- number of dead tuples
+ OUT dead_tuple_len BIGINT, -- total dead tuples length in bytes
+ OUT dead_tuple_percent FLOAT, -- dead tuples in %
+ OUT free_space BIGINT, -- free space in bytes
+ OUT free_percent FLOAT) -- free space in %
AS 'MODULE_PATHNAME', 'pgstattuple'
LANGUAGE C STRICT;
-CREATE OR REPLACE FUNCTION pgstattuple(oid)
-RETURNS pgstattuple_type
+CREATE OR REPLACE FUNCTION pgstattuple(IN reloid oid,
+ OUT table_len BIGINT, -- physical table length in bytes
+ OUT tuple_count BIGINT, -- number of live tuples
+ OUT tuple_len BIGINT, -- total tuples length in bytes
+ OUT tuple_percent FLOAT, -- live tuples in %
+ OUT dead_tuple_count BIGINT, -- number of dead tuples
+ OUT dead_tuple_len BIGINT, -- total dead tuples length in bytes
+ OUT dead_tuple_percent FLOAT, -- dead tuples in %
+ OUT free_space BIGINT, -- free space in bytes
+ OUT free_percent FLOAT) -- free space in %
AS 'MODULE_PATHNAME', 'pgstattuplebyid'
LANGUAGE C STRICT;
--
-- pgstatindex
--
-CREATE TYPE pgstatindex_type AS (
- version int4,
- tree_level int4,
- index_size int4,
- root_block_no int4,
- internal_pages int4,
- leaf_pages int4,
- empty_pages int4,
- deleted_pages int4,
- avg_leaf_density float8,
- leaf_fragmentation float8
-);
-
-CREATE OR REPLACE FUNCTION pgstatindex(text)
-RETURNS pgstatindex_type
+CREATE OR REPLACE FUNCTION pgstatindex(IN relname text,
+ OUT version int4,
+ OUT tree_level int4,
+ OUT index_size int4,
+ OUT root_block_no int4,
+ OUT internal_pages int4,
+ OUT leaf_pages int4,
+ OUT empty_pages int4,
+ OUT deleted_pages int4,
+ OUT avg_leaf_density float8,
+ OUT leaf_fragmentation float8)
AS 'MODULE_PATHNAME', 'pgstatindex'
-LANGUAGE 'C' STRICT;
+LANGUAGE C STRICT;
--
-- pg_relpages()
@@ -50,4 +50,4 @@ LANGUAGE 'C' STRICT;
CREATE OR REPLACE FUNCTION pg_relpages(text)
RETURNS int
AS 'MODULE_PATHNAME', 'pg_relpages'
-LANGUAGE 'C' STRICT;
+LANGUAGE C STRICT;
diff --git a/contrib/pgstattuple/uninstall_pgstattuple.sql b/contrib/pgstattuple/uninstall_pgstattuple.sql
index 16f3d9aa32..6d97590d4d 100644
--- a/contrib/pgstattuple/uninstall_pgstattuple.sql
+++ b/contrib/pgstattuple/uninstall_pgstattuple.sql
@@ -1,11 +1,7 @@
-- Adjust this setting to control where the objects get created.
SET search_path = public;
-DROP FUNCTION pgstattuple(oid);
DROP FUNCTION pgstattuple(text);
-DROP TYPE pgstattuple_type;
-
+DROP FUNCTION pgstattuple(oid);
DROP FUNCTION pgstatindex(text);
-DROP TYPE pgstatindex_type;
-
DROP FUNCTION pg_relpages(text);