From 91a6caa33c68afd73e0418972d5a582fe6fd7bdf Mon Sep 17 00:00:00 2001
From: Daniil Davidov <d.davydov@postgrespro.ru>
Date: Fri, 10 Apr 2026 22:21:23 +0700
Subject: [PATCH v17 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  | 109 ++++++++++++++++++
 2 files changed, 110 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..fa8037e4d1e
--- /dev/null
+++ b/src/test/modules/test_misc/t/012_temp_obj_multisession.pl
@@ -0,0 +1,109 @@
+# 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;));
+
+$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');
+
+# Index scans can use a different code path from the one sequential scans are
+# following. Make sure that we cannot access other sessions' temp tables during
+# index scan either.
+$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
+$node->safe_psql('postgres', "DROP TABLE $tempschema.foo;");
+
+# Clean up
+$psql1->quit;
+
+done_testing();
-- 
2.43.0

