Skip to content

Commit bb45156

Browse files
committed
Show names of DEALLOCATE as constants in pg_stat_statements
This commit switches query jumbling so as prepared statement names are treated as constants in DeallocateStmt. A boolean field is added to DeallocateStmt to make a distinction between ALL and named prepared statements, as "name" was used to make this difference before, NULL meaning DEALLOCATE ALL. Prior to this commit, DEALLOCATE was not tracked in pg_stat_statements, for the reason that it was not possible to treat its name parameter as a constant. Now that query jumbling applies to all the utility nodes, this reason does not apply anymore. Like 638d42a, this can be a huge advantage for monitoring where prepared statement names are randomly generated, preventing bloat in pg_stat_statements. A couple of tests are added to track the new behavior. Author: Dagfinn Ilmari Mannsåker, Michael Paquier Reviewed-by: Julien Rouhaud Discussion: https://postgr.es/m/ZMhT9kNtJJsHw6jK@paquier.xyz
1 parent e48b19c commit bb45156

File tree

5 files changed

+70
-8
lines changed

5 files changed

+70
-8
lines changed

contrib/pg_stat_statements/expected/utility.out

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,47 @@ SELECT pg_stat_statements_reset();
472472

473473
(1 row)
474474

475+
-- Execution statements
476+
SELECT 1 as a;
477+
a
478+
---
479+
1
480+
(1 row)
481+
482+
PREPARE stat_select AS SELECT $1 AS a;
483+
EXECUTE stat_select (1);
484+
a
485+
---
486+
1
487+
(1 row)
488+
489+
DEALLOCATE stat_select;
490+
PREPARE stat_select AS SELECT $1 AS a;
491+
EXECUTE stat_select (2);
492+
a
493+
---
494+
2
495+
(1 row)
496+
497+
DEALLOCATE PREPARE stat_select;
498+
DEALLOCATE ALL;
499+
DEALLOCATE PREPARE ALL;
500+
SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
501+
calls | rows | query
502+
-------+------+---------------------------------------
503+
2 | 0 | DEALLOCATE $1
504+
2 | 0 | DEALLOCATE ALL
505+
2 | 2 | PREPARE stat_select AS SELECT $1 AS a
506+
1 | 1 | SELECT $1 as a
507+
1 | 1 | SELECT pg_stat_statements_reset()
508+
(5 rows)
509+
510+
SELECT pg_stat_statements_reset();
511+
pg_stat_statements_reset
512+
--------------------------
513+
514+
(1 row)
515+
475516
-- SET statements.
476517
-- These use two different strings, still they count as one entry.
477518
SET work_mem = '1MB';

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100;
104104
* ignores.
105105
*/
106106
#define PGSS_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \
107-
!IsA(n, PrepareStmt) && \
108-
!IsA(n, DeallocateStmt))
107+
!IsA(n, PrepareStmt))
109108

110109
/*
111110
* Extension version number, for supporting older extension versions' objects
@@ -830,8 +829,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate)
830829

831830
/*
832831
* Clear queryId for prepared statements related utility, as those will
833-
* inherit from the underlying statement's one (except DEALLOCATE which is
834-
* entirely untracked).
832+
* inherit from the underlying statement's one.
835833
*/
836834
if (query->utilityStmt)
837835
{
@@ -1116,8 +1114,6 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
11161114
* calculated from the query tree) would be used to accumulate costs of
11171115
* ensuing EXECUTEs. This would be confusing, and inconsistent with other
11181116
* cases where planning time is not included at all.
1119-
*
1120-
* Likewise, we don't track execution of DEALLOCATE.
11211117
*/
11221118
if (pgss_track_utility && pgss_enabled(exec_nested_level) &&
11231119
PGSS_HANDLED_UTILITY(parsetree))

contrib/pg_stat_statements/sql/utility.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,19 @@ DROP DOMAIN domain_stats;
237237
SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
238238
SELECT pg_stat_statements_reset();
239239

240+
-- Execution statements
241+
SELECT 1 as a;
242+
PREPARE stat_select AS SELECT $1 AS a;
243+
EXECUTE stat_select (1);
244+
DEALLOCATE stat_select;
245+
PREPARE stat_select AS SELECT $1 AS a;
246+
EXECUTE stat_select (2);
247+
DEALLOCATE PREPARE stat_select;
248+
DEALLOCATE ALL;
249+
DEALLOCATE PREPARE ALL;
250+
SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
251+
SELECT pg_stat_statements_reset();
252+
240253
-- SET statements.
241254
-- These use two different strings, still they count as one entry.
242255
SET work_mem = '1MB';

src/backend/parser/gram.y

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11953,27 +11953,35 @@ DeallocateStmt: DEALLOCATE name
1195311953
DeallocateStmt *n = makeNode(DeallocateStmt);
1195411954

1195511955
n->name = $2;
11956+
n->isall = false;
11957+
n->location = @2;
1195611958
$$ = (Node *) n;
1195711959
}
1195811960
| DEALLOCATE PREPARE name
1195911961
{
1196011962
DeallocateStmt *n = makeNode(DeallocateStmt);
1196111963

1196211964
n->name = $3;
11965+
n->isall = false;
11966+
n->location = @3;
1196311967
$$ = (Node *) n;
1196411968
}
1196511969
| DEALLOCATE ALL
1196611970
{
1196711971
DeallocateStmt *n = makeNode(DeallocateStmt);
1196811972

1196911973
n->name = NULL;
11974+
n->isall = true;
11975+
n->location = -1;
1197011976
$$ = (Node *) n;
1197111977
}
1197211978
| DEALLOCATE PREPARE ALL
1197311979
{
1197411980
DeallocateStmt *n = makeNode(DeallocateStmt);
1197511981

1197611982
n->name = NULL;
11983+
n->isall = true;
11984+
n->location = -1;
1197711985
$$ = (Node *) n;
1197811986
}
1197911987
;

src/include/nodes/parsenodes.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3929,8 +3929,12 @@ typedef struct ExecuteStmt
39293929
typedef struct DeallocateStmt
39303930
{
39313931
NodeTag type;
3932-
char *name; /* The name of the plan to remove */
3933-
/* NULL means DEALLOCATE ALL */
3932+
/* The name of the plan to remove, NULL if DEALLOCATE ALL */
3933+
char *name pg_node_attr(query_jumble_ignore);
3934+
/* true if DEALLOCATE ALL */
3935+
bool isall;
3936+
/* token location, or -1 if unknown */
3937+
int location pg_node_attr(query_jumble_location);
39343938
} DeallocateStmt;
39353939

39363940
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy