[PATCH] CTLib handling of NVARCHAR

"Andrew Victor" <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
hi,

It seems that the CTLib implementation handles NVARCHAR strings as VARCHAR's.
These strings get converted to the single-byte character set when sent
to the MS-SQL server, which fails if the string actually contains a
multi-byte character.

The attached patch fixes this (tested with client charset = UTF-8).


Regards,
  Andrew Victor

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
unicode.patch (text/x-patch, 2.6 KB)
diff -urN freetds-0.82/src/ctlib/cs.c freetds-0.82.new/src/ctlib/cs.c
--- freetds-0.82/src/ctlib/cs.c	2008-11-24 15:26:22.000000000 +0200
+++ freetds-0.82.new/src/ctlib/cs.c	2008-11-24 15:26:36.000000000 +0200
@@ -527,6 +527,7 @@
 
 		case SYBCHAR:
 		case SYBVARCHAR:
+		case SYBNVARCHAR:
 		case SYBTEXT:
 			tdsdump_log(TDS_DBG_FUNC, "cs_convert() desttype = character\n");
 			if (src_len > destlen) {
@@ -755,6 +756,7 @@
 		break;
 	case SYBCHAR:
 	case SYBVARCHAR:
+	case SYBNVARCHAR:
 	case SYBTEXT:
 		if (len > destlen) {
 			fprintf(stderr, "error_handler: Data-conversion resulted in overflow.\n");
diff -urN freetds-0.82/src/ctlib/ct.c freetds-0.82.new/src/ctlib/ct.c
--- freetds-0.82/src/ctlib/ct.c	2008-11-24 15:26:18.000000000 +0200
+++ freetds-0.82.new/src/ctlib/ct.c	2008-11-24 15:26:36.000000000 +0200
@@ -1998,6 +1998,9 @@
 			return CS_UNICHAR_TYPE;
 		return CS_CHAR_TYPE;
 		break;
+	case SYBNVARCHAR:
+		return CS_UNICHAR_TYPE;
+		break;
 	}
 
 	return CS_FAIL;
@@ -2070,7 +2073,7 @@
 		return SYBLONGBINARY;
 		break;
 	case CS_UNICHAR_TYPE:
-		return SYBVARCHAR;
+		return SYBNVARCHAR;
 	default:
 		return -1;
 		break;
@@ -4241,7 +4244,10 @@
 				return NULL;
 			pcol->on_server.column_size = pcol->column_size = p->maxlen;
 			pcol->column_cur_size = temp_datalen;
-			if (temp_datalen > 0 && temp_datalen > p->maxlen)
+			if (p->maxlen == 0 && pcol->column_type == SYBNVARCHAR) {
+				pcol->on_server.column_size = pcol->column_size = temp_datalen*2;
+			}
+			else if (temp_datalen > 0 && temp_datalen > p->maxlen)
 				pcol->on_server.column_size = pcol->column_size = temp_datalen;
 		} else {
 			pcol->column_cur_size = pcol->column_size;
diff -urN freetds-0.82/src/tds/convert.c freetds-0.82.new/src/tds/convert.c
--- freetds-0.82/src/tds/convert.c	2008-02-04 09:55:39.000000000 +0200
+++ freetds-0.82.new/src/tds/convert.c	2008-11-24 15:28:46.000000000 +0200
@@ -358,6 +358,7 @@
 		return srclen;
 
 	case CASE_ALL_CHAR:
+	case SYBNVARCHAR:		/* CHAR return as Unicode */
 		cr->c = (TDS_CHAR *) malloc(srclen + 1);
 		test_alloc(cr->c);
 		memcpy(cr->c, src, srclen);
diff -urN freetds-0.82/src/tds/data.c freetds-0.82.new/src/tds/data.c
--- freetds-0.82/src/tds/data.c	2007-06-21 09:21:21.000000000 +0200
+++ freetds-0.82.new/src/tds/data.c	2008-11-24 15:26:36.000000000 +0200
@@ -85,6 +85,9 @@
 		case SYBBINARY:
 			type = XSYBBINARY;
 			break;
+		case SYBNVARCHAR:
+			type = XSYBNVARCHAR;
+			break;
 			/* avoid warning on other types */
 		default:
 			break;
@@ -152,6 +155,7 @@
 	case SYBNTEXT:
 		return SYBTEXT;
 	case XSYBNVARCHAR:
+		return SYBNVARCHAR;
 	case XSYBVARCHAR:
 		return SYBVARCHAR;
 	case XSYBNCHAR:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.