From 2e3cba343f3cfbff092e70b48c7d439fc368b6af Mon Sep 17 00:00:00 2001 From: Mikhail Samoylov <> Date: Sat, 20 Feb 2021 23:17:34 +0300 Subject: [PATCH] PG-183. Move tests to separate directory --- Makefile | 2 +- regression/expected/basic.out | 34 ++ regression/expected/basic_1.out | 35 ++ regression/expected/guc.out | 37 ++ regression/expected/guc_1.out | 38 ++ regression/expected/pg_stat_monitor.out | 436 +++++++++++++++++++++ regression/expected/pg_stat_monitor_1.out | 442 ++++++++++++++++++++++ regression/expected/relations.out | 40 ++ regression/expected/relations_1.out | 41 ++ regression/sql/basic.sql | 7 + regression/sql/guc.sql | 6 + regression/sql/pg_stat_monitor.sql | 198 ++++++++++ regression/sql/relations.sql | 15 + 13 files changed, 1330 insertions(+), 1 deletion(-) create mode 100644 regression/expected/basic.out create mode 100644 regression/expected/basic_1.out create mode 100644 regression/expected/guc.out create mode 100644 regression/expected/guc_1.out create mode 100644 regression/expected/pg_stat_monitor.out create mode 100644 regression/expected/pg_stat_monitor_1.out create mode 100644 regression/expected/relations.out create mode 100644 regression/expected/relations_1.out create mode 100644 regression/sql/basic.sql create mode 100644 regression/sql/guc.sql create mode 100644 regression/sql/pg_stat_monitor.sql create mode 100644 regression/sql/relations.sql diff --git a/Makefile b/Makefile index 8228920..97a68b4 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements" LDFLAGS_SL += $(filter -lm, $(LIBS)) -REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf +REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression REGRESS = guc relations basic pg_stat_monitor # Disabled because these tests require "shared_preload_libraries=pg_stat_statements", diff --git a/regression/expected/basic.out b/regression/expected/basic.out new file mode 100644 index 0000000..edf72fb --- /dev/null +++ b/regression/expected/basic.out @@ -0,0 +1,34 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +select pg_sleep(.5); + pg_sleep +---------- + +(1 row) + +SELECT 1; + ?column? +---------- + 1 +(1 row) + +SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query +-------------------------------- + SELECT $1 + SELECT pg_stat_monitor_reset() + select pg_sleep($1) +(3 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/basic_1.out b/regression/expected/basic_1.out new file mode 100644 index 0000000..5e5dba3 --- /dev/null +++ b/regression/expected/basic_1.out @@ -0,0 +1,35 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +select pg_sleep(.5); + pg_sleep +---------- + +(1 row) + +SELECT 1; + ?column? +---------- + 1 +(1 row) + +SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query +-------------------------------------------------------------- + SELECT $1 + SELECT pg_stat_monitor_reset() + SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C" + select pg_sleep($1) +(4 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/guc.out b/regression/expected/guc.out new file mode 100644 index 0000000..11f90bb --- /dev/null +++ b/regression/expected/guc.out @@ -0,0 +1,37 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +select pg_sleep(.5); + pg_sleep +---------- + +(1 row) + +SELECT * FROM pg_stat_monitor_settings ORDER BY name COLLATE "C"; + name | value | default_value | description | minimum | maximum | restart +------------------------------------------+--------+---------------+----------------------------------------------------------------------------------------------------------+---------+------------+--------- + pg_stat_monitor.pgsm_bucket_time | 300 | 300 | Sets the time in seconds per bucket. | 1 | 2147483647 | 1 + pg_stat_monitor.pgsm_enable | 1 | 1 | Enable/Disable statistics collector. | 0 | 0 | 0 + pg_stat_monitor.pgsm_histogram_buckets | 10 | 10 | Sets the maximum number of histogram buckets | 2 | 2147483647 | 1 + pg_stat_monitor.pgsm_histogram_max | 100000 | 100000 | Sets the time in millisecond. | 10 | 2147483647 | 1 + pg_stat_monitor.pgsm_histogram_min | 0 | 0 | Sets the time in millisecond. | 0 | 2147483647 | 1 + pg_stat_monitor.pgsm_max | 100 | 100 | Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor. | 1 | 1000 | 1 + pg_stat_monitor.pgsm_max_buckets | 10 | 10 | Sets the maximum number of buckets. | 1 | 10 | 1 + pg_stat_monitor.pgsm_normalized_query | 1 | 1 | Selects whether save query in normalized format. | 0 | 0 | 0 + pg_stat_monitor.pgsm_overflow_target | 0 | 1 | Sets the overflow target for pg_stat_monitor | 0 | 1 | 1 + pg_stat_monitor.pgsm_query_max_len | 1024 | 1024 | Sets the maximum length of query. | 1024 | 2147483647 | 1 + pg_stat_monitor.pgsm_query_shared_buffer | 20 | 20 | Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor. | 1 | 10000 | 1 + pg_stat_monitor.pgsm_track_utility | 1 | 1 | Selects whether utility commands are tracked. | 0 | 0 | 0 +(12 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/guc_1.out b/regression/expected/guc_1.out new file mode 100644 index 0000000..c840a74 --- /dev/null +++ b/regression/expected/guc_1.out @@ -0,0 +1,38 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +select pg_sleep(.5); + pg_sleep +---------- + +(1 row) + +SELECT * FROM pg_stat_monitor_settings ORDER BY name COLLATE "C"; + name | value | default_value | description | minimum | maximum | restart +------------------------------------------+--------+---------------+----------------------------------------------------------------------------------------------------------+---------+------------+--------- + pg_stat_monitor.pgsm_bucket_time | 300 | 300 | Sets the time in seconds per bucket. | 1 | 2147483647 | 1 + pg_stat_monitor.pgsm_enable | 1 | 1 | Enable/Disable statistics collector. | 0 | 0 | 0 + pg_stat_monitor.pgsm_histogram_buckets | 10 | 10 | Sets the maximum number of histogram buckets | 2 | 2147483647 | 1 + pg_stat_monitor.pgsm_histogram_max | 100000 | 100000 | Sets the time in millisecond. | 10 | 2147483647 | 1 + pg_stat_monitor.pgsm_histogram_min | 0 | 0 | Sets the time in millisecond. | 0 | 2147483647 | 1 + pg_stat_monitor.pgsm_max | 100 | 100 | Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor. | 1 | 1000 | 1 + pg_stat_monitor.pgsm_max_buckets | 10 | 10 | Sets the maximum number of buckets. | 1 | 10 | 1 + pg_stat_monitor.pgsm_normalized_query | 1 | 1 | Selects whether save query in normalized format. | 0 | 0 | 0 + pg_stat_monitor.pgsm_overflow_target | 1 | 1 | Sets the overflow target for pg_stat_monitor | 0 | 1 | 1 + pg_stat_monitor.pgsm_query_max_len | 1024 | 1024 | Sets the maximum length of query. | 1024 | 2147483647 | 1 + pg_stat_monitor.pgsm_query_shared_buffer | 20 | 20 | Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor. | 1 | 10000 | 1 + pg_stat_monitor.pgsm_track_planning | 0 | 1 | Selects whether planning statistics are tracked. | 0 | 0 | 0 + pg_stat_monitor.pgsm_track_utility | 1 | 1 | Selects whether utility commands are tracked. | 0 | 0 | 0 +(13 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/pg_stat_monitor.out b/regression/expected/pg_stat_monitor.out new file mode 100644 index 0000000..8d1de44 --- /dev/null +++ b/regression/expected/pg_stat_monitor.out @@ -0,0 +1,436 @@ +CREATE EXTENSION pg_stat_monitor; +-- +-- simple and compound statements +-- +SET pg_stat_monitor.track_utility = FALSE; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT 1 AS "int"; + int +----- + 1 +(1 row) + +SELECT 'hello' + -- multiline + AS "text"; + text +------- + hello +(1 row) + +SELECT 'world' AS "text"; + text +------- + world +(1 row) + +-- transaction +BEGIN; +SELECT 1 AS "int"; + int +----- + 1 +(1 row) + +SELECT 'hello' AS "text"; + text +------- + hello +(1 row) + +COMMIT; +-- compound transaction +BEGIN \; +SELECT 2.0 AS "float" \; +SELECT 'world' AS "text" \; +COMMIT; +-- compound with empty statements and spurious leading spacing +\;\; SELECT 3 + 3 \;\;\; SELECT ' ' || ' !' \;\; SELECT 1 + 4 \;; + ?column? +---------- + 5 +(1 row) + +-- non ;-terminated statements +SELECT 1 + 1 + 1 AS "add" \gset +SELECT :add + 1 + 1 AS "add" \; +SELECT :add + 1 + 1 AS "add" \gset +-- set operator +SELECT 1 AS i UNION SELECT 2 ORDER BY i; + i +--- + 1 + 2 +(2 rows) + +-- ? operator +select '{"a":1, "b":2}'::jsonb ? 'b'; + ?column? +---------- + t +(1 row) + +-- cte +WITH t(f) AS ( + VALUES (1.0), (2.0) +) + SELECT f FROM t ORDER BY f; + f +----- + 1.0 + 2.0 +(2 rows) + +-- prepared statement with parameter +PREPARE pgss_test (int) AS SELECT $1, 'test' LIMIT 1; +EXECUTE pgss_test(1); + ?column? | ?column? +----------+---------- + 1 | test +(1 row) + +DEALLOCATE pgss_test; +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------+-------+------ + BEGIN | 2 | 0 + COMMIT | 2 | 0 + PREPARE pgss_test (int) AS SELECT $1, $2 LIMIT $3 | 1 | 1 + SELECT $1 | 2 | 2 + SELECT $1 +| 4 | 4 + +| | + AS "text" | | + SELECT $1 + $2 | 2 | 2 + SELECT $1 + $2 + $3 AS "add" | 3 | 3 + SELECT $1 AS "float" | 1 | 1 + SELECT $1 AS i UNION SELECT $2 ORDER BY i | 1 | 2 + SELECT $1 || $2 | 1 | 1 + SELECT pg_stat_monitor_reset() | 1 | 1 + WITH t(f) AS ( +| 1 | 2 + VALUES ($1), ($2) +| | + ) +| | + SELECT f FROM t ORDER BY f | | + select $1::jsonb ? $2 | 1 | 1 +(13 rows) + +-- +-- CRUD: INSERT SELECT UPDATE DELETE on test table +-- +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +-- utility "create table" should not be shown +CREATE TEMP TABLE test (a int, b char(20)); +INSERT INTO test VALUES(generate_series(1, 10), 'aaa'); +UPDATE test SET b = 'bbb' WHERE a > 7; +DELETE FROM test WHERE a > 9; +-- explicit transaction +BEGIN; +UPDATE test SET b = '111' WHERE a = 1 ; +COMMIT; +BEGIN \; +UPDATE test SET b = '222' WHERE a = 2 \; +COMMIT ; +UPDATE test SET b = '333' WHERE a = 3 \; +UPDATE test SET b = '444' WHERE a = 4 ; +BEGIN \; +UPDATE test SET b = '555' WHERE a = 5 \; +UPDATE test SET b = '666' WHERE a = 6 \; +COMMIT ; +-- many INSERT values +INSERT INTO test (a, b) VALUES (1, 'a'), (2, 'b'), (3, 'c'); +-- SELECT with constants +SELECT * FROM test WHERE a > 5 ORDER BY a ; + a | b +---+---------------------- + 6 | 666 + 7 | aaa + 8 | bbb + 9 | bbb +(4 rows) + +SELECT * + FROM test + WHERE a > 9 + ORDER BY a ; + a | b +---+--- +(0 rows) + +-- SELECT without constants +SELECT * FROM test ORDER BY a; + a | b +---+---------------------- + 1 | a + 1 | 111 + 2 | b + 2 | 222 + 3 | c + 3 | 333 + 4 | 444 + 5 | 555 + 6 | 666 + 7 | aaa + 8 | bbb + 9 | bbb +(12 rows) + +-- SELECT with IN clause +SELECT * FROM test WHERE a IN (1, 2, 3, 4, 5); + a | b +---+---------------------- + 1 | 111 + 2 | 222 + 3 | 333 + 4 | 444 + 5 | 555 + 1 | a + 2 | b + 3 | c +(8 rows) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +-------------------------------------------------------------+-------+------ + BEGIN | 3 | 0 + COMMIT | 3 | 0 + CREATE TEMP TABLE test (a int, b char(20)) | 1 | 0 + DELETE FROM test WHERE a > $1 | 1 | 1 + INSERT INTO test (a, b) VALUES ($1, $2), ($3, $4), ($5, $6) | 1 | 3 + INSERT INTO test VALUES(generate_series($1, $2), $3) | 1 | 10 + SELECT * FROM test ORDER BY a | 1 | 12 + SELECT * FROM test WHERE a > $1 ORDER BY a | 2 | 4 + SELECT * FROM test WHERE a IN ($1, $2, $3, $4, $5) | 1 | 8 + SELECT pg_stat_monitor_reset() | 1 | 1 + UPDATE test SET b = $1 WHERE a = $2 | 6 | 6 + UPDATE test SET b = $1 WHERE a > $2 | 1 | 3 +(12 rows) + +-- +-- pg_stat_monitor.track = none +-- +SET pg_stat_monitor.track = 'none'; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT 1 AS "one"; + one +----- + 1 +(1 row) + +SELECT 1 + 1 AS "two"; + two +----- + 2 +(1 row) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +--------------------------------+-------+------ + SELECT $1 | 1 | 1 + SELECT $1 + $2 | 1 | 1 + SELECT pg_stat_monitor_reset() | 1 | 1 +(3 rows) + +-- +-- pg_stat_monitor.track = top +-- +SET pg_stat_monitor.track = 'top'; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DO LANGUAGE plpgsql $$ +BEGIN + -- this is a SELECT + PERFORM 'hello world'::TEXT; +END; +$$; +-- PL/pgSQL function +CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +DECLARE + r INTEGER; +BEGIN + SELECT (i + 1 + 1.0)::INTEGER INTO r; + RETURN r; +END; $$ LANGUAGE plpgsql; +SELECT PLUS_TWO(3); + plus_two +---------- + 5 +(1 row) + +SELECT PLUS_TWO(7); + plus_two +---------- + 9 +(1 row) + +-- SQL function --- use LIMIT to keep it from being inlined +CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL; +SELECT PLUS_ONE(8); + plus_one +---------- + 9 +(1 row) + +SELECT PLUS_ONE(10); + plus_one +---------- + 11 +(1 row) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +-----------------------------------------------------------+-------+------ + CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +| 1 | 0 + $$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL | | + CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$+| 1 | 0 + DECLARE +| | + r INTEGER; +| | + BEGIN +| | + SELECT (i + 1 + 1.0)::INTEGER INTO r; +| | + RETURN r; +| | + END; $$ LANGUAGE plpgsql | | + DO LANGUAGE plpgsql $$ +| 1 | 0 + BEGIN +| | + -- this is a SELECT +| | + PERFORM 'hello world'::TEXT; +| | + END; +| | + $$ | | + SELECT $1 +| 1 | 1 + +| | + AS "text" | | + SELECT (i + $2 + $3)::INTEGER | 2 | 2 + SELECT (i + $2)::INTEGER LIMIT $3 | 2 | 2 + SELECT PLUS_ONE($1) | 2 | 2 + SELECT PLUS_TWO($1) | 2 | 2 + SELECT pg_stat_monitor_reset() | 1 | 1 +(9 rows) + +-- +-- pg_stat_monitor.track = all +-- +SET pg_stat_monitor.track = 'all'; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +-- we drop and recreate the functions to avoid any caching funnies +DROP FUNCTION PLUS_ONE(INTEGER); +DROP FUNCTION PLUS_TWO(INTEGER); +-- PL/pgSQL function +CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +DECLARE + r INTEGER; +BEGIN + SELECT (i + 1 + 1.0)::INTEGER INTO r; + RETURN r; +END; $$ LANGUAGE plpgsql; +SELECT PLUS_TWO(-1); + plus_two +---------- + 1 +(1 row) + +SELECT PLUS_TWO(2); + plus_two +---------- + 4 +(1 row) + +-- SQL function --- use LIMIT to keep it from being inlined +CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL; +SELECT PLUS_ONE(3); + plus_one +---------- + 4 +(1 row) + +SELECT PLUS_ONE(1); + plus_one +---------- + 2 +(1 row) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +-----------------------------------------------------------+-------+------ + CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +| 1 | 0 + $$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL | | + CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$+| 1 | 0 + DECLARE +| | + r INTEGER; +| | + BEGIN +| | + SELECT (i + 1 + 1.0)::INTEGER INTO r; +| | + RETURN r; +| | + END; $$ LANGUAGE plpgsql | | + DROP FUNCTION PLUS_ONE(INTEGER) | 1 | 0 + DROP FUNCTION PLUS_TWO(INTEGER) | 1 | 0 + SELECT (i + $2 + $3)::INTEGER | 2 | 2 + SELECT (i + $2)::INTEGER LIMIT $3 | 2 | 2 + SELECT PLUS_ONE($1) | 2 | 2 + SELECT PLUS_TWO($1) | 2 | 2 + SELECT pg_stat_monitor_reset() | 1 | 1 +(9 rows) + +-- +-- utility commands +-- +SET pg_stat_monitor.track_utility = TRUE; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT 1; + ?column? +---------- + 1 +(1 row) + +CREATE INDEX test_b ON test(b); +DROP TABLE test \; +DROP TABLE IF EXISTS test \; +DROP FUNCTION PLUS_ONE(INTEGER); +NOTICE: table "test" does not exist, skipping +DROP TABLE IF EXISTS test \; +DROP TABLE IF EXISTS test \; +DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER); +NOTICE: table "test" does not exist, skipping +NOTICE: table "test" does not exist, skipping +NOTICE: function plus_one(pg_catalog.int4) does not exist, skipping +DROP FUNCTION PLUS_TWO(INTEGER); +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +-------------------------------------------+-------+------ + CREATE INDEX test_b ON test(b) | 1 | 0 + DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER) | 1 | 0 + DROP FUNCTION PLUS_ONE(INTEGER) | 1 | 0 + DROP FUNCTION PLUS_TWO(INTEGER) | 1 | 0 + DROP TABLE IF EXISTS test | 3 | 0 + DROP TABLE test | 1 | 0 + SELECT $1 | 1 | 1 + SELECT pg_stat_monitor_reset() | 1 | 1 +(8 rows) + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/pg_stat_monitor_1.out b/regression/expected/pg_stat_monitor_1.out new file mode 100644 index 0000000..e5f3dbc --- /dev/null +++ b/regression/expected/pg_stat_monitor_1.out @@ -0,0 +1,442 @@ +CREATE EXTENSION pg_stat_monitor; +-- +-- simple and compound statements +-- +SET pg_stat_monitor.track_utility = FALSE; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT 1 AS "int"; + int +----- + 1 +(1 row) + +SELECT 'hello' + -- multiline + AS "text"; + text +------- + hello +(1 row) + +SELECT 'world' AS "text"; + text +------- + world +(1 row) + +-- transaction +BEGIN; +SELECT 1 AS "int"; + int +----- + 1 +(1 row) + +SELECT 'hello' AS "text"; + text +------- + hello +(1 row) + +COMMIT; +-- compound transaction +BEGIN \; +SELECT 2.0 AS "float" \; +SELECT 'world' AS "text" \; +COMMIT; +-- compound with empty statements and spurious leading spacing +\;\; SELECT 3 + 3 \;\;\; SELECT ' ' || ' !' \;\; SELECT 1 + 4 \;; + ?column? +---------- + 5 +(1 row) + +-- non ;-terminated statements +SELECT 1 + 1 + 1 AS "add" \gset +SELECT :add + 1 + 1 AS "add" \; +SELECT :add + 1 + 1 AS "add" \gset +-- set operator +SELECT 1 AS i UNION SELECT 2 ORDER BY i; + i +--- + 1 + 2 +(2 rows) + +-- ? operator +select '{"a":1, "b":2}'::jsonb ? 'b'; + ?column? +---------- + t +(1 row) + +-- cte +WITH t(f) AS ( + VALUES (1.0), (2.0) +) + SELECT f FROM t ORDER BY f; + f +----- + 1.0 + 2.0 +(2 rows) + +-- prepared statement with parameter +PREPARE pgss_test (int) AS SELECT $1, 'test' LIMIT 1; +EXECUTE pgss_test(1); + ?column? | ?column? +----------+---------- + 1 | test +(1 row) + +DEALLOCATE pgss_test; +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------------------------------+-------+------ + BEGIN | 2 | 0 + COMMIT | 2 | 0 + PREPARE pgss_test (int) AS SELECT $1, $2 LIMIT $3 | 1 | 1 + SELECT $1 | 2 | 2 + SELECT $1 +| 4 | 4 + +| | + AS "text" | | + SELECT $1 + $2 | 2 | 2 + SELECT $1 + $2 + $3 AS "add" | 3 | 3 + SELECT $1 AS "float" | 1 | 1 + SELECT $1 AS i UNION SELECT $2 ORDER BY i | 1 | 2 + SELECT $1 || $2 | 1 | 1 + SELECT pg_stat_monitor_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | 0 + WITH t(f) AS ( +| 1 | 2 + VALUES ($1), ($2) +| | + ) +| | + SELECT f FROM t ORDER BY f | | + select $1::jsonb ? $2 | 1 | 1 +(14 rows) + +-- +-- CRUD: INSERT SELECT UPDATE DELETE on test table +-- +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +-- utility "create table" should not be shown +CREATE TEMP TABLE test (a int, b char(20)); +INSERT INTO test VALUES(generate_series(1, 10), 'aaa'); +UPDATE test SET b = 'bbb' WHERE a > 7; +DELETE FROM test WHERE a > 9; +-- explicit transaction +BEGIN; +UPDATE test SET b = '111' WHERE a = 1 ; +COMMIT; +BEGIN \; +UPDATE test SET b = '222' WHERE a = 2 \; +COMMIT ; +UPDATE test SET b = '333' WHERE a = 3 \; +UPDATE test SET b = '444' WHERE a = 4 ; +BEGIN \; +UPDATE test SET b = '555' WHERE a = 5 \; +UPDATE test SET b = '666' WHERE a = 6 \; +COMMIT ; +-- many INSERT values +INSERT INTO test (a, b) VALUES (1, 'a'), (2, 'b'), (3, 'c'); +-- SELECT with constants +SELECT * FROM test WHERE a > 5 ORDER BY a ; + a | b +---+---------------------- + 6 | 666 + 7 | aaa + 8 | bbb + 9 | bbb +(4 rows) + +SELECT * + FROM test + WHERE a > 9 + ORDER BY a ; + a | b +---+--- +(0 rows) + +-- SELECT without constants +SELECT * FROM test ORDER BY a; + a | b +---+---------------------- + 1 | a + 1 | 111 + 2 | b + 2 | 222 + 3 | c + 3 | 333 + 4 | 444 + 5 | 555 + 6 | 666 + 7 | aaa + 8 | bbb + 9 | bbb +(12 rows) + +-- SELECT with IN clause +SELECT * FROM test WHERE a IN (1, 2, 3, 4, 5); + a | b +---+---------------------- + 1 | 111 + 2 | 222 + 3 | 333 + 4 | 444 + 5 | 555 + 1 | a + 2 | b + 3 | c +(8 rows) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------------------------------+-------+------ + BEGIN | 3 | 0 + COMMIT | 3 | 0 + CREATE TEMP TABLE test (a int, b char(20)) | 1 | 0 + DELETE FROM test WHERE a > $1 | 1 | 1 + INSERT INTO test (a, b) VALUES ($1, $2), ($3, $4), ($5, $6) | 1 | 3 + INSERT INTO test VALUES(generate_series($1, $2), $3) | 1 | 10 + SELECT * FROM test ORDER BY a | 1 | 12 + SELECT * FROM test WHERE a > $1 ORDER BY a | 2 | 4 + SELECT * FROM test WHERE a IN ($1, $2, $3, $4, $5) | 1 | 8 + SELECT pg_stat_monitor_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | 0 + UPDATE test SET b = $1 WHERE a = $2 | 6 | 6 + UPDATE test SET b = $1 WHERE a > $2 | 1 | 3 +(13 rows) + +-- +-- pg_stat_monitor.track = none +-- +SET pg_stat_monitor.track = 'none'; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT 1 AS "one"; + one +----- + 1 +(1 row) + +SELECT 1 + 1 AS "two"; + two +----- + 2 +(1 row) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------------------------------+-------+------ + SELECT $1 | 1 | 1 + SELECT $1 + $2 | 1 | 1 + SELECT pg_stat_monitor_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | 0 +(4 rows) + +-- +-- pg_stat_monitor.track = top +-- +SET pg_stat_monitor.track = 'top'; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DO LANGUAGE plpgsql $$ +BEGIN + -- this is a SELECT + PERFORM 'hello world'::TEXT; +END; +$$; +-- PL/pgSQL function +CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +DECLARE + r INTEGER; +BEGIN + SELECT (i + 1 + 1.0)::INTEGER INTO r; + RETURN r; +END; $$ LANGUAGE plpgsql; +SELECT PLUS_TWO(3); + plus_two +---------- + 5 +(1 row) + +SELECT PLUS_TWO(7); + plus_two +---------- + 9 +(1 row) + +-- SQL function --- use LIMIT to keep it from being inlined +CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL; +SELECT PLUS_ONE(8); + plus_one +---------- + 9 +(1 row) + +SELECT PLUS_ONE(10); + plus_one +---------- + 11 +(1 row) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------------------------------+-------+------ + CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +| 1 | 0 + $$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL | | + CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +| 1 | 0 + DECLARE +| | + r INTEGER; +| | + BEGIN +| | + SELECT (i + 1 + 1.0)::INTEGER INTO r; +| | + RETURN r; +| | + END; $$ LANGUAGE plpgsql | | + DO LANGUAGE plpgsql $$ +| 1 | 0 + BEGIN +| | + -- this is a SELECT +| | + PERFORM 'hello world'::TEXT; +| | + END; +| | + $$ | | + SELECT $1 +| 1 | 1 + +| | + AS "text" | | + SELECT (i + $2 + $3)::INTEGER | 2 | 2 + SELECT (i + $2)::INTEGER LIMIT $3 | 2 | 2 + SELECT PLUS_ONE($1) | 2 | 2 + SELECT PLUS_TWO($1) | 2 | 2 + SELECT pg_stat_monitor_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | 0 +(10 rows) + +-- +-- pg_stat_monitor.track = all +-- +SET pg_stat_monitor.track = 'all'; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +-- we drop and recreate the functions to avoid any caching funnies +DROP FUNCTION PLUS_ONE(INTEGER); +DROP FUNCTION PLUS_TWO(INTEGER); +-- PL/pgSQL function +CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +DECLARE + r INTEGER; +BEGIN + SELECT (i + 1 + 1.0)::INTEGER INTO r; + RETURN r; +END; $$ LANGUAGE plpgsql; +SELECT PLUS_TWO(-1); + plus_two +---------- + 1 +(1 row) + +SELECT PLUS_TWO(2); + plus_two +---------- + 4 +(1 row) + +-- SQL function --- use LIMIT to keep it from being inlined +CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL; +SELECT PLUS_ONE(3); + plus_one +---------- + 4 +(1 row) + +SELECT PLUS_ONE(1); + plus_one +---------- + 2 +(1 row) + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------------------------------+-------+------ + CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +| 1 | 0 + $$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL | | + CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +| 1 | 0 + DECLARE +| | + r INTEGER; +| | + BEGIN +| | + SELECT (i + 1 + 1.0)::INTEGER INTO r; +| | + RETURN r; +| | + END; $$ LANGUAGE plpgsql | | + DROP FUNCTION PLUS_ONE(INTEGER) | 1 | 0 + DROP FUNCTION PLUS_TWO(INTEGER) | 1 | 0 + SELECT (i + $2 + $3)::INTEGER | 2 | 2 + SELECT (i + $2)::INTEGER LIMIT $3 | 2 | 2 + SELECT PLUS_ONE($1) | 2 | 2 + SELECT PLUS_TWO($1) | 2 | 2 + SELECT pg_stat_monitor_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | 0 +(10 rows) + +-- +-- utility commands +-- +SET pg_stat_monitor.track_utility = TRUE; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT 1; + ?column? +---------- + 1 +(1 row) + +CREATE INDEX test_b ON test(b); +DROP TABLE test \; +DROP TABLE IF EXISTS test \; +DROP FUNCTION PLUS_ONE(INTEGER); +NOTICE: table "test" does not exist, skipping +DROP TABLE IF EXISTS test \; +DROP TABLE IF EXISTS test \; +DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER); +NOTICE: table "test" does not exist, skipping +NOTICE: table "test" does not exist, skipping +NOTICE: function plus_one(pg_catalog.int4) does not exist, skipping +DROP FUNCTION PLUS_TWO(INTEGER); +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | calls | rows +---------------------------------------------------------------------------+-------+------ + CREATE INDEX test_b ON test(b) | 1 | 0 + DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER) | 1 | 0 + DROP FUNCTION PLUS_ONE(INTEGER) | 1 | 0 + DROP FUNCTION PLUS_TWO(INTEGER) | 1 | 0 + DROP TABLE IF EXISTS test | 3 | 0 + DROP TABLE test | 1 | 0 + SELECT $1 | 1 | 1 + SELECT pg_stat_monitor_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | 0 +(9 rows) + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/relations.out b/regression/expected/relations.out new file mode 100644 index 0000000..182772f --- /dev/null +++ b/regression/expected/relations.out @@ -0,0 +1,40 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +CREATE TABLE foo1(a int); +CREATE TABLE foo2(a int); +CREATE TABLE foo3(a int); +CREATE TABLE foo4(a int); +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT * FROM foo1, foo2, foo3, foo4; + a | a | a | a +---+---+---+--- +(0 rows) + +SELECT query, relations from pg_stat_monitor ORDER BY query; + query | relations +--------------------------------------+--------------------------------------------------- + SELECT * FROM foo1, foo2, foo3, foo4 | {public.foo1,public.foo2,public.foo3,public.foo4} + SELECT pg_stat_monitor_reset() | +(2 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP TABLE foo1; +DROP TABLE foo2; +DROP TABLE foo3; +DROP TABLE foo4; +DROP EXTENSION pg_stat_monitor; diff --git a/regression/expected/relations_1.out b/regression/expected/relations_1.out new file mode 100644 index 0000000..63ea0dd --- /dev/null +++ b/regression/expected/relations_1.out @@ -0,0 +1,41 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +CREATE TABLE foo1(a int); +CREATE TABLE foo2(a int); +CREATE TABLE foo3(a int); +CREATE TABLE foo4(a int); +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +SELECT * FROM foo1, foo2, foo3, foo4; + a | a | a | a +---+---+---+--- +(0 rows) + +SELECT query, relations from pg_stat_monitor ORDER BY query; + query | relations +-------------------------------------------------------------+--------------------------------------------------- + SELECT * FROM foo1, foo2, foo3, foo4 | {public.foo1,public.foo2,public.foo3,public.foo4} + SELECT pg_stat_monitor_reset() | + SELECT query, relations from pg_stat_monitor ORDER BY query | +(3 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP TABLE foo1; +DROP TABLE foo2; +DROP TABLE foo3; +DROP TABLE foo4; +DROP EXTENSION pg_stat_monitor; diff --git a/regression/sql/basic.sql b/regression/sql/basic.sql new file mode 100644 index 0000000..e40fb8a --- /dev/null +++ b/regression/sql/basic.sql @@ -0,0 +1,7 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); +select pg_sleep(.5); +SELECT 1; +SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C"; +SELECT pg_stat_monitor_reset(); +DROP EXTENSION pg_stat_monitor; diff --git a/regression/sql/guc.sql b/regression/sql/guc.sql new file mode 100644 index 0000000..bc46962 --- /dev/null +++ b/regression/sql/guc.sql @@ -0,0 +1,6 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); +select pg_sleep(.5); +SELECT * FROM pg_stat_monitor_settings ORDER BY name COLLATE "C"; +SELECT pg_stat_monitor_reset(); +DROP EXTENSION pg_stat_monitor; diff --git a/regression/sql/pg_stat_monitor.sql b/regression/sql/pg_stat_monitor.sql new file mode 100644 index 0000000..a46e25b --- /dev/null +++ b/regression/sql/pg_stat_monitor.sql @@ -0,0 +1,198 @@ +CREATE EXTENSION pg_stat_monitor; + +-- +-- simple and compound statements +-- +SET pg_stat_monitor.track_utility = FALSE; +SELECT pg_stat_monitor_reset(); + +SELECT 1 AS "int"; + +SELECT 'hello' + -- multiline + AS "text"; + +SELECT 'world' AS "text"; + +-- transaction +BEGIN; +SELECT 1 AS "int"; +SELECT 'hello' AS "text"; +COMMIT; + +-- compound transaction +BEGIN \; +SELECT 2.0 AS "float" \; +SELECT 'world' AS "text" \; +COMMIT; + +-- compound with empty statements and spurious leading spacing +\;\; SELECT 3 + 3 \;\;\; SELECT ' ' || ' !' \;\; SELECT 1 + 4 \;; + +-- non ;-terminated statements +SELECT 1 + 1 + 1 AS "add" \gset +SELECT :add + 1 + 1 AS "add" \; +SELECT :add + 1 + 1 AS "add" \gset + +-- set operator +SELECT 1 AS i UNION SELECT 2 ORDER BY i; + +-- ? operator +select '{"a":1, "b":2}'::jsonb ? 'b'; + +-- cte +WITH t(f) AS ( + VALUES (1.0), (2.0) +) + SELECT f FROM t ORDER BY f; + +-- prepared statement with parameter +PREPARE pgss_test (int) AS SELECT $1, 'test' LIMIT 1; +EXECUTE pgss_test(1); +DEALLOCATE pgss_test; + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + +-- +-- CRUD: INSERT SELECT UPDATE DELETE on test table +-- +SELECT pg_stat_monitor_reset(); + +-- utility "create table" should not be shown +CREATE TEMP TABLE test (a int, b char(20)); + +INSERT INTO test VALUES(generate_series(1, 10), 'aaa'); +UPDATE test SET b = 'bbb' WHERE a > 7; +DELETE FROM test WHERE a > 9; + +-- explicit transaction +BEGIN; +UPDATE test SET b = '111' WHERE a = 1 ; +COMMIT; + +BEGIN \; +UPDATE test SET b = '222' WHERE a = 2 \; +COMMIT ; + +UPDATE test SET b = '333' WHERE a = 3 \; +UPDATE test SET b = '444' WHERE a = 4 ; + +BEGIN \; +UPDATE test SET b = '555' WHERE a = 5 \; +UPDATE test SET b = '666' WHERE a = 6 \; +COMMIT ; + +-- many INSERT values +INSERT INTO test (a, b) VALUES (1, 'a'), (2, 'b'), (3, 'c'); + +-- SELECT with constants +SELECT * FROM test WHERE a > 5 ORDER BY a ; + +SELECT * + FROM test + WHERE a > 9 + ORDER BY a ; + +-- SELECT without constants +SELECT * FROM test ORDER BY a; + +-- SELECT with IN clause +SELECT * FROM test WHERE a IN (1, 2, 3, 4, 5); + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + +-- +-- pg_stat_monitor.track = none +-- +SET pg_stat_monitor.track = 'none'; +SELECT pg_stat_monitor_reset(); + +SELECT 1 AS "one"; +SELECT 1 + 1 AS "two"; + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + +-- +-- pg_stat_monitor.track = top +-- +SET pg_stat_monitor.track = 'top'; +SELECT pg_stat_monitor_reset(); + +DO LANGUAGE plpgsql $$ +BEGIN + -- this is a SELECT + PERFORM 'hello world'::TEXT; +END; +$$; + +-- PL/pgSQL function +CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +DECLARE + r INTEGER; +BEGIN + SELECT (i + 1 + 1.0)::INTEGER INTO r; + RETURN r; +END; $$ LANGUAGE plpgsql; + +SELECT PLUS_TWO(3); +SELECT PLUS_TWO(7); + +-- SQL function --- use LIMIT to keep it from being inlined +CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL; + +SELECT PLUS_ONE(8); +SELECT PLUS_ONE(10); + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + +-- +-- pg_stat_monitor.track = all +-- +SET pg_stat_monitor.track = 'all'; +SELECT pg_stat_monitor_reset(); + +-- we drop and recreate the functions to avoid any caching funnies +DROP FUNCTION PLUS_ONE(INTEGER); +DROP FUNCTION PLUS_TWO(INTEGER); + +-- PL/pgSQL function +CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$ +DECLARE + r INTEGER; +BEGIN + SELECT (i + 1 + 1.0)::INTEGER INTO r; + RETURN r; +END; $$ LANGUAGE plpgsql; + +SELECT PLUS_TWO(-1); +SELECT PLUS_TWO(2); + +-- SQL function --- use LIMIT to keep it from being inlined +CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS +$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL; + +SELECT PLUS_ONE(3); +SELECT PLUS_ONE(1); + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + +-- +-- utility commands +-- +SET pg_stat_monitor.track_utility = TRUE; +SELECT pg_stat_monitor_reset(); + +SELECT 1; +CREATE INDEX test_b ON test(b); +DROP TABLE test \; +DROP TABLE IF EXISTS test \; +DROP FUNCTION PLUS_ONE(INTEGER); +DROP TABLE IF EXISTS test \; +DROP TABLE IF EXISTS test \; +DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER); +DROP FUNCTION PLUS_TWO(INTEGER); + +SELECT query, calls, rows FROM pg_stat_monitor ORDER BY query COLLATE "C"; + +DROP EXTENSION pg_stat_monitor; diff --git a/regression/sql/relations.sql b/regression/sql/relations.sql new file mode 100644 index 0000000..7eaef72 --- /dev/null +++ b/regression/sql/relations.sql @@ -0,0 +1,15 @@ +CREATE EXTENSION pg_stat_monitor; +SELECT pg_stat_monitor_reset(); +CREATE TABLE foo1(a int); +CREATE TABLE foo2(a int); +CREATE TABLE foo3(a int); +CREATE TABLE foo4(a int); +SELECT pg_stat_monitor_reset(); +SELECT * FROM foo1, foo2, foo3, foo4; +SELECT query, relations from pg_stat_monitor ORDER BY query; +SELECT pg_stat_monitor_reset(); +DROP TABLE foo1; +DROP TABLE foo2; +DROP TABLE foo3; +DROP TABLE foo4; +DROP EXTENSION pg_stat_monitor;