*
  * Caller should have verified that the relation is a view, and therefore
  * we should find an ON SELECT action.
+ *
+ * Note that the pointer returned is into the relcache and therefore must
+ * be treated as read-only to the caller and not modified or scribbled on.
  */
 Query *
 get_view_query(Relation view)
    List       *view_targetlist;
    ListCell   *lc;
 
-   /* The view must be updatable, else fail */
-   viewquery = get_view_query(view);
+   /*
+    * Get the Query from the view's ON SELECT rule.  We're going to munge the
+    * Query to change the view's base relation into the target relation,
+    * along with various other changes along the way, so we need to make a
+    * copy of it (get_view_query() returns a pointer into the relcache, so we
+    * have to treat it as read-only).
+    */
+   viewquery = copyObject(get_view_query(view));
 
+   /* The view must be updatable, else fail */
    auto_update_detail =
        view_query_is_auto_updatable(viewquery,
                                     parsetree->commandType != CMD_DELETE);
     * outer query.  Perhaps someday we should refactor things enough so that
     * we can share code with the planner.)
     */
-   new_rte = (RangeTblEntry *) copyObject(base_rte);
+   new_rte = (RangeTblEntry *) base_rte;
    parsetree->rtable = lappend(parsetree->rtable, new_rte);
    new_rt_index = list_length(parsetree->rtable);
 
        new_rte->inh = false;
 
    /*
-    * Make a copy of the view's targetlist, adjusting its Vars to reference
-    * the new target RTE, ie make their varnos be new_rt_index instead of
-    * base_rt_index.  There can be no Vars for other rels in the tlist, so
-    * this is sufficient to pull up the tlist expressions for use in the
-    * outer query.  The tlist will provide the replacement expressions used
-    * by ReplaceVarsFromTargetList below.
+    * Adjust the view's targetlist Vars to reference the new target RTE, ie
+    * make their varnos be new_rt_index instead of base_rt_index.  There can
+    * be no Vars for other rels in the tlist, so this is sufficient to pull
+    * up the tlist expressions for use in the outer query.  The tlist will
+    * provide the replacement expressions used by ReplaceVarsFromTargetList
+    * below.
     */
-   view_targetlist = copyObject(viewquery->targetList);
+   view_targetlist = viewquery->targetList;
 
    ChangeVarNodes((Node *) view_targetlist,
                   base_rt_index,
    if (parsetree->commandType != CMD_INSERT &&
        viewquery->jointree->quals != NULL)
    {
-       Node       *viewqual = (Node *) copyObject(viewquery->jointree->quals);
+       Node       *viewqual = (Node *) viewquery->jointree->quals;
 
        ChangeVarNodes(viewqual, base_rt_index, new_rt_index, 0);
 
 
            if (viewquery->jointree->quals != NULL)
            {
-               wco->qual = (Node *) copyObject(viewquery->jointree->quals);
+               wco->qual = (Node *) viewquery->jointree->quals;
                ChangeVarNodes(wco->qual, base_rt_index, new_rt_index, 0);
 
                /*
 
 NOTICE:  drop cascades to view v1
 DROP FUNCTION snoop(anyelement);
 DROP FUNCTION leakproof(anyelement);
+CREATE TABLE tx1 (a integer);
+CREATE TABLE tx2 (b integer);
+CREATE TABLE tx3 (c integer);
+CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
+INSERT INTO vx1 values (1);
+SELECT * FROM tx1;
+ a 
+---
+ 1
+(1 row)
+
+SELECT * FROM vx1;
+ a 
+---
+(0 rows)
+
+DROP VIEW vx1;
+DROP TABLE tx1;
+DROP TABLE tx2;
+DROP TABLE tx3;
+CREATE TABLE tx1 (a integer);
+CREATE TABLE tx2 (b integer);
+CREATE TABLE tx3 (c integer);
+CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
+INSERT INTO vx1 VALUES (1);
+INSERT INTO vx1 VALUES (1);
+SELECT * FROM tx1;
+ a 
+---
+ 1
+ 1
+(2 rows)
+
+SELECT * FROM vx1;
+ a 
+---
+(0 rows)
+
+DROP VIEW vx1;
+DROP TABLE tx1;
+DROP TABLE tx2;
+DROP TABLE tx3;
+CREATE TABLE tx1 (a integer, b integer);
+CREATE TABLE tx2 (b integer, c integer);
+CREATE TABLE tx3 (c integer, d integer);
+ALTER TABLE tx1 DROP COLUMN b;
+ALTER TABLE tx2 DROP COLUMN c;
+ALTER TABLE tx3 DROP COLUMN d;
+CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
+INSERT INTO vx1 VALUES (1);
+INSERT INTO vx1 VALUES (1);
+SELECT * FROM tx1;
+ a 
+---
+ 1
+ 1
+(2 rows)
+
+SELECT * FROM vx1;
+ a 
+---
+(0 rows)
+
+DROP VIEW vx1;
+DROP TABLE tx1;
+DROP TABLE tx2;
+DROP TABLE tx3;
 
 DROP TABLE t1, t11, t12, t111 CASCADE;
 DROP FUNCTION snoop(anyelement);
 DROP FUNCTION leakproof(anyelement);
+
+CREATE TABLE tx1 (a integer);
+CREATE TABLE tx2 (b integer);
+CREATE TABLE tx3 (c integer);
+CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
+INSERT INTO vx1 values (1);
+SELECT * FROM tx1;
+SELECT * FROM vx1;
+
+DROP VIEW vx1;
+DROP TABLE tx1;
+DROP TABLE tx2;
+DROP TABLE tx3;
+
+CREATE TABLE tx1 (a integer);
+CREATE TABLE tx2 (b integer);
+CREATE TABLE tx3 (c integer);
+CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
+INSERT INTO vx1 VALUES (1);
+INSERT INTO vx1 VALUES (1);
+SELECT * FROM tx1;
+SELECT * FROM vx1;
+
+DROP VIEW vx1;
+DROP TABLE tx1;
+DROP TABLE tx2;
+DROP TABLE tx3;
+
+CREATE TABLE tx1 (a integer, b integer);
+CREATE TABLE tx2 (b integer, c integer);
+CREATE TABLE tx3 (c integer, d integer);
+ALTER TABLE tx1 DROP COLUMN b;
+ALTER TABLE tx2 DROP COLUMN c;
+ALTER TABLE tx3 DROP COLUMN d;
+CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c);
+INSERT INTO vx1 VALUES (1);
+INSERT INTO vx1 VALUES (1);
+SELECT * FROM tx1;
+SELECT * FROM vx1;
+
+DROP VIEW vx1;
+DROP TABLE tx1;
+DROP TABLE tx2;
+DROP TABLE tx3;