From de4f996975ffe180203c2e83edd1d1785d78f654 Mon Sep 17 00:00:00 2001 From: Andrei Lepikhov Date: Thu, 5 Nov 2026 19:47:17 +0100 Subject: [PATCH v0 1/2] Switch JOIN and SCAN filter explain output to floating point format --- src/backend/commands/explain.c | 2 +- src/test/regress/expected/explain.out | 39 +++++++++++++++++++++++++++ src/test/regress/sql/explain.sql | 12 +++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 4b1ad4227ac..ace016637af 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -4222,7 +4222,7 @@ show_instrumentation_count(const char *qlabel, int which, if (nfiltered > 0 || es->format != EXPLAIN_FORMAT_TEXT) { if (nloops > 0) - ExplainPropertyFloat(qlabel, NULL, nfiltered / nloops, 0, es); + ExplainPropertyFloat(qlabel, NULL, nfiltered / nloops, 2, es); else ExplainPropertyFloat(qlabel, NULL, 0.0, 0, es); } diff --git a/src/test/regress/expected/explain.out b/src/test/regress/expected/explain.out index 74a4d87801e..6f196bccf1f 100644 --- a/src/test/regress/expected/explain.out +++ b/src/test/regress/expected/explain.out @@ -832,3 +832,42 @@ select explain_filter('explain (analyze,buffers off,costs off) select sum(n) ove (9 rows) reset work_mem; +-- Rows Removed by Filter is averaged over loops, like actual rows, +-- and must be shown with fractional digits as well +explain (analyze, costs off, timing off, summary off, buffers off) +select count(*) from generate_series(0, 9) g join tenk1 b on b.unique1 = g +where b.ten <> 0; + QUERY PLAN +----------------------------------------------------------------------------------- + Aggregate (actual rows=1.00 loops=1) + -> Nested Loop (actual rows=9.00 loops=1) + -> Function Scan on generate_series g (actual rows=10.00 loops=1) + -> Index Scan using tenk1_unique1 on tenk1 b (actual rows=0.90 loops=10) + Index Cond: (unique1 = g.g) + Filter: (ten <> 0) + Rows Removed by Filter: 0.10 + Index Searches: 10 +(8 rows) + +-- Join Filter of a join that is itself rescanned +explain (analyze, costs off, timing off, summary off, buffers off) +select count(*) from generate_series(0, 9) g, + lateral (select 1 from tenk1 b join tenk1 c + on c.unique2 = b.unique1 and b.ten <> c.ten + where b.unique1 = g offset 0) s; + QUERY PLAN +----------------------------------------------------------------------------------------- + Aggregate (actual rows=1.00 loops=1) + -> Nested Loop (actual rows=7.00 loops=1) + -> Function Scan on generate_series g (actual rows=10.00 loops=1) + -> Nested Loop (actual rows=0.70 loops=10) + Join Filter: (b.ten <> c.ten) + Rows Removed by Join Filter: 0.30 + -> Index Scan using tenk1_unique1 on tenk1 b (actual rows=1.00 loops=10) + Index Cond: (unique1 = g.g) + Index Searches: 10 + -> Index Scan using tenk1_unique2 on tenk1 c (actual rows=1.00 loops=10) + Index Cond: (unique2 = g.g) + Index Searches: 10 +(12 rows) + diff --git a/src/test/regress/sql/explain.sql b/src/test/regress/sql/explain.sql index 2f163c64bf6..166c550d2e5 100644 --- a/src/test/regress/sql/explain.sql +++ b/src/test/regress/sql/explain.sql @@ -191,3 +191,15 @@ select explain_filter('explain (analyze,buffers off,costs off) select sum(n) ove -- Test tuplestore storage usage in Window aggregate (memory and disk case, final result is disk) select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over(partition by m) from (SELECT n < 3 as m, n from generate_series(1,2500) a(n))'); reset work_mem; + +-- Rows Removed by Filter is averaged over loops, like actual rows, +-- and must be shown with fractional digits as well +explain (analyze, costs off, timing off, summary off, buffers off) +select count(*) from generate_series(0, 9) g join tenk1 b on b.unique1 = g +where b.ten <> 0; +-- Join Filter of a join that is itself rescanned +explain (analyze, costs off, timing off, summary off, buffers off) +select count(*) from generate_series(0, 9) g, + lateral (select 1 from tenk1 b join tenk1 c + on c.unique2 = b.unique1 and b.ten <> c.ten + where b.unique1 = g offset 0) s; -- 2.56.0