diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index c5d9ab6ab82896f609f4fba074f32caf99c04d7f..7dc3fde0b259c04a9a2e8bd0377b605873a10a8e 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -252,7 +252,10 @@ CC_Constructor()
 		rv->transact_status = CONN_IN_AUTOCOMMIT;		/* autocommit by default */
 
 		memset(&rv->connInfo, 0, sizeof(ConnInfo));
-memcpy(&(rv->connInfo.drivers), &globals, sizeof(globals));
+#ifdef	DRIVER_CURSOR_IMPLEMENT
+		rv->connInfo.updatable_cursors = 1;
+#endif /* DRIVER_CURSOR_IMPLEMENT */
+		memcpy(&(rv->connInfo.drivers), &globals, sizeof(globals));
 		rv->sock = SOCK_Constructor(rv);
 		if (!rv->sock)
 			return NULL;
@@ -278,6 +281,7 @@ memcpy(&(rv->connInfo.drivers), &globals, sizeof(globals));
 		rv->pg_version_number = .0;
 		rv->pg_version_major = 0;
 		rv->pg_version_minor = 0;
+		rv->ms_jet = 0;
 #ifdef	MULTIBYTE
 		rv->client_encoding = NULL;
 		rv->server_encoding = NULL;
@@ -586,6 +590,7 @@ CC_connect(ConnectionClass *self, char do_password)
 
 		mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', database = '%s', username = '%s', password='%s'\n", ci->dsn, ci->server, ci->port, ci->database, ci->username, ci->password);
 
+another_version_retry:
 		/*
 		 * If the socket was closed for some reason (like a SQLDisconnect,
 		 * but no SQLFreeConnect then create a socket now.
@@ -690,6 +695,18 @@ CC_connect(ConnectionClass *self, char do_password)
 					self->errornumber = CONN_INVALID_AUTHENTICATION;
 					self->errormsg = msgbuffer;
 					qlog("ERROR from backend during authentication: '%s'\n", self->errormsg);
+					if (strncmp(msgbuffer, "Unsupported frontend protocol", 29) == 0)
+					{	/* retry older version */
+						if (PROTOCOL_63(ci))
+							strcpy(ci->protocol, PG62);
+						else
+							strcpy(ci->protocol, PG63);
+						SOCK_Destructor(sock);
+						self->sock = (SocketClass *) 0;
+						CC_initialize_pg_version(self);
+						goto another_version_retry;
+					}
+			
 					return 0;
 				case 'R':
 
diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h
index fc77bc8a7b490b5bf95a8b809236a31c1d6d6445..fc3560d35225b6264ff7d255476361a090677fab 100644
--- a/src/interfaces/odbc/connection.h
+++ b/src/interfaces/odbc/connection.h
@@ -160,6 +160,7 @@ typedef struct
 	char		translation_option[SMALL_REGISTRY_LEN];
 	char		focus_password;
 	char		disallow_premature;
+	char		updatable_cursors;
 	GLOBAL_VALUES	drivers; /* moved from driver's option */
 } ConnInfo;
 
@@ -274,6 +275,7 @@ struct ConnectionClass_
 	float		pg_version_number;
 	Int2		pg_version_major;
 	Int2		pg_version_minor;
+	char		ms_jet;
 #ifdef	MULTIBYTE
 	char		*client_encoding;
 	char		*server_encoding;
diff --git a/src/interfaces/odbc/dlg_specific.c b/src/interfaces/odbc/dlg_specific.c
index aaf9432c4fe64c86493c582c50b50f07fd351c80..c02f633fdb3dec8c78415f1ac7b9bb413902c88b 100644
--- a/src/interfaces/odbc/dlg_specific.c
+++ b/src/interfaces/odbc/dlg_specific.c
@@ -510,6 +510,7 @@ makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len)
 	char		got_dsn = (ci->dsn[0] != '\0');
 	char		encoded_conn_settings[LARGE_REGISTRY_LEN];
 	UWORD		hlen;
+	BOOL		abbrev = (len <= 400);
 
 	/* fundamental info */
 	sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s",
@@ -524,8 +525,9 @@ makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len)
 	encode(ci->conn_settings, encoded_conn_settings);
 
 	/* extra info */
