From cd4c0bf03310c77d1069fe05d185bb74fa5c0295 Mon Sep 17 00:00:00 2001 From: "zhaotinghai.zth" Date: Thu, 16 Jan 2025 10:15:53 +0800 Subject: [PATCH] limit length of queries --- contrib/pg_stat_statements/Makefile | 2 +- .../expected/max_length.out | 57 +++++++++++++++++++ .../pg_stat_statements/pg_stat_statements.c | 19 +++++++ contrib/pg_stat_statements/sql/max_length.sql | 29 ++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 contrib/pg_stat_statements/expected/max_length.out create mode 100644 contrib/pg_stat_statements/sql/max_length.sql diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile index 31e4fdeeb9..a40267a9ac 100644 --- a/contrib/pg_stat_statements/Makefile +++ b/contrib/pg_stat_statements/Makefile @@ -18,7 +18,7 @@ LDFLAGS_SL += $(filter -lm, $(LIBS)) REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf REGRESS = select dml cursors utility level_tracking planning \ - user_activity wal extended cleanup oldextversions + user_activity wal extended cleanup oldextversions max_length # Disabled because these tests require "shared_preload_libraries=pg_stat_statements", # which typical installcheck users do not have (e.g. buildfarm clients). NO_INSTALLCHECK = 1 diff --git a/contrib/pg_stat_statements/expected/max_length.out b/contrib/pg_stat_statements/expected/max_length.out new file mode 100644 index 0000000000..d1007ee004 --- /dev/null +++ b/contrib/pg_stat_statements/expected/max_length.out @@ -0,0 +1,57 @@ +CREATE EXTENSION pg_stat_statements; +CREATE TABLE pg_stat_statement_tmp (query text); +INSERT INTO pg_stat_statement_tmp +(SELECT substring(query, 1, 64) FROM pg_stat_statements WHERE query LIKE '%SELECT GROUPING%'); +SET pg_stat_statements.max_query_length=64; +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +-- check correctness +SELECT ( + SELECT ( + SELECT GROUPING(a,b) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + grouping +---------- + 0 + 0 + 0 +(3 rows) + +SELECT ( + SELECT ( + SELECT GROUPING(e,f) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + grouping +---------- + 3 + 0 + 1 +(3 rows) + +SELECT COUNT(a.query) FROM pg_stat_statement_tmp a +INNER JOIN pg_stat_statements b on a.query=b.query; + count +------- + 0 +(1 row) + +SELECT a.query FROM pg_stat_statement_tmp a +INNER JOIN pg_stat_statements b on a.query=b.query; + query +------- +(0 rows) + +-- check length +SELECT EXISTS (SELECT * FROM pg_stat_statements WHERE length(query) > 64); + exists +-------- + f +(1 row) + +DROP EXTENSION pg_stat_statements; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 55b957d251..bbb6cf7b87 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -289,6 +289,7 @@ static bool pgss_track_utility = true; /* whether to track utility commands */ static bool pgss_track_planning = false; /* whether to track planning * duration */ static bool pgss_save = true; /* whether to save stats across shutdown */ +static int pgss_max_query_length = 0; #define pgss_enabled(level) \ @@ -450,6 +451,19 @@ _PG_init(void) NULL, NULL); + DefineCustomIntVariable("pg_stat_statements.max_query_length", + "Max length of query which store in pgss_query_texts.stat", + NULL, + &pgss_max_query_length, + 0, + 0, + PG_INT32_MAX, + PGC_USERSET, + GUC_UNIT_BYTE, + NULL, + NULL, + NULL); + MarkGUCPrefixReserved("pg_stat_statements"); /* @@ -1294,6 +1308,11 @@ pgss_store(const char *query, uint64 queryId, LWLockAcquire(pgss->lock, LW_SHARED); } + if (pgss_max_query_length > 0) + { + query_len = Min(query_len, pgss_max_query_length); + } + /* Append new query text to file with only shared lock held */ stored = qtext_store(norm_query ? norm_query : query, query_len, &query_offset, &gc_count); diff --git a/contrib/pg_stat_statements/sql/max_length.sql b/contrib/pg_stat_statements/sql/max_length.sql new file mode 100644 index 0000000000..24dff60dde --- /dev/null +++ b/contrib/pg_stat_statements/sql/max_length.sql @@ -0,0 +1,29 @@ +CREATE EXTENSION pg_stat_statements; +CREATE TABLE pg_stat_statement_tmp (query text); +INSERT INTO pg_stat_statement_tmp +(SELECT substring(query, 1, 64) FROM pg_stat_statements WHERE query LIKE '%SELECT GROUPING%'); + +SET pg_stat_statements.max_query_length=64; +SELECT pg_stat_statements_reset(); + +-- check correctness +SELECT ( + SELECT ( + SELECT GROUPING(a,b) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); +SELECT ( + SELECT ( + SELECT GROUPING(e,f) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + +SELECT COUNT(a.query) FROM pg_stat_statement_tmp a +INNER JOIN pg_stat_statements b on a.query=b.query; + +SELECT a.query FROM pg_stat_statement_tmp a +INNER JOIN pg_stat_statements b on a.query=b.query; + +-- check length +SELECT EXISTS (SELECT * FROM pg_stat_statements WHERE length(query) > 64); +DROP EXTENSION pg_stat_statements; \ No newline at end of file -- 2.39.3