Bug #78196 [Opn]: PDOStatement::errorInfo() gives incorrect output
| From: | cmb@php.net | Date: | Tue, 29 Sep 2020 14:49:26 +0000 |
| Subject: | Bug #78196 [Opn]: PDOStatement::errorInfo() gives incorrect output | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-229268@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78196&edit=1
ID: 78196
Updated by: cmb@php.net
Reported by: dpuglielli at magnitude dot com
Summary: PDOStatement::errorInfo() gives incorrect output
Status: Open
Type: Bug
Package: PDO ODBC
Operating System: Windows 10
PHP Version: 7.3.6
Block user comment: N
Private report: N
New Comment:
This looks like a bug to me. Having the former status as fourth
element would be okay, but the driver specific error code and
message (second and third) need to match, but apparently don't:
Array
(
[0] => 00000
[1] => 0
[2] => [Microsoft][ODBC Driver 17 for SQL Server]Cursor type changed (SQLExecute[0] at
ext\pdo_odbc\odbc_stmt.c:254)
[3] => 01S02
)
Unfortunately, the test script is no longer available.
Previous Comments:
------------------------------------------------------------------------
[2019-06-22 00:39:05] daverandom@php.net
It's worth noting that the general PDO documentation is lowest common denominator, it defines
the minimum common behaviour for all drivers but may be extended if a particular driver has a need
to do so. In the case of PDOStatement::$errorInfo it would be more accurate to say that the result
will always contain *at least* those 3 elements, I have updated the docs
accordinglyâ½Â¹â¾.
Whether this is a bug is debatable - I can certainly see why it could be considered incorrect, but
it's also not definitely wrong either...
I'm not 100% on this, however I don't think 01S02 is a standard SQLSTATE value. It seems
to be in common usage - I found documentation from both MSâ½Â²â¾ and IBMâ½Â³â¾
which references it - but it is not included in the Wikipedia entryâ½â´â¾ or any other
generic/implementation independent documentation that I could find with a 5 minute Google. Since I
do not own a copy of ISO:9075 and don't have a spare CHF178 lying around I cannot confirm this
for sure. If it is non-standard, or indeed if there are other circumstances where ODBC may emit
non-standard values, this may be the reason for the current behaviour - the PDO documentation
explicitly states that this first element will be an ISO standard SQLSTATE code.
Regardless, the existing behaviour is arguably "better" than documented. Note that the
info returned on the first iteration of your test does in fact have the "correct" value
for the first element - it's only subsequent iterations where there's a discrepancy -
because it pertains to the previous operation. The later values are correctly reporting the previous
operation was successful because in those cases the previous operation was fetching a row, which
succeeded. By providing the SQLSTATE of the previous *query execution operation* in the additional
element, code can be structured such that the data is processed before errors without the need for
boilerplate code to store the error data in temporary var etc. While I wouldn't design code
like this myself, I can see why it might be desirable in some circumstances.
I will leave this bug open for now but I don't personally think this needs "fixing"
since it gives a bit of flexibility and it's not incompatible with the documented behaviour.
Perhaps the documentation for the PDO ODBC driver should be updated instead?
[1] https://svn.php.net/viewvc?view=revision&revision=347629
[2] https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecute-function
[3] https://www.ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/odbc/src/tpc/db2z_hdtab.html
[4] https://en.wikipedia.org/wiki/SQLSTATE
------------------------------------------------------------------------
[2019-06-21 22:06:53] dpuglielli at magnitude dot com
Description:
------------
Calling PDOStatement::errorInfo with the results of a batched query and a non-forward cursor yields
a four element array, with the fourth element as another SQLSTATE. This is not consistent with the
documentation, which states that there are three fields in this array (according to https://www.php.net/manual/en/pdostatement.errorinfo.php).
Moreover, the first element is an incorrect SQLSTATE.
The problem appears to lie in line 49 of ext/pdo_odbc/odbc_driver.c in pdo_odbc_fetch_error_func(),
where the three elements of the error array are populated. This occurs after an error code has
already been added in line 1678 of ext/pdo/pdo_stmt.c, producing four elements instead of three.
Test script:
---------------
https://github.com/david-puglielli/msphpsql/blob/pdo-errorinfo-bug/test/functional/pdo_sqlsrv/pdo_errorinfo_bug.phpt
Expected result:
----------------
The output of errorInfo() should have three elements. The first element should correctly correspond
to the diagnostic message in the third element, like so:
Array
(
[0] => 01S02
[1] => 0
[2] => [Microsoft][ODBC Driver 17 for SQL Server]Cursor type changed (SQLExecute[0] at
ext\pdo_odbc\odbc_stmt.c:254)
)
Actual result:
--------------
The output of the provided test script is as follows:
Database error info:
Array
(
[0] => 00000
[1] =>
[2] =>
)
Statement error info:
Array
(
[0] => 01S02
[1] => 0
[2] => [Microsoft][ODBC Driver 17 for SQL Server]Cursor type changed (SQLExecute[0] at
ext\pdo_odbc\odbc_stmt.c:254)
[3] => 01S02
)
Array
(
[0] => 00000
[1] => 0
[2] => [Microsoft][ODBC Driver 17 for SQL Server]Cursor type changed (SQLExecute[0] at
ext\pdo_odbc\odbc_stmt.c:254)
[3] => 01S02
)
Array
(
[0] => 00000
[1] => 0
[2] => [Microsoft][ODBC Driver 17 for SQL Server]Cursor type changed (SQLExecute[0] at
ext\pdo_odbc\odbc_stmt.c:254)
[3] => 01S02
)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78196&edit=1