Skip to content

Commit 9f452fe

Browse files
committed
Fix thinko in qual distribution.
deconstruct_distribute tweaks the outer join scope (ojscope) it passes to distribute_qual_to_rels when considering an outer join qual that's above potentially-commutable outer joins. However, if the current join is *not* potentially commutable, we shouldn't do that. The argument that distribute_qual_to_rels will not do something wrong with the bogus ojscope falls flat if we don't pass it non-null postponed_oj_qual_list. Moreover, there's no need to play games in this case since we aren't going to commute anything. Per SQLSmith testing by Robins Tharakan. Discussion: https://postgr.es/m/CAEP4nAw74k4b-=93gmfCNX3MOY3y4uPxqbk_MnCVEpdsqHJVsg@mail.gmail.com
1 parent 8538519 commit 9f452fe

File tree

3 files changed

+42
-15
lines changed

3 files changed

+42
-15
lines changed

src/backend/optimizer/plan/initsplan.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,23 +1189,8 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
11891189
if (j->jointype == JOIN_SEMI)
11901190
ojscope = NULL;
11911191
else
1192-
{
11931192
ojscope = bms_union(sjinfo->min_lefthand,
11941193
sjinfo->min_righthand);
1195-
1196-
/*
1197-
* Add back any commutable lower OJ relids that were removed
1198-
* from min_lefthand or min_righthand, else the ojscope
1199-
* cross-check in distribute_qual_to_rels will complain. If
1200-
* any such OJs were removed, we will postpone processing of
1201-
* non-degenerate clauses, so this addition doesn't affect
1202-
* anything except that cross-check and some Asserts. Real
1203-
* clause positioning decisions will be made later, when we
1204-
* revisit the postponed clauses.
1205-
*/
1206-
if (sjinfo->commute_below)
1207-
ojscope = bms_add_members(ojscope, sjinfo->commute_below);
1208-
}
12091194
}
12101195
else
12111196
{
@@ -1221,7 +1206,21 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
12211206
* they will drop down below this join anyway.)
12221207
*/
12231208
if (j->jointype == JOIN_LEFT && sjinfo->lhs_strict)
1209+
{
12241210
postponed_oj_qual_list = &jtitem->oj_joinclauses;
1211+
1212+
/*
1213+
* Add back any commutable lower OJ relids that were removed from
1214+
* min_lefthand or min_righthand, else the ojscope cross-check in
1215+
* distribute_qual_to_rels will complain. Since we are postponing
1216+
* processing of non-degenerate clauses, this addition doesn't
1217+
* affect anything except that cross-check. Real clause
1218+
* positioning decisions will be made later, when we revisit the
1219+
* postponed clauses.
1220+
*/
1221+
if (sjinfo->commute_below)
1222+
ojscope = bms_add_members(ojscope, sjinfo->commute_below);
1223+
}
12251224
else
12261225
postponed_oj_qual_list = NULL;
12271226

src/test/regress/expected/join.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4451,6 +4451,24 @@ select * from
44514451
doh! | 123 | 456 | hi de ho neighbor |
44524452
(2 rows)
44534453

4454+
-- check handling of a variable-free qual for a non-commutable outer join
4455+
explain (costs off)
4456+
select nspname
4457+
from (select 1 as x) ss1
4458+
left join
4459+
( select n.nspname, c.relname
4460+
from pg_class c left join pg_namespace n on n.oid = c.relnamespace
4461+
where c.relkind = 'r'
4462+
) ss2 on false;
4463+
QUERY PLAN
4464+
--------------------------------
4465+
Nested Loop Left Join
4466+
Join Filter: false
4467+
-> Result
4468+
-> Result
4469+
One-Time Filter: false
4470+
(5 rows)
4471+
44544472
--
44554473
-- test for appropriate join order in the presence of lateral references
44564474
--

src/test/regress/sql/join.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,16 @@ select * from
15351535
left join int4_tbl i4
15361536
on i8.q1 = i4.f1;
15371537

1538+
-- check handling of a variable-free qual for a non-commutable outer join
1539+
explain (costs off)
1540+
select nspname
1541+
from (select 1 as x) ss1
1542+
left join
1543+
( select n.nspname, c.relname
1544+
from pg_class c left join pg_namespace n on n.oid = c.relnamespace
1545+
where c.relkind = 'r'
1546+
) ss2 on false;
1547+
15381548
--
15391549
-- test for appropriate join order in the presence of lateral references
15401550
--

0 commit comments

Comments
 (0)