Commit ce6c4659028 for php
commit ce6c46590286f407a951830f24352375112b674a
Author: David Carlier <devnexen@gmail.com>
Date: Tue Oct 20 19:30:43 2026 +0100
ext/pdo_pgsql: persistent connection reset drops prepared statements and plans.
Fix #24461
Keep the rest of DISCARD ALL, and reset the connection if it fails.
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index cbfd55fc1aa..38d2044290d 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -1398,11 +1398,13 @@ static void pdo_pgsql_request_shutdown(pdo_dbh_t *dbh)
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
if(H->server) {
- res = PQexec(H->server, "DISCARD ALL");
+ res = PQexec(H->server, "CLOSE ALL; SET SESSION AUTHORIZATION DEFAULT; RESET ALL; UNLISTEN *; "
+ "SELECT pg_advisory_unlock_all(); DISCARD TEMP; DISCARD SEQUENCES");
- if(res) {
- PQclear(res);
+ if (PQresultStatus(res) != PGRES_COMMAND_OK && PQstatus(H->server) == CONNECTION_OK) {
+ PQreset(H->server);
}
+ PQclear(res);
}
}
diff --git a/ext/pdo_pgsql/tests/gh24461.phpt b/ext/pdo_pgsql/tests/gh24461.phpt
new file mode 100644
index 00000000000..600a58f5123
--- /dev/null
+++ b/ext/pdo_pgsql/tests/gh24461.phpt
@@ -0,0 +1,40 @@
+--TEST--
+GH-24461 (Persistent connections: session reset keeps prepared statements)
+--EXTENSIONS--
+pdo_pgsql
+--SKIPIF--
+<?php
+require __DIR__ . '/config.inc';
+require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+putenv('PDOTEST_ATTR='.serialize([PDO::ATTR_PERSISTENT => true]));
+
+require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
+
+$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt');
+$pid1 = (int) $pdo1->query('SELECT pg_backend_pid()')->fetchColumn();
+
+$pdo1->exec("SET application_name = 'gh24461'");
+$pdo1->exec('CREATE TEMP TABLE gh24461_tmp (i int)');
+$pdo1->exec('PREPARE gh24461_stmt AS SELECT 42');
+
+$pdo1 = null;
+
+$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt');
+$pid2 = (int) $pdo2->query('SELECT pg_backend_pid()')->fetchColumn();
+var_dump($pid1 === $pid2);
+
+var_dump($pdo2->query('SHOW application_name')->fetchColumn());
+var_dump($pdo2->query("SELECT to_regclass('pg_temp.gh24461_tmp')")->fetchColumn());
+var_dump($pdo2->query('EXECUTE gh24461_stmt')->fetchColumn());
+
+$pdo2->exec('DEALLOCATE gh24461_stmt');
+?>
+--EXPECT--
+bool(true)
+string(0) ""
+NULL
+string(2) "42"