Bug #44454 [Com]: Unexpected exception thrown in foreach() statement

From: Date: Thu, 03 Jun 2010 18:36:51 +0000
Subject: Bug #44454 [Com]: Unexpected exception thrown in foreach() statement
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-151063@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=44454&edit=1

 ID:               44454
 Comment by:       rgagnon24 at gmail dot com
 Reported by:      mfischer@php.net
 Summary:          Unexpected exception thrown in foreach() statement
 Status:           Verified
 Type:             Bug
 Package:          PDO related
 Operating System: *
 PHP Version:      5.*, 6CVS (2009-04-25)

 New Comment:

From: http://dev.mysql.com/doc/refman/5.0/en/mysql-errno.html

   "Note that some functions like mysql_fetch_row() don't set
mysql_errno() if they succeed."

And: http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html

   "Note that error is not reset between calls to mysql_fetch_row()"
-----------------------------------------------------------------------------
Since all the SELECT'd rows are fetched ok, the error from the botched
insert is still hanging around for mysql_errno() to find, and raise the
exact same exception after the data is finished being iterated.


Previous Comments:
------------------------------------------------------------------------
[2010-06-03 20:03:37] rgagnon24 at gmail dot com

Looking at pdo_mysql extension source code, I see the exception is
actually being raised twice, not being buffered.

from php5.2.13 source, file ext/pdo_mysql/mysql_statement.c is calling
_pdo_mysql_error() in two places.  Once from line 218 in
pdo_mysql_stmt_execute() after mysql_real_query() fails, and then again
at line 425 in pdo_mysql_stmt_fetch() because mysql_errno() indicates
there is an error.

------------------------------------------------------------------------
[2010-05-08 06:08:33] gregory at tiv dot net

Correction:
-----------
if ( $conn->errorCode() ) {

should be

if ( $conn->errorCode() !== '00000' ) {

------------------------------------------------------------------------
[2010-05-07 02:13:48] gregory at tiv dot net

I have a simpler test case, one solution/explanation and one
workaround.
Tested under:
Windows - PHP 5.2.13 (cli) (built: Feb 24 2010 14:32:32)
FreeBSD - PHP 5.2.12 with Suhosin-Patch 0.9.7 (cli) (built: Feb 24 2010
23:12:45)

Demonstration code:
-------------------

<?php
#
# PDO foreach exception bug
# Demonstration code
# Author: Gregory Karpinsky, http://www.tiv.net
# 2010-05-06

print '<p>This code works OK (Exception is cleaned artificially)</p>';
$conn = new PDO( 'mysql:host=localhost', 'test', 'test' );
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$oRS = $conn->query( "select 'OK'" );
foreach ( $oRS as $row ) {
	try {
		$conn->query( 'Bogus SQL' );
	} catch (PDOException $e) {}
	if ( $conn->errorCode() ) {
		$conn->query( "select 'CLEAN_PDO_ERROR'" );
	}
print '<p>NO exception will be thrown.</p>';
}

print '<p>This code works OK (two separate connections)</p>';
$conn = new PDO( 'mysql:host=localhost', 'test', 'test' );
$conn2 = new PDO( 'mysql:host=localhost', 'test', 'test' );
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$oRS = $conn->query( "select 'OK'" );
foreach ( $oRS as $row ) {
	try {
		$conn2->query( 'Bogus SQL' );
	} catch (PDOException $e) {}
print '<p>NO exception will be thrown.</p>';
}


print '<p>This code throws unexpected exception in foreach</p>';
$conn = new PDO( 'mysql:host=localhost', 'test', 'test' );
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$oRS = $conn->query( "select 'OK'" );
foreach ( $oRS as $row ) {
	try {
		$conn->query( 'Bogus SQL' );
	} catch (PDOException $e) {}
print '<p>Exception will be thrown after this...</p>';
}
?>

------------------------------------------------------------------------
[2009-04-25 17:16:14] mfischer@php.net

Using Windows snapshots, verified that the bug still exists in
5.2.10-dev and 5.3.0RC2-dev . Cannot test with 6.0.0-dev, the php.exe
doesn't even properly start.

------------------------------------------------------------------------
[2009-04-25 14:57:23] jani@php.net

Does this still exist? If so, update the version properly.. ;)

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=44454


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=44454&edit=1


Thread (16 messages)

« previous php.bugs (#151063) next »