]> granicus.if.org Git - postgresql/commitdiff
From Zoltan Kovacs back in April (sorry for the delay Zoltan!):
authorThomas G. Lockhart <lockhart@fourpalms.org>
Wed, 25 Oct 2000 14:15:49 +0000 (14:15 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Wed, 25 Oct 2000 14:15:49 +0000 (14:15 +0000)
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).

src/interfaces/odbc/connection.c
src/interfaces/odbc/options.c
src/interfaces/odbc/statement.c

index e3d444997ec32053df0853922ae8f62c0ef4e378..d5b0d12dffed1a651c160afc82ab38c3b9e0d15c 100644 (file)
@@ -947,6 +947,19 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont
                                        case 'E':
                                                SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
                                                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;
                                        }
                                }
@@ -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);
                        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)) {
                                self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
                                CC_set_no_trans(self);
+                               QR_set_status(res, PGRES_FATAL_ERROR);
                        }
-                       else
+                       else {
                                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 */
                        SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN);
index eb67dd590faecf20be952ab804fccbb7caba9d8b..217f063338ebde0622bf413bf0c82a8a05659726 100644 (file)
@@ -330,6 +330,15 @@ int i;
                switch(vParam) {
                case SQL_AUTOCOMMIT_OFF:
                        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;
 
                case SQL_AUTOCOMMIT_ON:
index 95c9e8986e7f6148bad61d45a1eb869bd75791ef..0fac4d6bc089fca1844f25bb36f8ef2b34c9e80a 100644 (file)
@@ -748,8 +748,14 @@ QueryInfo qi;
        /*      Begin a transaction if one is not already in progress */
        /*      The reason is because we can't use declare/fetch cursors without
                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);
                res = CC_send_query(conn, "BEGIN", NULL);
@@ -826,11 +832,14 @@ QueryInfo qi;
                self->result = CC_send_query(conn, self->stmt_with_params, NULL);
 
                /*      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);
            QR_Destructor(res);
            CC_set_no_trans(conn);
-               }
+               }*/             
 
        }
 
@@ -889,10 +898,12 @@ QueryInfo qi;
        if (self->errornumber == STMT_OK)
                return SQL_SUCCESS;
 
-       else if (self->errornumber == STMT_INFO_ONLY)
-               return SQL_SUCCESS_WITH_INFO;
-
        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);
                return SQL_ERROR;
        }