Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b746d0c

Browse files
committed
Fix old bug in get_loop_count().
While poking at David Kubečka's issue I noticed an ancient logic error in get_loop_count(): it used 1.0 as a "no data yet" indicator, but since that is actually a valid rowcount estimate, this doesn't work. If we have one input relation with 1.0 as rowcount and then another one with a larger rowcount, we should use 1.0 as the result, but we picked the larger rowcount instead. (I think when I coded this, I recognized the conflict, but mistakenly thought that the logic would pick the desired count anyway.) Fixing this changed the plan for one existing regression test case. Since the point of that test is to exercise creation of a particular shape of nestloop plan, I tweaked the query a little bit so it still results in the same plan choice. This is definitely a bug, but I'm hesitant to back-patch since it might change plan choices unexpectedly, and anyway failure to implement a heuristic precisely as intended is a pretty low-grade bug.
1 parent b557226 commit b746d0c

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,7 @@ get_loop_count(PlannerInfo *root, Index cur_relid, Relids outer_relids)
18861886
if (outer_relids == NULL)
18871887
return 1.0;
18881888

1889-
result = 1.0;
1889+
result = 0.0;
18901890
outer_relid = -1;
18911891
while ((outer_relid = bms_next_member(outer_relids, outer_relid)) >= 0)
18921892
{
@@ -1915,10 +1915,11 @@ get_loop_count(PlannerInfo *root, Index cur_relid, Relids outer_relids)
19151915
outer_rel->rows);
19161916

19171917
/* Remember smallest row count estimate among the outer rels */
1918-
if (result == 1.0 || result > rowcount)
1918+
if (result == 0.0 || result > rowcount)
19191919
result = rowcount;
19201920
}
1921-
return result;
1921+
/* Return 1.0 if we found no valid relations (shouldn't happen) */
1922+
return (result > 0.0) ? result : 1.0;
19221923
}
19231924

19241925
/*

src/test/regress/expected/join.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3074,14 +3074,14 @@ select f1, unique2, case when unique2 is null then f1 else 0 end
30743074
explain (costs off)
30753075
select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand)
30763076
from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand)
3077-
where a.unique2 = 5530 and coalesce(b.twothousand, a.twothousand) = 44;
3077+
where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44;
30783078
QUERY PLAN
30793079
---------------------------------------------------------------------------------------------
30803080
Nested Loop Left Join
30813081
-> Nested Loop Left Join
30823082
Filter: (COALESCE(b.twothousand, a.twothousand) = 44)
30833083
-> Index Scan using tenk1_unique2 on tenk1 a
3084-
Index Cond: (unique2 = 5530)
3084+
Index Cond: (unique2 < 10)
30853085
-> Bitmap Heap Scan on tenk1 b
30863086
Recheck Cond: (thousand = a.unique1)
30873087
-> Bitmap Index Scan on tenk1_thous_tenthous
@@ -3092,7 +3092,7 @@ select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand)
30923092

30933093
select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand)
30943094
from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand)
3095-
where a.unique2 = 5530 and coalesce(b.twothousand, a.twothousand) = 44;
3095+
where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44;
30963096
unique1 | unique1 | unique1 | coalesce
30973097
---------+---------+---------+----------
30983098
(0 rows)

src/test/regress/sql/join.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,11 +880,11 @@ select f1, unique2, case when unique2 is null then f1 else 0 end
880880
explain (costs off)
881881
select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand)
882882
from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand)
883-
where a.unique2 = 5530 and coalesce(b.twothousand, a.twothousand) = 44;
883+
where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44;
884884

885885
select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand)
886886
from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand)
887-
where a.unique2 = 5530 and coalesce(b.twothousand, a.twothousand) = 44;
887+
where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44;
888888

889889
--
890890
-- check handling of join aliases when flattening multiple levels of subquery

0 commit comments

Comments
 (0)