@@ -162,6 +162,14 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
162162 /* using a prepared statement */
163163
164164 if (!S -> is_prepared ) {
165+ /* don't break the whole current transaction when the first
166+ * prepare tentative fails (happens when the prepared statement
167+ * already exists). ignore those SAVEPOINT queries results because
168+ * we don't care (may be outside transaction?).
169+ */
170+ char buf [100 ]; /* stmt_name == "pdo_pgsql_cursor_%08x" */
171+ snprintf (buf , sizeof (buf ), "SAVEPOINT %s" , S -> stmt_name );
172+ PQexec (H -> server , buf );
165173stmt_retry :
166174 /* we deferred the prepare until now, because we didn't
167175 * know anything about the parameter types; now we do */
@@ -181,24 +189,30 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
181189 /* 42P05 means that the prepared statement already existed. this can happen if you use
182190 * a connection pooling software line pgpool which doesn't close the db-connection once
183191 * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
184- * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
185- * deallocate it and retry ONCE (thies 2005.12.15)
192+ * chance to DEALLOCATE the prepared statements it has created. Also happens if we tried
193+ * to DEALLOCATE the same statement name in an aborted transaction. so, if we hit a 42P05
194+ * we deallocate it and retry ONCE (thies 2005.12.15)
186195 */
187196 if (!strcmp (sqlstate , "42P05" )) {
188- char buf [100 ]; /* stmt_name == "pdo_crsr_%016lx" */
189197 PGresult * res ;
198+ snprintf (buf , sizeof (buf ), "ROLLBACK TO SAVEPOINT %s" , S -> stmt_name );
199+ PQexec (H -> server , buf );
190200 snprintf (buf , sizeof (buf ), "DEALLOCATE %s" , S -> stmt_name );
191201 res = PQexec (H -> server , buf );
192202 if (res ) {
193203 PQclear (res );
194204 }
195205 goto stmt_retry ;
196206 } else {
207+ snprintf (buf , sizeof (buf ), "RELEASE SAVEPOINT %s" , S -> stmt_name );
208+ PQexec (H -> server , buf );
197209 pdo_pgsql_error_stmt (stmt , status , sqlstate );
198210 return 0 ;
199211 }
200212 }
201213 }
214+ snprintf (buf , sizeof (buf ), "RELEASE SAVEPOINT %s" , S -> stmt_name );
215+ PQexec (H -> server , buf );
202216 }
203217 S -> result = PQexecPrepared (H -> server , S -> stmt_name ,
204218 stmt -> bound_params ?
0 commit comments