Show savepoint names as constants in pg_stat_statements
authorMichael Paquier <michael@paquier.xyz>
Thu, 27 Jul 2023 00:42:33 +0000 (09:42 +0900)
committerMichael Paquier <michael@paquier.xyz>
Thu, 27 Jul 2023 00:42:33 +0000 (09:42 +0900)
In pg_stat_statements, savepoint names now show up as constants with a
parameter symbol, using as base query string the one added as a new
entry to the PGSS hash table, leading to:
RELEASE $1
ROLLBACK TO $1
SAVEPOINT $1

Applying constants to these query parts is a huge advantage for
workloads that generate randomly savepoint points, like ORMs (Django is
at the origin of this patch).  The ODBC driver is a second layer that
likes a lot savepoints, though it does not use a random naming pattern.

A "location" field is added to TransactionStmt, now set only for
savepoints.  The savepoint name is ignored by the query jumbling.  The
location can be extended to other query patterns, if required, like 2PC
commands.  Some tests are added to pg_stat_statements for all the query
patterns supported by the parser.

ROLLBACK, ROLLBACK TO SAVEPOINT and ROLLBACK TRANSACTION TO SAVEPOINT
have the same Node representation, so all these are equivalents.  The
same happens for RELEASE and RELEASE SAVEPOINT.

Author: Greg Sabino Mullane
Discussion: https://postgr.es/m/CAKAnmm+2s9PA4OaumwMJReWHk8qvJ_-g1WqxDRDAN1BSUfxyTw@mail.gmail.com

contrib/pg_stat_statements/expected/utility.out
contrib/pg_stat_statements/sql/utility.sql
src/backend/parser/gram.y
src/include/nodes/parsenodes.h

index 0047aba5d1acbdf308a90c00b746b3691d62dc22..3d920fb5f7123ef2ae6328ce9900b9ad1e5a4218 100644 (file)
@@ -197,6 +197,37 @@ SELECT pg_stat_statements_reset();
  
 (1 row)
 
+-- Savepoints
+BEGIN;
+SAVEPOINT sp1;
+SAVEPOINT sp2;
+SAVEPOINT sp3;
+SAVEPOINT sp4;
+ROLLBACK TO sp4;
+ROLLBACK TO SAVEPOINT sp4;
+ROLLBACK TRANSACTION TO SAVEPOINT sp3;
+RELEASE sp3;
+RELEASE SAVEPOINT sp2;
+ROLLBACK TO sp1;
+RELEASE SAVEPOINT sp1;
+COMMIT;
+SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+ calls | rows |               query               
+-------+------+-----------------------------------
+     1 |    0 | BEGIN
+     1 |    0 | COMMIT
+     3 |    0 | RELEASE $1
+     4 |    0 | ROLLBACK TO $1
+     4 |    0 | SAVEPOINT $1
+     1 |    1 | SELECT pg_stat_statements_reset()
+(6 rows)
+
+SELECT pg_stat_statements_reset();
+ pg_stat_statements_reset 
+--------------------------
+(1 row)
+
 -- EXPLAIN statements
 -- A Query is used, normalized by the query jumbling.
 EXPLAIN (costs off) SELECT 1;
index 225d30a62a6455fce842d3cc7d5b457e2dc878be..859e57955e68c1f43f778205cfa1b51d698900f8 100644 (file)
@@ -115,6 +115,23 @@ COMMIT;
 SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
 SELECT pg_stat_statements_reset();
 
+-- Savepoints
+BEGIN;
+SAVEPOINT sp1;
+SAVEPOINT sp2;
+SAVEPOINT sp3;
+SAVEPOINT sp4;
+ROLLBACK TO sp4;
+ROLLBACK TO SAVEPOINT sp4;
+ROLLBACK TRANSACTION TO SAVEPOINT sp3;
+RELEASE sp3;
+RELEASE SAVEPOINT sp2;
+ROLLBACK TO sp1;
+RELEASE SAVEPOINT sp1;
+COMMIT;
+SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+SELECT pg_stat_statements_reset();
+
 -- EXPLAIN statements
 -- A Query is used, normalized by the query jumbling.
 EXPLAIN (costs off) SELECT 1;