-	hlen = strlen(connect_string),
-	sprintf(&connect_string[hlen],
+	hlen = strlen(connect_string);
+	if (!abbrev)
+		sprintf(&connect_string[hlen],
 			";READONLY=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;ROWVERSIONING=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s;FETCH=%d;SOCKET=%d;UNKNOWNSIZES=%d;MAXVARCHARSIZE=%d;MAXLONGVARCHARSIZE=%d;DEBUG=%d;COMMLOG=%d;OPTIMIZER=%d;KSQO=%d;USEDECLAREFETCH=%d;TEXTASLONGVARCHAR=%d;UNKNOWNSASLONGVARCHAR=%d;BOOLSASCHAR=%d;PARSE=%d;CANCELASFREESTMT=%d;EXTRASYSTABLEPREFIXES=%s",
 			ci->onlyread,
 			ci->protocol,
@@ -551,7 +553,7 @@ makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len)
 			ci->drivers.cancel_as_freestmt,
 			ci->drivers.extra_systable_prefixes);
 	/* Abbrebiation is needed ? */
-	if (strlen(connect_string) >= len)
+	if (abbrev || strlen(connect_string) >= len)
 		sprintf(&connect_string[hlen],
 			";A0=%s;A1=%s;A2=%s;A3=%s;A4=%s;A5=%s;A6=%s;A7=%d;A8=%d;A9=%d;B0=%d;B1=%d;B2=%d;B3=%d;B4=%d;B5=%d;B6=%d;B7=%d;B8=%d;B9=%d;C0=%d;C1=%d;C2=%s",
 			ci->onlyread,
@@ -630,7 +632,10 @@ copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
 	else if (stricmp(attribute, INI_DISALLOWPREMATURE) == 0 || stricmp(attribute, "C3") == 0)
 	{
 		ci->disallow_premature = atoi(value);
-		/* strcpy(ci->conn_settings, value); */
+	}
+	else if (stricmp(attribute, INI_UPDATABLECURSORS) == 0 || stricmp(attribute, "C4") == 0)
+	{
+		ci->updatable_cursors = atoi(value);
 	}
 
 	mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature);
@@ -803,6 +808,12 @@ getDSNinfo(ConnInfo *ci, char overwrite)
 		ci->disallow_premature = atoi(temp);
 	}
 
+	if (ci->updatable_cursors == 0 || overwrite)
+	{
+		SQLGetPrivateProfileString(DSN, INI_UPDATABLECURSORS, "", temp, sizeof(temp), ODBC_INI);
+		ci->updatable_cursors = atoi(temp);
+	}
+
 	/* Allow override of odbcinst.ini parameters here */
 	getCommonDefaults(DSN, ODBC_INI, ci);
 
@@ -916,6 +927,11 @@ writeDSNinfo(const ConnInfo *ci)
 								 INI_DISALLOWPREMATURE,
 								 temp,
 								 ODBC_INI);
+	sprintf(temp, "%d", ci->updatable_cursors); 
+	SQLWritePrivateProfileString(DSN,
+								 INI_UPDATABLECURSORS,
+								 temp,
+								 ODBC_INI);
 }
 
 
diff --git a/src/interfaces/odbc/dlg_specific.h b/src/interfaces/odbc/dlg_specific.h
index 8d37eb8a91a1faa9e75608853fe02fcf983f2460..6fc04ad2fb966b8b1ab8a955bf535767d1e8923b 100644
--- a/src/interfaces/odbc/dlg_specific.h
+++ b/src/interfaces/odbc/dlg_specific.h
@@ -96,6 +96,7 @@
 #define INI_TRANSLATIONDLL				"TranslationDLL"
 #define INI_TRANSLATIONOPTION			"TranslationOption"
 #define INI_DISALLOWPREMATURE			"DisallowPremature"
+#define INI_UPDATABLECURSORS			"UpdatableCursors"
 
 
 /*	Connection Defaults */
diff --git a/src/interfaces/odbc/drvconn.c b/src/interfaces/odbc/drvconn.c
index 80f1d69b7d649602581ab4dfd68899cb2e7816bf..781bdd54903eb16f4175912a944d9757dc3f5006 100644
--- a/src/interfaces/odbc/drvconn.c
+++ b/src/interfaces/odbc/drvconn.c
@@ -1,5 +1,5 @@
 /*-------
- * Module:			drvconn.c
+  Module:			drvconn.c
  *
  * Description:		This module contains only routines related to
  *					implementing SQLDriverConnect.
@@ -88,6 +88,7 @@ PGAPI_DriverConnect(
 	int			retval;
 	char		password_required = FALSE;
 	int			len = 0;
+	SWORD		lenStrout;
 
 
 	mylog("%s: entering...\n", func);
@@ -211,7 +212,10 @@ dialog:
 	 */
 	result = SQL_SUCCESS;
 
