On 06/11/2026 14:17, Ilia Evdokimov wrote:
> On 11/6/26 11:57, Andrei Lepikhov wrote:
>> The patch is a single-line change in show_instrumentation_count() plus two
>> tests. It is a concept, not a finished patch: I have not regenerated the 
>> other
>> expected outputs, where many values will change from "N" to "N.00" - you can
>> find a sketch for that in 0002-* file.
> 
> If we switch to fractional row counts, we should also remember to update the
> relevant examples in the doc, including "Rows Removed by Filter", "Rows 
> Removed
> by Index Recheck", "Rows Removed by Conflict Filter", "Rows Removed by Join
> Filter".
> 
> Regardless of whether we change this output format, it would be be useful to
> document in the "Using EXPLAIN" section (perform.sgml), in the paragraph
> describing "Rows Removed", that these counts are averages per execution of the
> node. This is already the case, but the paragraph does not mention it.
Ok, my AI coding agent detects such places quite nicely. See the patch v0-0002-*
in attachment.

>> rule as actual rows. The options I see are:
>>
>> 1. Always print two digits, as actual rows do now.
>> 2. Leave the math to users and print exact totals without dividing by nloops.
>>
>> The second approach is a much bigger change, with obvious pros and cons.
>> The first one is simpler and more conservative, and it is what the attached
>> patch does. In [1], depesz describes how the switch to fractional actual rows
>> affected his explain parser, and it needed only a small fix. So I expect this
>> change to be similarly harmless for tools.
> 
> I also prefer the first option, as it is more conservative and keeps these
> counters consistent with actual rows.
Hmm, I wouldn't say that I prefer the first approach. Reading explains quite
frequently that I'd prefer sums on all cycles for sure - sometimes huge work is
hidden in the third or even sixth digit after the point - because it is the
first non-zero digit. But I understand the reasoning and agree - it is a
contradictory question. So, No.1 is just a compromise.

-- 
regards, Andrei Lepikhov,
pgEdge
From de4f996975ffe180203c2e83edd1d1785d78f654 Mon Sep 17 00:00:00 2001
From: Andrei Lepikhov <[email protected]>
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

From 29e5990ce6e69b61d74e200a3678b87e69c5ec4b Mon Sep 17 00:00:00 2001
From: Andrei Lepikhov <[email protected]>
Date: Fri, 6 Nov 2026 08:44:45 +0000
Subject: [PATCH v0 2/2] Adjust regression tests and docs to fractional "Rows
 Removed by" counters

Follow-up to the previous commit: regenerate the expected outputs that
print Rows Removed by Filter / Join Filter / Index Recheck, and loosen the
partition_prune filter regexp to accept a fractional part.

Refresh the EXPLAIN examples in the documentation accordingly and state
explicitly in "Using EXPLAIN" that the Rows Removed counts are averages
per execution of the node, just like actual rows.  That was already the
case before this change, but the paragraph did not mention it.
---
 .../postgres_fdw/expected/postgres_fdw.out    |  6 ++---
 doc/src/sgml/bloom.sgml                       |  6 ++---
 doc/src/sgml/perform.sgml                     | 13 ++++++-----
 doc/src/sgml/planstats.sgml                   | 12 +++++-----
 doc/src/sgml/rules.sgml                       |  2 +-
 src/test/regress/expected/gin.out             | 20 ++++++++---------
 src/test/regress/expected/memoize.out         | 18 +++++++--------
 src/test/regress/expected/merge.out           |  2 +-
 src/test/regress/expected/partition_prune.out | 22 +++++++++----------
 src/test/regress/expected/select_parallel.out |  4 ++--
 src/test/regress/sql/partition_prune.sql      |  2 +-
 11 files changed, 55 insertions(+), 52 deletions(-)

diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out 
b/contrib/postgres_fdw/expected/postgres_fdw.out
index b946a6416a0..cb2801978f9 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -12836,7 +12836,7 @@ SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = 
async_pt.a AND local_tbl.c
  Nested Loop (actual rows=1.00 loops=1)
    ->  Seq Scan on local_tbl (actual rows=1.00 loops=1)
          Filter: (c = 'bar'::text)
