From d70b147d71ca15beb51187b75645587ed7de612f Mon Sep 17 00:00:00 2001
From: NikolayS <nik@postgres.ai>
Date: Fri, 12 Nov 2021 21:55:47 +0000
Subject: [PATCH] Enable BUFFERS by default in EXPLAIN ANALYZE

In many cases, people forget about the BUFFERS option in
EXPLAIN ANALYZE and share execution plans without it. Meanwhile,
the option has a lower overhead compared to TIMING (enabled by
default for EXPLAIN ANALYZE) and it is extremely useful for query
optimization.

This patch doesn't enable BUFFERS for EXPLAIN executed
without ANALYZE.

See also: https://www.postgresql.org/message-id/flat/b3197ba8-225f-f53c-326d-5b1756c77c3e%40postgresfriends.org
---
 doc/src/sgml/ref/explain.sgml  |  8 +++++---
 src/backend/commands/explain.c | 10 ++++++++++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml
index 4d758fb237..57a16ac32f 100644
--- a/doc/src/sgml/ref/explain.sgml
+++ b/doc/src/sgml/ref/explain.sgml
@@ -188,9 +188,11 @@ ROLLBACK;
       previously-dirtied blocks evicted from cache by this backend during
       query processing.
       The number of blocks shown for an
-      upper-level node includes those used by all its child nodes.  In text
-      format, only non-zero values are printed.  It defaults to
-      <literal>FALSE</literal>.
+      upper-level node includes those used by all its child nodes. In text
+      format, only non-zero values are printed. It defaults to
+      <literal>TRUE</literal> for <literal>EXPLAIN ANALYZE</literal> and
+      to <literal>FALSE</literal> for <literal>EXPLAIN</literal> executed
+      without the <literal>ANALYZE</literal> option.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 10644dfac4..85491defc8 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -171,6 +171,7 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
 	List	   *rewritten;
 	ListCell   *lc;
 	bool		timing_set = false;
+	bool		buffers_set = false;
 	bool		summary_set = false;
 
 	/* Parse options list. */
@@ -185,7 +186,10 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
 		else if (strcmp(opt->defname, "costs") == 0)
 			es->costs = defGetBoolean(opt);
 		else if (strcmp(opt->defname, "buffers") == 0)
+		{
+			buffers_set = true;
 			es->buffers = defGetBoolean(opt);
+		}
 		else if (strcmp(opt->defname, "wal") == 0)
 			es->wal = defGetBoolean(opt);
 		else if (strcmp(opt->defname, "settings") == 0)
@@ -241,6 +245,12 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("EXPLAIN option TIMING requires ANALYZE")));
 
+	/* if the buffers option was not set explicitly, set default value:
+	 *   - TRUE for EXPLAIN ANALYZE
+	 *   - FALSE for EXPLAIN without ANALYZE
+	 */
+	es->buffers = (buffers_set) ? es->buffers : es->analyze;
+
 	/* if the summary was not set explicitly, set default value */
 	es->summary = (summary_set) ? es->summary : es->analyze;
 
-- 
GitLab

