Re: 'update' as action of 'insert' rule: permission denied - Mailing list pgsql-bugs

From Tom Lane
Subject Re: 'update' as action of 'insert' rule: permission denied
Date
Msg-id 28483.1045172553@sss.pgh.pa.us
Whole thread Raw
In response to 'update' as action of 'insert' rule: permission denied  (Tim Burgess <tim@queens.unimelb.edu.au>)
List pgsql-bugs
Tim Burgess <tim@queens.unimelb.edu.au> writes:
> I'm surprised I can't find any descriptions of this in the archive
> already, since I had imagined it would be a common action, but
> apparently not!

I'm surprised too.  This bug seems to have escaped notice for quite awhile.
Attached is the patch against 7.3 (it would probably work in 7.2 or
earlier too, but I didn't try it).

            regards, tom lane


*** src/backend/rewrite/rewriteHandler.c.orig    Thu Jan 16 21:01:16 2003
--- src/backend/rewrite/rewriteHandler.c    Thu Feb 13 16:23:18 2003
***************
*** 62,70 ****
--- 62,72 ----
  {
      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,114 ****
       * 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
       * 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.
       */
!     sub_action->rtable = nconc((List *) copyObject(parsetree->rtable),
!                                sub_action->rtable);

      /*
       * Each rule action's jointree should be the main parsetree's jointree
--- 101,131 ----
       * 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 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.
       */
!     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

pgsql-bugs by date:

Previous
From: greg@turnstep.com
Date:
Subject: Re: Bug #895: incorrect error message when duplicate index name
Next
From: Tom Lane
Date:
Subject: Re: Bug #896: Column Constraint Not Working in ALTER TABLE ADD COLUMN?