[PATCH] SYBUINT<n> support

Ian Lister <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
Hi,

I was running into a problem due to FreeTDS not supporting Sybase's unsigned integer types (SYBUINT1/2/4/8). It was manifested as cs_convert failing to convert other types (such as SYBNUMERIC) to those unsigned types, and reporting:

cs_convert: cslib user api layer: external error: Conversion between 108 and -1 datatypes is not supported

I have attached a patch that addresses the issue for me, in the hope that it might be useful for others. I tried to make it fairly complete in the areas of the code that I touched, but I was only following my nose so have quite likely overlooked other parts of the code (including test cases) that are also lacking SYBUINTn support. YMMV etc.

Ian

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
freetds-uint.patch (application/octet-stream, 25.3 KB)
Index: include/tdsconvert.h
===================================================================
RCS file: /cvsroot/freetds/freetds/include/tdsconvert.h,v
retrieving revision 1.29
diff -u -d -r1.29 tdsconvert.h
--- include/tdsconvert.h	8 Aug 2011 12:33:18 -0000	1.29
+++ include/tdsconvert.h	22 Dec 2012 20:18:46 -0000
@@ -38,8 +38,11 @@
 {
 	TDS_TINYINT ti;
 	TDS_SMALLINT si;
+	TDS_USMALLINT usi;
 	TDS_INT i;
+	TDS_UINT ui;
 	TDS_INT8 bi;
+	TDS_UINT8 ubi;
 	TDS_FLOAT f;
 	TDS_REAL r;
 	TDS_CHAR *c;
Index: src/ctlib/cs.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/ctlib/cs.c,v
retrieving revision 1.82
diff -u -d -r1.82 cs.c
--- src/ctlib/cs.c	25 Sep 2011 11:36:24 -0000	1.82
+++ src/ctlib/cs.c	22 Dec 2012 20:18:46 -0000
@@ -661,9 +661,13 @@
 			}
 			break;
 		case SYBINT1:
+		case SYBUINT1:
 		case SYBINT2:
+		case SYBUINT2:
 		case SYBINT4:
+		case SYBUINT4:
 		case SYBINT8:
+		case SYBUINT8:
 		case SYBFLT8:
 		case SYBREAL:
 		case SYBBIT:
@@ -770,6 +774,7 @@
 	case SYBBITN:
 		/* fall trough, act same way of TINYINT */
 	case SYBINT1:
+	case SYBUINT1:
 		memcpy(dest, &(cres.ti), 1);
 		*resultlen = 1;
 		ret = CS_SUCCEED;
@@ -779,16 +784,31 @@
 		*resultlen = 2;
 		ret = CS_SUCCEED;
 		break;
+	case SYBUINT2:
+		memcpy(dest, &(cres.usi), 2);
+		*resultlen = 2;
+		ret = CS_SUCCEED;
+		break;
 	case SYBINT4:
 		memcpy(dest, &(cres.i), 4);
 		*resultlen = 4;
 		ret = CS_SUCCEED;
 		break;
+	case SYBUINT4:
+		memcpy(dest, &(cres.ui), 4);
+		*resultlen = 4;
+		ret = CS_SUCCEED;
+		break;
 	case SYBINT8:
 		memcpy(dest, &(cres.bi), 8);
 		*resultlen = 8;
 		ret = CS_SUCCEED;
 		break;
+	case SYBUINT8:
+		memcpy(dest, &(cres.ubi), 8);
+		*resultlen = 8;
+		ret = CS_SUCCEED;
+		break;
 	case SYBFLT8:
 		memcpy(dest, &(cres.f), 8);
 		*resultlen = 8;
Index: src/ctlib/ct.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/ctlib/ct.c,v
retrieving revision 1.225
diff -u -d -r1.225 ct.c
--- src/ctlib/ct.c	11 Mar 2012 15:52:22 -0000	1.225
+++ src/ctlib/ct.c	22 Dec 2012 20:18:47 -0000
@@ -2016,8 +2016,11 @@
 	case CS_VARCHAR_TYPE:		return SYBVARCHAR;
 	case CS_LONG_TYPE:
 	case CS_BIGINT_TYPE:		return SYBINT8;
