aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/connection.c')
-rw-r--r--src/interfaces/odbc/connection.c89
1 files changed, 61 insertions, 28 deletions
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index a26913db767..db237b3f952 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -298,8 +298,8 @@ CC_Constructor()
/* Statements under this conn will inherit these options */
InitializeStatementOptions(&rv->stmtOptions);
-
-
+ InitializeARDFields(&rv->ardOptions);
+ InitializeAPDFields(&rv->apdOptions);
}
return rv;
}
@@ -381,8 +381,6 @@ CC_begin(ConnectionClass *self)
{
ret = QR_command_successful(res);
QR_Destructor(res);
- if (ret)
- CC_set_in_trans(self);
}
else
return FALSE;
@@ -403,9 +401,6 @@ CC_commit(ConnectionClass *self)
{
QResultClass *res = CC_send_query(self, "COMMIT", NULL, CLEAR_RESULT_ON_ABORT);
mylog("CC_commit: sending COMMIT!\n");
-
- CC_set_no_trans(self);
-
if (res != NULL)
{
ret = QR_command_successful(res);
@@ -429,9 +424,6 @@ CC_abort(ConnectionClass *self)
{
QResultClass *res = CC_send_query(self, "ROLLBACK", NULL, CLEAR_RESULT_ON_ABORT);
mylog("CC_abort: sending ABORT!\n");
-
- CC_set_no_trans(self);
-
if (res != NULL)
QR_Destructor(res);
else
@@ -1118,6 +1110,23 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
}
+void CC_on_commit(ConnectionClass *conn, BOOL set_no_trans)
+{
+ if (CC_is_in_trans(conn))
+ {
+ if (set_no_trans)
+ CC_set_no_trans(conn);
+ }
+}
+void CC_on_abort(ConnectionClass *conn, BOOL set_no_trans)
+{
+ if (CC_is_in_trans(conn))
+ {
+ if (set_no_trans)
+ CC_set_no_trans(conn);
+ }
+}
+
/*
* The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
* the same existing QResultClass (this occurs when the tuple cache is depleted and
@@ -1134,7 +1143,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
*retres = NULL,
*res = NULL;
BOOL clear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0),
- create_keyset = ((flag & CREATE_KEYSET) != 0);
+ create_keyset = ((flag & CREATE_KEYSET) != 0),
+ issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self));
char swallow,
*wq;
int id;
@@ -1146,7 +1156,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
query_completed = FALSE,
before_64 = PG_VERSION_LT(self, 6.4),
aborted = FALSE,
- used_passed_result_object = FALSE;
+ used_passed_result_object = FALSE,
+ set_no_trans;
/* ERROR_MSG_LENGTH is suffcient */
static char msgbuffer[ERROR_MSG_LENGTH + 1];
@@ -1173,7 +1184,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
{
self->errornumber = CONNECTION_COULD_NOT_SEND;
self->errormsg = "Could not send Query to backend";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
return NULL;
}
@@ -1182,10 +1193,12 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
{
self->errornumber = CONNECTION_COULD_NOT_SEND;
self->errormsg = "Could not send Query to backend";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
return NULL;
}
+ if (issue_begin)
+ SOCK_put_n_char(sock, "begin;", 6);
SOCK_put_string(sock, query);
SOCK_flush_output(sock);
@@ -1193,7 +1206,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
{
self->errornumber = CONNECTION_COULD_NOT_SEND;
self->errormsg = "Could not send Query to backend";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
return NULL;
}
@@ -1230,7 +1243,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
self->errormsg = "No response from the backend";
mylog("send_query: 'id' - %s\n", self->errormsg);
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
ReadyToReturn = TRUE;
retres = NULL;
break;
@@ -1254,7 +1267,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
self->errornumber = CONNECTION_NO_RESPONSE;
self->errormsg = "No response from backend while receiving a portal query command";
mylog("send_query: 'C' - %s\n", self->errormsg);
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
ReadyToReturn = TRUE;
retres = NULL;
}
@@ -1270,6 +1283,24 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer);
+ if (strnicmp(cmdbuffer, "BEGIN", 5) == 0)
+ {
+ CC_set_in_trans(self);
+ if (issue_begin)
+ {
+ issue_begin = FALSE;
+ continue;
+ }
+ }
+ else if (strnicmp(cmdbuffer, "COMMIT", 6) == 0)
+ CC_on_commit(self, TRUE);
+ else if (strnicmp(cmdbuffer, "ROLLBACK", 8) == 0)
+ CC_on_abort(self, TRUE);
+ else if (strnicmp(cmdbuffer, "END", 3) == 0)
+ CC_on_commit(self, TRUE);
+ else if (strnicmp(cmdbuffer, "ABORT", 5) == 0)
+ CC_on_abort(self, TRUE);
+
if (QR_command_successful(res))
QR_set_status(res, PGRES_COMMAND_OK);
QR_set_command(res, cmdbuffer);
@@ -1352,14 +1383,15 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
qlog("ERROR from backend during send_query: '%s'\n", msgbuffer);
/* We should report that an error occured. Zoltan */
-
+ set_no_trans = FALSE;
if (!strncmp(msgbuffer, "FATAL", 5))
{
self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
- CC_set_no_trans(self);
+ set_no_trans = TRUE;
}
else
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
+ CC_on_abort(self, set_no_trans);
QR_set_status(res, PGRES_FATAL_ERROR);
QR_set_message(res, msgbuffer);
QR_set_aborted(res, TRUE);
@@ -1377,9 +1409,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
if (query_completed)
{
res->next = QR_Constructor();
- if (create_keyset)
- QR_set_haskeyset(res->next);
- mylog("send_query: 'T' no result_in: res = %u\n", res->next);
if (!res->next)
{
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
@@ -1388,6 +1417,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
retres = NULL;
break;
}
+ if (create_keyset)
+ QR_set_haskeyset(res->next);
+ mylog("send_query: 'T' no result_in: res = %u\n", res->next);
res = res->next;
if (qi)
@@ -1448,7 +1480,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
default:
self->errornumber = CONNECTION_BACKEND_CRAZY;
self->errormsg = "Unexpected protocol character from backend (send_query)";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
mylog("send_query: error - %s\n", self->errormsg);
ReadyToReturn = TRUE;
@@ -1536,7 +1568,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
{
self->errornumber = CONNECTION_COULD_NOT_SEND;
self->errormsg = "Could not send function to backend";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
return FALSE;
}
@@ -1545,7 +1577,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
{
self->errornumber = CONNECTION_COULD_NOT_SEND;
self->errormsg = "Could not send function to backend";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
return FALSE;
}
@@ -1594,6 +1626,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
case 'E':
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
self->errormsg = msgbuffer;
+ CC_on_abort(self, FALSE);
mylog("send_function(V): 'E' - %s\n", self->errormsg);
qlog("ERROR from backend during send_function: '%s'\n", self->errormsg);
@@ -1606,7 +1639,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
default:
self->errornumber = CONNECTION_BACKEND_CRAZY;
self->errormsg = "Unexpected protocol character from backend (send_function, args)";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
mylog("send_function: error - %s\n", self->errormsg);
return FALSE;
@@ -1640,7 +1673,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
case 'E':
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
self->errormsg = msgbuffer;
-
+ CC_on_abort(self, FALSE);
mylog("send_function(G): 'E' - %s\n", self->errormsg);
qlog("ERROR from backend during send_function: '%s'\n", self->errormsg);
@@ -1661,7 +1694,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
default:
self->errornumber = CONNECTION_BACKEND_CRAZY;
self->errormsg = "Unexpected protocol character from backend (send_function, result)";
- CC_set_no_trans(self);
+ CC_on_abort(self, TRUE);
mylog("send_function: error - %s\n", self->errormsg);
return FALSE;