Skip site navigation (1) Skip section navigation (2)

Re: ODBC and Large Objects, FAQ not working

From: "Hiroki Kataoka" <kataoka(at)interwiz(dot)koganei(dot)tokyo(dot)jp>
To: <pgsql-interfaces(at)postgreSQL(dot)org>
Subject: Re: ODBC and Large Objects, FAQ not working
Date: 1999-12-08 13:43:02
Message-ID: NDBBIKCHILNJOAAPDPKMIECDCAAA.kataoka@interwiz.koganei.tokyo.jp (view raw or flat)
Thread:
Lists: 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;
  			}
  		}


In response to

Responses

pgsql-interfaces by date

Next:From: stuartDate: 1999-12-08 15:57:28
Subject:
Previous:From: stuartDate: 1999-12-08 13:27:23
Subject: missing mail?

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group