diff --git a/src/backend/optimizer/prep/prepsecurity.c b/src/backend/optimizer/prep/prepsecurity.c
index af3ee61bef15010f751b2a4b4b2c68e1eb21ecb8..08309538ffabe90c858cc55b1fc8b5e9748e9745 100644
--- a/src/backend/optimizer/prep/prepsecurity.c
+++ b/src/backend/optimizer/prep/prepsecurity.c
@@ -37,7 +37,7 @@ typedef struct
 } security_barrier_replace_vars_context;
 
 static void expand_security_qual(PlannerInfo *root, List *tlist, int rt_index,
-					 RangeTblEntry *rte, Node *qual);
+					 RangeTblEntry *rte, Node *qual, bool targetRelation);
 
 static void security_barrier_replace_vars(Node *node,
 							  security_barrier_replace_vars_context *context);
@@ -63,6 +63,7 @@ expand_security_quals(PlannerInfo *root, List *tlist)
 	Query	   *parse = root->parse;
 	int			rt_index;
 	ListCell   *cell;
+	bool		targetRelation = false;
 
 	/*
 	 * Process each RTE in the rtable list.
@@ -98,6 +99,15 @@ expand_security_quals(PlannerInfo *root, List *tlist)
 		{
 			RangeTblEntry *newrte = copyObject(rte);
 
+			/*
+			 * We need to let expand_security_qual know if this is the target
+			 * relation, as it has additional work to do in that case.
+			 *
+			 * Capture that information here as we're about to replace
+			 * parse->resultRelation.
+			 */
+			targetRelation = true;
+
 			parse->rtable = lappend(parse->rtable, newrte);
 			parse->resultRelation = list_length(parse->rtable);
 
@@ -147,7 +157,8 @@ expand_security_quals(PlannerInfo *root, List *tlist)
 			rte->securityQuals = list_delete_first(rte->securityQuals);
 
 			ChangeVarNodes(qual, rt_index, 1, 0);
-			expand_security_qual(root, tlist, rt_index, rte, qual);
+			expand_security_qual(root, tlist, rt_index, rte, qual,
+								 targetRelation);
 		}
 	}
 }
