{
RelOptInfo *inner = root->simple_rel_array[r];
+ /*
+ * We don't accept result relation as either source or target relation
+ * of SJE, because result relation has different behavior in
+ * EvalPlanQual() and RETURNING clause.
+ */
+ if (root->parse->resultRelation == r)
+ continue;
+
k = r;
while ((k = bms_next_member(relids, k)) > 0)
PlanRowMark *imark = NULL;
List *uclauses = NIL;
+ if (root->parse->resultRelation == k)
+ continue;
+
/* A sanity check: the relations have the same Oid. */
Assert(root->simple_rte_array[k]->relid ==
root->simple_rte_array[r]->relid);
-> Seq Scan on emp1 t3
(6 rows)
--- Check that SJE replaces target relation correctly
+-- Check that SJE doesn't replace the target relation
explain (costs off)
WITH t1 AS (SELECT * FROM emp1)
UPDATE emp1 SET code = t1.code + 1 FROM t1
-WHERE t1.id = emp1.id RETURNING emp1.id, emp1.code;
- QUERY PLAN
-----------------------------------
+WHERE t1.id = emp1.id RETURNING emp1.id, emp1.code, t1.code;
+ QUERY PLAN
+-------------------------------------------------------
Update on emp1
- -> Seq Scan on emp1
- Filter: (id IS NOT NULL)
-(3 rows)
+ -> Nested Loop
+ -> Seq Scan on emp1
+ -> Index Scan using emp1_pkey on emp1 emp1_1
+ Index Cond: (id = emp1.id)
+(5 rows)
+
+INSERT INTO emp1 VALUES (1, 1), (2, 1);
+WITH t1 AS (SELECT * FROM emp1)
+UPDATE emp1 SET code = t1.code + 1 FROM t1
+WHERE t1.id = emp1.id RETURNING emp1.id, emp1.code, t1.code;
+ id | code | code
+----+------+------
+ 1 | 2 | 1
+ 2 | 2 | 1
+(2 rows)
+
+TRUNCATE emp1;
+EXPLAIN (COSTS OFF)
+UPDATE sj sq SET b = 1 FROM sj as sz WHERE sq.a = sz.a;
+ QUERY PLAN
+-------------------------------------
+ Update on sj sq
+ -> Nested Loop
+ Join Filter: (sq.a = sz.a)
+ -> Seq Scan on sj sq
+ -> Materialize
+ -> Seq Scan on sj sz
+(6 rows)
+CREATE RULE sj_del_rule AS ON DELETE TO sj
+ DO INSTEAD
+ UPDATE sj SET a = 1 WHERE a = old.a;
+EXPLAIN (COSTS OFF) DELETE FROM sj;
+ QUERY PLAN
+--------------------------------------
+ Update on sj sj_1
+ -> Nested Loop
+ Join Filter: (sj.a = sj_1.a)
+ -> Seq Scan on sj sj_1
+ -> Materialize
+ -> Seq Scan on sj
+(6 rows)
+
+DROP RULE sj_del_rule ON sj CASCADE;
-- Check that SJE does not mistakenly omit qual clauses (bug #18187)
insert into emp1 values (1, 1);
explain (costs off)
--
-- Test RowMarks-related code
--
--- TODO: Why this select returns two copies of ctid field? Should we fix it?
EXPLAIN (COSTS OFF) -- Both sides have explicit LockRows marks
SELECT a1.a FROM sj a1,sj a2 WHERE (a1.a=a2.a) FOR UPDATE;
QUERY PLAN
Filter: (a IS NOT NULL)
(3 rows)
-EXPLAIN (COSTS OFF) -- A RowMark exists for the table being kept
-UPDATE sj sq SET b = 1 FROM sj as sz WHERE sq.a = sz.a;
- QUERY PLAN
----------------------------------
- Update on sj sz
- -> Seq Scan on sj sz
- Filter: (a IS NOT NULL)
-(3 rows)
-
-CREATE RULE sj_del_rule AS ON DELETE TO sj
- DO INSTEAD
- UPDATE sj SET a = 1 WHERE a = old.a;
-EXPLAIN (COSTS OFF) DELETE FROM sj; -- A RowMark exists for the table being dropped
- QUERY PLAN
----------------------------------
- Update on sj
- -> Seq Scan on sj
- Filter: (a IS NOT NULL)
-(3 rows)
-
-DROP RULE sj_del_rule ON sj CASCADE;
reset enable_hashjoin;
reset enable_mergejoin;
--
(1 row)
EXPLAIN (costs off) DELETE FROM rw_view1 WHERE id = 1 AND snoop(data);
- QUERY PLAN
---------------------------------------------------
- Update on base_tbl
- -> Index Scan using base_tbl_pkey on base_tbl
- Index Cond: (id = 1)
- Filter: ((NOT deleted) AND snoop(data))
-(4 rows)
+ QUERY PLAN
+-------------------------------------------------------------------
+ Update on base_tbl base_tbl_1
+ -> Nested Loop
+ -> Index Scan using base_tbl_pkey on base_tbl base_tbl_1
+ Index Cond: (id = 1)
+ -> Index Scan using base_tbl_pkey on base_tbl
+ Index Cond: (id = 1)
+ Filter: ((NOT deleted) AND snoop(data))
+(7 rows)
DELETE FROM rw_view1 WHERE id = 1 AND snoop(data);
NOTICE: snooped value: Row 1
inner join emp1 t2 on t1.id = t2.id
left join emp1 t3 on t1.id > 1 and t1.id < 2;
--- Check that SJE replaces target relation correctly
+-- Check that SJE doesn't replace the target relation
explain (costs off)
WITH t1 AS (SELECT * FROM emp1)
UPDATE emp1 SET code = t1.code + 1 FROM t1
-WHERE t1.id = emp1.id RETURNING emp1.id, emp1.code;
+WHERE t1.id = emp1.id RETURNING emp1.id, emp1.code, t1.code;
+INSERT INTO emp1 VALUES (1, 1), (2, 1);
+WITH t1 AS (SELECT * FROM emp1)
+UPDATE emp1 SET code = t1.code + 1 FROM t1
+WHERE t1.id = emp1.id RETURNING emp1.id, emp1.code, t1.code;
+TRUNCATE emp1;
+
+EXPLAIN (COSTS OFF)
+UPDATE sj sq SET b = 1 FROM sj as sz WHERE sq.a = sz.a;
+
+CREATE RULE sj_del_rule AS ON DELETE TO sj
+ DO INSTEAD
+ UPDATE sj SET a = 1 WHERE a = old.a;
+EXPLAIN (COSTS OFF) DELETE FROM sj;
+DROP RULE sj_del_rule ON sj CASCADE;
-- Check that SJE does not mistakenly omit qual clauses (bug #18187)
insert into emp1 values (1, 1);
-- Test RowMarks-related code
--
--- TODO: Why this select returns two copies of ctid field? Should we fix it?
EXPLAIN (COSTS OFF) -- Both sides have explicit LockRows marks
SELECT a1.a FROM sj a1,sj a2 WHERE (a1.a=a2.a) FOR UPDATE;
-EXPLAIN (COSTS OFF) -- A RowMark exists for the table being kept
-UPDATE sj sq SET b = 1 FROM sj as sz WHERE sq.a = sz.a;
-
-CREATE RULE sj_del_rule AS ON DELETE TO sj
- DO INSTEAD
- UPDATE sj SET a = 1 WHERE a = old.a;
-EXPLAIN (COSTS OFF) DELETE FROM sj; -- A RowMark exists for the table being dropped
-DROP RULE sj_del_rule ON sj CASCADE;
-
reset enable_hashjoin;
reset enable_mergejoin;