@ -6187,14 +6187,16 @@ select p.* from sj p, sj q where q.a = p.a and q.b = q.a - 1;
explain (costs off)
select * from sj p
where exists (select * from sj q
where q.a = p.a and q.b < 10);
where q.a = p.a and q.b < 10);
QUERY PLAN
------------------------------------------
Seq Scan on sj q
Filter: ((a IS NOT NULL) AND (b < 10))
(2 rows)
select * from sj p where exists (select * from sj q where q.a = p.a and q.b < 10);
select * from sj p
where exists (select * from sj q
where q.a = p.a and q.b < 10);
a | b | c
---+---+---
2 | 1 | 1
@ -6216,8 +6218,8 @@ select * from sj t1, sj t2 where t1.a = t2.c and t1.b is not null;
-- Degenerated case.
explain (costs off)
select * from
(select a as x from sj where false) as q1,
(select a as y from sj where false) as q2
(select a as x from sj where false) as q1,
(select a as y from sj where false) as q2
where q1.x = q2.y;
QUERY PLAN
--------------------------
@ -6241,8 +6243,8 @@ select * from sj t1, sj t2 where t1.a = t1.b and t1.b = t2.b and t2.b = t2.a;
explain (costs off)
select * from sj t1, sj t2, sj t3
where t1.a = t1.b and t1.b = t2.b and t2.b = t2.a
and t1.b = t3.b and t3.b = t3.a;
where t1.a = t1.b and t1.b = t2.b and t2.b = t2.a and
t1.b = t3.b and t3.b = t3.a;
QUERY PLAN
------------------------------------
Nested Loop
@ -6262,8 +6264,10 @@ where t1.a = t1.b and t1.b = t2.b and t2.b = t2.a
-- the equivalence class is different from the first one, and we can
-- test the non-ec code path.
explain (costs off)
select * from sj t1 join sj t2 on t1.a = t2.a and t1.b = t2.b
join sj t3 on t2.a = t3.a and t2.b + 1 = t3.b + 1;
select *
from sj t1
join sj t2 on t1.a = t2.a and t1.b = t2.b
join sj t3 on t2.a = t3.a and t2.b + 1 = t3.b + 1;
QUERY PLAN
---------------------------------------------------------------------------
Seq Scan on sj t3
@ -6314,13 +6318,13 @@ left join int8_tbl z on y.a = z.q1;
(6 rows)
explain (costs off)
SELECT * FROM (
SELECT t1.*, t2.a AS ax FROM sj t1 JOIN sj t2
ON (t1.a = t2.a AND t1.c*t1.c = t2.c+2 AND t2.b IS NULL )
) AS q1
LEFT JOIN
(SELECT t3.* FROM sj t3, sj t4 WHERE t3.c = t4.c) AS q2
ON q1.ax = q2.a;
select * from (
select t1.*, t2.a as ax from sj t1 join sj t2
on (t1.a = t2.a and t1.c * t1.c = t2.c + 2 and t2.b is null )
) as q1
left join
(select t3.* from sj t3, sj t4 where t3.c = t4.c) as q2
on q1.ax = q2.a;
QUERY PLAN
---------------------------------------------------------------------------
Nested Loop Left Join
@ -6349,49 +6353,52 @@ on true;
-> Seq Scan on int8_tbl y
(7 rows)
-- Test processing target lists in lateral subqueries
-- Test that references to the removed rel in lateral subqueries are replaced
-- correctly after join removal
explain (verbose, costs off)
SELECT t3.a FROM sj t1, sj t2,
LATERAL (SELECT t1.a WHERE t1.a <> 1
GROUP BY (t1.a) HAVING t1.a > 0 ORDER BY t1.a LIMIT 1) t3,
LATERAL (SELECT t1.a,t3.a WHERE t1.a <> t3.a+t2.a
GROUP BY (t3.a) HAVING t1.a > t3.a*t3.a+t2.a/t1.a LIMIT 2) t4,
LATERAL (SELECT * FROM sj TABLESAMPLE bernoulli(t1.a/t2.a)
REPEATABLE (t1.a+t2.a)) t5,
LATERAL generate_series(1, t1.a + t2.a) AS t6
WHERE t1.a = t2.a;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
select t3.a from sj t1
join sj t2 on t1.a = t2.a
join lateral (select t1.a offset 0) t3 on true;
QUERY PLAN
------------------------------------
Nested Loop
Output: (t2.a)
-> Nested Loop
Output: t2.a, (t2.a)
-> Nested Loop
Output: t2.a, (t2.a)
-> Nested Loop
Output: t2.a, (t2.a)
-> Seq Scan on public.sj t2
Output: t2.a, t2.b, t2.c
Filter: (t2.a IS NOT NULL)
-> Limit
Output: (t2.a)
-> Group
Output: t2.a
-> Result
One-Time Filter: ((t2.a <> 1) AND (t2.a > 0))
-> Limit
Output: NULL::integer, ((t2.a))
-> Group
Output: NULL::integer, (t2.a)
-> Result
One-Time Filter: ((t2.a <> ((t2.a) + t2.a)) AND (t2.a > (((t2.a) * (t2.a)) + (t2.a / t2.a))))
-> Sample Scan on public.sj
Output: sj.a, sj.b, sj.c
Sampling: bernoulli ((t2.a / t2.a)) REPEATABLE ((t2.a + t2.a))
-> Function Scan on pg_catalog.generate_series t6
Output: t6.t6
Function Call: generate_series(1, (t2.a + t2.a))
(29 rows)
-> Seq Scan on public.sj t2
Output: t2.a, t2.b, t2.c
Filter: (t2.a IS NOT NULL)
-> Result
Output: t2.a
(7 rows)
explain (verbose, costs off)
select t3.a from sj t1
join sj t2 on t1.a = t2.a
join lateral (select * from (select t1.a offset 0) offset 0) t3 on true;
QUERY PLAN
------------------------------------
Nested Loop
Output: (t2.a)
-> Seq Scan on public.sj t2
Output: t2.a, t2.b, t2.c
Filter: (t2.a IS NOT NULL)
-> Result
Output: t2.a
(7 rows)
explain (verbose, costs off)
select t4.a from sj t1
join sj t2 on t1.a = t2.a
join lateral (select t3.a from sj t3, (select t1.a) offset 0) t4 on true;
QUERY PLAN
------------------------------------
Nested Loop
Output: t3.a
-> Seq Scan on public.sj t2
Output: t2.a, t2.b, t2.c
Filter: (t2.a IS NOT NULL)
-> Seq Scan on public.sj t3
Output: t3.a
(7 rows)
-- Check updating of Lateral links from top-level query to the removing relation
explain (COSTS OFF)
@ -6412,13 +6419,14 @@ SELECT * FROM pg_am am WHERE am.amname IN (
(6 rows)
--
-- SJR corner case: uniqueness of an inner is [partially] derived from
-- SJE corner case: uniqueness of an inner is [partially] derived from
-- baserestrictinfo clauses.
-- XXX: We really should allow SJR for these corner cases?
-- XXX: We really should allow SJE for these corner cases?
--
INSERT INTO sj VALUES (3, 1, 3);
explain (costs off) -- Don't remove SJ
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 3;
-- Don't remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 3;
QUERY PLAN
------------------------------
Nested Loop
@ -6429,92 +6437,87 @@ explain (costs off) -- Don't remove SJ
Filter: (a = 3)
(6 rows)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 3; -- Return one row
-- Return one row
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 3;
a | b | c | a | b | c
---+---+---+---+---+---
2 | 1 | 1 | 3 | 1 | 3
(1 row)
explain (costs off) -- Remove SJ, define uniqueness by a constant
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 2;
-- Remove SJ, define uniqueness by a constant
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 2;
QUERY PLAN
-----------------------------------------
Seq Scan on sj j2
Filter: ((b IS NOT NULL) AND (a = 2))
(2 rows)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 2; -- Return one row
-- Return one row
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2 AND j2.a = 2;
a | b | c | a | b | c
---+---+---+---+---+---
2 | 1 | 1 | 2 | 1 | 1
(1 row)
-- Remove SJ, define uniqueness by a constant expression
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b
AND j1.a = (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = j2.a
; -- Remove SJ, define uniqueness by a constant expression
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = j2.a;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
Seq Scan on sj j2
Filter: ((b IS NOT NULL) AND (a = (((EXTRACT(dow FROM CURRENT_TIMESTAMP(0)) / '15'::numeric) + '3'::numeric))::integer))
(2 rows)
-- Return one row
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b
AND j1.a = (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = j2.a
; -- Return one row
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = j2.a;
a | b | c | a | b | c
---+---+---+---+---+---
3 | 1 | 3 | 3 | 1 | 3
(1 row)
explain (costs off) -- Remove SJ
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 1 AND j2.a = 1;
-- Remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 1 AND j2.a = 1;
QUERY PLAN
-----------------------------------------
Seq Scan on sj j2
Filter: ((b IS NOT NULL) AND (a = 1))
(2 rows)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND j1.a = 1 AND j2.a = 1; -- Return no rows
-- Return no rows
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 1 AND j2.a = 1;
a | b | c | a | b | c
---+---+---+---+---+---
(0 rows)
explain (costs off) -- Shuffle a clause. Remove SJ
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND 1 = j1.a AND j2.a = 1;
-- Shuffle a clause. Remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND 1 = j1.a AND j2.a = 1;
QUERY PLAN
-----------------------------------------
Seq Scan on sj j2
Filter: ((b IS NOT NULL) AND (a = 1))
(2 rows)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND 1 = j1.a AND j2.a = 1; -- Return no rows
-- Return no rows
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND 1 = j1.a AND j2.a = 1;
a | b | c | a | b | c
---+---+---+---+---+---
(0 rows)
-- SJE Corner case: a 'a.x=a.x' clause, have replaced with 'a.x IS NOT NULL'
-- after SJ elimination it shouldn't be a mergejoinable clause.
SELECT t4.*
FROM (SELECT t1.*, t2.a AS a1 FROM sj t1, sj t2 WHERE t1.b = t2.b) AS t3
JOIN sj t4 ON (t4.a = t3.a) WHERE t3.a1 = 42;
a | b | c
---+---+---
(0 rows)
EXPLAIN (COSTS OFF)
SELECT t4.*
FROM (SELECT t1.*, t2.a AS a1 FROM sj t1, sj t2 WHERE t1.b = t2.b) AS t3
JOIN sj t4 ON (t4.a = t3.a) WHERE t3.a1 = 42
; -- SJs must be removed.
JOIN sj t4 ON (t4.a = t3.a) WHERE t3.a1 = 42;
QUERY PLAN
---------------------------------
Nested Loop
@ -6525,10 +6528,18 @@ JOIN sj t4 ON (t4.a = t3.a) WHERE t3.a1 = 42
Filter: (a IS NOT NULL)
(6 rows)
SELECT t4.*
FROM (SELECT t1.*, t2.a AS a1 FROM sj t1, sj t2 WHERE t1.b = t2.b) AS t3
JOIN sj t4 ON (t4.a = t3.a) WHERE t3.a1 = 42;
a | b | c
---+---+---
(0 rows)
-- Functional index
CREATE UNIQUE INDEX sj_fn_idx ON sj((a * a));
explain (costs off) -- Remove SJ
SELECT * FROM sj j1, sj j2
-- Remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND j1.a*j1.a = 1 AND j2.a*j2.a = 1;
QUERY PLAN
-----------------------------------------------
@ -6536,8 +6547,9 @@ explain (costs off) -- Remove SJ
Filter: ((b IS NOT NULL) AND ((a * a) = 1))
(2 rows)
explain (costs off) -- Don't remove SJ
SELECT * FROM sj j1, sj j2
-- Don't remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND j1.a*j1.a = 1 AND j2.a*j2.a = 2;
QUERY PLAN
-------------------------------
@ -6549,48 +6561,48 @@ explain (costs off) -- Don't remove SJ
Filter: ((a * a) = 2)
(6 rows)
-- Restriction contains expressions in both sides, Remove SJ.
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b
AND (j1.a*j1.a) = (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = (j2.a*j2.a)
; -- Restriction contains expressions in both sides, Remove SJ.
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = (j2.a*j2.a);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Seq Scan on sj j2
Filter: ((b IS NOT NULL) AND ((a * a) = (((EXTRACT(dow FROM CURRENT_TIMESTAMP(0)) / '15'::numeric) + '3'::numeric))::integer))
(2 rows)
-- Empty set of rows should be returned
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b
AND (j1.a*j1.a) = (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = (j2.a*j2.a)
; -- Empty set of rows should be returned
AND (EXTRACT(DOW FROM current_timestamp(0))/15 + 3)::int = (j2.a*j2.a);
a | b | c | a | b | c
---+---+---+---+---+---
(0 rows)
-- Restriction contains volatile function - disable SJE feature.
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b
AND (j1.a*j1.a) = (random()/3 + 3)::int
AND (random()/3 + 3)::int = (j2.a*j2.a)
; -- Restriction contains volatile function - disable SJR feature.
QUERY PLAN
-----------------------------------------------------------------------------------------------------
AND (j1.a*j1.c/3) = (random()/3 + 3)::int
AND (random()/3 + 3)::int = (j2.a*j2.c/3);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------
Nested Loop
Join Filter: (j1.b = j2.b)
-> Seq Scan on sj j1
Filter: ((a * a ) = (((random() / '3'::double precision) + '3'::double precision))::integer)
Filter: (((a * c) / 3 ) = (((random() / '3'::double precision) + '3'::double precision))::integer)
-> Seq Scan on sj j2
Filter: ((((random() / '3'::double precision) + '3'::double precision))::integer = (a * a ))
Filter: ((((random() / '3'::double precision) + '3'::double precision))::integer = ((a * c) / 3 ))
(6 rows)
-- Return one row
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b
AND (j1.a*j1.c/3) = (random()/3 + 3)::int
AND (random()/3 + 3)::int = (j2.a*j2.c/3)
; -- Return one row
AND (random()/3 + 3)::int = (j2.a*j2.c/3);
a | b | c | a | b | c
---+---+---+---+---+---
3 | 1 | 3 | 3 | 1 | 3
@ -6598,8 +6610,9 @@ WHERE j1.b = j2.b
-- Multiple filters
CREATE UNIQUE INDEX sj_temp_idx1 ON sj(a,b,c);
explain (costs off) -- Remove SJ
SELECT * FROM sj j1, sj j2
-- Remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND j1.a = 2 AND j1.c = 3 AND j2.a = 2 AND 3 = j2.c;
QUERY PLAN
-----------------------------------------------------
@ -6607,7 +6620,8 @@ explain (costs off) -- Remove SJ
Filter: ((b IS NOT NULL) AND (a = 2) AND (c = 3))
(2 rows)
explain (costs off) -- Don't remove SJ
-- Don't remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2
WHERE j1.b = j2.b AND 2 = j1.a AND j1.c = 3 AND j2.a = 1 AND 3 = j2.c;
QUERY PLAN
@ -6621,8 +6635,9 @@ explain (costs off) -- Don't remove SJ
(6 rows)
CREATE UNIQUE INDEX sj_temp_idx ON sj(a,b);
explain (costs off) -- Don't remove SJ
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2;
-- Don't remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND j1.a = 2;
QUERY PLAN
------------------------------
Nested Loop
@ -6632,8 +6647,9 @@ explain (costs off) -- Don't remove SJ
-> Seq Scan on sj j2
(5 rows)
explain (costs off) -- Don't remove SJ
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND 2 = j2.a;
-- Don't remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND 2 = j2.a;
QUERY PLAN
------------------------------
Nested Loop
@ -6643,8 +6659,9 @@ explain (costs off) -- Don't remove SJ
-> Seq Scan on sj j1
(5 rows)
explain (costs off) -- Don't remove SJ
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND (j1.a = 1 OR j2.a = 1);
-- Don't remove SJ
EXPLAIN (COSTS OFF)
SELECT * FROM sj j1, sj j2 WHERE j1.b = j2.b AND (j1.a = 1 OR j2.a = 1);
QUERY PLAN
---------------------------------------------------------------
Nested Loop
@ -6658,7 +6675,7 @@ DROP INDEX sj_fn_idx, sj_temp_idx1, sj_temp_idx;
-- Test that OR predicated are updated correctly after join removal
CREATE TABLE tab_with_flag ( id INT PRIMARY KEY, is_flag SMALLINT);
CREATE INDEX idx_test_is_flag ON tab_with_flag (is_flag);
explain (costs off )
EXPLAIN (COSTS OFF )
SELECT COUNT(*) FROM tab_with_flag
WHERE
(is_flag IS NULL OR is_flag = 0)
@ -6787,7 +6804,7 @@ reset join_collapse_limit;
reset enable_seqscan;
-- Check that clauses from the join filter list is not lost on the self-join removal
CREATE TABLE emp1 (id SERIAL PRIMARY KEY NOT NULL, code int);
explain (verbose, costs off )
EXPLAIN (VERBOSE, COSTS OFF )
SELECT * FROM emp1 e1, emp1 e2 WHERE e1.id = e2.id AND e2.code <> e1.code;
QUERY PLAN
------------------------------------------
@ -6799,7 +6816,7 @@ SELECT * FROM emp1 e1, emp1 e2 WHERE e1.id = e2.id AND e2.code <> e1.code;
-- Shuffle self-joined relations. Only in the case of iterative deletion
-- attempts explains of these queries will be identical.
CREATE UNIQUE INDEX ON emp1((id*id));
explain (costs off )
EXPLAIN (COSTS OFF )
SELECT count(*) FROM emp1 c1, emp1 c2, emp1 c3
WHERE c1.id=c2.id AND c1.id*c2.id=c3.id*c3.id;
QUERY PLAN
@ -6809,7 +6826,7 @@ WHERE c1.id=c2.id AND c1.id*c2.id=c3.id*c3.id;
Filter: ((id * id) IS NOT NULL)
(3 rows)
explain (costs off )
EXPLAIN (COSTS OFF )
SELECT count(*) FROM emp1 c1, emp1 c2, emp1 c3
WHERE c1.id=c3.id AND c1.id*c3.id=c2.id*c2.id;
QUERY PLAN
@ -6819,7 +6836,7 @@ WHERE c1.id=c3.id AND c1.id*c3.id=c2.id*c2.id;
Filter: ((id * id) IS NOT NULL)
(3 rows)
explain (costs off )
EXPLAIN (COSTS OFF )
SELECT count(*) FROM emp1 c1, emp1 c2, emp1 c3
WHERE c3.id=c2.id AND c3.id*c2.id=c1.id*c1.id;
QUERY PLAN
@ -6830,7 +6847,7 @@ WHERE c3.id=c2.id AND c3.id*c2.id=c1.id*c1.id;
(3 rows)
-- Check the usage of a parse tree by the set operations (bug #18170)
explain (costs off )
EXPLAIN (COSTS OFF )
SELECT c1.code FROM emp1 c1 LEFT JOIN emp1 c2 ON c1.id = c2.id
WHERE c2.id IS NOT NULL
EXCEPT ALL
@ -6928,7 +6945,7 @@ select * from emp1 t1
(5 rows)
-- Check that SJE doesn't replace the target relation
explain (costs off )
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, t1.code;
@ -7077,7 +7094,7 @@ where t1.b = t2.b and t2.a = 3 and t1.a = 3
(3 rows)
-- Join qual isn't mergejoinable, but inner is unique.
explain (COSTS OFF)
EXPLAIN (COSTS OFF)
SELECT n2.a FROM sj n1, sj n2 WHERE n1.a <> n2.a AND n2.a = 1;
QUERY PLAN
-------------------------------
@ -7088,9 +7105,9 @@ SELECT n2.a FROM sj n1, sj n2 WHERE n1.a <> n2.a AND n2.a = 1;
-> Seq Scan on sj n1
(5 rows)
explain (COSTS OFF)
EXPLAIN (COSTS OFF)
SELECT * FROM
(SELECT n2.a FROM sj n1, sj n2 WHERE n1.a <> n2.a) q0, sl
(SELECT n2.a FROM sj n1, sj n2 WHERE n1.a <> n2.a) q0, sl
WHERE q0.a = 1;
QUERY PLAN
-------------------------------
@ -7103,20 +7120,6 @@ WHERE q0.a = 1;
-> Seq Scan on sj n1
(7 rows)
--
---- Only one side is unique
--select * from sl t1, sl t2 where t1.a = t2.a and t1.b = 1;
--select * from sl t1, sl t2 where t1.a = t2.a and t2.b = 1;
--
---- Several uniques indexes match, and we select a different one
---- for each side, so the join is not removed
--create table sm(a int unique, b int unique, c int unique);
--explain (costs off)
--select * from sm m, sm n where m.a = n.b and m.c = n.c;
--explain (costs off)
--select * from sm m, sm n where m.a = n.c and m.b = n.b;
--explain (costs off)
--select * from sm m, sm n where m.c = n.b and m.a = n.a;
-- Check optimization disabling if it will violate special join conditions.
-- Two identical joined relations satisfies self join removal conditions but
-- stay in different special join infos.
@ -7175,7 +7178,8 @@ ON sj_t1.id = _t2t3t4.id;
--
-- Test RowMarks-related code
--
EXPLAIN (COSTS OFF) -- Both sides have explicit LockRows marks
-- Both sides have explicit LockRows marks
EXPLAIN (COSTS OFF)
SELECT a1.a FROM sj a1,sj a2 WHERE (a1.a=a2.a) FOR UPDATE;
QUERY PLAN
---------------------------------