-         Rows Removed by Filter: 1
+         Rows Removed by Filter: 1.00
    ->  Append (actual rows=1.00 loops=1)
          ->  Async Foreign Scan on async_p1 async_pt_1 (never executed)
          ->  Async Foreign Scan on async_p2 async_pt_2 (actual rows=1.00 
loops=1)
@@ -13081,7 +13081,7 @@ SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT 
count(*) FROM async_pt W
 
--------------------------------------------------------------------------------------------
  Nested Loop Left Join (actual rows=1.00 loops=1)
    Join Filter: (t1.a = async_pt.a)
-   Rows Removed by Join Filter: 399
+   Rows Removed by Join Filter: 399.00
    InitPlan expr_1
      ->  Aggregate (actual rows=1.00 loops=1)
            ->  Append (actual rows=400.00 loops=1)
@@ -13131,7 +13131,7 @@ SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
                Filter: (b === 505)
          ->  Seq Scan on async_p3 t1_3 (actual rows=1.00 loops=1)
                Filter: (b === 505)
-               Rows Removed by Filter: 101
+               Rows Removed by Filter: 101.00
 (9 rows)
 
 SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1;
diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml
index 3f6d38f377b..8af6283335e 100644
--- a/doc/src/sgml/bloom.sgml
+++ b/doc/src/sgml/bloom.sgml
@@ -120,7 +120,7 @@ SELECT 10000000
 
-------------------------------------------------------------------&zwsp;-----------------------------------
  Seq Scan on tbloom  (cost=0.00..213744.00 rows=250 width=24) (actual 
time=357.059..357.059 rows=0.00 loops=1)
    Filter: ((i2 = 898732) AND (i5 = 123451))
-   Rows Removed by Filter: 10000000
+   Rows Removed by Filter: 10000000.00
    Buffers: shared hit=63744
  Planning Time: 0.346 ms
  Execution Time: 357.076 ms
@@ -144,7 +144,7 @@ CREATE INDEX
 
-------------------------------------------------------------------&zwsp;-----------------------------------
  Seq Scan on tbloom  (cost=0.00..213744.00 rows=2 width=24) (actual 
time=351.016..351.017 rows=0.00 loops=1)
    Filter: ((i2 = 898732) AND (i5 = 123451))
-   Rows Removed by Filter: 10000000
+   Rows Removed by Filter: 10000000.00
    Buffers: shared hit=63744
  Planning Time: 0.138 ms
  Execution Time: 351.035 ms
@@ -168,7 +168,7 @@ CREATE INDEX
 
-------------------------------------------------------------------&zwsp;--------------------------------------------------
  Bitmap Heap Scan on tbloom  (cost=1792.00..1799.69 rows=2 width=24) (actual 
time=22.605..22.606 rows=0.00 loops=1)
    Recheck Cond: ((i2 = 898732) AND (i5 = 123451))
-   Rows Removed by Index Recheck: 2300
+   Rows Removed by Index Recheck: 2300.00
    Heap Blocks: exact=2256
    Buffers: shared hit=21864
    -&gt;  Bitmap Index Scan on bloomidx  (cost=0.00..178436.00 rows=1 width=0) 
(actual time=20.005..20.005 rows=2300.00 loops=1)
diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml
index ea8da01b779..77bc45571bc 100644
--- a/doc/src/sgml/perform.sgml
+++ b/doc/src/sgml/perform.sgml
@@ -960,7 +960,7 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten &lt; 7;
 
-------------------------------------------------------------------&zwsp;--------------------------------------
  Seq Scan on tenk1  (cost=0.00..470.00 rows=7000 width=244) (actual 
time=0.030..1.995 rows=7000.00 loops=1)
    Filter: (ten &lt; 7)
-   Rows Removed by Filter: 3000
+   Rows Removed by Filter: 3000.00
    Buffers: shared hit=345
  Planning Time: 0.102 ms
  Execution Time: 2.145 ms
@@ -969,7 +969,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten &lt; 7;
     These counts can be particularly valuable for filter conditions applied at
     join nodes.  The <quote>Rows Removed</quote> line only appears when at 
least
     one scanned row, or potential join pair in the case of a join node,
