Skip to content

Commit ec79850

Browse files
thomasschietdevnexen
authored andcommitted
Fix GH-21683: PDOStatement::fetch() throws on empty result With PDO::ATTR_FETCH attribute.
close GH-21684.
1 parent 9c6ec37 commit ec79850

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ PHP NEWS
4343
. Fix memory leak regression in openssl_pbkdf2(). (ndossche)
4444
. Fix a bunch of memory leaks and crashes on edge cases. (ndossche)
4545

46+
- PDO_PGSQL:
47+
. Fixed bug GH-21683 (pdo_pgsql throws with ATTR_PREFETCH=0
48+
on empty result set). (thomasschiet)
49+
4650
- Random:
4751
. Fixed bug GH-21731 (Random\Engine\Xoshiro256StarStar::__unserialize()
4852
accepts all-zero state). (iliaal)

ext/pdo_pgsql/pgsql_statement.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,12 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
573573
}
574574

575575
S->result = PQgetResult(S->H->server);
576+
if (!S->result) {
577+
S->is_running_unbuffered = false;
578+
stmt->row_count = 0;
579+
S->current_row = 0;
580+
return 0;
581+
}
576582
status = PQresultStatus(S->result);
577583

578584
if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK && status != PGRES_SINGLE_TUPLE) {

ext/pdo_pgsql/tests/gh21683.phpt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
PDO PgSQL single-row mode (ATTR_PREFETCH=0) on empty result set
3+
--EXTENSIONS--
4+
pdo
5+
pdo_pgsql
6+
--SKIPIF--
7+
<?php
8+
require __DIR__ . '/config.inc';
9+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
10+
PDOTest::skip();
11+
?>
12+
--FILE--
13+
<?php
14+
15+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
16+
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt');
17+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
18+
$pdo->setAttribute(PDO::ATTR_PREFETCH, 0);
19+
20+
$pdo->exec("CREATE TEMP TABLE empty_t (id int, val text)");
21+
22+
echo "=== query / fetch ===\n";
23+
$stmt = $pdo->query("SELECT * FROM empty_t");
24+
var_dump($stmt->fetch());
25+
26+
echo "=== prepare / fetchAll ===\n";
27+
$stmt = $pdo->prepare("SELECT * FROM empty_t");
28+
$stmt->execute();
29+
var_dump($stmt->fetchAll());
30+
31+
echo "=== connection still works ===\n";
32+
$stmt = $pdo->query("SELECT 1 AS alive");
33+
var_dump($stmt->fetch(PDO::FETCH_ASSOC));
34+
35+
echo "Done\n";
36+
?>
37+
--EXPECT--
38+
=== query / fetch ===
39+
bool(false)
40+
=== prepare / fetchAll ===
41+
array(0) {
42+
}
43+
=== connection still works ===
44+
array(1) {
45+
["alive"]=>
46+
string(1) "1"
47+
}
48+
Done

0 commit comments

Comments
 (0)