diff options
author | Michael Paquier <michael@paquier.xyz> | 2025-03-26 07:25:23 +0900 |
---|---|---|
committer | Michael Paquier <michael@paquier.xyz> | 2025-03-26 07:25:23 +0900 |
commit | 3430215fe35f96e4be355c93e275f00656800602 (patch) | |
tree | a186379d675cab8fffd9fb79e2bbd5b2ef18364b | |
parent | 626d7236b65da50423df7de035e86f273cd36b49 (diff) | |
download | postgresql-3430215fe35f96e4be355c93e275f00656800602.tar.gz postgresql-3430215fe35f96e4be355c93e275f00656800602.zip |
pg_stat_statements: Add more tests with temp tables and namespaces
These tests provide coverage for RangeTblEntry and how query jumbling
works with search_path, as well as the case where relations are
re-created, generating a different query ID as the relation OID is used
in the computation.
A patch is under discussion to switch to a different approach based on
the relation name, and there was no test coverage for this area,
including how queries are currently grouped with search_path. This is
useful to track how the situation changes between HEAD and any patches
proposed.
Christoph has proposed the test with ON COMMIT DROP temporary tables,
and I have written the second part.
Author: Christoph Berg <myon@debian.org>
Author: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/Z9iWXKGwkm8RAC93@msg.df7cb.de
-rw-r--r-- | contrib/pg_stat_statements/expected/select.out | 240 | ||||
-rw-r--r-- | contrib/pg_stat_statements/sql/select.sql | 69 |
2 files changed, 309 insertions, 0 deletions
diff --git a/contrib/pg_stat_statements/expected/select.out b/contrib/pg_stat_statements/expected/select.out index 37a30af034a..708c6b0e9c4 100644 --- a/contrib/pg_stat_statements/expected/select.out +++ b/contrib/pg_stat_statements/expected/select.out @@ -413,3 +413,243 @@ SELECT pg_stat_statements_reset() IS NOT NULL AS t; t (1 row) +-- Temporary table with same name, re-created. +BEGIN; + CREATE TEMP TABLE temp_t (id int) ON COMMIT DROP; + SELECT * FROM temp_t; + id +---- +(0 rows) + +COMMIT; +BEGIN; + CREATE TEMP TABLE temp_t (id int) ON COMMIT DROP; + SELECT * FROM temp_t; + id +---- +(0 rows) + +COMMIT; +SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; + calls | query +-------+------------------------------------------------------------------------ + 1 | SELECT * FROM temp_t + 1 | SELECT * FROM temp_t + 0 | SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C" + 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t +(4 rows) + +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + t +--- + t +(1 row) + +-- search_path with various schemas and temporary tables +CREATE SCHEMA pgss_schema_1; +CREATE SCHEMA pgss_schema_2; +-- Same attributes. +CREATE TABLE pgss_schema_1.tab_search_same (a int, b int); +CREATE TABLE pgss_schema_2.tab_search_same (a int, b int); +CREATE TEMP TABLE tab_search_same (a int, b int); +-- Different number of attributes, mapping types +CREATE TABLE pgss_schema_1.tab_search_diff_1 (a int); +CREATE TABLE pgss_schema_2.tab_search_diff_1 (a int, b int); +CREATE TEMP TABLE tab_search_diff_1 (a int, b int, c int); +-- Same number of attributes, different types +CREATE TABLE pgss_schema_1.tab_search_diff_2 (a int); +CREATE TABLE pgss_schema_2.tab_search_diff_2 (a text); +CREATE TEMP TABLE tab_search_diff_2 (a bigint); +-- First permanent schema +SET search_path = 'pgss_schema_1'; +SELECT count(*) FROM tab_search_same; + count +------- + 0 +(1 row) + +SELECT a, b FROM tab_search_same; + a | b +---+--- +(0 rows) + +SELECT count(*) FROM tab_search_diff_1; + count +------- + 0 +(1 row) + +SELECT count(*) FROM tab_search_diff_2; + count +------- + 0 +(1 row) + +SELECT a FROM tab_search_diff_2 AS t1; + a +--- +(0 rows) + +SELECT a FROM tab_search_diff_2; + a +--- +(0 rows) + +SELECT a AS a1 FROM tab_search_diff_2; + a1 +---- +(0 rows) + +-- Second permanent schema +SET search_path = 'pgss_schema_2'; +SELECT count(*) FROM tab_search_same; + count +------- + 0 +(1 row) + +SELECT a, b FROM tab_search_same; + a | b +---+--- +(0 rows) + +SELECT count(*) FROM tab_search_diff_1; + count +------- + 0 +(1 row) + +SELECT count(*) FROM tab_search_diff_2; + count +------- + 0 +(1 row) + +SELECT a FROM tab_search_diff_2 AS t1; + a +--- +(0 rows) + +SELECT a FROM tab_search_diff_2; + a +--- +(0 rows) + +SELECT a AS a1 FROM tab_search_diff_2; + a1 +---- +(0 rows) + +-- Temporary schema +SET search_path = 'pg_temp'; +SELECT count(*) FROM tab_search_same; + count +------- + 0 +(1 row) + +SELECT a, b FROM tab_search_same; + a | b +---+--- +(0 rows) + +SELECT count(*) FROM tab_search_diff_1; + count +------- + 0 +(1 row) + +SELECT count(*) FROM tab_search_diff_2; + count +------- + 0 +(1 row) + +SELECT a FROM tab_search_diff_2 AS t1; + a +--- +(0 rows) + +SELECT a FROM tab_search_diff_2; + a +--- +(0 rows) + +SELECT a AS a1 FROM tab_search_diff_2; + a1 +---- +(0 rows) + +RESET search_path; +-- Schema qualifications +SELECT count(*) FROM pgss_schema_1.tab_search_same; + count +------- + 0 +(1 row) + +SELECT a, b FROM pgss_schema_1.tab_search_same; + a | b +---+--- +(0 rows) + +SELECT count(*) FROM pgss_schema_2.tab_search_diff_1; + count +------- + 0 +(1 row) + +SELECT count(*) FROM pg_temp.tab_search_diff_2; + count +------- + 0 +(1 row) + +SELECT a FROM pgss_schema_2.tab_search_diff_2 AS t1; + a +--- +(0 rows) + +SELECT a FROM pgss_schema_2.tab_search_diff_2; + a +--- +(0 rows) + +SELECT a AS a1 FROM pgss_schema_2.tab_search_diff_2; + a1 +---- +(0 rows) + +SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; + calls | query +-------+------------------------------------------------------------------------ + 3 | SELECT a FROM pgss_schema_2.tab_search_diff_2 AS t1 + 9 | SELECT a FROM tab_search_diff_2 AS t1 + 1 | SELECT a, b FROM pgss_schema_1.tab_search_same + 3 | SELECT a, b FROM tab_search_same + 0 | SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C" + 1 | SELECT count(*) FROM pgss_schema_1.tab_search_same + 1 | SELECT count(*) FROM pgss_schema_2.tab_search_diff_1 + 3 | SELECT count(*) FROM tab_search_diff_1 + 4 | SELECT count(*) FROM tab_search_diff_2 + 3 | SELECT count(*) FROM tab_search_same + 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t +(11 rows) + +DROP SCHEMA pgss_schema_1 CASCADE; +NOTICE: drop cascades to 3 other objects +DETAIL: drop cascades to table pgss_schema_1.tab_search_same +drop cascades to table pgss_schema_1.tab_search_diff_1 +drop cascades to table pgss_schema_1.tab_search_diff_2 +DROP SCHEMA pgss_schema_2 CASCADE; +NOTICE: drop cascades to 3 other objects +DETAIL: drop cascades to table pgss_schema_2.tab_search_same +drop cascades to table pgss_schema_2.tab_search_diff_1 +drop cascades to table pgss_schema_2.tab_search_diff_2 +DROP TABLE tab_search_same, tab_search_diff_1, tab_search_diff_2; +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + t +--- + t +(1 row) + diff --git a/contrib/pg_stat_statements/sql/select.sql b/contrib/pg_stat_statements/sql/select.sql index e0be58d5e24..9a35471b271 100644 --- a/contrib/pg_stat_statements/sql/select.sql +++ b/contrib/pg_stat_statements/sql/select.sql @@ -148,3 +148,72 @@ SELECT ( SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%SELECT GROUPING%'; SELECT pg_stat_statements_reset() IS NOT NULL AS t; + +-- Temporary table with same name, re-created. +BEGIN; + CREATE TEMP TABLE temp_t (id int) ON COMMIT DROP; + SELECT * FROM temp_t; +COMMIT; +BEGIN; + CREATE TEMP TABLE temp_t (id int) ON COMMIT DROP; + SELECT * FROM temp_t; +COMMIT; +SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + +-- search_path with various schemas and temporary tables +CREATE SCHEMA pgss_schema_1; +CREATE SCHEMA pgss_schema_2; +-- Same attributes. +CREATE TABLE pgss_schema_1.tab_search_same (a int, b int); +CREATE TABLE pgss_schema_2.tab_search_same (a int, b int); +CREATE TEMP TABLE tab_search_same (a int, b int); +-- Different number of attributes, mapping types +CREATE TABLE pgss_schema_1.tab_search_diff_1 (a int); +CREATE TABLE pgss_schema_2.tab_search_diff_1 (a int, b int); +CREATE TEMP TABLE tab_search_diff_1 (a int, b int, c int); +-- Same number of attributes, different types +CREATE TABLE pgss_schema_1.tab_search_diff_2 (a int); +CREATE TABLE pgss_schema_2.tab_search_diff_2 (a text); +CREATE TEMP TABLE tab_search_diff_2 (a bigint); +-- First permanent schema +SET search_path = 'pgss_schema_1'; +SELECT count(*) FROM tab_search_same; +SELECT a, b FROM tab_search_same; +SELECT count(*) FROM tab_search_diff_1; +SELECT count(*) FROM tab_search_diff_2; +SELECT a FROM tab_search_diff_2 AS t1; +SELECT a FROM tab_search_diff_2; +SELECT a AS a1 FROM tab_search_diff_2; +-- Second permanent schema +SET search_path = 'pgss_schema_2'; +SELECT count(*) FROM tab_search_same; +SELECT a, b FROM tab_search_same; +SELECT count(*) FROM tab_search_diff_1; +SELECT count(*) FROM tab_search_diff_2; +SELECT a FROM tab_search_diff_2 AS t1; +SELECT a FROM tab_search_diff_2; +SELECT a AS a1 FROM tab_search_diff_2; +-- Temporary schema +SET search_path = 'pg_temp'; +SELECT count(*) FROM tab_search_same; +SELECT a, b FROM tab_search_same; +SELECT count(*) FROM tab_search_diff_1; +SELECT count(*) FROM tab_search_diff_2; +SELECT a FROM tab_search_diff_2 AS t1; +SELECT a FROM tab_search_diff_2; +SELECT a AS a1 FROM tab_search_diff_2; +RESET search_path; +-- Schema qualifications +SELECT count(*) FROM pgss_schema_1.tab_search_same; +SELECT a, b FROM pgss_schema_1.tab_search_same; +SELECT count(*) FROM pgss_schema_2.tab_search_diff_1; +SELECT count(*) FROM pg_temp.tab_search_diff_2; +SELECT a FROM pgss_schema_2.tab_search_diff_2 AS t1; +SELECT a FROM pgss_schema_2.tab_search_diff_2; +SELECT a AS a1 FROM pgss_schema_2.tab_search_diff_2; +SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; +DROP SCHEMA pgss_schema_1 CASCADE; +DROP SCHEMA pgss_schema_2 CASCADE; +DROP TABLE tab_search_same, tab_search_diff_1, tab_search_diff_2; +SELECT pg_stat_statements_reset() IS NOT NULL AS t; |