]> granicus.if.org Git - postgresql/commitdiff
Restrict pgrowlocks function to superusers. (This might be too strict,
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 27 Aug 2007 00:13:51 +0000 (00:13 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 27 Aug 2007 00:13:51 +0000 (00:13 +0000)
but no permissions check at all is certainly no good.)  Clean up usage
of some deprecated APIs.

contrib/pgrowlocks/README.pgrowlocks
contrib/pgrowlocks/pgrowlocks.c
contrib/pgrowlocks/pgrowlocks.sql.in
contrib/pgrowlocks/uninstall_pgrowlocks.sql

index ebaea4ca5a3bb406020dc0cb970c4e5d453ba29e..6964cc9c73e0463506d0870692640c437f1a317f 100644 (file)
@@ -1,4 +1,4 @@
-$PostgreSQL: pgsql/contrib/pgrowlocks/README.pgrowlocks,v 1.1 2006/04/23 01:12:58 ishii Exp $
+$PostgreSQL: pgsql/contrib/pgrowlocks/README.pgrowlocks,v 1.2 2007/08/27 00:13:51 tgl Exp $
 
 pgrowlocks README                      Tatsuo Ishii
 
@@ -6,16 +6,14 @@ pgrowlocks README                     Tatsuo Ishii
 
    pgrowlocks shows row locking information for specified table.
 
-   pgrowlocks returns following data type:
+   pgrowlocks returns following columns:
 
-CREATE TYPE pgrowlocks_type AS (
        locked_row TID,         -- row TID
        lock_type TEXT,         -- lock type
        locker XID,             -- locking XID
        multi bool,             -- multi XID?
        xids xid[],             -- multi XIDs
        pids INTEGER[]          -- locker's process id
-);
 
   Here is a sample execution of pgrowlocks:
 
@@ -62,14 +60,6 @@ test=# SELECT * FROM pgrowlocks('t1');
 
 3. How to use pgrowlocks
 
-   The calling sequence for pgrowlocks is as follows:
-
-   CREATE OR REPLACE FUNCTION pgrowlocks(text) RETURNS pgrowlocks_type
-     AS 'MODULE_PATHNAME', 'pgrowlocks'
-     LANGUAGE 'c' WITH (isstrict);
-
-   The parameter is a name of table. pgrowlocks returns type pgrowlocks_type.
-
    pgrowlocks grab AccessShareLock for the target table and read each
    row one by one to get the row locking information. You should
    notice that:
index 002536b920196588d10ef777abbe339f77ad31ba..73dea0c4a56188f546dceec3bc0eb574fdc0a4fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pgrowlocks/pgrowlocks.c,v 1.5 2006/10/04 00:29:46 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/pgrowlocks/pgrowlocks.c,v 1.6 2007/08/27 00:13:51 tgl Exp $
  *
  * Copyright (c) 2005-2006     Tatsuo Ishii
  *
 
 #include "postgres.h"
 
-#include "funcapi.h"
 #include "access/heapam.h"
-#include "access/transam.h"
+#include "access/multixact.h"
 #include "access/xact.h"
 #include "catalog/namespace.h"
-#include "catalog/pg_type.h"
-#include "storage/proc.h"
+#include "funcapi.h"
+#include "miscadmin.h"
+#include "storage/procarray.h"
 #include "utils/builtins.h"
 
-#ifdef HEAP_XMAX_SHARED_LOCK
-#include "access/multixact.h"
-#include "storage/procarray.h"
-#endif
 
 PG_MODULE_MAGIC;
 
@@ -47,22 +43,11 @@ extern Datum pgrowlocks(PG_FUNCTION_ARGS);
 /* ----------
  * pgrowlocks:
  * returns tids of rows being locked
- *
- * C FUNCTION definition
- * pgrowlocks(text) returns set of pgrowlocks_type
- * see pgrowlocks.sql for pgrowlocks_type
  * ----------
  */
 
-#define DUMMY_TUPLE "public.pgrowlocks_type"
 #define NCHARS 32
 
-/*
- * define this if makeRangeVarFromNameList() has two arguments. As far
- * as I know, this only happens in 8.0.x.
- */
-#undef MAKERANGEVARFROMNAMELIST_HAS_TWO_ARGS
-
 typedef struct
 {
        Relation        rel;
@@ -82,6 +67,11 @@ pgrowlocks(PG_FUNCTION_ARGS)
        MyData     *mydata;
        Relation        rel;
 
+       if (!superuser())
+               ereport(ERROR,
+                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                (errmsg("must be superuser to use pgrowlocks"))));
+
        if (SRF_IS_FIRSTCALL())
        {
                text       *relname;
@@ -91,17 +81,17 @@ pgrowlocks(PG_FUNCTION_ARGS)
                funcctx = SRF_FIRSTCALL_INIT();
                oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-               tupdesc = RelationNameGetTupleDesc(DUMMY_TUPLE);
+               /* Build a tuple descriptor for our result type */
+               if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+                       elog(ERROR, "return type must be a row type");
+
                attinmeta = TupleDescGetAttInMetadata(tupdesc);
                funcctx->attinmeta = attinmeta;
 
                relname = PG_GETARG_TEXT_P(0);
-#ifdef MAKERANGEVARFROMNAMELIST_HAS_TWO_ARGS
-               relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname, "pgrowlocks"));
-#else
                relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
