6
6
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
- * $Id: view.c,v 1.50 2000/10/26 17:04:12 tgl Exp $
9
+ * $Id: view.c,v 1.51 2000/12/21 17:36:15 tgl Exp $
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
@@ -156,12 +156,12 @@ FormViewRetrieveRule(char *viewName, Query *viewParse)
156
156
static void
157
157
DefineViewRules (char * viewName , Query * viewParse )
158
158
{
159
- RuleStmt * retrieve_rule = NULL ;
159
+ RuleStmt * retrieve_rule ;
160
160
161
161
#ifdef NOTYET
162
- RuleStmt * replace_rule = NULL ;
163
- RuleStmt * append_rule = NULL ;
164
- RuleStmt * delete_rule = NULL ;
162
+ RuleStmt * replace_rule ;
163
+ RuleStmt * append_rule ;
164
+ RuleStmt * delete_rule ;
165
165
166
166
#endif
167
167
@@ -198,24 +198,29 @@ DefineViewRules(char *viewName, Query *viewParse)
198
198
* Of course we must also increase the 'varnos' of all the Var nodes
199
199
* by 2...
200
200
*
201
- * These extra RT entries are not actually used in the query, obviously.
202
- * We add them so that views look the same as ON SELECT rules ---
203
- * the rule rewriter assumes that ALL rules have OLD and NEW RTEs.
204
- *
205
- * NOTE: these are destructive changes. It would be difficult to
206
- * make a complete copy of the parse tree and make the changes
207
- * in the copy.
201
+ * These extra RT entries are not actually used in the query,
202
+ * except for run-time permission checking.
208
203
*---------------------------------------------------------------
209
204
*/
210
- static void
205
+ static Query *
211
206
UpdateRangeTableOfViewParse (char * viewName , Query * viewParse )
212
207
{
213
208
List * new_rt ;
214
209
RangeTblEntry * rt_entry1 ,
215
210
* rt_entry2 ;
216
211
217
212
/*
218
- * create the 2 new range table entries and form the new range
213
+ * Make a copy of the given parsetree. It's not so much that we
214
+ * don't want to scribble on our input, it's that the parser has
215
+ * a bad habit of outputting multiple links to the same subtree
216
+ * for constructs like BETWEEN, and we mustn't have OffsetVarNodes
217
+ * increment the varno of a Var node twice. copyObject will expand
218
+ * any multiply-referenced subtree into multiple copies.
219
+ */
220
+ viewParse = (Query * ) copyObject (viewParse );
221
+
222
+ /*
223
+ * Create the 2 new range table entries and form the new range
219
224
* table... OLD first, then NEW....
220
225
*/
221
226
rt_entry1 = addRangeTableEntry (NULL , viewName ,
@@ -230,16 +235,14 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
230
235
231
236
new_rt = lcons (rt_entry1 , lcons (rt_entry2 , viewParse -> rtable ));
232
237
233
- /*
234
- * Now the tricky part.... Update the range table in place... Be
235
- * careful here, or hell breaks loooooooooooooOOOOOOOOOOOOOOOOOOSE!
236
- */
237
238
viewParse -> rtable = new_rt ;
238
239
239
240
/*
240
- * now offset all var nodes by 2, and jointree RT indexes too.
241
+ * Now offset all var nodes by 2, and jointree RT indexes too.
241
242
*/
242
243
OffsetVarNodes ((Node * ) viewParse , 2 , 0 );
244
+
245
+ return viewParse ;
243
246
}
244
247
245
248
/*-------------------------------------------------------------------
@@ -257,15 +260,11 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
257
260
void
258
261
DefineView (char * viewName , Query * viewParse )
259
262
{
260
- List * viewTlist ;
261
-
262
- viewTlist = viewParse -> targetList ;
263
-
264
263
/*
265
264
* Create the "view" relation NOTE: if it already exists, the xact
266
265
* will be aborted.
267
266
*/
268
- DefineVirtualRelation (viewName , viewTlist );
267
+ DefineVirtualRelation (viewName , viewParse -> targetList );
269
268
270
269
/*
271
270
* The relation we have just created is not visible to any other
@@ -276,11 +275,13 @@ DefineView(char *viewName, Query *viewParse)
276
275
277
276
/*
278
277
* The range table of 'viewParse' does not contain entries for the
279
- * "OLD" and "NEW" relations. So... add them! NOTE: we make the
280
- * update in place! After this call 'viewParse' will never be what it
281
- * used to be...
278
+ * "OLD" and "NEW" relations. So... add them!
279
+ */
280
+ viewParse = UpdateRangeTableOfViewParse (viewName , viewParse );
281
+
282
+ /*
283
+ * Now create the rules associated with the view.
282
284
*/
283
- UpdateRangeTableOfViewParse (viewName , viewParse );
284
285
DefineViewRules (viewName , viewParse );
285
286
}
286
287
0 commit comments