@@ -160,7 +171,7 @@ expand_security_quals(PlannerInfo *root, List *tlist)
  */
 static void
 expand_security_qual(PlannerInfo *root, List *tlist, int rt_index,
-					 RangeTblEntry *rte, Node *qual)
+					 RangeTblEntry *rte, Node *qual, bool targetRelation)
 {
 	Query	   *parse = root->parse;
 	Oid			relid = rte->relid;
@@ -219,10 +230,11 @@ expand_security_qual(PlannerInfo *root, List *tlist, int rt_index,
 			 * Now deal with any PlanRowMark on this RTE by requesting a lock
 			 * of the same strength on the RTE copied down to the subquery.
 			 *
-			 * Note that we can't push the user-defined quals down since they
-			 * may included untrusted functions and that means that we will
-			 * end up locking all rows which pass the securityQuals, even if
-			 * those rows don't pass the user-defined quals.  This is
+			 * Note that we can only push down user-defined quals if they are
+			 * only using leakproof (and therefore trusted) functions and
+			 * operators.  As a result, we may end up locking more rows than
+			 * strictly necessary (and, in the worst case, we could end up
+			 * locking all rows which pass the securityQuals).  This is
 			 * currently documented behavior, but it'd be nice to come up with
 			 * a better solution some day.
 			 */
@@ -255,6 +267,15 @@ expand_security_qual(PlannerInfo *root, List *tlist, int rt_index,
 				root->rowMarks = list_delete(root->rowMarks, rc);
 			}
 
+			/*
+			 * When we are replacing the target relation with a subquery, we
+			 * need to make sure to add a locking clause explicitly to the
+			 * generated subquery since there won't be any row marks against
+			 * the target relation itself.
+			 */
+			if (targetRelation)
+				applyLockingClause(subquery, 1, LCS_FORUPDATE,
+								   LockWaitBlock, false);
 			/*
 			 * Replace any variables in the outer query that refer to the
 			 * original relation RTE with references to columns that we will
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 21817d8b75594d1c2936c75228ca55a5f2985223..f41bef170443fe04a4ac2462a5b167564c9fdd84 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -1034,22 +1034,25 @@ EXPLAIN (COSTS OFF) EXECUTE p2(2);
 --
 SET SESSION AUTHORIZATION rls_regress_user1;
 EXPLAIN (COSTS OFF) UPDATE t1 SET b = b || b WHERE f_leak(b);
-             QUERY PLAN              
--------------------------------------
+                QUERY PLAN                 
+-------------------------------------------
  Update on t1 t1_3
    ->  Subquery Scan on t1
          Filter: f_leak(t1.b)
-         ->  Seq Scan on t1 t1_4
-               Filter: ((a % 2) = 0)
+         ->  LockRows
+               ->  Seq Scan on t1 t1_4
+                     Filter: ((a % 2) = 0)
    ->  Subquery Scan on t1_1
          Filter: f_leak(t1_1.b)
-         ->  Seq Scan on t2
-               Filter: ((a % 2) = 0)
+         ->  LockRows
+               ->  Seq Scan on t2
+                     Filter: ((a % 2) = 0)
    ->  Subquery Scan on t1_2
          Filter: f_leak(t1_2.b)
-         ->  Seq Scan on t3
-               Filter: ((a % 2) = 0)
-(13 rows)
+         ->  LockRows
+               ->  Seq Scan on t3
+                     Filter: ((a % 2) = 0)
+(16 rows)
 
 UPDATE t1 SET b = b || b WHERE f_leak(b);
 NOTICE:  f_leak => bbb
@@ -1058,14 +1061,15 @@ NOTICE:  f_leak => bcd
 NOTICE:  f_leak => def
 NOTICE:  f_leak => yyy
 EXPLAIN (COSTS OFF) UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
-             QUERY PLAN              
--------------------------------------
+                QUERY PLAN                 
+-------------------------------------------
  Update on t1 t1_1
    ->  Subquery Scan on t1
          Filter: f_leak(t1.b)
-         ->  Seq Scan on t1 t1_2
-               Filter: ((a % 2) = 0)
-(5 rows)
+         ->  LockRows
+               ->  Seq Scan on t1 t1_2
+                     Filter: ((a % 2) = 0)
+(6 rows)
 
 UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
 NOTICE:  f_leak => bbbbbb
@@ -1131,32 +1135,36 @@ SELECT * FROM t1;
 SET SESSION AUTHORIZATION rls_regress_user1;
 SET row_security TO ON;
 EXPLAIN (COSTS OFF) DELETE FROM only t1 WHERE f_leak(b);
-             QUERY PLAN              
--------------------------------------
+                QUERY PLAN                 
+-------------------------------------------
  Delete on t1 t1_1
    ->  Subquery Scan on t1
          Filter: f_leak(t1.b)
-         ->  Seq Scan on t1 t1_2
-               Filter: ((a % 2) = 0)
-(5 rows)
+         ->  LockRows
+               ->  Seq Scan on t1 t1_2
+                     Filter: ((a % 2) = 0)
+(6 rows)
 
 EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b);
-             QUERY PLAN              
--------------------------------------
+                QUERY PLAN                 
+-------------------------------------------
  Delete on t1 t1_3
    ->  Subquery Scan on t1
          Filter: f_leak(t1.b)
-         ->  Seq Scan on t1 t1_4
-               Filter: ((a % 2) = 0)
+         ->  LockRows
+               ->  Seq Scan on t1 t1_4
+                     Filter: ((a % 2) = 0)
    ->  Subquery Scan on t1_1
          Filter: f_leak(t1_1.b)
-         ->  Seq Scan on t2
-               Filter: ((a % 2) = 0)
+         ->  LockRows
+               ->  Seq Scan on t2
+                     Filter: ((a % 2) = 0)
    ->  Subquery Scan on t1_2
          Filter: f_leak(t1_2.b)
-         ->  Seq Scan on t3
-               Filter: ((a % 2) = 0)
-(13 rows)
+         ->  LockRows
+               ->  Seq Scan on t3
+                     Filter: ((a % 2) = 0)
+(16 rows)
 
 DELETE FROM only t1 WHERE f_leak(b) RETURNING oid, *, t1;
 NOTICE:  f_leak => bbbbbb_updt
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
index 80c5706b0b65979026012c63b17be4a3228df9fc..c49e769bf830b78cf72c9bbea0d749a486a68f8d 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -1842,24 +1842,26 @@ EXPLAIN (costs off) SELECT * FROM rw_view1 WHERE snoop(person);
 (4 rows)
 
 EXPLAIN (costs off) UPDATE rw_view1 SET person=person WHERE snoop(person);
-                     QUERY PLAN                      
------------------------------------------------------
+                        QUERY PLAN                         
+-----------------------------------------------------------
  Update on base_tbl base_tbl_1
    ->  Subquery Scan on base_tbl
          Filter: snoop(base_tbl.person)
-         ->  Seq Scan on base_tbl base_tbl_2
-               Filter: (visibility = 'public'::text)
-(5 rows)
+         ->  LockRows
+               ->  Seq Scan on base_tbl base_tbl_2
+                     Filter: (visibility = 'public'::text)
+(6 rows)
 
 EXPLAIN (costs off) DELETE FROM rw_view1 WHERE NOT snoop(person);
-                     QUERY PLAN                      
------------------------------------------------------
+                        QUERY PLAN                         
+-----------------------------------------------------------
  Delete on base_tbl base_tbl_1
    ->  Subquery Scan on base_tbl
          Filter: (NOT snoop(base_tbl.person))
-         ->  Seq Scan on base_tbl base_tbl_2
-               Filter: (visibility = 'public'::text)
-(5 rows)
+         ->  LockRows
+               ->  Seq Scan on base_tbl base_tbl_2
+                     Filter: (visibility = 'public'::text)
+(6 rows)
 
 -- security barrier view on top of security barrier view
 CREATE VIEW rw_view2 WITH (security_barrier = true) AS
@@ -1922,28 +1924,30 @@ EXPLAIN (costs off) SELECT * FROM rw_view2 WHERE snoop(person);
 (6 rows)
 
 EXPLAIN (costs off) UPDATE rw_view2 SET person=person WHERE snoop(person);
-                        QUERY PLAN                         
------------------------------------------------------------
+                           QUERY PLAN                            
+-----------------------------------------------------------------
  Update on base_tbl base_tbl_1
    ->  Subquery Scan on base_tbl
          Filter: snoop(base_tbl.person)
          ->  Subquery Scan on base_tbl_2
                Filter: snoop(base_tbl_2.person)
-               ->  Seq Scan on base_tbl base_tbl_3
-                     Filter: (visibility = 'public'::text)
-(7 rows)
+               ->  LockRows
+                     ->  Seq Scan on base_tbl base_tbl_3
+                           Filter: (visibility = 'public'::text)
+(8 rows)
 
 EXPLAIN (costs off) DELETE FROM rw_view2 WHERE NOT snoop(person);
-                        QUERY PLAN                         
------------------------------------------------------------
+                           QUERY PLAN                            
+-----------------------------------------------------------------
  Delete on base_tbl base_tbl_1
    ->  Subquery Scan on base_tbl
          Filter: (NOT snoop(base_tbl.person))
          ->  Subquery Scan on base_tbl_2
                Filter: snoop(base_tbl_2.person)
-               ->  Seq Scan on base_tbl base_tbl_3
-                     Filter: (visibility = 'public'::text)
-(7 rows)
+               ->  LockRows
+                     ->  Seq Scan on base_tbl base_tbl_3
+                           Filter: (visibility = 'public'::text)
+(8 rows)
 
 DROP TABLE base_tbl CASCADE;
 NOTICE:  drop cascades to 2 other objects
@@ -2057,70 +2061,78 @@ SELECT * FROM v1 WHERE a=8;
 
 EXPLAIN (VERBOSE, COSTS OFF)
 UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a = 3;
-                                        QUERY PLAN                                         
--------------------------------------------------------------------------------------------
+                                                             QUERY PLAN                                                             
+------------------------------------------------------------------------------------------------------------------------------------
  Update on public.t1 t1_4
    ->  Subquery Scan on t1
          Output: 100, t1.b, t1.c, t1.ctid
          Filter: snoop(t1.a)
-         ->  Nested Loop Semi Join
-               Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c
-               ->  Seq Scan on public.t1 t1_5
-                     Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c
-                     Filter: ((t1_5.a > 5) AND (t1_5.a = 3) AND leakproof(t1_5.a))
-               ->  Append
-                     ->  Seq Scan on public.t12
-                           Output: t12.a
-                           Filter: (t12.a = 3)
-                     ->  Seq Scan on public.t111
-                           Output: t111.a
-                           Filter: (t111.a = 3)
+         ->  LockRows
+               Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
+                     ->  Seq Scan on public.t1 t1_5
+                           Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c
+                           Filter: ((t1_5.a > 5) AND (t1_5.a = 3) AND leakproof(t1_5.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12
+                                 Output: t12.ctid, t12.tableoid, t12.a
+                                 Filter: (t12.a = 3)
+                           ->  Seq Scan on public.t111
+                                 Output: t111.ctid, t111.tableoid, t111.a
+                                 Filter: (t111.a = 3)
    ->  Subquery Scan on t1_1
          Output: 100, t1_1.b, t1_1.c, t1_1.d, t1_1.ctid
          Filter: snoop(t1_1.a)
-         ->  Nested Loop Semi Join
-               Output: t11.ctid, t11.a, t11.b, t11.c, t11.d
-               ->  Seq Scan on public.t11
-                     Output: t11.ctid, t11.a, t11.b, t11.c, t11.d
-                     Filter: ((t11.a > 5) AND (t11.a = 3) AND leakproof(t11.a))
-               ->  Append
-                     ->  Seq Scan on public.t12 t12_1
-                           Output: t12_1.a
-                           Filter: (t12_1.a = 3)
-                     ->  Seq Scan on public.t111 t111_1
-                           Output: t111_1.a
-                           Filter: (t111_1.a = 3)
+         ->  LockRows
+               Output: t11.ctid, t11.a, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t11.ctid, t11.a, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
+                     ->  Seq Scan on public.t11
+                           Output: t11.ctid, t11.a, t11.b, t11.c, t11.d
+                           Filter: ((t11.a > 5) AND (t11.a = 3) AND leakproof(t11.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12 t12_1
+                                 Output: t12_1.ctid, t12_1.tableoid, t12_1.a
+                                 Filter: (t12_1.a = 3)
+                           ->  Seq Scan on public.t111 t111_1
+                                 Output: t111_1.ctid, t111_1.tableoid, t111_1.a
+                                 Filter: (t111_1.a = 3)
    ->  Subquery Scan on t1_2
          Output: 100, t1_2.b, t1_2.c, t1_2.e, t1_2.ctid
          Filter: snoop(t1_2.a)
-         ->  Nested Loop Semi Join
-               Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e
-               ->  Seq Scan on public.t12 t12_2
-                     Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e
-                     Filter: ((t12_2.a > 5) AND (t12_2.a = 3) AND leakproof(t12_2.a))
-               ->  Append
-                     ->  Seq Scan on public.t12 t12_3
-                           Output: t12_3.a
-                           Filter: (t12_3.a = 3)
-                     ->  Seq Scan on public.t111 t111_2
-                           Output: t111_2.a
-                           Filter: (t111_2.a = 3)
+         ->  LockRows
+               Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
+                     ->  Seq Scan on public.t12 t12_2
+                           Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e
+                           Filter: ((t12_2.a > 5) AND (t12_2.a = 3) AND leakproof(t12_2.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12 t12_3
+                                 Output: t12_3.ctid, t12_3.tableoid, t12_3.a
+                                 Filter: (t12_3.a = 3)
+                           ->  Seq Scan on public.t111 t111_2
+                                 Output: t111_2.ctid, t111_2.tableoid, t111_2.a
+                                 Filter: (t111_2.a = 3)
    ->  Subquery Scan on t1_3
          Output: 100, t1_3.b, t1_3.c, t1_3.d, t1_3.e, t1_3.ctid
          Filter: snoop(t1_3.a)
-         ->  Nested Loop Semi Join
-               Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e
-               ->  Seq Scan on public.t111 t111_3
-                     Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e
-                     Filter: ((t111_3.a > 5) AND (t111_3.a = 3) AND leakproof(t111_3.a))
-               ->  Append
-                     ->  Seq Scan on public.t12 t12_4
-                           Output: t12_4.a
-                           Filter: (t12_4.a = 3)
-                     ->  Seq Scan on public.t111 t111_4
-                           Output: t111_4.a
-                           Filter: (t111_4.a = 3)
-(61 rows)
+         ->  LockRows
+               Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
+                     ->  Seq Scan on public.t111 t111_3
+                           Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e
+                           Filter: ((t111_3.a > 5) AND (t111_3.a = 3) AND leakproof(t111_3.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12 t12_4
+                                 Output: t12_4.ctid, t12_4.tableoid, t12_4.a
+                                 Filter: (t12_4.a = 3)
+                           ->  Seq Scan on public.t111 t111_4
+                                 Output: t111_4.ctid, t111_4.tableoid, t111_4.a
+                                 Filter: (t111_4.a = 3)
+(69 rows)
 
 UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a = 3;
 SELECT * FROM v1 WHERE a=100; -- Nothing should have been changed to 100
@@ -2135,70 +2147,78 @@ SELECT * FROM t1 WHERE a=100; -- Nothing should have been changed to 100
 
 EXPLAIN (VERBOSE, COSTS OFF)
 UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
-                                        QUERY PLAN                                         
--------------------------------------------------------------------------------------------
+                                                             QUERY PLAN                                                             
+------------------------------------------------------------------------------------------------------------------------------------
  Update on public.t1 t1_4
    ->  Subquery Scan on t1
          Output: (t1.a + 1), t1.b, t1.c, t1.ctid
          Filter: snoop(t1.a)
-         ->  Nested Loop Semi Join
-               Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c
-               ->  Seq Scan on public.t1 t1_5
-                     Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c
-                     Filter: ((t1_5.a > 5) AND (t1_5.a = 8) AND leakproof(t1_5.a))
-               ->  Append
-                     ->  Seq Scan on public.t12
-                           Output: t12.a
-                           Filter: (t12.a = 8)
-                     ->  Seq Scan on public.t111
-                           Output: t111.a
-                           Filter: (t111.a = 8)
+         ->  LockRows
+               Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
+                     ->  Seq Scan on public.t1 t1_5
+                           Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c
+                           Filter: ((t1_5.a > 5) AND (t1_5.a = 8) AND leakproof(t1_5.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12
+                                 Output: t12.ctid, t12.tableoid, t12.a
+                                 Filter: (t12.a = 8)
+                           ->  Seq Scan on public.t111
+                                 Output: t111.ctid, t111.tableoid, t111.a
+                                 Filter: (t111.a = 8)
    ->  Subquery Scan on t1_1
          Output: (t1_1.a + 1), t1_1.b, t1_1.c, t1_1.d, t1_1.ctid
          Filter: snoop(t1_1.a)
-         ->  Nested Loop Semi Join
-               Output: t11.a, t11.ctid, t11.b, t11.c, t11.d
-               ->  Seq Scan on public.t11
-                     Output: t11.a, t11.ctid, t11.b, t11.c, t11.d
-                     Filter: ((t11.a > 5) AND (t11.a = 8) AND leakproof(t11.a))
-               ->  Append
-                     ->  Seq Scan on public.t12 t12_1
-                           Output: t12_1.a
-                           Filter: (t12_1.a = 8)
-                     ->  Seq Scan on public.t111 t111_1
-                           Output: t111_1.a
-                           Filter: (t111_1.a = 8)
+         ->  LockRows
+               Output: t11.a, t11.ctid, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t11.a, t11.ctid, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
+                     ->  Seq Scan on public.t11
+                           Output: t11.a, t11.ctid, t11.b, t11.c, t11.d
+                           Filter: ((t11.a > 5) AND (t11.a = 8) AND leakproof(t11.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12 t12_1
+                                 Output: t12_1.ctid, t12_1.tableoid, t12_1.a
+                                 Filter: (t12_1.a = 8)
+                           ->  Seq Scan on public.t111 t111_1
+                                 Output: t111_1.ctid, t111_1.tableoid, t111_1.a
+                                 Filter: (t111_1.a = 8)
    ->  Subquery Scan on t1_2
          Output: (t1_2.a + 1), t1_2.b, t1_2.c, t1_2.e, t1_2.ctid
          Filter: snoop(t1_2.a)
-         ->  Nested Loop Semi Join
-               Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e
-               ->  Seq Scan on public.t12 t12_2
-                     Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e
-                     Filter: ((t12_2.a > 5) AND (t12_2.a = 8) AND leakproof(t12_2.a))
-               ->  Append
-                     ->  Seq Scan on public.t12 t12_3
-                           Output: t12_3.a
-                           Filter: (t12_3.a = 8)
-                     ->  Seq Scan on public.t111 t111_2
-                           Output: t111_2.a
-                           Filter: (t111_2.a = 8)
+         ->  LockRows
+               Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
+                     ->  Seq Scan on public.t12 t12_2
+                           Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e
+                           Filter: ((t12_2.a > 5) AND (t12_2.a = 8) AND leakproof(t12_2.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12 t12_3
+                                 Output: t12_3.ctid, t12_3.tableoid, t12_3.a
+                                 Filter: (t12_3.a = 8)
+                           ->  Seq Scan on public.t111 t111_2
+                                 Output: t111_2.ctid, t111_2.tableoid, t111_2.a
+                                 Filter: (t111_2.a = 8)
    ->  Subquery Scan on t1_3
          Output: (t1_3.a + 1), t1_3.b, t1_3.c, t1_3.d, t1_3.e, t1_3.ctid
          Filter: snoop(t1_3.a)
-         ->  Nested Loop Semi Join
-               Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e
-               ->  Seq Scan on public.t111 t111_3
-                     Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e
-                     Filter: ((t111_3.a > 5) AND (t111_3.a = 8) AND leakproof(t111_3.a))
-               ->  Append
-                     ->  Seq Scan on public.t12 t12_4
-                           Output: t12_4.a
-                           Filter: (t12_4.a = 8)
-                     ->  Seq Scan on public.t111 t111_4
-                           Output: t111_4.a
-                           Filter: (t111_4.a = 8)
-(61 rows)
+         ->  LockRows
+               Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
+               ->  Nested Loop Semi Join
+                     Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
+                     ->  Seq Scan on public.t111 t111_3
+                           Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e
+                           Filter: ((t111_3.a > 5) AND (t111_3.a = 8) AND leakproof(t111_3.a))
+                     ->  Append
+                           ->  Seq Scan on public.t12 t12_4
+                                 Output: t12_4.ctid, t12_4.tableoid, t12_4.a
+                                 Filter: (t12_4.a = 8)
+                           ->  Seq Scan on public.t111 t111_4
+                                 Output: t111_4.ctid, t111_4.tableoid, t111_4.a
+                                 Filter: (t111_4.a = 8)
+(69 rows)
 
 UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
 NOTICE:  snooped value: 8