+	case CS_UBIGINT_TYPE:		return SYBUINT8;
 	case CS_INT_TYPE:		return SYBINT4;
+	case CS_UINT_TYPE:		return SYBUINT4;
 	case CS_SMALLINT_TYPE:		return SYBINT2;
+	case CS_USMALLINT_TYPE:		return SYBUINT2;
 	case CS_TINYINT_TYPE:		return SYBINT1;
 	case CS_REAL_TYPE:		return SYBREAL;
 	case CS_FLOAT_TYPE:		return SYBFLT8;
Index: src/tds/convert.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/convert.c,v
retrieving revision 1.217
diff -u -d -r1.217 convert.c
--- src/tds/convert.c	11 Aug 2011 12:50:26 -0000	1.217
+++ src/tds/convert.c	22 Dec 2012 20:18:47 -0000
@@ -90,6 +90,7 @@
 
 #define IS_TINYINT(x) ( 0 <= (x) && (x) <= 0xff )
 #define IS_SMALLINT(x) ( -32768 <= (x) && (x) <= 32767 )
+#define IS_USMALLINT(x) ( 0 <= (x) && (x) <= 65535 )
 /*
  * f77: I don't write -2147483648, some compiler seem to have some problem 
  * with this constant although is a valid 32bit value
@@ -98,10 +99,16 @@
 #define TDS_INT_MAX 2147483647l
 #define IS_INT(x) (TDS_INT_MIN <= (x) && (x) <= TDS_INT_MAX)
 
+#define TDS_UINT_MAX 4294967295lu
+#define IS_UINT(x) (0 <= (x) && (x) <= TDS_UINT_MAX)
+
 #define TDS_INT8_MAX ((((TDS_INT8) 0x7fffffffl) << 32) + 0xfffffffflu)
 #define TDS_INT8_MIN  (((TDS_INT8) (-0x7fffffffl-1)) << 32)
 #define IS_INT8(x) (TDS_INT8_MIN <= (x) && (x) <= TDS_INT8_MAX)
 
+#define TDS_UINT8_MAX ((((TDS_UINT8) 0xfffffffflu) << 32) + 0xfffffffflu)
+#define IS_UINT8(x) (0 <= (x) && (x) <= TDS_UINT8_MAX)
+
 /**
  * \ingroup libtds
  * \defgroup convert Conversion
@@ -127,6 +134,7 @@
 
 static TDS_INT string_to_int(const char *buf, const char *pend, TDS_INT * res);
 static TDS_INT string_to_int8(const char *buf, const char *pend, TDS_INT8 * res);
+static TDS_INT string_to_uint8(const char *buf, const char *pend, TDS_UINT8 * res);
 
 static int store_hour(const char *, const char *, struct tds_time *);
 static int store_time(const char *, struct tds_time *);
@@ -255,9 +263,13 @@
 		return binary_to_result(src, srclen, cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 	case SYBINT2:
+	case SYBUINT2:
 	case SYBINT4:
+	case SYBUINT4:
 	case SYBINT8:
+	case SYBUINT8:
 	case SYBMONEY4:
 	case SYBMONEY:
 	case SYBREAL:
@@ -341,6 +353,7 @@
 	unsigned int places;
 	TDS_INT tds_i;
 	TDS_INT8 tds_i8;
+	TDS_UINT8 tds_ui8;
 	TDS_INT rc;
 	TDS_CHAR *ib;
 
@@ -383,6 +396,7 @@
 		return tds_char2hex(ib, desttype == TDS_CONVERT_BINARY ? cr->cb.len : 0xffffffffu, src, srclen);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if ((rc = string_to_int(src, src + srclen, &tds_i)) < 0)
 			return rc;
 		if (!IS_TINYINT(tds_i))
@@ -398,18 +412,38 @@
 		cr->si = tds_i;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		if ((rc = string_to_int(src, src + srclen, &tds_i)) < 0)
+			return rc;
+		if (!IS_USMALLINT(tds_i))
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = tds_i;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		if ((rc = string_to_int(src, src + srclen, &tds_i)) < 0)
 			return rc;
 		cr->i = tds_i;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		if ((rc = string_to_int8(src, src + srclen, &tds_i8)) < 0)
+			return rc;
+		cr->ui = tds_i8;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		if ((rc = string_to_int8(src, src + srclen, &tds_i8)) < 0)
 			return rc;
 		cr->bi = tds_i8;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		if ((rc = string_to_uint8(src, src + srclen, &tds_ui8)) < 0)
+			return rc;
+		cr->ubi = tds_ui8;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBFLT8:
 		/* FIXME not null terminated */
 		/* TODO check syntax and overflow */
