mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Fix some issues with tracking nesting level in pg_stat_statements.
When we decide that we don't want to track execution time of a specific planner or ProcessUtility call, we still have to increment the nesting depth, or we'll make the wrong determination of whether we are at top level when considering nested statements. (PREPARE and EXECUTE are exceptions, for reasons explained in the code.) Counting planner nesting depth separately from executor nesting depth was a mistake: it causes us to make the wrong determination of whether we are at top level when considering nested statements that get executed during planning (as a result of constant-folding of functions, for example). Merge those counters into one. In passing, get rid of the PGSS_HANDLED_UTILITY macro in favor of explicitly listing statement types. It seems somewhat coincidental that PREPARE and EXECUTE are handled alike in each of the places where that was used: the reasoning tends to be different for each one. Thus, the macro seems as likely to encourage future bugs as prevent them, since it's quite unclear whether any future statement type that might need special-casing here would also need the same choices at each spot. Sergei Kornilov, Julien Rouhaud, and Tom Lane, per bug #17552 from Maxim Boguk. This is pretty clearly a bug fix, but it's also a behavioral change that might surprise somebody, so no back-patch. Discussion: https://postgr.es/m/17552-213b534c56ab5d02@postgresql.org
This commit is contained in:
@ -33,6 +33,39 @@ END; $$;
|
||||
SELECT toplevel, calls, query FROM pg_stat_statements
|
||||
ORDER BY query COLLATE "C", toplevel;
|
||||
|
||||
-- DO block - top-level tracking without utility.
|
||||
SET pg_stat_statements.track = 'top';
|
||||
SET pg_stat_statements.track_utility = FALSE;
|
||||
SELECT pg_stat_statements_reset();
|
||||
DELETE FROM stats_track_tab;
|
||||
DO $$
|
||||
BEGIN
|
||||
DELETE FROM stats_track_tab;
|
||||
END; $$;
|
||||
DO LANGUAGE plpgsql $$
|
||||
BEGIN
|
||||
-- this is a SELECT
|
||||
PERFORM 'hello world'::TEXT;
|
||||
END; $$;
|
||||
SELECT toplevel, calls, query FROM pg_stat_statements
|
||||
ORDER BY query COLLATE "C", toplevel;
|
||||
|
||||
-- DO block - all-level tracking without utility.
|
||||
SET pg_stat_statements.track = 'all';
|
||||
SELECT pg_stat_statements_reset();
|
||||
DELETE FROM stats_track_tab;
|
||||
DO $$
|
||||
BEGIN
|
||||
DELETE FROM stats_track_tab;
|
||||
END; $$;
|
||||
DO LANGUAGE plpgsql $$
|
||||
BEGIN
|
||||
-- this is a SELECT
|
||||
PERFORM 'hello world'::TEXT;
|
||||
END; $$;
|
||||
SELECT toplevel, calls, query FROM pg_stat_statements
|
||||
ORDER BY query COLLATE "C", toplevel;
|
||||
|
||||
-- PL/pgSQL function - top-level tracking.
|
||||
SET pg_stat_statements.track = 'top';
|
||||
SET pg_stat_statements.track_utility = FALSE;
|
||||
@ -57,6 +90,15 @@ SELECT PLUS_ONE(10);
|
||||
|
||||
SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
|
||||
|
||||
-- immutable SQL function --- can be executed at plan time
|
||||
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||
|
||||
SELECT PLUS_THREE(8);
|
||||
SELECT PLUS_THREE(10);
|
||||
|
||||
SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
|
||||
|
||||
-- PL/pgSQL function - all-level tracking.
|
||||
SET pg_stat_statements.track = 'all';
|
||||
SELECT pg_stat_statements_reset();
|
||||
@ -64,6 +106,7 @@ SELECT pg_stat_statements_reset();
|
||||
-- we drop and recreate the functions to avoid any caching funnies
|
||||
DROP FUNCTION PLUS_ONE(INTEGER);
|
||||
DROP FUNCTION PLUS_TWO(INTEGER);
|
||||
DROP FUNCTION PLUS_THREE(INTEGER);
|
||||
|
||||
-- PL/pgSQL function
|
||||
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||
@ -85,7 +128,15 @@ SELECT PLUS_ONE(3);
|
||||
SELECT PLUS_ONE(1);
|
||||
|
||||
SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
|
||||
DROP FUNCTION PLUS_ONE(INTEGER);
|
||||
|
||||
-- immutable SQL function --- can be executed at plan time
|
||||
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||
|
||||
SELECT PLUS_THREE(8);
|
||||
SELECT PLUS_THREE(10);
|
||||
|
||||
SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
|
||||
|
||||
--
|
||||
-- pg_stat_statements.track = none
|
||||
|
Reference in New Issue
Block a user