summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2007-08-27 00:13:51 +0000
committerTom Lane2007-08-27 00:13:51 +0000
commit1dd9998befe1c2a84ceb50e776b29fd316eab463 (patch)
tree5e03b10cbc88e0534add1803156ca7c9e60192ab
parentb0335ca6920bae01205548c8935229c4c5efb4c2 (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.pgrowlocks12
-rw-r--r--contrib/pgrowlocks/pgrowlocks.c48
-rw-r--r--contrib/pgrowlocks/pgrowlocks.sql.in21
-rw-r--r--contrib/pgrowlocks/uninstall_pgrowlocks.sql2
4 files changed, 24 insertions, 59 deletions
diff --git a/contrib/pgrowlocks/README.pgrowlocks b/contrib/pgrowlocks/README.pgrowlocks
index ed238bc575..e06fbeee77 100644
--- a/contrib/pgrowlocks/README.pgrowlocks
+++ b/contrib/pgrowlocks/README.pgrowlocks
@@ -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 f3a7822d83..8197379ec2 100644
--- a/contrib/pgrowlocks/pgrowlocks.c
+++ b/contrib/pgrowlocks/pgrowlocks.c
@@ -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;