php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37870 Deallocation of prepared statement that hasn't been allocated under postgresql
Submitted: 2006-06-21 07:52 UTC Modified: 2006-09-19 15:46 UTC
Votes:7
Avg. Score:4.4 ± 0.9
Reproduced:7 of 7 (100.0%)
Same Version:5 (71.4%)
Same OS:3 (42.9%)
From: sagi at adamnet dot co dot il Assigned:
Status: Closed Package: PDO related
PHP Version: CVS OS: Debian Sarge
Private report: No CVE-ID: None
 [2006-06-21 07:52 UTC] sagi at adamnet dot co dot il
Description:
------------
Using PHP 5.1.4 to connect to a postgresql 8.1.4 database, native prepared statements.

When allocating a prepared statement and then trying to unset it, PDO attemps to deallocate it even if it never been used (eg. when running a query against an empty set).

PDO does not throw an exception in such case, but an error such as:
ERROR:  prepared statement "pdo_pgsql_stmt_085b2f2c" does not exist

Appers in the server log.

When running inside a transaction, such error aborts it.

Reproduce code:
---------------
$pdo->beginTransaction();

$stmt = $pdo->prepare("SELECT 'never executed'");
unset($stmt);

$res = $pdo->query('SELECT 123');


Actual result:
--------------
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[25P02]: In failed sql transaction: 7 ERROR:  current transaction is aborted, commands ignored until end of transaction block' in XXX:13
Stack trace:
#0 XXX: PDO->query('SELECT 123')


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-08-02 14:18 UTC] iliaa@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip

Appears to work fine (at least for me) in latest CVS.
 [2006-08-10 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2006-08-20 10:01 UTC] sagi at adamnet dot co dot il
Same with the latest CVS version:

sagi@future:~/XXX/tmp$ /usr/local/php5-dev/bin/php -v
PHP 5.2.0RC3-dev (cli) (built: Aug 20 2006 12:46:20)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies
sagi@future:~/XXX/tmp$ /usr/local/php5-dev/bin/php preptest.php
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[25P02]: In failed sql transaction: 7 ERROR:  current transaction is aborted, commands ignored until end of transaction block' in /home/XXX/tmp/preptest.php:13
Stack trace:
#0 /home/XXX/tmp/preptest.php(13): PDO->query('SELECT 123')
#1 {main}
  thrown in /home/XXX/tmp/preptest.php on line 13

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[25P02]: In failed sql transaction: 7 ERROR:  current transaction is aborted, commands ignored until end of transaction block' in /home/XXX/tmp/preptest.php:13
Stack trace:
#0 /home/XXX/tmp/preptest.php(13): PDO->query('SELECT 123')
#1 {main}
  thrown in /home/XXX/tmp/preptest.php on line 13
sagi@future:~/XXX/tmp$
 [2006-08-30 08:06 UTC] ce at netage dot bg
I would suggest the following patch:

--- pgsql_statement.c~  2006-08-30 10:54:31.000000000 +0300
+++ pgsql_statement.c   2006-08-30 10:54:31.000000000 +0300
@@ -60,10 +60,13 @@ static int pgsql_stmt_dtor(pdo_stmt_t *s
                char *q = NULL;
                PGresult *res;

-               spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
-               res = PQexec(H->server, q);
-               efree(q);
-               if (res) PQclear(res);
+                if (S->is_prepared)
+                {
+                  spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
+                  res = PQexec(H->server, q);
+                  efree(q);
+                  if (res) PQclear(res);
+                }
                efree(S->stmt_name);
                S->stmt_name = NULL;
        }
 [2006-08-31 16:56 UTC] konstantin dot ryabitsev at mcgill dot ca
Transaction failing quietly for no reason is a pretty nasty bug. We have just spent several hours troubleshooting this problem, and I can confirm that the bug is 100% on target. If a prepared transaction is never executed, the transaction will quietly fail.
 [2006-09-19 15:46 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2018-04-21 16:56 UTC] aksuska at esoteritech dot com
I am experiencing the exact same problem: PDO deallocating a prepared statement that is never called causes PostgreSQL error but PDO does not capture either the deallocation error nor the transaction commit error so it causes a silent fail. This is in PHP 5.6.31 on CentOS. Curiously I do not experience this problem with 5.6.32 on MAMP/Mac OS X.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 06:01:30 2024 UTC