Commit 78581318c40 for php
commit 78581318c408693bea892607958ff47c6a1ab509
Author: lazerg <lazerg2@gmail.com>
Date: Tue Nov 3 03:25:20 2026 +0800
Fix GH-24990: pdo_sqlite statement unusable after failed execute() (#24991)
Reset the SQLite statement after every failed step, including constraint
failures. Previously only SQLITE_ERROR triggered a reset, leaving a statement
whose first execute() failed unusable for a subsequent execute(). Add a
regression test covering repeated failures and successful retries.
Closes #24991
diff --git a/NEWS b/NEWS
index 0a32ea70a19..309b14f9c04 100644
--- a/NEWS
+++ b/NEWS
@@ -246,6 +246,7 @@ PHP NEWS
out-of-range column index). (Ilia Alshanetsky)
- PDO_SQLite:
+ . Fixed bug GH-24990 (Statement unusable after a failed execute()). (lazerg)
. Fixed bug GH-25021 (SQLite createFunction corrupts large integers).
(mvorisek)
diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c
index 2d79a6d0fc1..8c0d9069ee6 100644
--- a/ext/pdo_sqlite/sqlite_statement.c
+++ b/ext/pdo_sqlite/sqlite_statement.c
@@ -62,11 +62,10 @@ static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt)
return 1;
case SQLITE_ERROR:
- sqlite3_reset(S->stmt);
- ZEND_FALLTHROUGH;
case SQLITE_MISUSE:
case SQLITE_BUSY:
default:
+ sqlite3_reset(S->stmt);
pdo_sqlite_error_stmt(stmt);
return 0;
}
diff --git a/ext/pdo_sqlite/tests/gh24990.phpt b/ext/pdo_sqlite/tests/gh24990.phpt
new file mode 100644
index 00000000000..89bfe35e74b
--- /dev/null
+++ b/ext/pdo_sqlite/tests/gh24990.phpt
@@ -0,0 +1,33 @@
+--TEST--
+GH-24990 (Statement unusable after a failed execute())
+--EXTENSIONS--
+pdo_sqlite
+--FILE--
+<?php
+$db = new PDO('sqlite::memory:', options: [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
+$db->exec('CREATE TABLE test (k TEXT PRIMARY KEY NOT NULL)');
+$db->exec("INSERT INTO test VALUES ('a')");
+
+$stmt = $db->prepare('INSERT INTO test (k) VALUES (?)');
+foreach (['a', 'b', 'b', 'c'] as $k) {
+ try {
+ var_dump($stmt->execute([$k]));
+ } catch (PDOException $e) {
+ echo $e->getMessage(), "\n";
+ }
+}
+var_dump($db->query('SELECT k FROM test ORDER BY k')->fetchAll(PDO::FETCH_COLUMN));
+?>
+--EXPECT--
+SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: test.k
+bool(true)
+SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: test.k
+bool(true)
+array(3) {
+ [0]=>
+ string(1) "a"
+ [1]=>
+ string(1) "b"
+ [2]=>
+ string(1) "c"
+}