summaryrefslogtreecommitdiff
path: root/src/test/regress/sql/stats.sql
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/regress/sql/stats.sql')
-rw-r--r--src/test/regress/sql/stats.sql189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql
index 7c77c331215..4d26671da7b 100644
--- a/src/test/regress/sql/stats.sql
+++ b/src/test/regress/sql/stats.sql
@@ -13,6 +13,8 @@ SET enable_seqscan TO on;
SET enable_indexscan TO on;
-- for the moment, we don't want index-only scans here
SET enable_indexonlyscan TO off;
+-- not enabled by default, but we want to test it...
+SET track_functions TO 'all';
-- save counters
BEGIN;
@@ -121,9 +123,196 @@ FROM prevstats AS pr;
COMMIT;
+----
+-- Basic tests for track_functions
+---
+CREATE FUNCTION stats_test_func1() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$;
+SELECT 'stats_test_func1()'::regprocedure::oid AS stats_test_func1_oid \gset
+CREATE FUNCTION stats_test_func2() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$;
+SELECT 'stats_test_func2()'::regprocedure::oid AS stats_test_func2_oid \gset
+
+-- test that stats are accumulated
+BEGIN;
+SET LOCAL stats_fetch_consistency = none;
+SELECT pg_stat_get_function_calls(:stats_test_func1_oid);
+SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid);
+SELECT stats_test_func1();
+SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid);
+SELECT stats_test_func1();
+SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid);
+SELECT pg_stat_get_function_calls(:stats_test_func1_oid);
+COMMIT;
+
+-- Verify that function stats are not transactional
+
+-- rolled back savepoint in committing transaction
+BEGIN;
+SELECT stats_test_func2();
+SAVEPOINT foo;
+SELECT stats_test_func2();
+ROLLBACK TO SAVEPOINT foo;
+SELECT pg_stat_get_xact_function_calls(:stats_test_func2_oid);
+SELECT stats_test_func2();
+COMMIT;
+
+-- rolled back transaction
+BEGIN;
+SELECT stats_test_func2();
+ROLLBACK;
+
+SELECT pg_stat_force_next_flush();
+
+-- check collected stats
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid;
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func2_oid;
+
+
+-- check that a rolled back drop function stats leaves stats alive
+BEGIN;
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid;
+DROP FUNCTION stats_test_func1();
+-- shouldn't be visible via view
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid;
+-- but still via oid access
+SELECT pg_stat_get_function_calls(:stats_test_func1_oid);
+ROLLBACK;
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid;
+SELECT pg_stat_get_function_calls(:stats_test_func1_oid);
+
+
+-- check that function dropped in main transaction leaves no stats behind
+BEGIN;
+DROP FUNCTION stats_test_func1();
+COMMIT;
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid;
+SELECT pg_stat_get_function_calls(:stats_test_func1_oid);
+
+-- check that function dropped in a subtransaction leaves no stats behind
+BEGIN;
+SELECT stats_test_func2();
+SAVEPOINT a;
+SELECT stats_test_func2();
+SAVEPOINT b;
+DROP FUNCTION stats_test_func2();
+COMMIT;
+SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func2_oid;
+SELECT pg_stat_get_function_calls(:stats_test_func2_oid);
+
+
+-- Check that stats for relations are dropped. For that we need to access stats
+-- by oid after the DROP TABLE. Save oids.
+CREATE TABLE drop_stats_test();
+INSERT INTO drop_stats_test DEFAULT VALUES;
+SELECT 'drop_stats_test'::regclass::oid AS drop_stats_test_oid \gset
+
+CREATE TABLE drop_stats_test_xact();
+INSERT INTO drop_stats_test_xact DEFAULT VALUES;
+SELECT 'drop_stats_test_xact'::regclass::oid AS drop_stats_test_xact_oid \gset
+
+CREATE TABLE drop_stats_test_subxact();
+INSERT INTO drop_stats_test_subxact DEFAULT VALUES;
+SELECT 'drop_stats_test_subxact'::regclass::oid AS drop_stats_test_subxact_oid \gset
+
+SELECT pg_stat_force_next_flush();
+
+SELECT pg_stat_get_live_tuples(:drop_stats_test_oid);
+DROP TABLE drop_stats_test;
+SELECT pg_stat_get_live_tuples(:drop_stats_test_oid);
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_oid);
+
+-- check that rollback protects against having stats dropped and that local
+-- modifications don't pose a problem
+SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid);
+SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid);
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid);
+BEGIN;
+INSERT INTO drop_stats_test_xact DEFAULT VALUES;
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid);
+DROP TABLE drop_stats_test_xact;
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid);
+ROLLBACK;
+SELECT pg_stat_force_next_flush();
+SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid);
+SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid);
+
+-- transactional drop
+SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid);
+SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid);
+BEGIN;
+INSERT INTO drop_stats_test_xact DEFAULT VALUES;
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid);
+DROP TABLE drop_stats_test_xact;
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid);
+COMMIT;
+SELECT pg_stat_force_next_flush();
+SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid);
+SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid);
+
+-- savepoint rollback (2 levels)
+SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
+BEGIN;
+INSERT INTO drop_stats_test_subxact DEFAULT VALUES;
+SAVEPOINT sp1;
+INSERT INTO drop_stats_test_subxact DEFAULT VALUES;
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_subxact_oid);
+SAVEPOINT sp2;
+DROP TABLE drop_stats_test_subxact;
+ROLLBACK TO SAVEPOINT sp2;
+SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_subxact_oid);
+COMMIT;
+SELECT pg_stat_force_next_flush();
+SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
+
+-- savepoint rolback (1 level)
+SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
+BEGIN;
+SAVEPOINT sp1;
+DROP TABLE drop_stats_test_subxact;
+SAVEPOINT sp2;
+ROLLBACK TO SAVEPOINT sp1;
+COMMIT;
+SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
+
+-- and now actually drop
+SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
+BEGIN;
+SAVEPOINT sp1;
+DROP TABLE drop_stats_test_subxact;
+SAVEPOINT sp2;
+RELEASE SAVEPOINT sp1;
+COMMIT;
+SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
+
DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4;
DROP TABLE prevstats;
+----
+-- pg_stat_get_snapshot_timestamp behavior
+----
+BEGIN;
+SET LOCAL stats_fetch_consistency = snapshot;
+-- no snapshot yet, return NULL
+SELECT pg_stat_get_snapshot_timestamp();
+-- any attempt at accessing stats will build snapshot
+SELECT pg_stat_get_function_calls(0);
+SELECT pg_stat_get_snapshot_timestamp() >= NOW();
+-- shows NULL again after clearing
+SELECT pg_stat_clear_snapshot();
+SELECT pg_stat_get_snapshot_timestamp();
+COMMIT;
+
+----
+-- pg_stat_have_stats behavior
+----
+-- fixed-numbered stats exist
+SELECT pg_stat_have_stats('bgwriter', 0, 0);
+-- unknown stats kinds error out
+SELECT pg_stat_have_stats('zaphod', 0, 0);
+-- db stats have objoid 0
+SELECT pg_stat_have_stats('database', (SELECT oid FROM pg_database WHERE datname = current_database()), 1);
+SELECT pg_stat_have_stats('database', (SELECT oid FROM pg_database WHERE datname = current_database()), 0);
+
+
-- ensure that stats accessors handle NULL input correctly
SELECT pg_stat_get_replication_slot(NULL);
SELECT pg_stat_get_subscription_stats(NULL);