mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
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).
This commit is contained in:
@ -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
|
|||||||
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;
|
|||||||
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;
|
|||||||
/* 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;
|
|||||||
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;
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user