aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-08-26 23:59:50 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-08-26 23:59:50 +0000
commit38c75ecf8345bd338112ad2a3221dfc47929fb7e (patch)
tree0f276f68263c40607ba2eb14d8612e8c6066cea4
parent0effa088f5a5b55ab5b963159d18cc26dc7ccc4e (diff)
downloadpostgresql-38c75ecf8345bd338112ad2a3221dfc47929fb7e.tar.gz
postgresql-38c75ecf8345bd338112ad2a3221dfc47929fb7e.zip
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 0c2c9a14484..3018b6aedd1 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 64e7f982fba..9072a37aa91 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 77a5e2d4b2d..ec8f8b1bbe0 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 16f3d9aa321..6d97590d4d6 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);