-    is rejected by the filter condition.
+    is rejected by the filter condition.  Like the actual
+    <literal>rows</literal> value, these counts are averages per execution of
+    the node; multiply by the <literal>loops</literal> value to get the total
+    number of rows removed across all executions.
    </para>
 
    <para>
@@ -984,7 +987,7 @@ EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; 
polygon '(0.5,2.0)';
 
-------------------------------------------------------------------&zwsp;-----------------------------------
  Seq Scan on polygon_tbl  (cost=0.00..1.09 rows=1 width=85) (actual 
time=0.023..0.023 rows=0.00 loops=1)
    Filter: (f1 @&gt; '((0.5,2))'::polygon)
-   Rows Removed by Filter: 7
+   Rows Removed by Filter: 7.00
    Buffers: shared hit=1
  Planning Time: 0.039 ms
  Execution Time: 0.033 ms
@@ -1004,7 +1007,7 @@ EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; 
polygon '(0.5,2.0)';
 
-------------------------------------------------------------------&zwsp;-------------------------------------------------------
  Index Scan using gpolygonind on polygon_tbl  (cost=0.13..8.15 rows=1 
width=85) (actual time=0.074..0.074 rows=0.00 loops=1)
    Index Cond: (f1 @&gt; '((0.5,2))'::polygon)
-   Rows Removed by Index Recheck: 1
+   Rows Removed by Index Recheck: 1.00
    Index Searches: 1
    Buffers: shared hit=1
  Planning Time: 0.039 ms
@@ -1208,7 +1211,7 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 &lt; 
100 AND unique2 &gt; 9000
    -&gt;  Index Scan using tenk1_unique2 on tenk1  (cost=0.29..70.50 rows=10 
width=244) (actual time=0.051..0.070 rows=2.00 loops=1)
          Index Cond: (unique2 &gt; 9000)
          Filter: (unique1 &lt; 100)
-         Rows Removed by Filter: 287
+         Rows Removed by Filter: 287.00
          Index Searches: 1
          Buffers: shared hit=16
  Planning Time: 0.077 ms
diff --git a/doc/src/sgml/planstats.sgml b/doc/src/sgml/planstats.sgml
index e57867ba617..c94d1ba0605 100644
--- a/doc/src/sgml/planstats.sgml
+++ b/doc/src/sgml/planstats.sgml
@@ -494,7 +494,7 @@ EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t 
WHERE a = 1;
 
-------------------------------------------------------------------&zwsp;------------
  Seq Scan on t  (cost=0.00..170.00 rows=100 width=8) (actual rows=100.00 
loops=1)
    Filter: (a = 1)
-   Rows Removed by Filter: 9900
+   Rows Removed by Filter: 9900.00
 </programlisting>
 
     The planner examines the condition and determines the selectivity
@@ -511,7 +511,7 @@ EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t 
WHERE a = 1 AND b = 1
 
-------------------------------------------------------------------&zwsp;----------
  Seq Scan on t  (cost=0.00..195.00 rows=1 width=8) (actual rows=100.00 loops=1)
    Filter: ((a = 1) AND (b = 1))
-   Rows Removed by Filter: 9900
+   Rows Removed by Filter: 9900.00
 </programlisting>
 
     The planner estimates the selectivity for each condition individually,
@@ -535,7 +535,7 @@ EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t 
WHERE a = 1 AND b = 1
 
-------------------------------------------------------------------&zwsp;------------
  Seq Scan on t  (cost=0.00..195.00 rows=100 width=8) (actual rows=100.00 
loops=1)
    Filter: ((a = 1) AND (b = 1))
-   Rows Removed by Filter: 9900
+   Rows Removed by Filter: 9900.00
 </programlisting>
    </para>
   </sect2>
@@ -620,7 +620,7 @@ EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t 
WHERE a = 1 AND b = 1
 
-------------------------------------------------------------------&zwsp;------------
  Seq Scan on t  (cost=0.00..195.00 rows=100 width=8) (actual rows=100.00 
loops=1)
    Filter: ((a = 1) AND (b = 1))
-   Rows Removed by Filter: 9900
+   Rows Removed by Filter: 9900.00
 </programlisting>
 
     The estimate is as accurate as with the functional dependencies, mostly