-#endif
                rel = heap_openrv(relrv, AccessShareLock);
+
                scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
                mydata = palloc(sizeof(*mydata));
                mydata->rel = rel;
@@ -135,17 +125,12 @@ pgrowlocks(PG_FUNCTION_ARGS)
                        i = 0;
                        values[i++] = (char *) DirectFunctionCall1(tidout, PointerGetDatum(&tuple->t_self));
 
-#ifdef HEAP_XMAX_SHARED_LOCK
                        if (tuple->t_data->t_infomask & HEAP_XMAX_SHARED_LOCK)
                                values[i++] = pstrdup("Shared");
                        else
                                values[i++] = pstrdup("Exclusive");
-#else
-                       values[i++] = pstrdup("Exclusive");
-#endif
                        values[i] = palloc(NCHARS * sizeof(char));
                        snprintf(values[i++], NCHARS, "%d", HeapTupleHeaderGetXmax(tuple->t_data));
-#ifdef HEAP_XMAX_SHARED_LOCK
                        if (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)
                        {
                                TransactionId *xids;
@@ -198,11 +183,6 @@ pgrowlocks(PG_FUNCTION_ARGS)
                                values[i] = palloc(NCHARS * sizeof(char));
                                snprintf(values[i++], NCHARS, "{%d}", BackendXidGetPid(HeapTupleHeaderGetXmax(tuple->t_data)));
                        }
-#else
-                       values[i++] = pstrdup("false");
-                       values[i++] = pstrdup("{}");
-                       values[i++] = pstrdup("{}");
-#endif
 
                        LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
 
index 0607c44349072aeb24017ca01002161ee4ad5aa8..0370831e66a682aa2b16b32829c2e9ed9ce4338c 100644 (file)
@@ -1,16 +1,13 @@
 -- Adjust this setting to control where the objects get created.
 SET search_path = public;
 
-CREATE TYPE pgrowlocks_type AS (
-       locked_row TID,         -- row TID
-       lock_type TEXT,         -- lock type
-       locker XID,             -- locking XID
-       multi bool,             -- multi XID?
-       xids xid[],             -- multi XIDs
-       pids INTEGER[]          -- locker's process id
-);
-
-CREATE OR REPLACE FUNCTION pgrowlocks(text)
-RETURNS setof pgrowlocks_type
+CREATE OR REPLACE FUNCTION pgrowlocks(IN relname text,
+    OUT locked_row TID,                -- row TID
+    OUT lock_type TEXT,                -- lock type
+    OUT locker XID,            -- locking XID
+    OUT multi bool,            -- multi XID?
+    OUT xids xid[],            -- multi XIDs
+    OUT pids INTEGER[])                -- locker's process id
+RETURNS SETOF record
 AS 'MODULE_PATHNAME', 'pgrowlocks'
-LANGUAGE 'C' STRICT;
+LANGUAGE C STRICT;
index 9e37d11975540eca7c81e69a3576676ff784cafa..b1a1f58b52d2b91ae253924c54350ae150239af9 100644 (file)
@@ -1,5 +1,3 @@
 SET search_path = public;
 
 DROP FUNCTION pgrowlocks(text);
-
-DROP TYPE pgrowlocks_type;