-	makeConnectString(connStrOut, ci, cbConnStrOutMax);
+	lenStrout = cbConnStrOutMax;
+	if (conn->ms_jet && lenStrout > 255)
+		lenStrout = 255; 
+	makeConnectString(connStrOut, ci, lenStrout);
 	len = strlen(connStrOut);
 
 	if (szConnStrOut)
diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c
index 431a9b1d14017c3f96153bed2e8810c27d2a5e99..6ff0d0b12e47482a5a67dd5a5cd4a88845771a09 100644
--- a/src/interfaces/odbc/info.c
+++ b/src/interfaces/odbc/info.c
@@ -166,19 +166,17 @@ PGAPI_GetInfo(
 		case SQL_CURSOR_COMMIT_BEHAVIOR:		/* ODBC 1.0 */
 			len = 2;
 			value = SQL_CB_CLOSE;
-#ifdef	DRIVER_CURSOR_IMPLEMENT
-			if (!ci->drivers.use_declarefetch)
-				value = SQL_CB_PRESERVE;
-#endif /* DRIVER_CURSOR_IMPLEMENT */
+			if (ci->updatable_cursors)
+				if (!ci->drivers.use_declarefetch)
+					value = SQL_CB_PRESERVE;
 			break;
 
 		case SQL_CURSOR_ROLLBACK_BEHAVIOR:		/* ODBC 1.0 */
 			len = 2;
 			value = SQL_CB_CLOSE;
-#ifdef	DRIVER_CURSOR_IMPLEMENT
-			if (!ci->drivers.use_declarefetch)
-				value = SQL_CB_PRESERVE;
-#endif /* DRIVER_CURSOR_IMPLEMENT */
+			if (ci->updatable_cursors)
+				if (!ci->drivers.use_declarefetch)
+					value = SQL_CB_PRESERVE;
 			break;
 
 		case SQL_DATA_SOURCE_NAME:		/* ODBC 1.0 */
@@ -235,7 +233,7 @@ PGAPI_GetInfo(
 				if (dver[0])
 				{
 					int	major, minor;
-					mylog("REIGISTRY_ODBC_VER = %s\n", dver)
+					mylog("REGISTRY_ODBC_VER = %s\n", dver)
 ;
 					if (sscanf(dver, "%x.%x", &major, &minor) >= 2)
 					{
@@ -524,6 +522,8 @@ PGAPI_GetInfo(
 		case SQL_POS_OPERATIONS:		/* ODBC 2.0 */
 			len = 4;
 			value = ci->drivers.lie ? (SQL_POS_POSITION | SQL_POS_REFRESH | SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD) : (SQL_POS_POSITION | SQL_POS_REFRESH);
+			if (ci->updatable_cursors)
+				value |= (SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD);
 			break;
 
 		case SQL_POSITIONED_STATEMENTS: /* ODBC 2.0 */
@@ -571,7 +571,7 @@ PGAPI_GetInfo(
 			 * Driver doesn't support keyset-driven or mixed cursors, so
 			 * not much point in saying row updates are supported
 			 */
-			p = ci->drivers.lie ? "Y" : "N";
+			p = (ci->drivers.lie || ci->updatable_cursors) ? "Y" : "N";
 			break;
 
 		case SQL_SCROLL_CONCURRENCY:	/* ODBC 1.0 */
@@ -579,7 +579,10 @@ PGAPI_GetInfo(
 			value = ci->drivers.lie ? (SQL_SCCO_READ_ONLY |
 								   SQL_SCCO_LOCK |
 								   SQL_SCCO_OPT_ROWVER |
-							 SQL_SCCO_OPT_VALUES) : (SQL_SCCO_READ_ONLY);
+							 SQL_SCCO_OPT_VALUES) :
+ (SQL_SCCO_READ_ONLY);
+			if (ci->updatable_cursors)
+				value |= SQL_SCCO_OPT_ROWVER;
 			break;
 
 		case SQL_SCROLL_OPTIONS:		/* ODBC 1.0 */
@@ -588,7 +591,10 @@ PGAPI_GetInfo(
 								   SQL_SO_STATIC |
 								   SQL_SO_KEYSET_DRIVEN |
 								   SQL_SO_DYNAMIC |
-								   SQL_SO_MIXED) : (ci->drivers.use_declarefetch ? SQL_SO_FORWARD_ONLY : (SQL_SO_FORWARD_ONLY | SQL_SO_STATIC));
+								   SQL_SO_MIXED)
+ : (ci->drivers.use_declarefetch ? SQL_SO_FORWARD_ONLY : (SQL_SO_FORWARD_ONLY | SQL_SO_STATIC));
+			if (ci->updatable_cursors)
+ 				value |= 0; /* SQL_SO_KEYSET_DRIVEN in the furure */
 			break;
 
 		case SQL_SEARCH_PATTERN_ESCAPE: /* ODBC 1.0 */
@@ -606,6 +612,8 @@ PGAPI_GetInfo(
 		case SQL_STATIC_SENSITIVITY:	/* ODBC 2.0 */
 			len = 4;
 			value = ci->drivers.lie ? (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES) : 0;
+			if (ci->updatable_cursors)
+				value |= (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES);
 			break;
 
 		case SQL_STRING_FUNCTIONS:		/* ODBC 1.0 */
diff --git a/src/interfaces/odbc/options.c b/src/interfaces/odbc/options.c
index aa18bb1615c62faf03ecfef9de1ef08f6460e4d4..a9a0a287fbd350046bf3a3a436de7a5ee2db97c8 100644
--- a/src/interfaces/odbc/options.c
+++ b/src/interfaces/odbc/options.c
@@ -412,6 +412,15 @@ PGAPI_SetConnectOption(
 				conn->errormsg = "Unknown connect option (Set)";
 				conn->errornumber = CONN_UNSUPPORTED_OPTION;
 				sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
+				if (fOption == 30002 && vParam)
+				{
+					if (strcmp((char *) vParam, "Microsoft Jet") == 0)
+					{
+						conn->errornumber = 0;
+						conn->ms_jet = 1;
+						return SQL_SUCCESS;
+					}
+				}
 				CC_log_error(func, option, conn);
 				return SQL_ERROR;
 			}
diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c
index 3cfe5fb74b147eda27792391f23fae5775bec20c..2475eeef9e3b0be7632a7487f743adb61de02f82 100644
--- a/src/interfaces/odbc/results.c
+++ b/src/interfaces/odbc/results.c
@@ -164,12 +164,12 @@ PGAPI_NumResultCols(
 		}
 
 		*pccol = QR_NumResultCols(result);
-#ifdef	DRIVER_CURSOR_IMPLEMENT
-		if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY)
+		/* updatable cursors */
+		if (ci->updatable_cursors &&
+		    stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY)
 		{
 			*pccol -= 2;
 		}
-#endif /* DRIVER_CURSOR_IMPLEMENT */
 	}
 
 	return SQL_SUCCESS;
@@ -1224,13 +1224,46 @@ PGAPI_MoreResults(
 
 
 #ifdef	DRIVER_CURSOR_IMPLEMENT
+/*
+ *	Stuff for updatable cursors. 
+ */
+static QResultClass *
+positioned_load(StatementClass *stmt, BOOL latest, int res_cols, UInt4 oid, const char *tidval)
+{
+	int	i;
+	QResultClass	*qres;
+	char	selstr[4096];
+
+	sprintf(selstr, "select");
+	for (i = 0; i < res_cols; i++)
+		sprintf(selstr, "%s \"%s\",", selstr, stmt->fi[i]->name);
+	sprintf(selstr, "%s CTID, OID from \"%s\" where", selstr, stmt->ti[0]->name);
+	if (tidval)
+	{
+		if (latest)
+			sprintf(selstr, "%s ctid = currtid2('%s', '%s') and",
+				selstr, stmt->ti[0]->name, tidval);
+		else
+			sprintf(selstr, "%s ctid = '%s' and", selstr, tidval);
+	}
+	sprintf(selstr, "%s oid = %u", selstr, oid), 
+	mylog("selstr=%s\n", selstr);
+	qres = CC_send_query(SC_get_conn(stmt), selstr, NULL);
+	if (qres && QR_aborted(qres))
+	{
+		QR_Destructor(qres);
+		qres = (QResultClass *) 0;
+	}
+	return qres;
+}
+
 RETCODE SQL_API
 SC_pos_reload(StatementClass *stmt, UWORD irow, UWORD *count)
 {
 	int	i, res_cols;
 	UWORD	rcnt, global_ridx;
+	UInt4	oid;
 	QResultClass	*res, *qres;
-	char	selstr[4096];
 	RETCODE	ret = SQL_ERROR;
 	char	*tidval, *oidval;
 
@@ -1247,22 +1280,16 @@ SC_pos_reload(StatementClass *stmt, UWORD irow, UWORD *count)
 		stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
 		return SQL_ERROR;
 	}
-	strcpy(selstr, "select");
 	global_ridx = irow + stmt->rowset_start;
 	res_cols = QR_NumResultCols(res);
 	if (!(oidval = QR_get_value_backend_row(res, global_ridx, res_cols - 1)))
 	{
 		return SQL_SUCCESS_WITH_INFO;
-	} 
+	}
+	sscanf(oidval, "%u", &oid); 
 	tidval = QR_get_value_backend_row(res, global_ridx, res_cols - 2);
 	res_cols -= 2;
-	for (i = 0; i < res_cols; i++)
-		sprintf(selstr, "%s \"%s\",", selstr, stmt->fi[i]->name);
-	sprintf(selstr, "%s CTID, OID from \"%s\" where ctid = currtid2('%s', '%s') and oid = %s",
-		selstr, stmt->ti[0]->name, stmt->ti[0]->name, tidval, oidval), 
-	mylog("selstr=%s\n", selstr);
-	qres = CC_send_query(SC_get_conn(stmt), selstr, NULL);
-	if (qres && QR_command_successful(qres))
+	if (qres = positioned_load(stmt, TRUE, res_cols, oid, tidval), qres)
 	{
 		TupleField	*tupleo, *tuplen;
 
@@ -1296,22 +1323,20 @@ SC_pos_reload(StatementClass *stmt, UWORD irow, UWORD *count)
 				tupleo[res_cols + 1].len = 0;
 			}
 		}
+		QR_Destructor(qres);
 	}
 	else if (stmt->errornumber == 0)
 		stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND;
-	if (qres)
-		QR_Destructor(qres);
 	if (count)
 		*count = rcnt;
 	return ret;
 }
 
 RETCODE SQL_API
-SC_pos_newload(StatementClass *stmt, Int4 oid, const char *tidval)
+SC_pos_newload(StatementClass *stmt, UInt4 oid, const char *tidval)
 {
-	int	i, res_cols;
+	int	i;
 	QResultClass	*res, *qres;
-	char	selstr[4096];
 	RETCODE	ret = SQL_ERROR;
 
 	mylog("positioned new fi=%x ti=%x\n", stmt->fi, stmt->ti);
@@ -1324,20 +1349,8 @@ SC_pos_newload(StatementClass *stmt, Int4 oid, const char *tidval)
 		stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
 		return SQL_ERROR;
 	}
-	sprintf(selstr, "select");
-	res_cols = QR_NumResultCols(res);
-	res_cols -= 2;
-	for (i = 0; i < res_cols; i++)
-		sprintf(selstr, "%s \"%s\",", selstr, stmt->fi[i]->name);
-	sprintf(selstr, "%s CTID, OID from \"%s\" where", selstr, stmt->ti[0]->name);
-	if (tidval)
-		sprintf(selstr, "%s ctid = currtid2('%s', '%s') and",
-			selstr, stmt->ti[0]->name, tidval);
-	sprintf(selstr, "%s oid = %u", selstr, oid), 
-	mylog("selstr=%s\n", selstr);
-	qres = CC_send_query(SC_get_conn(stmt), selstr, NULL);
-	if (qres && QR_command_successful(qres))
-	{
+	if (qres = positioned_load(stmt, TRUE, QR_NumResultCols(res) - 2, oid, tidval), qres)
+	{ 
 		TupleField	*tupleo, *tuplen;
 		int	count = QR_get_num_tuples(qres);
 		QR_set_position(qres, 0);
@@ -1380,10 +1393,9 @@ SC_pos_newload(StatementClass *stmt, Int4 oid, const char *tidval)
 			stmt->errormsg = "the content was changed before updation";
 			ret = SQL_SUCCESS_WITH_INFO;
 		}
+		QR_Destructor(qres);
 		/*stmt->currTuple = stmt->rowset_start + irow;*/
 	}
-	if (qres)
-		QR_Destructor(qres);
 	return ret;
 }
 
@@ -1666,7 +1678,7 @@ SC_pos_add(StatementClass *stmt,
 		else
 		{
 			int	addcnt;
-			Int4	oid;
+			UInt4	oid;
 			const char *cmdstr = QR_get_command(qstmt->result);
 			if (cmdstr &&
 			    sscanf(cmdstr, "INSERT %u %d", &oid, &addcnt) == 2 &&
@@ -1696,6 +1708,9 @@ SC_pos_add(StatementClass *stmt,
 	PGAPI_FreeStmt(hstmt, SQL_DROP);
 	return ret;
 }
+/*
+ *	Stuff for updatable cursors end. 
+ */
 #endif /* DRIVER_CURSOR_IMPLEMENT */
 
 /*