@@ -677,7 +677,7 @@ EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t 
WHERE a = 1 AND b = 1
 
-------------------------------------------------------------------&zwsp;--------
  Seq Scan on t  (cost=0.00..195.00 rows=1 width=8) (actual rows=0.00 loops=1)
    Filter: ((a = 1) AND (b = 10))
-   Rows Removed by Filter: 10000
+   Rows Removed by Filter: 10000.00
 </programlisting>
 
     Secondly, <acronym>MCV</acronym> lists handle a wider range of clause 
types,
@@ -690,7 +690,7 @@ EXPLAIN (ANALYZE, TIMING OFF, BUFFERS OFF) SELECT * FROM t 
WHERE a &lt;= 49 AND
 
-------------------------------------------------------------------&zwsp;--------
  Seq Scan on t  (cost=0.00..195.00 rows=1 width=8) (actual rows=0.00 loops=1)
    Filter: ((a &lt;= 49) AND (b &gt; 49))
-   Rows Removed by Filter: 10000
+   Rows Removed by Filter: 10000.00
 </programlisting>
 
    </para>
diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml
index 9f9fa978f2d..4ae9cc4bdbd 100644
--- a/doc/src/sgml/rules.sgml
+++ b/doc/src/sgml/rules.sgml
@@ -1033,7 +1033,7 @@ SELECT count(*) FROM words WHERE word = 'caterpiler';
  Aggregate  (cost=21763.99..21764.00 rows=1 width=0) (actual 
time=188.180..188.181 rows=1.00 loops=1)
    -&gt;  Foreign Scan on words  (cost=0.00..21761.41 rows=1032 width=0) 
(actual time=188.177..188.177 rows=0.00 loops=1)
          Filter: (word = 'caterpiler'::text)
-         Rows Removed by Filter: 479829
+         Rows Removed by Filter: 479829.00
          Foreign File: /usr/share/dict/words
          Foreign File Size: 4953699
  Planning time: 0.118 ms
diff --git a/src/test/regress/expected/gin.out 
b/src/test/regress/expected/gin.out
index 118bc26d8cd..43bf8cc78f8 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -187,16 +187,16 @@ from
   lateral execute_text_query_heap($$select string_agg((i, j)::text, ' ') from 
t_gin_test_tbl where $$ || query) res_heap;
                    query                   | return by index | removed by 
recheck | match 
 
-------------------------------------------+-----------------+--------------------+-------
-  i @> '{}'                                | 7.00            | 0               
   | t
-  j @> '{}'                                | 6.00            | 0               
   | t
-  i @> '{}' and j @> '{}'                  | 4.00            | 0               
   | t
-  i @> '{1}'                               | 5.00            | 0               
   | t
-  i @> '{1}' and j @> '{}'                 | 3.00            | 0               
   | t
-  i @> '{1}' and i @> '{}' and j @> '{}'   | 3.00            | 0               
   | t
-  j @> '{10}'                              | 4.00            | 0               
   | t
-  j @> '{10}' and i @> '{}'                | 3.00            | 0               
   | t
-  j @> '{10}' and j @> '{}' and i @> '{}'  | 3.00            | 0               
   | t
-  i @> '{1}' and j @> '{10}'               | 2.00            | 0               
   | t
+  i @> '{}'                                | 7.00            | 0.00            
   | t
+  j @> '{}'                                | 6.00            | 0.00            
   | t
+  i @> '{}' and j @> '{}'                  | 4.00            | 0.00            
   | t
+  i @> '{1}'                               | 5.00            | 0.00            
   | t
+  i @> '{1}' and j @> '{}'                 | 3.00            | 0.00            
   | t
+  i @> '{1}' and i @> '{}' and j @> '{}'   | 3.00            | 0.00            
   | t
+  j @> '{10}'                              | 4.00            | 0.00            
   | t
+  j @> '{10}' and i @> '{}'                | 3.00            | 0.00            
   | t
+  j @> '{10}' and j @> '{}' and i @> '{}'  | 3.00            | 0.00            
   | t
