|
7 | 7 | * Portions Copyright (c) 1994, Regents of the University of California
|
8 | 8 | *
|
9 | 9 | * IDENTIFICATION
|
10 |
| - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.116 2003/01/17 02:01:16 tgl Exp $ |
| 10 | + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.117 2003/02/13 21:39:50 tgl Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
@@ -62,9 +62,11 @@ rewriteRuleAction(Query *parsetree,
|
62 | 62 | {
|
63 | 63 | int current_varno,
|
64 | 64 | new_varno;
|
| 65 | + List *main_rtable; |
65 | 66 | int rt_length;
|
66 | 67 | Query *sub_action;
|
67 | 68 | Query **sub_action_ptr;
|
| 69 | + List *rt; |
68 | 70 |
|
69 | 71 | /*
|
70 | 72 | * Make modifiable copies of rule action and qual (what we're passed
|
@@ -99,16 +101,31 @@ rewriteRuleAction(Query *parsetree,
|
99 | 101 | * Generate expanded rtable consisting of main parsetree's rtable plus
|
100 | 102 | * rule action's rtable; this becomes the complete rtable for the rule
|
101 | 103 | * action. Some of the entries may be unused after we finish
|
102 |
| - * rewriting, but if we tried to clean those out we'd have a much |
| 104 | + * rewriting, but if we tried to remove them we'd have a much |
103 | 105 | * harder job to adjust RT indexes in the query's Vars. It's OK to
|
104 | 106 | * have unused RT entries, since planner will ignore them.
|
105 | 107 | *
|
106 | 108 | * NOTE: because planner will destructively alter rtable, we must ensure
|
107 | 109 | * that rule action's rtable is separate and shares no substructure
|
108 | 110 | * with the main rtable. Hence do a deep copy here.
|
| 111 | + * |
| 112 | + * Also, we must disable write-access checking in all the RT entries |
| 113 | + * copied from the main query. This is safe since in fact the rule action |
| 114 | + * won't write on them, and it's necessary because the rule action may |
| 115 | + * have a different commandType than the main query, causing |
| 116 | + * ExecCheckRTEPerms() to make an inappropriate check. The read-access |
| 117 | + * checks can be left enabled, although they're probably redundant. |
109 | 118 | */
|
110 |
| - sub_action->rtable = nconc((List *) copyObject(parsetree->rtable), |
111 |
| - sub_action->rtable); |
| 119 | + main_rtable = (List *) copyObject(parsetree->rtable); |
| 120 | + |
| 121 | + foreach(rt, main_rtable) |
| 122 | + { |
| 123 | + RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt); |
| 124 | + |
| 125 | + rte->checkForWrite = false; |
| 126 | + } |
| 127 | + |
| 128 | + sub_action->rtable = nconc(main_rtable, sub_action->rtable); |
112 | 129 |
|
113 | 130 | /*
|
114 | 131 | * Each rule action's jointree should be the main parsetree's jointree
|
|
0 commit comments