From f4a72f773cc3599ade0d32690fa356a7873e5c95 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 13 Feb 2003 21:39:50 +0000
Subject: [PATCH] Repair rule permissions-checking bug reported by Tim Burgess
 10-Feb-02: the table(s) modified by the original query would get checked for
 the type of write permission needed by a rule query.

---
 src/backend/rewrite/rewriteHandler.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 5ddee1ab194..916c4d4c3f3 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.116 2003/01/17 02:01:16 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.117 2003/02/13 21:39:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -62,9 +62,11 @@ rewriteRuleAction(Query *parsetree,
 {
 	int			current_varno,
 				new_varno;
+	List	   *main_rtable;
 	int			rt_length;
 	Query	   *sub_action;
 	Query	  **sub_action_ptr;
+	List	   *rt;
 
 	/*
 	 * Make modifiable copies of rule action and qual (what we're passed
@@ -99,16 +101,31 @@ rewriteRuleAction(Query *parsetree,
 	 * Generate expanded rtable consisting of main parsetree's rtable plus
 	 * rule action's rtable; this becomes the complete rtable for the rule
 	 * action.	Some of the entries may be unused after we finish
-	 * rewriting, but if we tried to clean those out we'd have a much
+	 * rewriting, but if we tried to remove them we'd have a much
 	 * harder job to adjust RT indexes in the query's Vars.  It's OK to
 	 * have unused RT entries, since planner will ignore them.
 	 *
 	 * NOTE: because planner will destructively alter rtable, we must ensure
 	 * that rule action's rtable is separate and shares no substructure
 	 * with the main rtable.  Hence do a deep copy here.
+	 *
+	 * Also, we must disable write-access checking in all the RT entries
+	 * copied from the main query.  This is safe since in fact the rule action
+	 * won't write on them, and it's necessary because the rule action may
+	 * have a different commandType than the main query, causing
+	 * ExecCheckRTEPerms() to make an inappropriate check.  The read-access
+	 * checks can be left enabled, although they're probably redundant.
 	 */
-	sub_action->rtable = nconc((List *) copyObject(parsetree->rtable),
-							   sub_action->rtable);
+	main_rtable = (List *) copyObject(parsetree->rtable);
+
+	foreach(rt, main_rtable)
+	{
+		RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
+
+		rte->checkForWrite = false;
+	}
+
+	sub_action->rtable = nconc(main_rtable, sub_action->rtable);
 
 	/*
 	 * Each rule action's jointree should be the main parsetree's jointree
-- 
GitLab