diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c index 16802b8..f91f717 100644 --- a/src/backend/executor/nodeTidscan.c +++ b/src/backend/executor/nodeTidscan.c @@ -143,7 +143,7 @@ TidListEval(TidScanState *tidstate) */ if (tidstate->ss.ss_currentScanDesc == NULL) tidstate->ss.ss_currentScanDesc = - table_beginscan(tidstate->ss.ss_currentRelation, + table_beginscan_tid(tidstate->ss.ss_currentRelation, tidstate->ss.ps.state->es_snapshot, 0, NULL); scan = tidstate->ss.ss_currentScanDesc; diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 696451f..de2de9a 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -830,6 +830,21 @@ table_beginscan_sampling(Relation rel, Snapshot snapshot, } /* + * table_beginscan_tid is an alternative entry point for setting up a + * TableScanDesc for a Tid scan. Although that scan technology is + * really quite unlike a standard seqscan, there is just enough commonality to + * make it worth using the same data structure. + */ +static inline TableScanDesc +table_beginscan_tid(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key) +{ + uint32 flags = SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* * table_beginscan_analyze is an alternative entry point for setting up a * TableScanDesc for an ANALYZE scan. As with bitmap scans, it's worth using * the same data structure although the behavior is rather different. diff --git a/src/test/regress/expected/tidscan.out b/src/test/regress/expected/tidscan.out index 9b5eb04..13c3c36 100644 --- a/src/test/regress/expected/tidscan.out +++ b/src/test/regress/expected/tidscan.out @@ -277,4 +277,20 @@ SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; (1 row) RESET enable_hashjoin; +-- check predicate lock on CTID +BEGIN ISOLATION LEVEL SERIALIZABLE; +SELECT * FROM tidscan WHERE ctid = '(0,1)'; + id +---- + 1 +(1 row) + +-- locktype should be 'tuple' +SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock'; + locktype | mode +----------+------------ + tuple | SIReadLock +(1 row) + +ROLLBACK; DROP TABLE tidscan; diff --git a/src/test/regress/sql/tidscan.sql b/src/test/regress/sql/tidscan.sql index ef05c09..313e0fb 100644 --- a/src/test/regress/sql/tidscan.sql +++ b/src/test/regress/sql/tidscan.sql @@ -94,4 +94,11 @@ SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; RESET enable_hashjoin; +-- check predicate lock on CTID +BEGIN ISOLATION LEVEL SERIALIZABLE; +SELECT * FROM tidscan WHERE ctid = '(0,1)'; +-- locktype should be 'tuple' +SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock'; +ROLLBACK; + DROP TABLE tidscan;