*
* 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;