summaryrefslogtreecommitdiff
path: root/options.c
diff options
context:
space:
mode:
authorHiroshi Inoue2016-10-18 12:04:38 +0000
committerHiroshi Inoue2016-10-18 12:04:38 +0000
commit7849ba3d632d14cda929418d52859c5375ed02dc (patch)
treee1053ccc0a7c1b424b9d2c1ab033f4203603c373 /options.c
parent0f70eb058428527dde9ed249a86528f39f9c720a (diff)
Allow setting isolation level before the establishment of connection.
Diffstat (limited to 'options.c')
-rw-r--r--options.c78
1 files changed, 20 insertions, 58 deletions
diff --git a/options.c b/options.c
index da6aef0..9812ed4 100644
--- a/options.c
+++ b/options.c
@@ -372,7 +372,7 @@ PGAPI_SetConnectOption(HDBC hdbc,
#ifdef _HANDLE_ENLIST_IN_DTC_
if (CC_is_in_global_trans(conn))
{
- CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Don't change AUTOCOMMIT mode in a distributed transaction", func);
+ CC_set_error(conn, CONN_ILLEGAL_TRANSACT_STATE, "Don't change AUTOCOMMIT mode in a distributed transaction", func);
return SQL_ERROR;
}
#endif /* _HANDLE_ENLIST_IN_DTC_ */
@@ -393,73 +393,35 @@ PGAPI_SetConnectOption(HDBC hdbc,
break;
case SQL_TXN_ISOLATION:
- retval = SQL_SUCCESS;
if (conn->isolation == vParam)
break;
- switch (vParam)
- {
- case SQL_TXN_SERIALIZABLE:
- break;
- case SQL_TXN_REPEATABLE_READ:
- if (PG_VERSION_LT(conn, 8.0))
- retval = SQL_ERROR;
- break;
- case SQL_TXN_READ_COMMITTED:
- break;
- case SQL_TXN_READ_UNCOMMITTED:
- if (PG_VERSION_LT(conn, 8.0))
- retval = SQL_ERROR;
- break;
- default:
- retval = SQL_ERROR;
- }
- if (SQL_ERROR == retval)
+ /*
+ * If the connection is not established, just record the setting to
+ * reflect it upon connection.
+ */
+ if (conn->status == CONN_NOT_CONNECTED || conn->status == CONN_DOWN)
{
- CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_TXN_ISOLATION", func);
- return SQL_ERROR;
+ conn->isolation = (UInt4) vParam;
+ conn->isolation_set_delay = 1;
+ break;
}
- else
- {
- char *query;
- QResultClass *res;
- if (CC_is_in_trans(conn))
- {
- if (CC_does_autocommit(conn) && !CC_is_in_error_trans(conn))
- CC_commit(conn);
- else
- {
- CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Cannot switch isolation level while a transaction is in progress", func);
- return SQL_ERROR;
- }
- }
- switch (vParam)
- {
- case SQL_TXN_SERIALIZABLE:
- query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE";
- break;
- case SQL_TXN_REPEATABLE_READ:
- query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ";
- break;
- case SQL_TXN_READ_UNCOMMITTED:
- query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
- break;
- default:
- query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED";
- break;
- }
- res = CC_send_query(conn, query, NULL, 0, NULL);
- if (!QR_command_maybe_successful(res))
- retval = SQL_ERROR;
+ /* The ODBC spec prohibits changing the isolation level while in manual transaction. */
+ if (CC_is_in_trans(conn))
+ {
+ if (CC_does_autocommit(conn) && !CC_is_in_error_trans(conn))
+ CC_commit(conn);
else
- conn->isolation = (UInt4) vParam;
- QR_Destructor(res);
- if (SQL_ERROR == retval)
{
- CC_set_error(conn, CONN_EXEC_ERROR, "ISOLATION change request to the server error", func);
+ CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Cannot switch isolation level while a transaction is in progress", func);
return SQL_ERROR;
}
}
+
+ if (!CC_set_transact(conn, (UInt4) vParam))
+ return SQL_ERROR;
+
+ conn->isolation = (UInt4) vParam;
break;
/* These options should be handled by driver manager */