From f52fb4833538265055332da8e4d1ff68515ad683 Mon Sep 17 00:00:00 2001 From: mpyw Date: Fri, 19 Nov 2021 01:14:55 +0900 Subject: [PATCH] Fix restoring PDO::ATTR_ERRMODE after PDO::lastInsertId() call failed (#1330) --- source/pdo_sqlsrv/pdo_dbh.cpp | 3 ++ ...restore_original_errmode_after_failed.phpt | 52 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 test/functional/pdo_sqlsrv/pdo_lastInsertId_restore_original_errmode_after_failed.phpt diff --git a/source/pdo_sqlsrv/pdo_dbh.cpp b/source/pdo_sqlsrv/pdo_dbh.cpp index bddbd542..ddd5ca5e 100644 --- a/source/pdo_sqlsrv/pdo_dbh.cpp +++ b/source/pdo_sqlsrv/pdo_dbh.cpp @@ -1598,6 +1598,9 @@ zend_string * pdo_sqlsrv_dbh_last_id(_Inout_ pdo_dbh_t *dbh, _In_ const zend_str driver_stmt->~sqlsrv_stmt(); } catch( core::CoreException& ) { + // restore error handling to its previous mode + dbh->error_mode = prev_err_mode; + // copy any errors on the statement to the connection so that the user sees them, since the statement is released // before this method returns strcpy_s( dbh->error_code, sizeof( dbh->error_code ), diff --git a/test/functional/pdo_sqlsrv/pdo_lastInsertId_restore_original_errmode_after_failed.phpt b/test/functional/pdo_sqlsrv/pdo_lastInsertId_restore_original_errmode_after_failed.phpt new file mode 100644 index 00000000..700c20c7 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_lastInsertId_restore_original_errmode_after_failed.phpt @@ -0,0 +1,52 @@ +--TEST-- +Confirm that PDO::ATTR_ERRMODE value should be restored whether PDO::lastInsertId() call succeeded or not. +--SKIPIF-- + +--FILE-- + "int")); + createTable($conn, "table2", array(new columnMeta("int", "id", "IDENTITY(200,2)"), "val" => "int")); + createTable($conn, "table3", array("id" => "int", "val" => "int")); + + insertRow($conn, "table1", array("val" => 1), "exec"); + insertRow($conn, "table2", array("val" => 2), "exec"); + $conn->lastInsertId(); + var_dump($conn->getAttribute(PDO::ATTR_ERRMODE)); + + insertRow($conn, "table2", array("val" => 3), "exec"); + insertRow($conn, "table1", array("val" => 4), "exec"); + $conn->lastInsertId(); + var_dump($conn->getAttribute(PDO::ATTR_ERRMODE)); + + // Should restore original value even if PDO::lastInsertId() failed. + insertRow($conn, "table3", array("id" => 1, "val" => 1), "exec"); + $conn->lastInsertId(); + var_dump($conn->getAttribute(PDO::ATTR_ERRMODE)); + + dropTable($conn, "table1"); + dropTable($conn, "table2"); + dropTable($conn, "table3"); + + // Should trigger exception + $tsql = "SELECT * FROM dummy"; + $conn->exec($tsql); + + unset($conn); +} catch (PDOException $e) { + print_r($e->getMessage()); + exit; +} + + +?> +--EXPECTREGEX-- +int\(2\) +int\(2\) +int\(2\) +.*Invalid object name \'dummy\'\.