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..162e1b6 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -47,18 +47,19 @@ typedef enum ScanOptions
 	SO_TYPE_SEQSCAN = 1 << 0,
 	SO_TYPE_BITMAPSCAN = 1 << 1,
 	SO_TYPE_SAMPLESCAN = 1 << 2,
-	SO_TYPE_ANALYZE = 1 << 3,
+	SO_TYPE_TIDSCAN = 1 << 3,
+	SO_TYPE_ANALYZE = 1 << 4,
 
 	/* several of SO_ALLOW_* may be specified */
 	/* allow or disallow use of access strategy */
-	SO_ALLOW_STRAT = 1 << 4,
+	SO_ALLOW_STRAT = 1 << 5,
 	/* report location to syncscan logic? */
-	SO_ALLOW_SYNC = 1 << 5,
+	SO_ALLOW_SYNC = 1 << 6,
 	/* verify visibility page-at-a-time? */
-	SO_ALLOW_PAGEMODE = 1 << 6,
+	SO_ALLOW_PAGEMODE = 1 << 7,
 
 	/* unregister snapshot at scan end? */
-	SO_TEMP_SNAPSHOT = 1 << 7
+	SO_TEMP_SNAPSHOT = 1 << 8
 } ScanOptions;
 
 /*
@@ -830,6 +831,23 @@ 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.
+ * For now, There are no cases where SO_TYPE_TIDSCAN is used, 
+ * but it may be useful to improve future Tid scans.
+ */
+static inline TableScanDesc
+table_beginscan_tid(Relation rel, Snapshot snapshot,
+				int nkeys, struct ScanKeyData *key)
+{
+	uint32		flags = SO_TYPE_TIDSCAN;
+
+	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;
