From dadb718b103d6675399547d3f6c12d0726f9537e Mon Sep 17 00:00:00 2001
From: Hiroshi Inoue <inoue@tpf.co.jp>
Date: Mon, 11 Mar 2002 10:25:57 +0000
Subject: [PATCH] Bug fixes for the 2002-03-08 change. 1) Put back the error
 message for SQLError(). 2) Change Disallow premature to handle the SELECTed  
  result. 3) Put back the behavior of AUTUCOMMIT mode change. 4) Fix
 SQLColumns for ODBC3.0.

5) Improve the handling of variable bookmark in ODBC3.0.
6) Enable Recognize Unique Index Button.
---
 src/interfaces/odbc/bind.c         | 18 +++++++++++++-----
 src/interfaces/odbc/connection.c   | 17 +++++++++++------
 src/interfaces/odbc/convert.c      |  4 ++--
 src/interfaces/odbc/dlg_specific.c | 10 ++++------
 src/interfaces/odbc/info.c         | 24 +++++++++++++++++++++++-
 src/interfaces/odbc/options.c      |  4 ++--
 src/interfaces/odbc/psqlodbc.h     |  2 +-
 src/interfaces/odbc/results.c      | 28 +++++++++++++++++++---------
 src/interfaces/odbc/statement.c    |  5 ++---
 9 files changed, 77 insertions(+), 35 deletions(-)

diff --git a/src/interfaces/odbc/bind.c b/src/interfaces/odbc/bind.c
index 6ce32c7982..b7303c4785 100644
--- a/src/interfaces/odbc/bind.c
+++ b/src/interfaces/odbc/bind.c
@@ -199,12 +199,20 @@ PGAPI_BindCol(
 		else
 		{
 			/* Make sure it is the bookmark data type */
-			if (fCType != SQL_C_BOOKMARK)
+			if (fCType == SQL_C_BOOKMARK)
+			switch (fCType)
 			{
-				stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
-				stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
-				SC_log_error(func, "", stmt);
-				return SQL_ERROR;
+				case SQL_C_BOOKMARK:
+#if (ODBCVER >= 0x0300)
+				case SQL_C_VARBOOKMARK:
+#endif /* ODBCVER */
+					break;
+				default:
+					stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
+inolog("Column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
+					stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
+					SC_log_error(func, "", stmt);
+					return SQL_ERROR;
 			}
 
 			stmt->bookmark.buffer = rgbValue;
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index 44d7589496..d176d925d4 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -1322,7 +1322,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
 				if ((swallow != '\0') || SOCK_get_errcode(sock) != 0)
 				{
 					self->errornumber = CONNECTION_BACKEND_CRAZY;
-					self->errormsg = "Unexpected protocol character from backend (send_query - I)";
+					QR_set_message(res, "Unexpected protocol character from backend (send_query - I)");
 					QR_set_status(res, PGRES_FATAL_ERROR);
 					ReadyToReturn = TRUE;
 					retres = cmdres;
@@ -1346,14 +1346,13 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
 				if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n')
 					msgbuffer[strlen(msgbuffer) - 1] = '\0';
 
-				self->errormsg = msgbuffer;
 
-				mylog("send_query: 'E' - %s\n", self->errormsg);
-				qlog("ERROR from backend during send_query: '%s'\n", self->errormsg);
+				mylog("send_query: 'E' - %s\n", msgbuffer);
+				qlog("ERROR from backend during send_query: '%s'\n", msgbuffer);
 
 				/* We should report that an error occured. Zoltan */
 
-				if (!strncmp(self->errormsg, "FATAL", 5))
+				if (!strncmp(msgbuffer, "FATAL", 5))
 				{
 					self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
 					CC_set_no_trans(self);
@@ -1361,6 +1360,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
 				else
 					self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
 				QR_set_status(res, PGRES_FATAL_ERROR);
+				QR_set_message(res, msgbuffer);
 				QR_set_aborted(res, TRUE);
 				aborted = TRUE;
 				while (msg_truncated)
@@ -1487,7 +1487,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
 					retres = NULL;
 				}
 			}
-			else
+			if (retres)
 			{
 				/*
 				 *	discard results other than errors.
@@ -1501,6 +1501,11 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
 					qres->next = NULL;
 					QR_Destructor(qres);
 				}
+				/*
+				 *	If error message isn't set
+				 */
+				if (retres && (!self->errormsg || !self->errormsg[0]))
+					self->errormsg = QR_get_message(retres);
 			}
 		}
 	}
diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c
index a38ffd1de8..6ba6587f64 100644
--- a/src/interfaces/odbc/convert.c
+++ b/src/interfaces/odbc/convert.c
@@ -349,8 +349,8 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
 	{
 		pbic = &stmt->bindings[stmt->current_col];
 		if (pbic->data_left == -2)
-			pbic->data_left = (cbValueMax > 0) ? 0 : -1;		/* This seems to be *
-																 * needed for ADO ? */
+			pbic->data_left = (cbValueMax > 0) ? 0 : -1; /* This seems to be *
+						 * needed for ADO ? */
 		if (pbic->data_left == 0)
 		{
 			if (pbic->ttlbuf != NULL)
diff --git a/src/interfaces/odbc/dlg_specific.c b/src/interfaces/odbc/dlg_specific.c
index 4fbf037cec..d165f1300f 100644
--- a/src/interfaces/odbc/dlg_specific.c
+++ b/src/interfaces/odbc/dlg_specific.c
@@ -175,9 +175,9 @@ driver_options_update(HWND hdlg, ConnInfo *ci, BOOL updateProfile)
 	comval->commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
 	comval->disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER);
 	comval->ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO);
+	comval->unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX);
 	if (!ci)
 	{
-		comval->unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX);
 		comval->onlyread = IsDlgButtonChecked(hdlg, DRV_READONLY);
 	}
 	comval->use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH);
