From 07dd5ecd204420678a100b64a01347227f4fef4f Mon Sep 17 00:00:00 2001 From: Jim Jones Date: Wed, 8 Apr 2026 14:56:57 +0200 Subject: [PATCH v16 2/2] Test cross-session access on temporary tables --- src/test/modules/test_misc/meson.build | 1 + .../test_misc/t/012_temp_obj_multisession.pl | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 src/test/modules/test_misc/t/012_temp_obj_multisession.pl diff --git a/src/test/modules/test_misc/meson.build b/src/test/modules/test_misc/meson.build index 1b25d98f7f3..a54599cc301 100644 --- a/src/test/modules/test_misc/meson.build +++ b/src/test/modules/test_misc/meson.build @@ -20,6 +20,7 @@ tests += { 't/009_log_temp_files.pl', 't/010_index_concurrently_upsert.pl', 't/011_lock_stats.pl', + 't/012_temp_obj_multisession.pl', ], # The injection points are cluster-wide, so disable installcheck 'runningcheck': false, diff --git a/src/test/modules/test_misc/t/012_temp_obj_multisession.pl b/src/test/modules/test_misc/t/012_temp_obj_multisession.pl new file mode 100644 index 00000000000..4d599152740 --- /dev/null +++ b/src/test/modules/test_misc/t/012_temp_obj_multisession.pl @@ -0,0 +1,117 @@ +# Copyright (c) 2026, PostgreSQL Global Development Group + +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use PostgreSQL::Test::BackgroundPsql; +use Test::More; + +# Set up a fresh node +my $node = PostgreSQL::Test::Cluster->new('temp_lock'); +$node->init; +$node->start; + +# Create a long-lived session +my $psql1 = $node->background_psql('postgres'); + +$psql1->query_safe( + q(CREATE TEMP TABLE foo AS SELECT 42 AS val;)); + +# Create an index so the index-scan path (ReadBufferExtended) can be tested +$psql1->query_safe( + q(CREATE INDEX ON foo(val);)); + +my $tempschema = $node->safe_psql( + 'postgres', + q{ + SELECT n.nspname + FROM pg_class c + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE relname = 'foo' AND relpersistence = 't'; + } +); +chomp $tempschema; +ok($tempschema =~ /^pg_temp_\d+$/, "got temp schema: $tempschema"); + + +# SELECT TEMPORARY TABLE from other session +my ($stdout, $stderr); +$node->psql( + 'postgres', + "SELECT val FROM $tempschema.foo;", + stdout => \$stdout, + stderr => \$stderr +); +like($stderr, qr/cannot access temporary relations of other sessions/, + 'SELECT on other session temp table is not allowed'); + +# UPDATE TEMPORARY TABLE from other session +$node->psql( + 'postgres', + "UPDATE $tempschema.foo SET val = NULL;", + stderr => \$stderr +); +like($stderr, qr/cannot access temporary relations of other sessions/, + 'UPDATE on other session temp table is not allowed'); + +# DELETE records from TEMPORARY TABLE from other session +$node->psql( + 'postgres', + "DELETE FROM $tempschema.foo;", + stderr => \$stderr +); +like($stderr, qr/cannot access temporary relations of other sessions/, + 'DELETE on other session temp table is not allowed'); + +# TRUNCATE TEMPORARY TABLE from other session +$node->psql( + 'postgres', + "TRUNCATE TABLE $tempschema.foo;", + stderr => \$stderr +); +like($stderr, qr/cannot truncate temporary tables of other sessions/, + 'TRUNCATE on other session temp table is not allowed'); + +# INSERT INTO TEMPORARY TABLE from other session +$node->psql( + 'postgres', + "INSERT INTO $tempschema.foo VALUES (73);", + stderr => \$stderr +); +like($stderr, qr/cannot access temporary relations of other sessions/, + 'INSERT INTO on other session temp table is not allowed'); + +# COPY TEMPORARY TABLE from other session +$node->psql( + 'postgres', + "COPY $tempschema.foo TO STDOUT;", + stderr => \$stderr +); +like($stderr, qr/cannot access temporary relations of other sessions/, + 'COPY on other session temp table is blocked'); + +# SELECT via index scan from other session. +# Sequential scans are blocked at read_stream_begin_relation(); index scans +# bypass that path entirely and reach ReadBufferExtended() in bufmgr.c +# (nbtree's _bt_getbuf calls ReadBuffer directly for individual page fetches). +# enable_seqscan=off forces the planner to use the index. +$node->psql( + 'postgres', + "SET enable_seqscan = off; SELECT val FROM $tempschema.foo WHERE val = 42;", + stderr => \$stderr +); +like($stderr, qr/cannot access temporary relations of other sessions/, + 'index scan on other session temp table is not allowed (exercises ReadBufferExtended path)'); + +# DROP TEMPORARY TABLE from other session +my $ok = $node->psql( + 'postgres', + "DROP TABLE $tempschema.foo;" +); +ok($ok == 0, 'DROP TABLE executed successfully'); + +# Clean up +$psql1->quit; + +done_testing(); -- 2.43.0