Commit c404d91c authored by Thomas G. Lockhart's avatar Thomas G. Lockhart

From Zoltan Kovacs back in April (sorry for the delay Zoltan!):

I modified the current ODBC driver for

* referential integrity error reporting,
* SELECT in transactions and
* disabling autocommit.

I tested these changes with Borland C++ Builder -> ODBCExpress ->
WinODBC driver (DLL) -> Postgres 7.0beta1 and Borland C++ Builder -> BDE ->
WinODBC driver (DLL) -> Postgres 7.0beta1. The patch is based on snapshot of
22th April (I don't think that someone has modified it since that: Byron
hasn't gave any sign of living for about a month and I didn't find any
comments about the ODBC driver on the list).
parent 48f04908
...@@ -947,6 +947,19 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont ...@@ -947,6 +947,19 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont
case 'E': case 'E':
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
qlog("ERROR from backend during clear: '%s'\n", cmdbuffer); qlog("ERROR from backend during clear: '%s'\n", cmdbuffer);
/* We must report this type of error as well
(practically for reference integrity violation
error reporting, from PostgreSQL 7.0).
(Zoltan Kovacs, 04/26/2000)
*/
self->errormsg = cmdbuffer;
if ( ! strncmp(self->errormsg, "FATAL", 5)) {
self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
CC_set_no_trans(self);
}
else
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
QR_set_status(res, PGRES_NONFATAL_ERROR);
break; break;
} }
} }
...@@ -1001,14 +1014,20 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont ...@@ -1001,14 +1014,20 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont
mylog("send_query: 'E' - %s\n", self->errormsg); mylog("send_query: 'E' - %s\n", self->errormsg);
qlog("ERROR from backend during send_query: '%s'\n", self->errormsg); qlog("ERROR from backend during send_query: '%s'\n", self->errormsg);
/* We should report that an error occured. Zoltan */
res = QR_Constructor();
if ( ! strncmp(self->errormsg, "FATAL", 5)) { if ( ! strncmp(self->errormsg, "FATAL", 5)) {
self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
CC_set_no_trans(self); CC_set_no_trans(self);
QR_set_status(res, PGRES_FATAL_ERROR);
} }
else else {
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
QR_set_status(res, PGRES_NONFATAL_ERROR);
}
return NULL; return res; /* instead of NULL. Zoltan */
case 'P' : /* get the Portal name */ case 'P' : /* get the Portal name */
SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN);
......
...@@ -330,6 +330,15 @@ int i; ...@@ -330,6 +330,15 @@ int i;
switch(vParam) { switch(vParam) {
case SQL_AUTOCOMMIT_OFF: case SQL_AUTOCOMMIT_OFF:
CC_set_autocommit_off(conn); CC_set_autocommit_off(conn);
/* The following two lines are new.
With this modification the SELECT statements
are also included in the transactions.
Error handling should be written,
this is missing yet, see
SC_execute in statement.c for details. Zoltan
*/
CC_send_query(conn,"BEGIN",NULL);
CC_set_in_trans(conn);
break; break;
case SQL_AUTOCOMMIT_ON: case SQL_AUTOCOMMIT_ON:
......
...@@ -748,8 +748,14 @@ QueryInfo qi; ...@@ -748,8 +748,14 @@ QueryInfo qi;
/* Begin a transaction if one is not already in progress */ /* Begin a transaction if one is not already in progress */
/* The reason is because we can't use declare/fetch cursors without /* The reason is because we can't use declare/fetch cursors without
starting a transaction first. starting a transaction first.
A transaction should be begun if and only if
we use declare/fetch and the statement is SELECT.
We assume that the Postgres backend has an autocommit
feature as default. (Zoltan Kovacs, 04/26/2000)
*/ */
if ( ! self->internal && ! CC_is_in_trans(conn) && (globals.use_declarefetch || STMT_UPDATE(self))) { // if ( ! self->internal && ! CC_is_in_trans(conn) && (globals.use_declarefetch || STMT_UPDATE(self))) {
if ( ! self->internal && ! CC_is_in_trans(conn) && globals.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) {
mylog(" about to begin a transaction on statement = %u\n", self); mylog(" about to begin a transaction on statement = %u\n", self);
res = CC_send_query(conn, "BEGIN", NULL); res = CC_send_query(conn, "BEGIN", NULL);
...@@ -826,11 +832,14 @@ QueryInfo qi; ...@@ -826,11 +832,14 @@ QueryInfo qi;
self->result = CC_send_query(conn, self->stmt_with_params, NULL); self->result = CC_send_query(conn, self->stmt_with_params, NULL);
/* If we are in autocommit, we must send the commit. */ /* If we are in autocommit, we must send the commit. */
if ( ! self->internal && CC_is_in_autocommit(conn) && STMT_UPDATE(self)) { /* No, we shouldn't. Postgres backend does the
autocommit if neccessary. (Zoltan, 04/26/2000)
*/
/* if ( ! self->internal && CC_is_in_autocommit(conn) && STMT_UPDATE(self)) {
res = CC_send_query(conn, "COMMIT", NULL); res = CC_send_query(conn, "COMMIT", NULL);
QR_Destructor(res); QR_Destructor(res);
CC_set_no_trans(conn); CC_set_no_trans(conn);
} }*/
} }
...@@ -889,10 +898,12 @@ QueryInfo qi; ...@@ -889,10 +898,12 @@ QueryInfo qi;
if (self->errornumber == STMT_OK) if (self->errornumber == STMT_OK)
return SQL_SUCCESS; return SQL_SUCCESS;
else if (self->errornumber == STMT_INFO_ONLY)
return SQL_SUCCESS_WITH_INFO;
else { else {
// Modified, 04/29/2000, Zoltan
if (self->errornumber == STMT_INFO_ONLY)
self->errormsg = "Error while executing the query (non-fatal)";
else
self->errormsg = "Unknown error";
SC_log_error(func, "", self); SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment