summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/lockfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/lockfuncs.c')
-rw-r--r--src/backend/utils/adt/lockfuncs.c86
1 files changed, 63 insertions, 23 deletions
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 2263a946039..e78d74f9efe 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -6,7 +6,7 @@
* Copyright (c) 2002-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/lockfuncs.c,v 1.28 2007/01/05 22:19:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/lockfuncs.c,v 1.29 2007/09/05 18:10:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,7 @@ static const char *const LockTagTypeNames[] = {
"page",
"tuple",
"transactionid",
+ "virtualxid",
"object",
"userlock",
"advisory"
@@ -39,6 +40,27 @@ typedef struct
int currIdx; /* current PROCLOCK index */
} PG_Lock_Status;
+
+/*
+ * VXIDGetDatum - Construct a text representation of a VXID
+ *
+ * This is currently only used in pg_lock_status, so we put it here.
+ */
+static Datum
+VXIDGetDatum(BackendId bid, LocalTransactionId lxid)
+{
+ /*
+ * The representation is "<bid>/<lxid>", decimal and unsigned decimal
+ * respectively. Note that elog.c also knows how to format a vxid.
+ */
+ char vxidstr[32];
+
+ snprintf(vxidstr, sizeof(vxidstr), "%d/%u", bid, lxid);
+
+ return DirectFunctionCall1(textin, CStringGetDatum(vxidstr));
+}
+
+
/*
* pg_lock_status - produce a view with one row per held or awaited lock mode
*/
@@ -64,7 +86,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
/* build tupdesc for result tuples */
/* this had better match pg_locks view in system_views.sql */
- tupdesc = CreateTemplateTupleDesc(13, false);
+ tupdesc = CreateTemplateTupleDesc(14, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "locktype",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database",
@@ -75,21 +97,23 @@ pg_lock_status(PG_FUNCTION_ARGS)
INT4OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "tuple",
INT2OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 6, "transactionid",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 6, "virtualxid",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 7, "transactionid",
XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 7, "classid",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 8, "classid",
OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 8, "objid",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 9, "objid",
OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 9, "objsubid",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 10, "objsubid",
INT2OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 10, "transaction",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 11, "pid",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 11, "virtualtransaction",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 12, "pid",
INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 12, "mode",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 13, "mode",
TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 13, "granted",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 14, "granted",
BOOLOID, -1, 0);
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
@@ -120,8 +144,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
LOCKMODE mode = 0;
const char *locktypename;
char tnbuf[32];
- Datum values[13];
- char nulls[13];
+ Datum values[14];
+ char nulls[14];
HeapTuple tuple;
Datum result;
@@ -193,7 +217,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
values[0] = DirectFunctionCall1(textin,
CStringGetDatum(locktypename));
-
switch (lock->tag.locktag_type)
{
case LOCKTAG_RELATION:
@@ -206,6 +229,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
nulls[6] = 'n';
nulls[7] = 'n';
nulls[8] = 'n';
+ nulls[9] = 'n';
break;
case LOCKTAG_PAGE:
values[1] = ObjectIdGetDatum(lock->tag.locktag_field1);
@@ -216,6 +240,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
nulls[6] = 'n';
nulls[7] = 'n';
nulls[8] = 'n';
+ nulls[9] = 'n';
break;
case LOCKTAG_TUPLE:
values[1] = ObjectIdGetDatum(lock->tag.locktag_field1);
@@ -226,9 +251,22 @@ pg_lock_status(PG_FUNCTION_ARGS)
nulls[6] = 'n';
nulls[7] = 'n';
nulls[8] = 'n';
+ nulls[9] = 'n';
break;
case LOCKTAG_TRANSACTION:
- values[5] = TransactionIdGetDatum(lock->tag.locktag_field1);
+ values[6] = TransactionIdGetDatum(lock->tag.locktag_field1);
+ nulls[1] = 'n';
+ nulls[2] = 'n';
+ nulls[3] = 'n';
+ nulls[4] = 'n';
+ nulls[5] = 'n';
+ nulls[7] = 'n';
+ nulls[8] = 'n';
+ nulls[9] = 'n';
+ break;
+ case LOCKTAG_VIRTUALTRANSACTION:
+ values[5] = VXIDGetDatum(lock->tag.locktag_field1,
+ lock->tag.locktag_field2);
nulls[1] = 'n';
nulls[2] = 'n';
nulls[3] = 'n';
@@ -236,31 +274,33 @@ pg_lock_status(PG_FUNCTION_ARGS)
nulls[6] = 'n';
nulls[7] = 'n';
nulls[8] = 'n';
+ nulls[9] = 'n';
break;
case LOCKTAG_OBJECT:
case LOCKTAG_USERLOCK:
case LOCKTAG_ADVISORY:
default: /* treat unknown locktags like OBJECT */
values[1] = ObjectIdGetDatum(lock->tag.locktag_field1);
- values[6] = ObjectIdGetDatum(lock->tag.locktag_field2);
- values[7] = ObjectIdGetDatum(lock->tag.locktag_field3);
- values[8] = Int16GetDatum(lock->tag.locktag_field4);
+ values[7] = ObjectIdGetDatum(lock->tag.locktag_field2);
+ values[8] = ObjectIdGetDatum(lock->tag.locktag_field3);
+ values[9] = Int16GetDatum(lock->tag.locktag_field4);
nulls[2] = 'n';
nulls[3] = 'n';
nulls[4] = 'n';
nulls[5] = 'n';
+ nulls[6] = 'n';
break;
}
- values[9] = TransactionIdGetDatum(proc->xid);
+ values[10] = VXIDGetDatum(proc->backendId, proc->lxid);
if (proc->pid != 0)
- values[10] = Int32GetDatum(proc->pid);
+ values[11] = Int32GetDatum(proc->pid);
else
- nulls[10] = 'n';
- values[11] = DirectFunctionCall1(textin,
+ nulls[11] = 'n';
+ values[12] = DirectFunctionCall1(textin,
CStringGetDatum(GetLockmodeName(LOCK_LOCKMETHOD(*lock),
mode)));
- values[12] = BoolGetDatum(granted);
+ values[13] = BoolGetDatum(granted);
tuple = heap_formtuple(funcctx->tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);