summaryrefslogtreecommitdiff
path: root/ext/pdo_pgsql/pgsql_driver.c
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2016-08-14 19:33:24 +0200
committerAnatol Belski <ab@php.net>2016-08-14 19:33:24 +0200
commit977cbc2fff1a3ec9d29a2c0904fae01bfd64c6c2 (patch)
tree888036771ece2b24d00feef56c3101af8f6fae0e /ext/pdo_pgsql/pgsql_driver.c
parent9f1d962ed6057a3996f1b5aa82467a3172e41e8f (diff)
downloadphp-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.c14
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);
}