On 2026-07-13 08:28, Andrei Lepikhov wrote:
I don't see any explain or other logging activity in the log. I wonder
if
extended protocol faces the same problem.
Thank you for providing the reproduction steps.
With this step, FETCH retrieves only one row, so standard_ExecutorRun()
reaches `LogQueryPlanPending = false` without another opportunity to
call ExecProcNode().
If FETCH 1 FROM c is changed to FETCH 2 FROM c, the plan is logged:
[local] psql [85735] LOG: 00000: query and its plan running on
backend with PID 85735 are:
Query Text: DECLARE c CURSOR FOR
SELECT pg_advisory_xact_lock(g) FROM generate_series(1, 5)
g;
Function Scan on generate_series g (cost=0.00..0.08 rows=5
width=4)
So, it potentially makes sense to add a statistics field to the
activity stat to
let users know whether the logging (and how many signals, if replace
flag with a
counter) is awaiting execution.
That might be useful for some users, but personally I feel that adding
a column to pg_stat_activity solely for pg_log_query_plan() might be
excessive.
Maybe it doesn't need to clean up the 'pending' flag at all if no query
has been
executed yet - the query might be under planning, and the EXPLAIN will
be logged
right at the beginning of execution.
Without this cleanup, as the comment says, the plan could instead be
logged when a different query is subsequently executed in the same
session. I imagine users don't expect this behavior.
As an alternative, I wondered whether we could change the existing code
in standard_ExecutorRun() so that, if LogQueryPlanPending is still
true, it logs a message before clearing the flag:
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -413,7 +413,12 @@ standard_ExecutorRun(QueryDesc *queryDesc,
* logging the plan. Otherwise plan will be logged at the next
query
* execution on the same session.
*/
- LogQueryPlanPending = false;
+ if (LogQueryPlanPending)
+ {
+ ereport(LOG,
+ errmsg("query plan logging was
requested but there was no opportunity to do it"));
+ LogQueryPlanPending = false;
+ }
}
What do you think about this approach?
BTW there is another case where pg_log_query_plan() silently gives up
without logging a plan, as discussed in [1]. If we decide to take this
approach, I'm going to change this to log a message as well:
---
The first two messages seem fairly unhelpful to me:
the user isn't going to understand the distinction between those two
states and it's unclear why we should give them that information. I'm
not sure if we should log a generic message in these kinds of cases or
log nothing at all, but I feel like this is too much technical
information.
I'm not sure if this is the best approach, but I changed them to log
nothing in these cases.
---
On Mon, Jul 6, 2026 at 10:05 PM Andrei Lepikhov <[email protected]>
wrote:
In addition, I wonder why this code doesn't use standard planstate
walker. It
seems to me that something like the following should work:
As discussed in [2], the set of nodes handled here slightly differs
from that handled by planstate_tree_walker_impl(), so I'd like
to confirm whether it is appropriate to use the standard walker here.
---
BTW I haven’t looked into this in detail yet, but I’m a little curious
whether the absence of T_CteScan in functions like
planstate_tree_walker_impl() is intentional.
I don't think that function needs any special handling for T_CteScan.
planstate_tree_walker_impl() and other functions need special handling
for cases where a node has children that are not in the lefttree,
righttree, initPlan list, or subPlan list; but a CteScan has no extra
Plan pointer:
---
[1]
https://www.postgresql.org/message-id/6143f00af4bfdba95a85cf866f4acb41%40oss.nttdata.com
[2]
https://www.postgresql.org/message-id/CA%2BTgmoY81r7npTS34N_5MLA_u6ghfor5HoSaar53veXUYu1OxQ%40mail.gmail.com
--
Thanks,
--
Atsushi Torikoshi
Seconded from NTT DATA CORPORATION to SRA OSS K.K.