summaryrefslogtreecommitdiff
path: root/ext/pdo_pgsql/pgsql_statement.c
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2005-12-17 17:59:05 +0000
committerIlia Alshanetsky <iliaa@php.net>2005-12-17 17:59:05 +0000
commitc2ed71a8795567622b582f456af4148a7b54ae22 (patch)
tree6a9b3a90d3b08d1583fd639e332f017dde6d64fc /ext/pdo_pgsql/pgsql_statement.c
parent94518ca8e4c385f8664fec7c63499dbc598f6268 (diff)
downloadphp-git-c2ed71a8795567622b582f456af4148a7b54ae22.tar.gz
Retry on failed prepare resulting from duplicate statement name.
Diffstat (limited to 'ext/pdo_pgsql/pgsql_statement.c')
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index aaf3664b6b..441ebd39ae 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -126,7 +126,8 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
if (S->stmt_name) {
/* using a prepared statement */
- if (!stmt->executed) {
+ if (!S->is_prepared) {
+stmt_retry:
/* we deferred the prepare until now, because we didn't
* know anything about the parameter types; now we do */
S->result = PQprepare(H->server, S->stmt_name, S->query,
@@ -137,12 +138,31 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
case PGRES_COMMAND_OK:
case PGRES_TUPLES_OK:
/* it worked */
+ S->is_prepared = 1;
PQclear(S->result);
break;
- default:
- pdo_pgsql_error_stmt(stmt, status,
- pdo_pgsql_sqlstate(S->result));
- return 0;
+ default: {
+ char *sqlstate = pdo_pgsql_sqlstate(S->result);
+ /* 42P05 means that the prepared statement already existed. this can happen if you use
+ * a connection pooling software line pgpool which doesn't close the db-connection once
+ * php disconnects. if php dies (no chanche to run RSHUTDOWN) during execution it has no
+ * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
+ * deallocate it and retry ONCE (thies 2005.12.15)
+ */
+ if (!strcmp(sqlstate, "42P05")) {
+ char buf[100]; /* stmt_name == "pdo_pgsql_cursor_%08x" */
+ PGresult *res;
+ snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
+ res = PQexec(H->server, buf);
+ if (res) {
+ PQclear(res);
+ }
+ goto stmt_retry;
+ } else {
+ pdo_pgsql_error_stmt(stmt, status, sqlstate);
+ return 0;
+ }
+ }
}
}
S->result = PQexecPrepared(H->server, S->stmt_name,