@@ -442,15 +442,13 @@ updateCommons(const ConnInfo *ci)
 	SQLWritePrivateProfileString(sectionName,
 								 INI_KSQO, tmp, fileName);
 
+	sprintf(tmp, "%d", comval->unique_index);
+	SQLWritePrivateProfileString(sectionName, INI_UNIQUEINDEX, tmp, fileName);
 	/*
-	 * Never update the onlyread, unique_index from this module.
+	 * Never update the onlyread from this module.
 	 */
 	if (!ci)
 	{
-		sprintf(tmp, "%d", comval->unique_index);
-		SQLWritePrivateProfileString(sectionName, INI_UNIQUEINDEX, tmp,
-									 fileName);
-
 		sprintf(tmp, "%d", comval->onlyread);
 		SQLWritePrivateProfileString(sectionName, INI_READONLY, tmp,
 									 fileName);
diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c
index fc5dcef341..10a900207c 100644
--- a/src/interfaces/odbc/info.c
+++ b/src/interfaces/odbc/info.c
@@ -1734,7 +1734,11 @@ PGAPI_Columns(
 	 * a statement is actually executed, so we'll have to do this
 	 * ourselves.
 	 */
+#if (ODBCVER >= 0x0300)
+	result_cols = 18;
+#else
 	result_cols = 14;
+#endif /* ODBCVER */
 	extend_bindings(stmt, result_cols);
 
 	/* set the field names */
@@ -1803,7 +1807,12 @@ PGAPI_Columns(
 			set_tuplefield_string(&row->tuple[11], "");
 
 #if (ODBCVER >= 0x0300)
+			set_tuplefield_null(&row->tuple[12]);
 			set_tuplefield_int2(&row->tuple[13], sqltype);
+			set_tuplefield_null(&row->tuple[14]);
+			set_tuplefield_int4(&row->tuple[15], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
+			set_tuplefield_int4(&row->tuple[16], 0);
+			set_tuplefield_string(&row->tuple[17], "No");
 #else
 			set_tuplefield_int4(&row->tuple[12], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC));
 			set_tuplefield_int4(&row->tuple[13], the_type);
@@ -1918,9 +1927,12 @@ PGAPI_Columns(
 				break;
 			default:
 				set_tuplefield_int2(&row->tuple[13], sqltype);
+				set_tuplefield_null(&row->tuple[14]);
 				break;
 		}
+		set_tuplefield_int4(&row->tuple[15], pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC));
 		set_tuplefield_int4(&row->tuple[16], field_number);
+		set_tuplefield_null(&row->tuple[17]);
 #else
 		set_tuplefield_int4(&row->tuple[13], field_type);
 #endif /* ODBCVER */
@@ -1956,7 +1968,8 @@ PGAPI_Columns(
 		set_tuplefield_string(&row->tuple[1], "");
 		set_tuplefield_string(&row->tuple[2], table_name);
 		set_tuplefield_string(&row->tuple[3], "xmin");
-		set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type));
+		sqltype = pgtype_to_sqltype(stmt, the_type);
+		set_tuplefield_int2(&row->tuple[4], sqltype);
 		set_tuplefield_string(&row->tuple[5], pgtype_to_name(stmt, the_type));
 		set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
 		set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
@@ -1964,8 +1977,17 @@ PGAPI_Columns(
 		set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
 		set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
 		set_tuplefield_string(&row->tuple[11], "");
+#if (ODBCVER >= 0x0300)
+		set_tuplefield_null(&row->tuple[12]);
+		set_tuplefield_int2(&row->tuple[13], sqltype);
+		set_tuplefield_null(&row->tuple[14]);
+		set_tuplefield_int4(&row->tuple[15], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
+		set_tuplefield_int4(&row->tuple[16], 0);
+		set_tuplefield_string(&row->tuple[17], "No");
+#else
 		set_tuplefield_int4(&row->tuple[12], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC));
 		set_tuplefield_int4(&row->tuple[13], the_type);
+#endif /* ODBCVER */
 
 		QR_add_tuple(res, row);
 	}
diff --git a/src/interfaces/odbc/options.c b/src/interfaces/odbc/options.c
index d58f84916f..c8e07700c8 100644
--- a/src/interfaces/odbc/options.c
+++ b/src/interfaces/odbc/options.c
@@ -342,9 +342,9 @@ PGAPI_SetConnectOption(
 			break;
 
 		case SQL_AUTOCOMMIT:
-			if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_trans(conn))
+			if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn))
 				break;
