Re: ODBC and Large Objects, FAQ not working - Mailing list pgsql-interfaces
From | Hiroki Kataoka |
---|---|
Subject | Re: ODBC and Large Objects, FAQ not working |
Date | |
Msg-id | NDBBIKCHILNJOAAPDPKMIECDCAAA.kataoka@interwiz.koganei.tokyo.jp Whole thread Raw |
In response to | Re: ODBC and Large Objects, FAQ not working ("Christian Hang" <christian.hang@gmx.de>) |
Responses |
Re: [INTERFACES] Re: ODBC and Large Objects, FAQ not working
|
List | pgsql-interfaces |
> > Reason of this problem is that PsqlODBC handles the large object without > > transaction. Since PostgreSQL 6.5, the large object must be handled in > > transaction. > > > > To solve, we should insert source code to begin transaction > > into PsqlODBC > > source before calling lo_create and lo_open functions. Also > > should commit > > transaction after calling lo_close too. > > > > Sorry, I have not tested this solution yet. > > > > Is there a driver update in the near future planed, or can you give > me a hint, how I can manage this on my own? I have some > experiences with C, but how to update the current driver in > Windows with the new code is off my limits. I will attach a patch for PsqlODBC 6.40.0007 to solve this problem. This patch also includes another large object patch reported by Sam in this mailing list. I have done short test with this patch. ===== Hiroki Kataoka ===== cur here ===== diff -rc src.v06-40-0007/bind.c src.v06-40-0007.test/bind.c *** src.v06-40-0007/bind.c Fri Jan 8 11:32:46 1999 --- src.v06-40-0007.test/bind.c Wed Dec 8 21:31:35 1999 *************** *** 124,130 **** } if (stmt->parameters[ipar].EXEC_buffer) { ! free(stmt->parameters[ipar].EXEC_buffer); stmt->parameters[ipar].EXEC_buffer = NULL; } --- 124,131 ---- } if (stmt->parameters[ipar].EXEC_buffer) { ! if (stmt->parameters[ipar].SQLType != SQL_LONGVARBINARY) ! free(stmt->parameters[ipar].EXEC_buffer); stmt->parameters[ipar].EXEC_buffer = NULL; } diff -rc src.v06-40-0007/convert.c src.v06-40-0007.test/convert.c *** src.v06-40-0007/convert.c Fri Apr 9 18:47:40 1999 --- src.v06-40-0007.test/convert.c Wed Dec 8 21:36:30 1999 *************** *** 40,45 **** --- 40,46 ---- #include <math.h> #include "convert.h" #include "statement.h" + #include "qresult.h" #include "bind.h" #include "pgtypes.h" #include "lobj.h" *************** *** 895,901 **** --- 896,926 ---- } else { + + /* begin transaction if needed */ + if(!CC_is_in_trans(stmt->hdbc)) { + QResultClass *res; + char ok; + res = CC_send_query(stmt->hdbc, "BEGIN", NULL); + if (!res) { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + + CC_set_in_trans(stmt->hdbc); + } + /* store the oid */ lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); if (lobj_oid == 0) { *************** *** 917,922 **** --- 942,971 ---- retval = lo_write(stmt->hdbc, lobj_fd, buffer, used); lo_close(stmt->hdbc,lobj_fd); + + /* commit transaction if needed */ + if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "COMMIT", NULL); + if (!res) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + + CC_set_no_trans(stmt->hdbc); + } } /* the oid of the large object -- just put that in for the *************** *** 1340,1345 **** --- 1389,1417 ---- */ if ( ! bindInfo || bindInfo->data_left == -1) { + + /* begin transaction if needed */ + if(!CC_is_in_trans(stmt->hdbc)) { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "BEGIN", NULL); + if (!res) { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + return COPY_GENERAL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + return COPY_GENERAL_ERROR; + } + + CC_set_in_trans(stmt->hdbc); + } + oid = atoi(value); stmt->lobj_fd = lo_open(stmt->hdbc, oid, INV_READ); if (stmt->lobj_fd < 0){ *************** *** 1374,1379 **** --- 1446,1474 ---- retval = lo_read(stmt->hdbc, stmt->lobj_fd, (char *) rgbValue, cbValueMax); if (retval < 0) { lo_close(stmt->hdbc, stmt->lobj_fd); + + /* commit transaction if needed */ + if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "COMMIT", NULL); + if (!res) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + return COPY_GENERAL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + return COPY_GENERAL_ERROR; + } + + CC_set_no_trans(stmt->hdbc); + } + stmt->lobj_fd = -1; stmt->errornumber = STMT_EXEC_ERROR; *************** *** 1396,1401 **** --- 1491,1519 ---- if (! bindInfo || bindInfo->data_left == 0) { lo_close(stmt->hdbc, stmt->lobj_fd); + + /* commit transaction if needed */ + if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "COMMIT", NULL); + if (!res) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + return COPY_GENERAL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + return COPY_GENERAL_ERROR; + } + + CC_set_no_trans(stmt->hdbc); + } + stmt->lobj_fd = -1; /* prevent further reading */ } diff -rc src.v06-40-0007/execute.c src.v06-40-0007.test/execute.c *** src.v06-40-0007/execute.c Fri Jan 8 11:33:02 1999 --- src.v06-40-0007.test/execute.c Wed Dec 8 21:38:45 1999 *************** *** 517,522 **** --- 517,547 ---- /* close the large object */ if ( stmt->lobj_fd >= 0) { lo_close(stmt->hdbc, stmt->lobj_fd); + + /* commit transaction if needed */ + if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "COMMIT", NULL); + if (!res) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + + CC_set_no_trans(stmt->hdbc); + } + stmt->lobj_fd = -1; } *************** *** 607,612 **** --- 632,661 ---- /* Handle Long Var Binary with Large Objects */ if ( current_param->SQLType == SQL_LONGVARBINARY){ + /* begin transaction if needed */ + if(!CC_is_in_trans(stmt->hdbc)) { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "BEGIN", NULL); + if (!res) { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + + CC_set_in_trans(stmt->hdbc); + } + /* store the oid */ current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); if (current_param->lobj_oid == 0) { diff -rc src.v06-40-0007/statement.c src.v06-40-0007.test/statement.c *** src.v06-40-0007/statement.c Thu Sep 2 22:08:04 1999 --- src.v06-40-0007.test/statement.c Wed Dec 8 21:40:15 1999 *************** *** 327,333 **** } if (self->parameters[i].EXEC_buffer) { ! free(self->parameters[i].EXEC_buffer); self->parameters[i].EXEC_buffer = NULL; } } --- 327,334 ---- } if (self->parameters[i].EXEC_buffer) { ! if (self->parameters[i].SQLType != SQL_LONGVARBINARY) ! free(self->parameters[i].EXEC_buffer); self->parameters[i].EXEC_buffer = NULL; } }
pgsql-interfaces by date: