Skip to content

Commit 9ff988a

Browse files
pdo_pgsql: Reset persistent session state on disconnect-equivalent processing
1 parent ca914ee commit 9ff988a

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

ext/pdo_pgsql/pgsql_driver.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,20 @@ static const zend_function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, i
13401340
}
13411341
}
13421342

1343+
static void pdo_pgsql_request_shutdown(pdo_dbh_t *dbh)
1344+
{
1345+
PGresult *res;
1346+
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
1347+
1348+
if(H->server) {
1349+
res = PQexec(H->server, "DISCARD ALL");
1350+
1351+
if(res) {
1352+
PQclear(res);
1353+
}
1354+
}
1355+
}
1356+
13431357
static bool pdo_pgsql_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
13441358
{
13451359
bool bval;
@@ -1383,7 +1397,7 @@ static const struct pdo_dbh_methods pgsql_methods = {
13831397
pdo_pgsql_get_attribute,
13841398
pdo_pgsql_check_liveness, /* check_liveness */
13851399
pdo_pgsql_get_driver_methods, /* get_driver_methods */
1386-
NULL,
1400+
pdo_pgsql_request_shutdown,
13871401
pgsql_handle_in_transaction,
13881402
NULL, /* get_gc */
13891403
pdo_pgsql_scanner
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Persistent connections: session state reset when performing disconnect-equivalent processing (general case)
3+
--EXTENSIONS--
4+
pdo_pgsql
5+
--SKIPIF--
6+
<?php
7+
require __DIR__ . '/config.inc';
8+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
9+
PDOTest::skip();
10+
?>
11+
--FILE--
12+
<?php
13+
putenv('PDOTEST_ATTR='.serialize([PDO::ATTR_PERSISTENT => true]));
14+
15+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
16+
17+
$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt');
18+
19+
$defaultValue = (int)$pdo1
20+
->query('show log_min_duration_statement;')
21+
->fetchColumn(0);
22+
23+
$setValue = $defaultValue + 1;
24+
25+
$pdo1->exec("SET log_min_duration_statement = {$setValue};");
26+
27+
$pdo1 = null;
28+
29+
$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt');
30+
31+
$expectedValue = (int)$pdo2
32+
->query('show log_min_duration_statement;')
33+
->fetchColumn(0);
34+
35+
echo "defaultValue: {$defaultValue}\n";
36+
echo "setValue: {$setValue}\n";
37+
echo "expectedValue: {$expectedValue}\n";
38+
39+
?>
40+
--EXPECT--
41+
defaultValue: -1
42+
setValue: 0
43+
expectedValue: -1
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Persistent connections: session state reset when performing disconnect-equivalent processing (advisory lock case)
3+
--EXTENSIONS--
4+
pdo_pgsql
5+
--SKIPIF--
6+
<?php
7+
require __DIR__ . '/config.inc';
8+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
9+
PDOTest::skip();
10+
?>
11+
--FILE--
12+
<?php
13+
putenv('PDOTEST_ATTR='.serialize([PDO::ATTR_PERSISTENT => true]));
14+
15+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
16+
17+
$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt');
18+
19+
$lockResult1 = (bool)$pdo1
20+
->query('select pg_try_advisory_lock(42)::int;')
21+
->fetchColumn(0);
22+
23+
$pdo1 = null;
24+
25+
$dsn = getenv('PDO_PGSQL_TEST_DSN');
26+
$dsn .= ';';
27+
putenv('PDO_PGSQL_TEST_DSN='.$dsn);
28+
29+
$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt');
30+
31+
$lockResult2 = (bool)$pdo2
32+
->query('select pg_try_advisory_lock(42)::int;')
33+
->fetchColumn(0);
34+
35+
echo "lock1: " . ($lockResult1 ? 'success' : 'failure') . "\n";
36+
echo "lock2: " . ($lockResult2 ? 'success' : 'failure') . "\n";
37+
38+
?>
39+
--EXPECT--
40+
lock1: success
41+
lock2: success

0 commit comments

Comments
 (0)