mirror of https://github.com/postgres/postgres
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.
This commit is contained in:
parent
38c75ecf83
commit
56f3fb3ba1
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
SET search_path = public;
|
||||
|
||||
DROP FUNCTION pgrowlocks(text);
|
||||
|
||||
DROP TYPE pgrowlocks_type;
|
||||
|
|
Loading…
Reference in New Issue