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/[email protected]
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

+41
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

+2-6
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

+13
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

+8
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

+6-2
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)