diff options
author | Anatol Belski <ab@php.net> | 2016-08-14 19:33:24 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2016-08-14 19:33:24 +0200 |
commit | 977cbc2fff1a3ec9d29a2c0904fae01bfd64c6c2 (patch) | |
tree | 888036771ece2b24d00feef56c3101af8f6fae0e /ext/pdo_pgsql/pgsql_driver.c | |
parent | 9f1d962ed6057a3996f1b5aa82467a3172e41e8f (diff) | |
download | php-git-977cbc2fff1a3ec9d29a2c0904fae01bfd64c6c2.tar.gz |
Fixed bug #72759 Regression in pgo_pgsql
This is caused by the fix for #72633. Namely, lastval() throws an error,
if no nextval() was called earlier in the same session. This is by all
means correct so far, however inside a transaction it leads to an abort.
This is the opposite to MySQL's last_insert_id() which doesn't produce
any error no matter something were autoincremented or not.
To avoid existing scripts breakage in the stable branches, the previous
patch is extended to revert the transaction to the state before the lastval()
call in case of error. It is done only for 5.6 and 7.0 to retain BC. For 7.1+,
the clean behavior should persist. This is already the current behavior, when
the sequence name is explicitly passed. So there's no reason to obfuscate the
errors where this breakage is valid.
Diffstat (limited to 'ext/pdo_pgsql/pgsql_driver.c')
-rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 5b78bcc438..b27753b47f 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -360,8 +360,15 @@ static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned char *id = NULL; PGresult *res; ExecStatusType status; + zend_bool savepoint = 0; if (name == NULL) { + savepoint = pgsql_handle_in_transaction(dbh); + + if (savepoint) { + /* The savepoint is overwritten every time. */ + (void)PQexec(H->server, "SAVEPOINT _php_lastid_savepoint"); + } res = PQexec(H->server, "SELECT LASTVAL()"); } else { const char *q[1]; @@ -375,10 +382,17 @@ static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned id = estrdup((char *)PQgetvalue(res, 0, 0)); *len = PQgetlength(res, 0, 0); } else { + if (savepoint) { + (void)PQexec(H->server, "ROLLBACK TO SAVEPOINT _php_lastid_savepoint"); + } pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res)); *len = spprintf(&id, 0, "%ld", (long) H->pgoid); } + if (savepoint) { + (void)PQexec(H->server, "RELEASE SAVEPOINT _php_lastid_savepoint"); + } + if (res) { PQclear(res); } |