From c3e0ddd403d74b161cd83cdccbb0adc45788934f Mon Sep 17 00:00:00 2001
From: Stephen Frost <sfrost@snowman.net>
Date: Tue, 8 Sep 2015 17:02:49 -0400
Subject: [PATCH] Lock all relations referred to in updatable views

Even views considered "simple" enough to be automatically updatable may
have mulitple relations involved (eg: in a where clause).  We need to
make sure and lock those relations when rewriting the query.

Back-patch to 9.3 where updatable views were added.

Pointed out by Andres, patch thanks to Dean Rasheed.
---
 src/backend/rewrite/rewriteHandler.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 761047ca082..db3c2c7a76e 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -2764,6 +2764,21 @@ rewriteTargetView(Query *parsetree, Relation view)
 
 	heap_close(base_rel, NoLock);
 
+	/*
+	 * If the view query contains any sublink subqueries then we need to also
+	 * acquire locks on any relations they refer to.  We know that there won't
+	 * be any subqueries in the range table or CTEs, so we can skip those, as
+	 * in AcquireRewriteLocks.
+	 */
+	if (viewquery->hasSubLinks)
+	{
+		acquireLocksOnSubLinks_context context;
+
+		context.for_execute = true;
+		query_tree_walker(viewquery, acquireLocksOnSubLinks, &context,
+						  QTW_IGNORE_RC_SUBQUERIES);
+	}
+
 	/*
 	 * Create a new target RTE describing the base relation, and add it to the
 	 * outer query's rangetable.  (What's happening in the next few steps is
-- 
GitLab