Thread: BUG #15513: PID=0 in pgrowlocks output when using savepoints

BUG #15513: PID=0 in pgrowlocks output when using savepoints

From
PG Bug reporting form
Date:
The following bug has been logged on the website:

Bug reference:      15513
Logged by:          Steven Winfield
Email address:      steven.winfield@cantabcapital.com
PostgreSQL version: 10.4
Operating system:   RHEL 7.5
Description:

CREATE EXTENSION IF NOT EXISTS pgrowlocks;

CREATE TABLE lock_test (id integer, name text);
INSERT INTO lock_test VALUES (1, 'foo');

BEGIN;
SELECT * FROM lock_test WHERE id = 1 FOR KEY SHARE;
SELECT pids FROM pgrowlocks('lock_test');

-- Returns an array with one element - the current backend PID - as
expected

ROLLBACK;

BEGIN;
SAVEPOINT sp;
SELECT * FROM lock_test WHERE id = 1 FOR KEY SHARE;
SELECT pids FROM pgrowlocks('lock_test');

-- Returns an array with a single element - zero. I expected the current
backend PID again.

ROLLBACK;


It looks like this is because in pgrowlocks.c the 'pids' array is filled
using BackendXidGetPid(xmax), whose documentation says:

/*
 * BackendXidGetPid -- get a backend's pid given its XID
 *
 * Returns 0 if not found or it's a prepared transaction.  Note that
 * it is up to the caller to be sure that the question remains
 * meaningful for long enough for the answer to be used ...
 *
 * Only main transaction Ids are considered.  This function is mainly
 * useful for determining what backend owns a lock.
 *
 * Beware that not every xact has an XID assigned.  However, as long as
you
 * only call this using an XID found on disk, you're safe.
 */

It looks like xmax is coming from disk...

while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
...
xmax = HeapTupleHeaderGetRawXmax(tuple->t_data);

...and a savepoint isn't a prepared transaction (is it?), so perhaps xmax is
now not a "main transaction Id"?

Either way, it would be nice if pgrowlocks worked for locks taken inside
savepoints or if the presence of zeros (and their possible meanings) was
explained in the pgrowlocks documentation.

Thanks,
Steven.