+  i @> '{1}' and j @> '{10}'               | 2.00            | 0.00            
   | t
 (10 rows)
 
 reset enable_seqscan;
diff --git a/src/test/regress/expected/memoize.out 
b/src/test/regress/expected/memoize.out
index 30bf5f5667e..7d50ce553e4 100644
--- a/src/test/regress/expected/memoize.out
+++ b/src/test/regress/expected/memoize.out
@@ -43,7 +43,7 @@ WHERE t2.unique1 < 1000;', false);
    ->  Nested Loop (actual rows=1000.00 loops=N)
          ->  Seq Scan on tenk1 t2 (actual rows=1000.00 loops=N)
                Filter: (unique1 < 1000)
-               Rows Removed by Filter: 9000
+               Rows Removed by Filter: 9000.00
          ->  Memoize (actual rows=1.00 loops=N)
                Cache Key: t2.twenty
                Cache Mode: logical
@@ -75,7 +75,7 @@ WHERE t1.unique1 < 1000;', false);
    ->  Nested Loop (actual rows=1000.00 loops=N)
          ->  Seq Scan on tenk1 t1 (actual rows=1000.00 loops=N)
                Filter: (unique1 < 1000)
-               Rows Removed by Filter: 9000
+               Rows Removed by Filter: 9000.00
          ->  Memoize (actual rows=1.00 loops=N)
                Cache Key: t1.twenty
                Cache Mode: binary
@@ -117,7 +117,7 @@ WHERE t1.unique1 < 10;', false);
                Hits: 8  Misses: 2  Evictions: Zero  Overflows: 0  Memory 
Usage: NkB
                ->  Subquery Scan on t2 (actual rows=2.00 loops=N)
                      Filter: (t1.two = t2.two)
-                     Rows Removed by Filter: 2
+                     Rows Removed by Filter: 2.00
                      ->  Index Scan using tenk1_unique1 on tenk1 t2_1 (actual 
rows=4.00 loops=N)
                            Index Cond: (unique1 < 4)
                            Index Searches: N
@@ -146,14 +146,14 @@ WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false);
    ->  Nested Loop (actual rows=1000.00 loops=N)
          ->  Seq Scan on tenk1 t1 (actual rows=1000.00 loops=N)
                Filter: (unique1 < 1000)
-               Rows Removed by Filter: 9000
+               Rows Removed by Filter: 9000.00
          ->  Memoize (actual rows=1.00 loops=N)
                Cache Key: (t1.two + 1)
                Cache Mode: binary
                Hits: 998  Misses: 2  Evictions: Zero  Overflows: 0  Memory 
Usage: NkB
                ->  Index Only Scan using tenk1_unique1 on tenk1 t2 (actual 
rows=1.00 loops=N)
                      Filter: ((t1.two + 1) = unique1)
-                     Rows Removed by Filter: 9999
+                     Rows Removed by Filter: 9999.00
                      Heap Fetches: N
                      Index Searches: N
 (14 rows)
@@ -179,14 +179,14 @@ WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false);
    ->  Nested Loop (actual rows=1000.00 loops=N)
          ->  Seq Scan on tenk1 t1 (actual rows=1000.00 loops=N)
                Filter: (unique1 < 1000)
-               Rows Removed by Filter: 9000
+               Rows Removed by Filter: 9000.00
          ->  Memoize (actual rows=1.00 loops=N)
                Cache Key: t1.two, t1.twenty
                Cache Mode: binary
                Hits: 980  Misses: 20  Evictions: Zero  Overflows: 0  Memory 
Usage: NkB
                ->  Seq Scan on tenk1 t2 (actual rows=1.00 loops=N)
                      Filter: ((t1.twenty = unique1) AND (t1.two = two))
-                     Rows Removed by Filter: 9999
+                     Rows Removed by Filter: 9999.00
 (12 rows)
 
 -- And check we get the expected results.
@@ -246,7 +246,7 @@ WHERE t2.unique1 < 1200;', true);
    ->  Nested Loop (actual rows=1200.00 loops=N)
          ->  Seq Scan on tenk1 t2 (actual rows=1200.00 loops=N)
                Filter: (unique1 < 1200)