index 856d5dee0e7e41ed457043967eeecaf21005f941..15ece871a0142cbd35665bf5854508ec6e3b9b9a 100644 (file)
@@ -10841,6 +10841,7 @@ TransactionStmt:
                                        n->kind = TRANS_STMT_ROLLBACK;
                                        n->options = NIL;
                                        n->chain = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | START TRANSACTION transaction_mode_list_or_empty
@@ -10849,6 +10850,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_START;
                                        n->options = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | COMMIT opt_transaction opt_transaction_chain
@@ -10858,6 +10860,7 @@ TransactionStmt:
                                        n->kind = TRANS_STMT_COMMIT;
                                        n->options = NIL;
                                        n->chain = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | ROLLBACK opt_transaction opt_transaction_chain
@@ -10867,6 +10870,7 @@ TransactionStmt:
                                        n->kind = TRANS_STMT_ROLLBACK;
                                        n->options = NIL;
                                        n->chain = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | SAVEPOINT ColId
@@ -10875,6 +10879,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_SAVEPOINT;
                                        n->savepoint_name = $2;
+                                       n->location = @2;
                                        $$ = (Node *) n;
                                }
                        | RELEASE SAVEPOINT ColId
@@ -10883,6 +10888,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_RELEASE;
                                        n->savepoint_name = $3;
+                                       n->location = @3;
                                        $$ = (Node *) n;
                                }
                        | RELEASE ColId
@@ -10891,6 +10897,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_RELEASE;
                                        n->savepoint_name = $2;
+                                       n->location = @2;
                                        $$ = (Node *) n;
                                }
                        | ROLLBACK opt_transaction TO SAVEPOINT ColId
@@ -10899,6 +10906,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_ROLLBACK_TO;
                                        n->savepoint_name = $5;
+                                       n->location = @5;
                                        $$ = (Node *) n;
                                }
                        | ROLLBACK opt_transaction TO ColId
@@ -10907,6 +10915,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_ROLLBACK_TO;
                                        n->savepoint_name = $4;
+                                       n->location = @4;
                                        $$ = (Node *) n;
                                }
                        | PREPARE TRANSACTION Sconst
@@ -10915,6 +10924,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_PREPARE;
                                        n->gid = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | COMMIT PREPARED Sconst
@@ -10923,6 +10933,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_COMMIT_PREPARED;
                                        n->gid = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | ROLLBACK PREPARED Sconst
@@ -10931,6 +10942,7 @@ TransactionStmt:
 
                                        n->kind = TRANS_STMT_ROLLBACK_PREPARED;
                                        n->gid = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                ;
@@ -10942,6 +10954,7 @@ TransactionStmtLegacy:
 
                                        n->kind = TRANS_STMT_BEGIN;
                                        n->options = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                        | END_P opt_transaction opt_transaction_chain
@@ -10951,6 +10964,7 @@ TransactionStmtLegacy:
                                        n->kind = TRANS_STMT_COMMIT;
                                        n->options = NIL;
                                        n->chain = $3;
+                                       n->location = -1;
                                        $$ = (Node *) n;
                                }
                ;
index 228cdca0f1b5e9a86e9b51afc3e1923cb95ba380..fe003ded5043dffd910b9a90f87f3fe6fbc7b1c2 100644 (file)
@@ -3538,9 +3538,12 @@ typedef struct TransactionStmt
        NodeTag         type;
        TransactionStmtKind kind;       /* see above */
        List       *options;            /* for BEGIN/START commands */
-       char       *savepoint_name; /* for savepoint commands */
+       /* for savepoint commands */
+       char       *savepoint_name pg_node_attr(query_jumble_ignore);
        char       *gid;                        /* for two-phase-commit related commands */
        bool            chain;                  /* AND CHAIN option */
+       /* token location, or -1 if unknown */
+       int                     location pg_node_attr(query_jumble_location);
 } TransactionStmt;
 
 /* ----------------------