Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5d8aa8b

Browse files
committed
Fix missed optimization in relation_excluded_by_constraints().
In commit 3fc6e2d, I (tgl) argued that we only need to check for a constant-FALSE restriction clause when there's exactly one restriction clause, on the grounds that const-folding would have thrown away anything ANDed with a Const FALSE. That's true just after const-folding has been applied, but subsequent processing such as equivalence class expansion could result in cases where a Const FALSE is ANDed with some other stuff. (Compare for instance joinrels.c's restriction_is_constant_false.) Hence, tweak this logic to check all the elements of the baserestrictinfo list, not just one; that's cheap enough to not be worth worrying about. There is one existing test case where this visibly improves the plan. There would not be any savings in runtime, but the planner effort and executor startup effort will be reduced, and anyway it's odd that we can detect related cases but not this one. Richard Guo (independently discovered by David Rowley) Discussion: https://postgr.es/m/CAMbWs4_x3-CnVVrCboS1LkEhB5V+W7sLSCabsRiG+n7+5_kqbg@mail.gmail.com
1 parent 16671ba commit 5d8aa8b

File tree

2 files changed

+12
-13
lines changed

2 files changed

+12
-13
lines changed

src/backend/optimizer/util/plancat.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -1549,16 +1549,17 @@ relation_excluded_by_constraints(PlannerInfo *root,
15491549

15501550
/*
15511551
* Regardless of the setting of constraint_exclusion, detect
1552-
* constant-FALSE-or-NULL restriction clauses. Because const-folding will
1553-
* reduce "anything AND FALSE" to just "FALSE", any such case should
1554-
* result in exactly one baserestrictinfo entry. This doesn't fire very
1555-
* often, but it seems cheap enough to be worth doing anyway. (Without
1556-
* this, we'd miss some optimizations that 9.5 and earlier found via much
1557-
* more roundabout methods.)
1552+
* constant-FALSE-or-NULL restriction clauses. Although const-folding
1553+
* will reduce "anything AND FALSE" to just "FALSE", the baserestrictinfo
1554+
* list can still have other members besides the FALSE constant, due to
1555+
* qual pushdown and other mechanisms; so check them all. This doesn't
1556+
* fire very often, but it seems cheap enough to be worth doing anyway.
1557+
* (Without this, we'd miss some optimizations that 9.5 and earlier found
1558+
* via much more roundabout methods.)
15581559
*/
1559-
if (list_length(rel->baserestrictinfo) == 1)
1560+
foreach(lc, rel->baserestrictinfo)
15601561
{
1561-
RestrictInfo *rinfo = (RestrictInfo *) linitial(rel->baserestrictinfo);
1562+
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
15621563
Expr *clause = rinfo->clause;
15631564

15641565
if (clause && IsA(clause, Const) &&

src/test/regress/expected/join.out

+3-5
Original file line numberDiff line numberDiff line change
@@ -5788,13 +5788,11 @@ explain (costs off)
57885788
select p.* from
57895789
parent p left join child c on (p.k = c.k)
57905790
where p.k = 1 and p.k = 2;
5791-
QUERY PLAN
5792-
------------------------------------------------
5791+
QUERY PLAN
5792+
--------------------------
57935793
Result
57945794
One-Time Filter: false
5795-
-> Index Scan using parent_pkey on parent p
5796-
Index Cond: (k = 1)
5797-
(4 rows)
5795+
(2 rows)
57985796

57995797
select p.* from
58005798
(parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k

0 commit comments

Comments
 (0)