11/*
2- * $PostgreSQL: pgsql/contrib/pgrowlocks/pgrowlocks.c,v 1.5 2006/10/04 00:29:46 momjian Exp $
2+ * $PostgreSQL: pgsql/contrib/pgrowlocks/pgrowlocks.c,v 1.6 2007/08/27 00:13:51 tgl Exp $
33 *
44 * Copyright (c) 2005-2006Tatsuo Ishii
55 *
2424
2525#include "postgres.h"
2626
27- #include "funcapi.h"
2827#include "access/heapam.h"
29- #include "access/transam .h"
28+ #include "access/multixact .h"
3029#include "access/xact.h"
3130#include "catalog/namespace.h"
32- #include "catalog/pg_type.h"
33- #include "storage/proc.h"
31+ #include "funcapi.h"
32+ #include "miscadmin.h"
33+ #include "storage/procarray.h"
3434#include "utils/builtins.h"
3535
36- #ifdef HEAP_XMAX_SHARED_LOCK
37- #include "access/multixact.h"
38- #include "storage/procarray.h"
39- #endif
4036
4137PG_MODULE_MAGIC ;
4238
@@ -47,22 +43,11 @@ extern Datum pgrowlocks(PG_FUNCTION_ARGS);
4743/* ----------
4844 * pgrowlocks:
4945 * returns tids of rows being locked
50- *
51- * C FUNCTION definition
52- * pgrowlocks(text) returns set of pgrowlocks_type
53- * see pgrowlocks.sql for pgrowlocks_type
5446 * ----------
5547 */
5648
57- #define DUMMY_TUPLE "public.pgrowlocks_type"
5849#define NCHARS 32
5950
60- /*
61- * define this if makeRangeVarFromNameList() has two arguments. As far
62- * as I know, this only happens in 8.0.x.
63- */
64- #undef MAKERANGEVARFROMNAMELIST_HAS_TWO_ARGS
65-
6651typedef struct
6752{
6853Relation rel ;
@@ -82,6 +67,11 @@ pgrowlocks(PG_FUNCTION_ARGS)
8267MyData * mydata ;
8368Relation rel ;
8469
70+ if (!superuser ())
71+ ereport (ERROR ,
72+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
73+ (errmsg ("must be superuser to use pgrowlocks" ))));
74+
8575if (SRF_IS_FIRSTCALL ())
8676{
8777text * relname ;
@@ -91,17 +81,17 @@ pgrowlocks(PG_FUNCTION_ARGS)
9181funcctx = SRF_FIRSTCALL_INIT ();
9282oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
9383
94- tupdesc = RelationNameGetTupleDesc (DUMMY_TUPLE );
84+ /* Build a tuple descriptor for our result type */
85+ if (get_call_result_type (fcinfo ,NULL ,& tupdesc )!= TYPEFUNC_COMPOSITE )
86+ elog (ERROR ,"return type must be a row type" );
87+
9588attinmeta = TupleDescGetAttInMetadata (tupdesc );
9689funcctx -> attinmeta = attinmeta ;
9790
9891relname = PG_GETARG_TEXT_P (0 );
99- #ifdef MAKERANGEVARFROMNAMELIST_HAS_TWO_ARGS
100- relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ,"pgrowlocks" ));
101- #else
10292relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ));
103- #endif
10493rel = heap_openrv (relrv ,AccessShareLock );
94+
10595scan = heap_beginscan (rel ,SnapshotNow ,0 ,NULL );
10696mydata = palloc (sizeof (* mydata ));
10797mydata -> rel = rel ;
@@ -135,17 +125,12 @@ pgrowlocks(PG_FUNCTION_ARGS)
135125i = 0 ;
136126values [i ++ ]= (char * )DirectFunctionCall1 (tidout ,PointerGetDatum (& tuple -> t_self ));
137127
138- #ifdef HEAP_XMAX_SHARED_LOCK
139128if (tuple -> t_data -> t_infomask & HEAP_XMAX_SHARED_LOCK )
140129values [i ++ ]= pstrdup ("Shared" );
141130else
142131values [i ++ ]= pstrdup ("Exclusive" );
143- #else
144- values [i ++ ]= pstrdup ("Exclusive" );
145- #endif
146132values [i ]= palloc (NCHARS * sizeof (char ));
147133snprintf (values [i ++ ],NCHARS ,"%d" ,HeapTupleHeaderGetXmax (tuple -> t_data ));
148- #ifdef HEAP_XMAX_SHARED_LOCK
149134if (tuple -> t_data -> t_infomask & HEAP_XMAX_IS_MULTI )
150135{
151136TransactionId * xids ;
@@ -198,11 +183,6 @@ pgrowlocks(PG_FUNCTION_ARGS)
198183values [i ]= palloc (NCHARS * sizeof (char ));
199184snprintf (values [i ++ ],NCHARS ,"{%d}" ,BackendXidGetPid (HeapTupleHeaderGetXmax (tuple -> t_data )));
200185}
201- #else
202- values [i ++ ]= pstrdup ("false" );
203- values [i ++ ]= pstrdup ("{}" );
204- values [i ++ ]= pstrdup ("{}" );
205- #endif
206186
207187LockBuffer (scan -> rs_cbuf ,BUFFER_LOCK_UNLOCK );
208188