explain_float_row_v3.patch
application/octet-stream
Filename: explain_float_row_v3.patch
Type: application/octet-stream
Part: 0
Message:
Re: explain analyze rows=%.0f
Patch
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| src/backend/commands/explain.c | 40 | 9 |
| src/test/regress/expected/partition_prune.out | 8 | 8 |
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index e29c2ae206..ae078d86de 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -13,6 +13,8 @@
*/
#include "postgres.h"
+#include <math.h>
+
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "commands/createas.h"
@@ -54,6 +56,9 @@ explain_get_index_name_hook_type explain_get_index_name_hook = NULL;
#define X_CLOSE_IMMEDIATE 2
#define X_NOWHITESPACE 4
+/* Check if float/double has any decimal number */
+#define HAS_DECIMAL(x) (floor(x) != x)
+
static void ExplainOneQuery(Query *query, int cursorOptions,
IntoClause *into, ExplainState *es,
const char *queryString, ParamListInfo params,
@@ -1643,16 +1648,29 @@ ExplainNode(PlanState *planstate, List *ancestors,
double total_ms = 1000.0 * planstate->instrument->total / nloops;
double rows = planstate->instrument->ntuples / nloops;
+ /*
+ * If the number of loops is greater than one, display the
+ * actual rows up to two decimal places instead of rounding
+ * off the value.
+ */
if (es->format == EXPLAIN_FORMAT_TEXT)
{
if (es->timing)
+ {
+ appendStringInfo(es->str, " (actual time=%.3f..%.3f",
+ startup_ms, total_ms);
appendStringInfo(es->str,
- " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
- startup_ms, total_ms, rows, nloops);
+ (nloops == 1 || !HAS_DECIMAL(rows)) ?
+ " rows=%.0f loops=%.0f)" : " rows=%.2f loops=%.0f)",
+ rows, nloops);
+ }
else
+ {
appendStringInfo(es->str,
- " (actual rows=%.0f loops=%.0f)",
+ (nloops == 1 || !HAS_DECIMAL(rows)) ?
+ " (actual rows=%.0f loops=%.0f)" : " (actual rows=%.2f loops=%.0f)",
rows, nloops);
+ }
}
else
{
@@ -1663,7 +1681,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
ExplainPropertyFloat("Actual Total Time", "ms", total_ms,
3, es);
}
- ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es);
+ ExplainPropertyFloat("Actual Rows", NULL, rows, (nloops == 1 || !HAS_DECIMAL(rows)) ? 0 : 2, es);
ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es);
}
}
@@ -1707,18 +1725,30 @@ ExplainNode(PlanState *planstate, List *ancestors,
rows = instrument->ntuples / nloops;
ExplainOpenWorker(n, es);
+ /*
+ * If the number of loops is greater than one, display the
+ * actual rows up to two decimal places instead of rounding
+ * off the value.
+ */
if (es->format == EXPLAIN_FORMAT_TEXT)
{
ExplainIndentText(es);
if (es->timing)
+ {
+ appendStringInfo(es->str, "actual time=%.3f..%.3f",
+ startup_ms, total_ms);
appendStringInfo(es->str,
- "actual time=%.3f..%.3f rows=%.0f loops=%.0f\n",
- startup_ms, total_ms, rows, nloops);
+ (nloops == 1 || !HAS_DECIMAL(rows)) ?
+ " rows=%.0f loops=%.0f" : " rows=%.2f loops=%.0f",
+ rows, nloops);
+ }
else
- appendStringInfo(es->str,
- "actual rows=%.0f loops=%.0f\n",
+ {
+ appendStringInfo(es->str, (nloops == 1 || !HAS_DECIMAL(rows)) ?
+ "actual rows=%.0f loops=%.0f" : "actual rows=%.2f loops=%.0f",
rows, nloops);
+ }
}
else
{
@@ -1729,7 +1759,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
ExplainPropertyFloat("Actual Total Time", "ms",
total_ms, 3, es);
}
- ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es);
+ ExplainPropertyFloat("Actual Rows", NULL, rows,
+ (nloops == 1 || !HAS_DECIMAL(rows)) ? 0 : 2, es);
ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es);
}
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index 7555764c77..002e5cc33d 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -2635,14 +2635,14 @@ order by tbl1.col1, tprt.col1;
insert into tbl1 values (1001), (1010), (1011);
explain (analyze, costs off, summary off, timing off)
select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
- QUERY PLAN
---------------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------
Nested Loop (actual rows=23 loops=1)
-> Seq Scan on tbl1 (actual rows=5 loops=1)
- -> Append (actual rows=5 loops=5)
+ -> Append (actual rows=4.60 loops=5)
-> Index Scan using tprt1_idx on tprt_1 (actual rows=2 loops=5)
Index Cond: (col1 < tbl1.col1)
- -> Index Scan using tprt2_idx on tprt_2 (actual rows=3 loops=4)
+ -> Index Scan using tprt2_idx on tprt_2 (actual rows=2.75 loops=4)
Index Cond: (col1 < tbl1.col1)
-> Index Scan using tprt3_idx on tprt_3 (actual rows=1 loops=2)
Index Cond: (col1 < tbl1.col1)
@@ -2656,16 +2656,16 @@ select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
explain (analyze, costs off, summary off, timing off)
select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
- QUERY PLAN
---------------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------
Nested Loop (actual rows=3 loops=1)
-> Seq Scan on tbl1 (actual rows=5 loops=1)
- -> Append (actual rows=1 loops=5)
+ -> Append (actual rows=0.60 loops=5)
-> Index Scan using tprt1_idx on tprt_1 (never executed)
Index Cond: (col1 = tbl1.col1)
-> Index Scan using tprt2_idx on tprt_2 (actual rows=1 loops=2)
Index Cond: (col1 = tbl1.col1)
- -> Index Scan using tprt3_idx on tprt_3 (actual rows=0 loops=3)
+ -> Index Scan using tprt3_idx on tprt_3 (actual rows=0.33 loops=3)
Index Cond: (col1 = tbl1.col1)
-> Index Scan using tprt4_idx on tprt_4 (never executed)
Index Cond: (col1 = tbl1.col1)