@@ -598,6 +632,7 @@
 		return binary_to_result(src, 1, cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		cr->ti = canonic;
 		return sizeof(TDS_TINYINT);
 		break;
@@ -605,14 +640,26 @@
 		cr->si = canonic;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		cr->usi = canonic;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		cr->i = canonic;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		cr->ui = canonic;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = canonic;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = canonic;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBFLT8:
 		cr->f = canonic;
 		return sizeof(TDS_FLOAT);
@@ -663,6 +710,7 @@
 		return binary_to_result(src, 1, cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		cr->ti = buf;
 		return sizeof(TDS_TINYINT);
 		break;
@@ -670,14 +718,26 @@
 		cr->si = buf;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		cr->usi = buf;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		cr->i = buf;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		cr->ui = buf;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = buf;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = buf;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = buf ? 1 : 0;
@@ -732,6 +792,7 @@
 		return binary_to_result(src, 2, cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if (!IS_TINYINT(buf))
 			return TDS_CONVERT_OVERFLOW;
 		cr->ti = (TDS_TINYINT) buf;
@@ -741,14 +802,26 @@
 		cr->si = buf;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		cr->usi = buf;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		cr->i = buf;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		cr->ui = buf;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = buf;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = buf;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = buf ? 1 : 0;
@@ -803,6 +876,7 @@
 		return binary_to_result(src, 4, cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if (!IS_TINYINT(buf))
 			return TDS_CONVERT_OVERFLOW;
 		cr->ti = buf;
@@ -814,14 +888,28 @@
 		cr->si = buf;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		if (!IS_USMALLINT(buf))
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = buf;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		cr->i = buf;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		cr->ui = buf;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = buf;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = buf;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = buf ? 1 : 0;
@@ -879,6 +967,7 @@
 		return binary_to_result(src, sizeof(TDS_INT8), cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if (!IS_TINYINT(buf))
 			return TDS_CONVERT_OVERFLOW;
 		cr->ti = (TDS_TINYINT) buf;
@@ -890,16 +979,32 @@
 		cr->si = (TDS_SMALLINT) buf;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		if (!IS_USMALLINT(buf))
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = (TDS_USMALLINT) buf;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		if (!IS_INT(buf))
 			return TDS_CONVERT_OVERFLOW;
 		cr->i = (TDS_INT) buf;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		if (!IS_UINT(buf))
+			return TDS_CONVERT_OVERFLOW;
+		cr->ui = (TDS_UINT) buf;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = buf;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = buf;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = buf ? 1 : 0;
@@ -959,6 +1064,7 @@
 		return binary_to_result(src, sizeof(TDS_NUMERIC), cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		cr->n = *src;
 		ret = tds_numeric_change_prec_scale(&(cr->n), 3, 0);
 		if (ret < 0)
@@ -983,6 +1089,21 @@
 		cr->si = (TDS_SMALLINT) i;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		cr->n = *src;
+		ret = tds_numeric_change_prec_scale(&(cr->n), 5, 0);
+		if (ret < 0)
+			return ret;
+		if (cr->n.array[1])
+			return TDS_CONVERT_OVERFLOW;
+		i = TDS_GET_UA2BE(&(cr->n.array[2]));
+		if (cr->n.array[0])
+			return TDS_CONVERT_OVERFLOW;
+		if (i > 65535)
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = (TDS_USMALLINT) i;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		cr->n = *src;
 		ret = tds_numeric_change_prec_scale(&(cr->n), 10, 0);
@@ -998,6 +1119,17 @@
 		cr->i = i;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		cr->n = *src;
+		ret = tds_numeric_change_prec_scale(&(cr->n), 10, 0);
+		if (ret < 0)
+			return ret;
+		if (cr->n.array[0] || cr->n.array[1])
+			return TDS_CONVERT_OVERFLOW;
+		i = TDS_GET_UA4BE(&(cr->n.array[2]));
+		cr->ui = i;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->n = *src;
 		ret = tds_numeric_change_prec_scale(&(cr->n), 20, 0);
@@ -1014,6 +1146,18 @@
 		cr->bi = bi;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->n = *src;
+		ret = tds_numeric_change_prec_scale(&(cr->n), 20, 0);
+		if (ret < 0)
+			return ret;
+		if (cr->n.array[0] || cr->n.array[1])
+			return TDS_CONVERT_OVERFLOW;
+		bi = TDS_GET_UA4BE(&(cr->n.array[2]));
+		bi = (bi << 32) + TDS_GET_UA4BE(&(cr->n.array[6]));
+		cr->ubi = bi;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = 0;
@@ -1091,6 +1235,7 @@
 		return binary_to_result(src, sizeof(TDS_MONEY4), cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		dollars = mny.mny4 / 10000;
 		if (!IS_TINYINT(dollars))
 			return TDS_CONVERT_OVERFLOW;
@@ -1104,14 +1249,29 @@
 		cr->si = (TDS_SMALLINT) dollars;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		dollars = mny.mny4 / 10000;
+		if (!IS_USMALLINT(dollars))
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = (TDS_USMALLINT) dollars;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		cr->i = mny.mny4 / 10000;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		cr->ui = mny.mny4 / 10000;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = mny.mny4 / 10000;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = mny.mny4 / 10000;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = mny.mny4 ? 1 : 0;
@@ -1181,6 +1341,7 @@
 		return binary_to_result(src, sizeof(TDS_MONEY), cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if (mymoney <= -10000 || mymoney >= 256 * 10000)
 			return TDS_CONVERT_OVERFLOW;
 		/* TODO: round ?? */
@@ -1193,6 +1354,12 @@
 		cr->si = (TDS_SMALLINT) (((TDS_INT) mymoney) / 10000);
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		if (mymoney <= -1 * 10000 || mymoney >= 65536 * 10000)
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = (TDS_USMALLINT) (((TDS_INT) mymoney) / 10000);
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		dollars = mymoney / 10000;
 		if (!IS_INT(dollars))
@@ -1200,10 +1367,21 @@
 		cr->i = (TDS_INT) dollars;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		dollars = mymoney / 10000;
+		if (!IS_UINT(dollars))
+			return TDS_CONVERT_OVERFLOW;
+		cr->ui = (TDS_UINT) dollars;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		cr->bi = mymoney / 10000;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		cr->ubi = mymoney / 10000;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = mymoney ? 1 : 0;
@@ -1281,9 +1459,13 @@
 	case SYBBIT:
 	case SYBBITN:
 	case SYBINT1:
+	case SYBUINT1:
 	case SYBINT2:
+	case SYBUINT2:
 	case SYBINT4:
+	case SYBUINT4:
 	case SYBINT8:
+	case SYBUINT8:
 	case SYBMONEY4:
 	case SYBMONEY:
 	case SYBNUMERIC:
@@ -1340,9 +1522,13 @@
 	case SYBBIT:
 	case SYBBITN:
 	case SYBINT1:
+	case SYBUINT1:
 	case SYBINT2:
+	case SYBUINT2:
 	case SYBINT4:
+	case SYBUINT4:
 	case SYBINT8:
+	case SYBUINT8:
 	case SYBMONEY4:
 	case SYBMONEY:
 	case SYBNUMERIC:
@@ -1397,6 +1583,7 @@
 		return binary_to_result(src, sizeof(TDS_REAL), cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if (!IS_TINYINT(the_value))
 			return TDS_CONVERT_OVERFLOW;
 		cr->ti = (TDS_TINYINT) the_value;
@@ -1408,18 +1595,36 @@
 		cr->si = (TDS_SMALLINT) the_value;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		if (!IS_USMALLINT(the_value))
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = (TDS_USMALLINT) the_value;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		if (!IS_INT(the_value))
 			return TDS_CONVERT_OVERFLOW;
 		cr->i = (TDS_INT) the_value;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		if (!IS_UINT(the_value))
+			return TDS_CONVERT_OVERFLOW;
+		cr->ui = (TDS_UINT) the_value;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		if (the_value > (TDS_REAL) TDS_INT8_MAX || the_value < (TDS_REAL) TDS_INT8_MIN)
 			return TDS_CONVERT_OVERFLOW;
 		cr->bi = (TDS_INT8) the_value;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		if (the_value > (TDS_REAL) TDS_UINT8_MAX || the_value < 0)
+			return TDS_CONVERT_OVERFLOW;
+		cr->ubi = (TDS_UINT8) the_value;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = the_value ? 1 : 0;
@@ -1491,6 +1696,7 @@
 		return binary_to_result(src, sizeof(TDS_FLOAT), cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		if (!IS_TINYINT(the_value))
 			return TDS_CONVERT_OVERFLOW;
 		cr->ti = (TDS_TINYINT) the_value;
@@ -1502,18 +1708,36 @@
 		cr->si = (TDS_SMALLINT) the_value;
 		return sizeof(TDS_SMALLINT);
 		break;
+	case SYBUINT2:
+		if (!IS_USMALLINT(the_value))
+			return TDS_CONVERT_OVERFLOW;
+		cr->usi = (TDS_USMALLINT) the_value;
+		return sizeof(TDS_USMALLINT);
+		break;
 	case SYBINT4:
 		if (!IS_INT(the_value))
 			return TDS_CONVERT_OVERFLOW;
 		cr->i = (TDS_INT) the_value;
 		return sizeof(TDS_INT);
 		break;
+	case SYBUINT4:
+		if (!IS_UINT(the_value))
+			return TDS_CONVERT_OVERFLOW;
+		cr->ui = (TDS_UINT) the_value;
+		return sizeof(TDS_UINT);
+		break;
 	case SYBINT8:
 		if (the_value > (TDS_FLOAT) TDS_INT8_MAX || the_value < (TDS_FLOAT) TDS_INT8_MIN)
 			return TDS_CONVERT_OVERFLOW;
 		cr->bi = (TDS_INT8) the_value;
 		return sizeof(TDS_INT8);
 		break;
+	case SYBUINT8:
+		if (the_value > (TDS_FLOAT) TDS_UINT8_MAX || the_value < 0)
+			return TDS_CONVERT_OVERFLOW;
+		cr->ubi = (TDS_UINT8) the_value;
+		return sizeof(TDS_UINT8);
+		break;
 	case SYBBIT:
 	case SYBBITN:
 		cr->ti = the_value ? 1 : 0;
@@ -1591,9 +1815,13 @@
 	case SYBBIT:
 	case SYBBITN:
 	case SYBINT1:
+	case SYBUINT1:
 	case SYBINT2:
+	case SYBUINT2:
 	case SYBINT4:
+	case SYBUINT4:
 	case SYBINT8:
+	case SYBUINT8:
 	case SYBMONEY4:
 	case SYBMONEY:
 	case SYBDATETIME4:
@@ -1657,15 +1885,19 @@
 		length = tds_convert_bit(srctype, src, desttype, cr);
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 		length = tds_convert_int1(srctype, src, desttype, cr);
 		break;
 	case SYBINT2:
+	case SYBUINT2:
 		length = tds_convert_int2(srctype, src, desttype, cr);
 		break;
 	case SYBINT4:
+	case SYBUINT4:
 		length = tds_convert_int4(srctype, src, desttype, cr);
 		break;
 	case SYBINT8:
+	case SYBUINT8:
 		length = tds_convert_int8(srctype, src, desttype, cr);
 		break;
 	case SYBREAL:
@@ -2688,9 +2920,13 @@
 		return SYBVARCHAR;
 		break;
 	case SYBINT1:
+	case SYBUINT1:
 	case SYBINT2:
+	case SYBUINT2:
 	case SYBINT4:
+	case SYBUINT4:
 	case SYBINT8:
+	case SYBUINT8:
 		return SYBINTN;
 		break;
 	case SYBREAL:
@@ -3201,5 +3437,56 @@
 	return sizeof(TDS_INT8);
 }
 
+/**
+ * \brief convert a number in string to TDS_UINT8
+ *
+ * \return TDS_CONVERT_* or failure code on error
+ */
+static TDS_INT	/* copied from string_to_int8 and modified */
+string_to_uint8(const char *buf, const char *pend, TDS_UINT8 * res)
+{
+	enum
+	{ blank = ' ' };
+	const char *p;
+	TDS_UINT8 num;
+
+	p = buf;
+
+	/* ignore leading spaces */
+	while (p != pend && *p == blank)
+		++p;
+	if (p == pend) {
+		*res = 0;
+		return sizeof(TDS_UINT8);
+	}
+
+	num = 0;
+	for (; p != pend; ++p) {
+		/* check for trailing spaces */
+		if (*p == blank) {
+			while (p != pend && *++p == blank);
+			if (p != pend)
+				return TDS_CONVERT_SYNTAX;
+			break;
+		}
+
+		/* must be a digit */
+		if (!isdigit((unsigned char) *p))
+			return TDS_CONVERT_SYNTAX;
+
+		/* add a digit to number and check for overflow */
+		if (num > ((((TDS_UINT8) 1) << 63) / ((TDS_UINT8) 10)))
+			return TDS_CONVERT_OVERFLOW;
+		num = num * 10u + (*p - '0');
+	}
+
+	/* check for overflow and convert unsigned to signed */
+	if (num >= (((TDS_UINT8) 1) << 63))
+		return TDS_CONVERT_OVERFLOW;
+	*res = num;
+
+	return sizeof(TDS_UINT8);
+}
+
 
 /** @} */
Index: src/tds/tds_willconvert.pl
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/tds_willconvert.pl,v
retrieving revision 1.3
diff -u -d -r1.3 tds_willconvert.pl
--- src/tds/tds_willconvert.pl	3 Jan 2009 15:26:09 -0000	1.3
+++ src/tds/tds_willconvert.pl	22 Dec 2012 20:18:47 -0000
@@ -35,26 +35,30 @@
 __DATA__
           To
 From
-          VARCHAR CHAR TEXT BINARY VARBINARY IMAGE INT1 INT2 INT4 INT8 FLT8 REAL NUMERIC DECIMAL BIT MONEY MONEY4 DATETIME DATETIME4 BOUNDARY UNIQUE SENSITIVITY
-VARCHAR     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
-CHAR        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
-TEXT        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
-BINARY      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-VARBINARY   T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-IMAGE       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-INT1        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-INT2        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-INT4        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-INT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-FLT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-REAL        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-NUMERIC     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-DECIMAL     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-BIT         T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-MONEY       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-MONEY4      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
-DATETIME    T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F        F
-DATETIME4   T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F        F
-BOUNDARY    T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     T        F        F
-UNIQUE      T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     F        T        F
-SENSITIVITY t      t   t    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     F        F        t
+          VARCHAR CHAR TEXT BINARY VARBINARY IMAGE INT1 UINT1 INT2 UINT2 INT4 UINT4 INT8 UINT8 FLT8 REAL NUMERIC DECIMAL BIT MONEY MONEY4 DATETIME DATETIME4 BOUNDARY UNIQUE SENSITIVITY
+VARCHAR     T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
+CHAR        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
+TEXT        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
+BINARY      T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+VARBINARY   T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+IMAGE       T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+INT1        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+UINT1       T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+INT2        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+UINT2       T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+INT4        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+UINT4       T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+INT8        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+UINT8       T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+FLT8        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+REAL        T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+NUMERIC     T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+DECIMAL     T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+BIT         T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+MONEY       T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+MONEY4      T      T   T    T	   T         T     T	T     T    T     T    T     T    T     T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
+DATETIME    T      T   T    T	   T         T     F	F     F    F     F    F     F    T     F    F	 F	 F	 F   F     F	  T	   T	     F        F        F
+DATETIME4   T      T   T    T	   T         T     F	F     F    F     F    F     F    T     F    F	 F	 F	 F   F     F	  T	   T	     F        F        F
+BOUNDARY    T      T   T    F	   F         F     F	F     F    F     F    F     F    T     F    F	 F	 F	 F   F     F	  F	   F	     T        F        F
+UNIQUE      T      T   T    F	   F         F     F	F     F    F     F    F     F    T     F    F	 F	 F	 F   F     F	  F	   F	     F        T        F
+SENSITIVITY t      t   t    F	   F         F     F	F     F    F     F    F     F    T     F    F	 F	 F	 F   F     F	  F	   F	     F        F        t
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.