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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sagi at adamnet dot co dot il
New email:
PHP Version: OS:

 

 [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

Pull Requests

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: Thu Nov 21 11:01:29 2024 UTC