diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2017-02-04 15:19:41 +0000 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2017-02-04 15:19:41 +0000 |
commit | 9054eeccc0460908865e5462973fd82c148a9315 (patch) | |
tree | 62a6c7f636b8c34344e2ede9486c36aba4ac82dc /psycopg/connection_int.c | |
parent | 665e9dc665cf72086c00871756c48e8d38bade2f (diff) | |
download | psycopg2-9054eeccc0460908865e5462973fd82c148a9315.tar.gz |
Set default_transaction_* GUC if session state is changed in autocomit
Diffstat (limited to 'psycopg/connection_int.c')
-rw-r--r-- | psycopg/connection_int.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 0cb4cf3..e6906eb 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -41,7 +41,7 @@ const char *srv_isolevels[] = { "REPEATABLE READ", "SERIALIZABLE", "READ UNCOMMITTED", - "" /* default */ + "default" /* only to set GUC, not for BEGIN */ }; /* Read only false, true */ @@ -58,6 +58,15 @@ const char *srv_deferrable[] = { "" /* default */ }; +/* On/Off/Default GUC states + */ +const char *srv_state_guc[] = { + "off", + "on", + "default" +}; + + /* Return a new "string" from a char* from the database. * * On Py2 just get a string, on Py3 decode it in the connection codec. @@ -1186,6 +1195,10 @@ RAISES_NEG int conn_set_session(connectionObject *self, int autocommit, int isolevel, int readonly, int deferrable) { + int rv = -1; + PGresult *pgres = NULL; + char *error = NULL; + /* Promote an isolation level to one of the levels supported by the server */ if (self->server_version < 80000) { if (isolevel == ISOLATION_LEVEL_READ_UNCOMMITTED) { @@ -1199,19 +1212,75 @@ conn_set_session(connectionObject *self, int autocommit, Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); + if (autocommit) { + /* we are in autocommit state, so no BEGIN will be issued: + * configure the session with the characteristics requested */ + if (isolevel != self->isolevel) { + if (0 > pq_set_guc_locked(self, + "default_transaction_isolation", srv_isolevels[isolevel], + &pgres, &error, &_save)) { + goto endlock; + } + } + if (readonly != self->readonly) { + if (0 > pq_set_guc_locked(self, + "default_transaction_read_only", srv_state_guc[readonly], + &pgres, &error, &_save)) { + goto endlock; + } + } + if (deferrable != self->deferrable && self->server_version >= 90100) { + if (0 > pq_set_guc_locked(self, + "default_transaction_deferrable", srv_state_guc[deferrable], + &pgres, &error, &_save)) { + goto endlock; + } + } + } + else if (self->autocommit) { + /* we are moving from autocommit to not autocommit, so revert the + * characteristics to defaults to let BEGIN do its work */ + if (0 > pq_set_guc_locked(self, + "default_transaction_isolation", "default", + &pgres, &error, &_save)) { + goto endlock; + } + if (0 > pq_set_guc_locked(self, + "default_transaction_read_only", "default", + &pgres, &error, &_save)) { + goto endlock; + } + if (self->server_version >= 90100) { + if (0 > pq_set_guc_locked(self, + "default_transaction_deferrable", "default", + &pgres, &error, &_save)) { + goto endlock; + } + } + } + + self->autocommit = autocommit; self->isolevel = isolevel; self->readonly = readonly; self->deferrable = deferrable; - self->autocommit = autocommit; + rv = 0; +endlock: pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; + if (rv < 0) { + pq_complete_error(self, &pgres, &error); + goto exit; + } + Dprintf( "conn_set_session: autocommit %d, isolevel %d, readonly %d, deferrable %d", autocommit, isolevel, readonly, deferrable); - return 0; + +exit: + return rv; } |