-			else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_trans(conn))
+			else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn))
 				break;
 			if (CC_is_in_trans(conn))
 				CC_commit(conn);
diff --git a/src/interfaces/odbc/psqlodbc.h b/src/interfaces/odbc/psqlodbc.h
index 534678e280..8fba1abd30 100644
--- a/src/interfaces/odbc/psqlodbc.h
+++ b/src/interfaces/odbc/psqlodbc.h
@@ -5,7 +5,7 @@
  *
  * Comments:		See "notice.txt" for copyright and license information.
  *
- * $Id: psqlodbc.h,v 1.58 2002/03/08 08:52:53 inoue Exp $
+ * $Id: psqlodbc.h,v 1.59 2002/03/11 10:25:57 inoue Exp $
  *
  */
 
diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c
index e43c0e3db4..13f223b720 100644
--- a/src/interfaces/odbc/results.c
+++ b/src/interfaces/odbc/results.c
@@ -189,6 +189,7 @@ PGAPI_DescribeCol(
 
 	/* gets all the information about a specific column */
 	StatementClass *stmt = (StatementClass *) hstmt;
+	ConnectionClass *conn;
 	QResultClass *res;
 	char	   *col_name = NULL;
 	Int4		fieldtype = 0;
@@ -200,7 +201,7 @@ PGAPI_DescribeCol(
 	int			len = 0;
 	RETCODE		result;
 
-	mylog("%s: entering...\n", func);
+	mylog("%s: entering.%d..\n", func, icol);
 
 	if (!stmt)
 	{
@@ -208,14 +209,16 @@ PGAPI_DescribeCol(
 		return SQL_INVALID_HANDLE;
 	}
 
-	ci = &(SC_get_conn(stmt)->connInfo);
+	conn = SC_get_conn(stmt);
+	ci = &(conn->connInfo);
 
 	SC_clear_error(stmt);
 
 #if (ODBCVER >= 0x0300)
 	if (0 == icol) /* bookmark column */
 	{
-		SQLSMALLINT	fType = SQL_INTEGER;
+		SQLSMALLINT	fType = stmt->options.use_bookmarks == SQL_UB_VARIABLE ? SQL_BINARY : SQL_INTEGER;
+
 		if (szColName && cbColNameMax > 0)
 			*szColName = '\0';
 		if (pcbColName)
@@ -440,7 +443,7 @@ PGAPI_ColAttributes(
 				break;
 			case SQL_DESC_TYPE:
 				if (pfDesc)
-					*pfDesc = SQL_INTEGER;
+					*pfDesc = stmt->options.use_bookmarks == SQL_UB_VARIABLE ? SQL_BINARY : SQL_INTEGER;
 				break;
 		}
 		return SQL_SUCCESS;
@@ -813,12 +816,19 @@ PGAPI_GetData(
 		}
 
 		/* Make sure it is the bookmark data type */
-		if (fCType != SQL_C_BOOKMARK)
+		switch (fCType)
 		{
-			stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
-			stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
-			SC_log_error(func, "", stmt);
-			return SQL_ERROR;
+			case SQL_C_BOOKMARK:
+#if (ODBCVER >= 0x0300)
+			case SQL_C_VARBOOKMARK:
+#endif /* ODBCVER */
+				break;
+			default:
+				stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
+inolog("Column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
+				stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
+				SC_log_error(func, "", stmt);
+				return SQL_ERROR;
 		}
 
 		get_bookmark = TRUE;
diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c
index 513c916019..4bb884dbf8 100644
--- a/src/interfaces/odbc/statement.c
+++ b/src/interfaces/odbc/statement.c
@@ -959,8 +959,7 @@ SC_execute(StatementClass *self)
 		mylog("       Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name);
 
 		/* send the declare/select */
-		res = CC_send_query(conn, self->stmt_with_params, NULL, TRUE);
-
+		res = CC_send_query(conn, self->stmt_with_params, NULL, FALSE);
 		if (SC_is_fetchcursor(self) && res != NULL &&
 			QR_command_successful(res))
 		{
@@ -1068,7 +1067,7 @@ SC_execute(StatementClass *self)
 		else
 		{
 			self->errornumber = STMT_EXEC_ERROR;
-			self->errormsg = "Error while executing the query";
+			self->errormsg = conn->errormsg;
 		}
 
 		if (!self->internal)
-- 
2.50.1