summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2007-08-27 00:13:51 +0000
committerTom Lane2007-08-27 00:13:51 +0000
commit56f3fb3ba1aed1efbfb6b50e55159df8a0ad2f39 (patch)
tree18646babf3491ef3c493b7925cd3cb056dd216ac
parent38c75ecf8345bd338112ad2a3221dfc47929fb7e (diff)
Restrict pgrowlocks function 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/pgrowlocks/README.pgrowlocks14
-rw-r--r--contrib/pgrowlocks/pgrowlocks.c50
-rw-r--r--contrib/pgrowlocks/pgrowlocks.sql.in21
-rw-r--r--contrib/pgrowlocks/uninstall_pgrowlocks.sql2
4 files changed, 26 insertions, 61 deletions
diff --git a/contrib/pgrowlocks/README.pgrowlocks b/contrib/pgrowlocks/README.pgrowlocks
index ebaea4ca5a..6964cc9c73 100644
--- a/contrib/pgrowlocks/README.pgrowlocks
+++ b/contrib/pgrowlocks/README.pgrowlocks
@@ -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:
diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c
index 002536b920..73dea0c4a5 100644
--- a/contrib/pgrowlocks/pgrowlocks.c
+++ b/contrib/pgrowlocks/pgrowlocks.c
@@ -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
*
@@ -24,19 +24,15 @@
#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);
diff --git a/contrib/pgrowlocks/pgrowlocks.sql.in b/contrib/pgrowlocks/pgrowlocks.sql.in
index 0607c44349..0370831e66 100644
--- a/contrib/pgrowlocks/pgrowlocks.sql.in
+++ b/contrib/pgrowlocks/pgrowlocks.sql.in
@@ -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;
diff --git a/contrib/pgrowlocks/uninstall_pgrowlocks.sql b/contrib/pgrowlocks/uninstall_pgrowlocks.sql
index 9e37d11975..b1a1f58b52 100644
--- a/contrib/pgrowlocks/uninstall_pgrowlocks.sql
+++ b/contrib/pgrowlocks/uninstall_pgrowlocks.sql
@@ -1,5 +1,3 @@
SET search_path = public;
DROP FUNCTION pgrowlocks(text);
-
-DROP TYPE pgrowlocks_type;