OSDN Git Service

Restrict pgstattuple functions to superusers. (This might be too strict,
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 26 Aug 2007 23:59:50 +0000 (23:59 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 26 Aug 2007 23:59:50 +0000 (23:59 +0000)
but no permissions check at all is certainly no good.)  Clean up usage
of some deprecated APIs.

contrib/pgstattuple/pgstatindex.c
contrib/pgstattuple/pgstattuple.c
contrib/pgstattuple/pgstattuple.sql.in
contrib/pgstattuple/uninstall_pgstattuple.sql

index 0c2c9a1..3018b6a 100644 (file)
 
 #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);
 
index 64e7f98..9072a37 100644 (file)
@@ -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
  *
 
 #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);
 
index 77a5e2d..ec8f8b1 100644 (file)
@@ -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;
index 16f3d9a..6d97590 100644 (file)
@@ -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);