---- -- Regression test to Global Temporary Table implementation -- -- Test for GTT defined inside a PLPGSQL function. -- ---- -- Import the library LOAD 'pgtt'; CREATE OR REPLACE FUNCTION test_temp_table () RETURNS integer AS $$ DECLARE nrows integer; BEGIN CREATE /*GLOBAL*/ TEMPORARY TABLE t_glob_temptable1(id int, lbl text) ON COMMIT PRESERVE ROWS; INSERT INTO t_glob_temptable1 (id, lbl) SELECT i, md5(i::text) FROM generate_series(1, 10) i; SELECT count(*) INTO nrows FROM t_glob_temptable1 ; RETURN nrows; END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Look at Global Temporary Table definition: none SELECT nspname, relname, preserved, code FROM pgtt_schema.pg_global_temp_tables; nspname | relname | preserved | code ---------+---------+-----------+------ (0 rows) -- Call the function, must returns 10 rows SELECT test_temp_table(); test_temp_table ----------------- 10 (1 row) -- Look at Global Temporary Table definition: table exists SELECT nspname, relname, preserved, code FROM pgtt_schema.pg_global_temp_tables; nspname | relname | preserved | code -------------+-------------------+-----------+------------------ pgtt_schema | t_glob_temptable1 | t | id int, lbl text (1 row) -- Look if the temporary table exists outside the function call SELECT regexp_replace(n.nspname, '\d+', 'x', 'g'), c.relname FROM pg_class c JOIN pg_namespace n ON (c.relnamespace=n.oid) WHERE relname = 't_glob_temptable1'; regexp_replace | relname ----------------+------------------- pgtt_schema | t_glob_temptable1 pg_temp_x | t_glob_temptable1 (2 rows) -- A "template" unlogged table should exists SET pgtt.enabled TO off; SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod), (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), a.attnotnull, pg_catalog.col_description(a.attrelid, a.attnum) FROM pg_catalog.pg_attribute a WHERE a.attrelid = ( SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = 't_glob_temptable1' AND n.nspname = 'pgtt_schema' ) AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum; attname | format_type | substring | attnotnull | col_description ---------+-------------+-----------+------------+----------------- id | integer | | f | lbl | text | | f | (2 rows) -- Get rows from the template table SELECT * FROM pgtt_schema.t_glob_temptable1; id | lbl ----+----- (0 rows) -- Get rows from the temporary table SET pgtt.enabled TO on; SELECT * FROM t_glob_temptable1; id | lbl ----+---------------------------------- 1 | c4ca4238a0b923820dcc509a6f75849b 2 | c81e728d9d4c2f636f067f89cc14862c 3 | eccbc87e4b5ce2fe28308fd9f2a7baf3 4 | a87ff679a2f3e71d9181a67b7542122c 5 | e4da3b7fbbce2345d7772b0674a318d5 6 | 1679091c5a880faf6fb5e6087eb1b2dc 7 | 8f14e45fceea167a5a36dedd4bea2543 8 | c9f0f895fb98ab9159f51fd0297e236d 9 | 45c48cce2e2d7fbdea1afc51c7c6ad26 10 | d3d9446802a44259755d38e6d163e820 (10 rows) -- Reconnect without dropping the global temporary table \c - - LOAD 'pgtt'; SET pgtt.enabled TO off; -- Verify that only the temporary table have been dropped -- Only the "template" unlogged table should exists SELECT regexp_replace(n.nspname, '\d+', 'x', 'g'), c.relname FROM pg_class c JOIN pg_namespace n ON (c.relnamespace=n.oid) WHERE relname = 't_glob_temptable1'; regexp_replace | relname ----------------+------------------- pgtt_schema | t_glob_temptable1 (1 row) -- Look at Global Temporary Table definition, the table must be present SELECT nspname, relname, preserved, code FROM pgtt_schema.pg_global_temp_tables; nspname | relname | preserved | code -------------+-------------------+-----------+------------------ pgtt_schema | t_glob_temptable1 | t | id int, lbl text (1 row) SET pgtt.enabled TO on; -- Call the function a second time - must fail the table already exists SELECT test_temp_table(); ERROR: relation "t_glob_temptable1" already exists CONTEXT: SQL statement "CREATE UNLOGGED TABLE pgtt_schema.t_glob_temptable1 (id int, lbl text)" SQL statement "CREATE /*GLOBAL*/ TEMPORARY TABLE t_glob_temptable1(id int, lbl text) ON COMMIT PRESERVE ROWS" PL/pgSQL function test_temp_table() line 6 at SQL statement -- Look at temporary table content, must be empty after the reconnect and function failure SELECT * FROM t_glob_temptable1; id | lbl ----+----- (0 rows) -- Now the "template" unlogged table should exists as well as the temporary table SELECT regexp_replace(n.nspname, '\d+', 'x', 'g'), c.relname FROM pg_class c JOIN pg_namespace n ON (c.relnamespace=n.oid) WHERE relname = 't_glob_temptable1'; regexp_replace | relname ----------------+------------------- pgtt_schema | t_glob_temptable1 pg_temp_x | t_glob_temptable1 (2 rows) -- Reconnect and drop it \c - - LOAD 'pgtt'; -- Cleanup DROP TABLE t_glob_temptable1; DROP FUNCTION test_temp_table();