A little tweak to the code.
GetTopTransactionIdIfAny() != InvalidTransactionId
changed to
TransactionIdIsValid(GetTopTransactionIdIfAny()


On 2024/1/12 08:51, jian he wrote:
Hi
...
with patch:
src3=# explain(analyze, costs off) select 1 from pg_sleep(10);
2024-01-12 08:43:14.750 CST [5739] jian@src3/psql XID:0 LOG:
duration: 10010.167 ms  plan:
         Query Text: explain(analyze, costs off) select 1 from pg_sleep(10);
         Function Scan on pg_sleep  (cost=0.00..0.01 rows=1 width=4)
(actual time=10010.155..10010.159 rows=1 loops=1)
2024-01-12 08:43:14.750 CST [5739] jian@src3/psql XID:0 LOG:
statement: explain(analyze, costs off) select 1 from pg_sleep(10);
                                  QUERY PLAN
-----------------------------------------------------------------------------
  Function Scan on pg_sleep (actual time=10010.155..10010.159 rows=1 loops=1)
  Planning Time: 0.115 ms
  Execution Time: 10010.227 ms
(3 rows)
This problem does exist in a statement that takes a long time to run.
XID is applied only for the first change tuple. If the user want to see it in a single statement log, they have to wait until the statement has finished executing. And we don't know how long it will take until the statement ends. It is not appropriate to output the log twice because of xid. Besides, without parsing log_line_prefix we don't know if the user wants to see xid.
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 1a34bd3715..bd08b64450 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -1064,8 +1064,9 @@ exec_simple_query(const char *query_string)
         */
        parsetree_list = pg_parse_query(query_string);
 
-       /* Log immediately if dictated by log_statement */
-       if (check_log_statement(parsetree_list))
+       /* Log immediately if dictated by log_statement and XID assigned. */
+       if (TransactionIdIsValid(GetTopTransactionIdIfAny()) &&
+                       check_log_statement(parsetree_list))
        {
                ereport(LOG,
                                (errmsg("statement: %s", query_string),
@@ -1282,6 +1283,16 @@ exec_simple_query(const char *query_string)
 
                PortalDrop(portal, false);
 
+               /* Log if dictated by log_statement and has not been logged. */
+               if (!was_logged && check_log_statement(parsetree_list))
+               {
+                       ereport(LOG,
+                                       (errmsg("statement: %s", query_string),
+                                       errhidestmt(true),
+                                       errdetail_execute(parsetree_list)));
+                       was_logged = true;
+               }
+
                if (lnext(parsetree_list, parsetree_item) == NULL)
                {
                        /*

Reply via email to