-               Rows Removed by Filter: 8800
+               Rows Removed by Filter: 8800.00
          ->  Memoize (actual rows=1.00 loops=N)
                Cache Key: t2.thousand
                Cache Mode: logical
@@ -698,7 +698,7 @@ WHERE t2.a IS NULL;', false);
                Hits: 97  Misses: 3  Evictions: Zero  Overflows: 0  Memory 
Usage: NkB
                ->  Subquery Scan on t2 (actual rows=0.67 loops=N)
                      Filter: ((t1.a + 1) = t2.a)
-                     Rows Removed by Filter: 2
+                     Rows Removed by Filter: 2.00
                      ->  Unique (actual rows=2.67 loops=N)
                            ->  Sort (actual rows=67.33 loops=N)
                                  Sort Key: t2_1.a
diff --git a/src/test/regress/expected/merge.out 
b/src/test/regress/expected/merge.out
index 9cb1d87066a..000c2b19e34 100644
--- a/src/test/regress/expected/merge.out
+++ b/src/test/regress/expected/merge.out
@@ -1801,7 +1801,7 @@ WHEN MATCHED AND t.a < 10 THEN
                Sort Method: quicksort  Memory: xxx
                ->  Seq Scan on ex_mtarget t (actual rows=0.00 loops=1)
                      Filter: (a < '-1000'::integer)
-                     Rows Removed by Filter: 54
+                     Rows Removed by Filter: 54.00
          ->  Sort (never executed)
                Sort Key: s.a
                ->  Seq Scan on ex_msource s (never executed)
diff --git a/src/test/regress/expected/partition_prune.out 
b/src/test/regress/expected/partition_prune.out
index 3506ecec477..caa046b36f8 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -2535,16 +2535,16 @@ explain (analyze, costs off, summary off, timing off, 
buffers off) select * from
  Append (actual rows=0.00 loops=1)
    ->  Seq Scan on list_part1 list_part_1 (actual rows=0.00 loops=1)
          Filter: (a = (list_part_fn(1) + a))
-         Rows Removed by Filter: 1
+         Rows Removed by Filter: 1.00
    ->  Seq Scan on list_part2 list_part_2 (actual rows=0.00 loops=1)
          Filter: (a = (list_part_fn(1) + a))
-         Rows Removed by Filter: 1
+         Rows Removed by Filter: 1.00
    ->  Seq Scan on list_part3 list_part_3 (actual rows=0.00 loops=1)
          Filter: (a = (list_part_fn(1) + a))
-         Rows Removed by Filter: 1
+         Rows Removed by Filter: 1.00
    ->  Seq Scan on list_part4 list_part_4 (actual rows=0.00 loops=1)
          Filter: (a = (list_part_fn(1) + a))
-         Rows Removed by Filter: 1
+         Rows Removed by Filter: 1.00
 (13 rows)
 
 rollback;
@@ -2570,7 +2570,7 @@ begin
     loop
         ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: 
N');
         ln := regexp_replace(ln, 'actual rows=\d+(?:\.\d+)? loops=\d+', 
'actual rows=N loops=N');
-        ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed 
by Filter: N');
+        ln := regexp_replace(ln, 'Rows Removed by Filter: \d+(?:\.\d+)?', 
'Rows Removed by Filter: N');
         perform regexp_matches(ln, 'Index Searches: \d+');
         if found then
           continue;
@@ -3068,7 +3068,7 @@ explain (analyze, costs off, summary off, timing off, 
buffers off) execute ab_q6
          Filter: ((a = $1) AND (b = (InitPlan expr_1).col1))
    ->  Seq Scan on xy_1 (actual rows=0.00 loops=1)
          Filter: ((x = $1) AND (y = (InitPlan expr_1).col1))
-         Rows Removed by Filter: 1
+         Rows Removed by Filter: 1.00
    ->  Seq Scan on ab_a1_b1 ab_4 (never executed)
          Filter: ((a = $1) AND (b = (InitPlan expr_1).col1))
    ->  Seq Scan on ab_a1_b2 ab_5 (never executed)
@@ -3732,7 +3732,7 @@ select * from boolp where a = (select value from 
boolvalues where value);
    InitPlan expr_1
      ->  Seq Scan on boolvalues (actual rows=1.00 loops=1)
            Filter: value
-           Rows Removed by Filter: 1
+           Rows Removed by Filter: 1.00
    ->  Seq Scan on boolp_f boolp_1 (never executed)
          Filter: (a = (InitPlan expr_1).col1)
    ->  Seq Scan on boolp_t boolp_2 (actual rows=0.00 loops=1)
@@ -3747,7 +3747,7 @@ select * from boolp where a = (select value from 
boolvalues where not value);
    InitPlan expr_1
      ->  Seq Scan on boolvalues (actual rows=1.00 loops=1)
            Filter: (NOT value)
-           Rows Removed by Filter: 1
+           Rows Removed by Filter: 1.00
    ->  Seq Scan on boolp_f boolp_1 (actual rows=0.00 loops=1)
          Filter: (a = (InitPlan expr_1).col1)
    ->  Seq Scan on boolp_t boolp_2 (never executed)
@@ -3776,11 +3776,11 @@ explain (analyze, costs off, summary off, timing off, 
buffers off) execute mt_q1
    Subplans Removed: 1
    ->  Index Scan using ma_test_p2_b_idx on ma_test_p2 ma_test_1 (actual 
rows=1.00 loops=1)
          Filter: ((a >= $1) AND ((a % 10) = 5))
-         Rows Removed by Filter: 9
+         Rows Removed by Filter: 9.00
          Index Searches: 1
    ->  Index Scan using ma_test_p3_b_idx on ma_test_p3 ma_test_2 (actual 
rows=1.00 loops=1)
          Filter: ((a >= $1) AND ((a % 10) = 5))
-         Rows Removed by Filter: 9
+         Rows Removed by Filter: 9.00
          Index Searches: 1
 (11 rows)
 
@@ -3799,7 +3799,7 @@ explain (analyze, costs off, summary off, timing off, 
buffers off) execute mt_q1
    Subplans Removed: 2
    ->  Index Scan using ma_test_p3_b_idx on ma_test_p3 ma_test_1 (actual 
rows=1.00 loops=1)
          Filter: ((a >= $1) AND ((a % 10) = 5))
-         Rows Removed by Filter: 9
+         Rows Removed by Filter: 9.00
          Index Searches: 1
 (7 rows)
 
diff --git a/src/test/regress/expected/select_parallel.out 
b/src/test/regress/expected/select_parallel.out
index e1344215644..a71f453a5a3 100644
--- a/src/test/regress/expected/select_parallel.out
+++ b/src/test/regress/expected/select_parallel.out
@@ -589,13 +589,13 @@ explain (analyze, timing off, summary off, costs off, 
buffers off)
    ->  Nested Loop (actual rows=98000.00 loops=1)
          ->  Seq Scan on tenk2 (actual rows=10.00 loops=1)
                Filter: (thousand = 0)
-               Rows Removed by Filter: 9990
+               Rows Removed by Filter: 9990.00
          ->  Gather (actual rows=9800.00 loops=10)
                Workers Planned: 4
                Workers Launched: 4
                ->  Parallel Seq Scan on tenk1 (actual rows=1960.00 loops=50)
                      Filter: (hundred > 1)
-                     Rows Removed by Filter: 40
+                     Rows Removed by Filter: 40.00
 (11 rows)
 
 alter table tenk2 reset (parallel_workers);
diff --git a/src/test/regress/sql/partition_prune.sql 
b/src/test/regress/sql/partition_prune.sql
index d6e096dc565..b642690061f 100644
--- a/src/test/regress/sql/partition_prune.sql
+++ b/src/test/regress/sql/partition_prune.sql
@@ -680,7 +680,7 @@ begin
     loop
         ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: 
N');
         ln := regexp_replace(ln, 'actual rows=\d+(?:\.\d+)? loops=\d+', 
'actual rows=N loops=N');
-        ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed 
by Filter: N');
+        ln := regexp_replace(ln, 'Rows Removed by Filter: \d+(?:\.\d+)?', 
'Rows Removed by Filter: N');
         perform regexp_matches(ln, 'Index Searches: \d+');
         if found then
           continue;
-- 
2.56.0

Reply via email to