Skip to Content.
Sympa Menu

freetds - Freetds bigint support patch

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Jason Borden" <jborden AT sorenson.com>
  • To: freetds AT franklin.oit.unc.edu
  • Subject: Freetds bigint support patch
  • Date: Wed, 9 Oct 2002 02:17:06 -0400


Here's a patch for bigint conversion support in src/tds and also bigint
support in src/odbc.

Cheers,
Jason

diff -r -u freetds/include/tdsconvert.h freetds-jb/include/tdsconvert.h
--- freetds/include/tdsconvert.h Fri Sep 13 14:13:16 2002
+++ freetds-jb/include/tdsconvert.h Tue Oct 8 23:54:56 2002
@@ -29,6 +29,7 @@
TDS_TINYINT ti;
TDS_SMALLINT si;
TDS_INT i;
+ TDS_INT8 bi;
TDS_FLOAT f;
TDS_REAL r;
TDS_CHAR *c;
@@ -55,6 +56,8 @@
int desttype,unsigned char *dest,TDS_INT destlen);
TDS_INT _convert_int4(int srctype,unsigned char *src,
int desttype,unsigned char *dest,TDS_INT destlen);
+TDS_INT _convert_int8(int srctype,unsigned char *src,
+ int desttype,unsigned char *dest,TDS_INT destlen);
TDS_INT _convert_flt8(int srctype,unsigned char *src,int
desttype,unsigned char *dest,TDS_INT destlen);
TDS_INT _convert_datetime(int srctype,unsigned char *src,int
desttype,unsigned char *dest,TDS_INT destlen);
int _get_conversion_type(int srctype, int colsize);
diff -r -u freetds/src/odbc/convert_sql2string.c
freetds-jb/src/odbc/convert_sql2string.c
--- freetds/src/odbc/convert_sql2string.c Sun Sep 15 10:08:24 2002
+++ freetds-jb/src/odbc/convert_sql2string.c Tue Oct 8 23:54:56 2002
@@ -46,6 +46,7 @@
case SQL_C_BIT:
return SYBBIT;
#if (ODBCVER >= 0x0300)
+ case SQL_BIGINT:
case SQL_C_SBIGINT:
case SQL_C_UBIGINT:
return SYBINT8;
diff -r -u freetds/src/odbc/convert_tds2sql.c
freetds-jb/src/odbc/convert_tds2sql.c
--- freetds/src/odbc/convert_tds2sql.c Sun Sep 15 10:08:24 2002
+++ freetds-jb/src/odbc/convert_tds2sql.c Tue Oct 8 23:54:56 2002
@@ -50,6 +50,11 @@
case SQL_C_TIMESTAMP:
return SYBDATETIME;

+ case SQL_BIGINT:
+ case SQL_C_SBIGINT:
+ case SQL_C_UBIGINT:
+ return SYBINT8;
+
case SQL_C_LONG:
case SQL_C_ULONG:
case SQL_C_SLONG:
@@ -96,6 +101,7 @@
TIMESTAMP_STRUCT *tssp;
SQL_NUMERIC_STRUCT *num;

+ TDS_UINT8 *uip8;
TDS_UINT *uip;
TDS_USMALLINT *usip;

@@ -196,6 +202,18 @@
ret = sizeof(TIMESTAMP_STRUCT);
break;

+ case SQL_BIGINT:
+ case SQL_C_SBIGINT:
+ memcpy(dest, &(ores.i), sizeof(TDS_INT8));
+ ret = sizeof(TDS_INT8);
+ break;
+
+ case SQL_C_UBIGINT:
+ uip = (TDS_UINT8 *)dest;
+ *uip = ores.i;
+ ret = sizeof(TDS_UINT8);
+ break;
+
case SQL_C_LONG:
case SQL_C_SLONG:
memcpy(dest, &(ores.i), sizeof(TDS_INT));
diff -r -u freetds/src/odbc/odbc.c freetds-jb/src/odbc/odbc.c
--- freetds/src/odbc/odbc.c Sun Sep 15 10:08:24 2002
+++ freetds-jb/src/odbc/odbc.c Tue Oct 8 23:54:56 2002
@@ -2265,6 +2265,8 @@
return SQL_C_SSHORT;
case SQL_INTEGER:
return SQL_C_SLONG;
+ case SQL_BIGINT:
+ return SQL_C_SBIGINT;
case SQL_REAL:
return SQL_C_FLOAT;
case SQL_FLOAT:
--- freetds/src/tds/convert.c Fri Sep 13 17:43:58 2002
+++ freetds-jb/src/tds/convert.c Tue Oct 8 23:55:09 2002
@@ -63,6 +63,12 @@
*/
static TDS_INT string_to_int(const char *buf,const char *pend,TDS_INT*
res);

+/**
+ * conver a number in string to TDS_INT8
+ * @return TDS_FAIL if failure
+ */
+static TDS_INT8 string_to_int8(const char *buf, const char *pend,
TDS_INT8* res);
+
#define TDS_CONVERT_NOAVAIL -2
/**
* convert, same as tds_convert but not return error to client
@@ -256,6 +262,7 @@
case SYBINT1:
case SYBINT2:
case SYBINT4:
+ case SYBINT8:
case SYBMONEY4:
case SYBMONEY:
case SYBREAL:
@@ -301,6 +308,7 @@
const char *ptr, *pend;
int point_found, places;
TDS_INT tds_i;
+TDS_INT8 tds_i8;


switch(desttype) {
@@ -425,7 +433,13 @@
return TDS_FAIL;
cr->i = tds_i;
return 4;
- break;
+ break;
+ case SYBINT8:
+ if (string_to_int8(src, src + srclen, &tds_i8) ==
TDS_FAIL)
+ return TDS_FAIL;
+ cr->bi = tds_i8;
+ return 8;
+ break;
case SYBFLT8:
cr->f = atof(src);
return 8;
@@ -601,6 +615,10 @@
cr->i = canonic;
return 4;
break;
+ case SYBINT8:
+ cr->bi = canonic;
+ return 8;
+ break;
case SYBFLT8:
cr->f = canonic;
return 8;
@@ -667,6 +685,10 @@
cr->i = buf;
return 4;
break;
+ case SYBINT8:
+ cr->bi = buf;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = buf ? 1 : 0;
@@ -738,6 +760,10 @@
cr->i = buf;
return 4;
break;
+ case SYBINT8:
+ cr->bi = buf;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = buf ? 1 : 0;
@@ -811,6 +837,10 @@
cr->i = buf;
return 4;
break;
+ case SYBINT8:
+ cr->bi = buf;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = buf ? 1 : 0;
@@ -852,6 +882,85 @@
return TDS_FAIL;
}
static TDS_INT
+tds_convert_int8(int srctype,TDS_CHAR *src,
+ int desttype,TDS_INT destlen, CONV_RESULT *cr)
+{
+TDS_INT8 buf;
+TDS_CHAR tmp_str[20];
+
+ memcpy(&buf,src,sizeof(buf));
+ switch(desttype) {
+ case SYBCHAR:
+ case SYBTEXT:
+ case SYBVARCHAR:
+ sprintf(tmp_str,"%lld",buf);
+ return string_to_result(tmp_str,cr);
+ break;
+ case SYBBINARY:
+ case SYBIMAGE:
+ return binary_to_result(src,8,cr);
+ break;
+ case SYBINT1:
+ if (!IS_TINYINT(buf))
+ return TDS_FAIL;
+ cr->ti = buf;
+ return 1;
+ break;
+ case SYBINT2:
+ if ( !IS_SMALLINT(buf) )
+ return TDS_FAIL;
+ cr->si = buf;
+ return 2;
+ break;
+ case SYBINT4:
+ cr->i = buf;
+ return 4;
+ break;
+ case SYBINT8:
+ cr->bi = buf;
+ return 8;
+ break;
+ case SYBBIT:
+ case SYBBITN:
+ cr->ti = buf ? 1 : 0;
+ return 1;
+ break;
+ case SYBFLT8:
+ cr->f = buf;
+ return 8;
+ break;
+ case SYBREAL:
+ cr->r = buf;
+ return 4;
+ break;
+ case SYBMONEY4:
+ if (buf > 214748 || buf < -214748)
+ return TDS_FAIL;
+ cr->m4.mny4 = buf * 10000;
+ return 4;
+ break;
+ case SYBMONEY:
+ cr->m.mny = (TDS_INT8)buf * 10000;
+ return sizeof(TDS_MONEY);
+ break;
+ case SYBNUMERIC:
+ case SYBDECIMAL:
+ sprintf(tmp_str,"%lld",buf);
+ return stringz_to_numeric(tmp_str,cr);
+ break;
+ /* conversions not allowed */
+ case SYBUNIQUE:
+ case SYBDATETIME4:
+ case SYBDATETIME:
+ case SYBDATETIMN:
+ break;
+ default:
+ LOG_CONVERT();
+ return TDS_FAIL;
+ }
+ return TDS_FAIL;
+}
+static TDS_INT
tds_convert_numeric(int srctype,TDS_NUMERIC *src,TDS_INT srclen,
int desttype,TDS_INT destlen, CONV_RESULT *cr)
{
@@ -893,6 +1002,11 @@
cr->i = i;
return 4;
break;
+ case SYBINT8:
+ tds_numeric_to_string(src,tmpstr);
+ cr->bi = atoll(tmpstr);
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = 0;
@@ -978,6 +1092,10 @@
cr->i = mny.mny4 / 10000;
return 4;
break;
+ case SYBINT8:
+ cr->bi = (TDS_INT8)mny.mny4 / 10000;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = mny.mny4 ? 1 : 0;
@@ -1110,6 +1228,11 @@
cr->i = dollars;
return 4;
break;
+ case SYBINT8:
+ dollars = mymoney / 10000;
+ cr->bi = dollars;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = mymoney ? 1 : 0;
@@ -1263,6 +1386,7 @@
case SYBINT1:
case SYBINT2:
case SYBINT4:
+ case SYBINT8:
case SYBMONEY4:
case SYBMONEY:
case SYBNUMERIC:
@@ -1373,6 +1497,7 @@
case SYBINT1:
case SYBINT2:
case SYBINT4:
+ case SYBINT8:
case SYBMONEY4:
case SYBMONEY:
case SYBNUMERIC:
@@ -1428,6 +1553,10 @@
cr->i = the_value;
return 4;
break;
+ case SYBINT8:
+ cr->bi = the_value;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = the_value ? 1 : 0;
@@ -1511,6 +1640,10 @@
cr->i = the_value;
return 4;
break;
+ case SYBINT8:
+ cr->bi = the_value;
+ return 8;
+ break;
case SYBBIT:
case SYBBITN:
cr->ti = the_value ? 1 : 0;
@@ -1589,6 +1722,7 @@
case SYBINT1:
case SYBINT2:
case SYBINT4:
+ case SYBINT8:
case SYBMONEY4:
case SYBMONEY:
case SYBDATETIME4:
@@ -1721,6 +1855,9 @@
case SYBINT4:
length= tds_convert_int4(srctype,src,
desttype,destlen, cr);
break;
+ case SYBINT8:
+ length= tds_convert_int8(srctype,src,
desttype,destlen, cr);
+ break;
case SYBREAL:
length= tds_convert_real(srctype,src,
desttype,destlen, cr);
break;
@@ -2645,6 +2782,7 @@
case SYBINT1:
case SYBINT2:
case SYBINT4:
+ case SYBINT8:
return SYBINTN;
break;
case SYBREAL:
@@ -3004,6 +3142,72 @@
return TDS_FAIL;
*res = num;
}
+
+ return TDS_SUCCEED;
+}
+
+static TDS_INT8
+string_to_int8(const char *buf,const char *pend,TDS_INT8* res)
+{
+enum { blank = ' ' };
+const char *p;
+int sign;
+unsigned int num; /* we use unsigned here for best overflow check */
+
+ p = buf;
+
+ /* ignore leading spaces */
+ while( p != pend && *p == blank )
+ ++p;
+ if (p==pend) return TDS_FAIL;
+
+ /* check for sign */
+ sign = 0;
+ switch ( *p ) {
+ case '-':
+ sign = 1;
+ /* fall thru */
+ case '+':
+ /* skip spaces between sign and number */
+ ++p;
+ while( p != pend && *p == blank )
+ ++p;
+ break;
+ }
+
+ /* a digit must be present */
+ if (p == pend )
+ return TDS_FAIL;
+
+ num = 0;
+ for(;p != pend;++p) {
+ /* check for trailing spaces */
+ if (*p == blank) {
+ while( p != pend && *++p == blank);
+ if (p!=pend) return TDS_FAIL;
+ break;
+ }
+
+ /* must be a digit */
+ if (!isdigit(*p))
+ return TDS_FAIL;
+
+ /* add a digit to number and check for overflow */
+ if (num > 922337203685477580ull)
+ return TDS_FAIL;
+ num = num * 10u + (*p-'0');
+ }
+
+ /* check for overflow and convert unsigned to signed */
+ if (sign) {
+ if (num > 9223372036854775808ull)
+ return TDS_FAIL;
+ *res = 0 - num;
+ } else {
+ if (num >= 9223372036854775808ull)
+ return TDS_FAIL;
+ *res = num;
+ }

return TDS_SUCCEED;
}
diff -r -u freetds/src/tds/tds_willconvert.h
freetds-jb/src/tds/tds_willconvert.h
--- freetds/src/tds/tds_willconvert.h Thu Aug 15 23:58:04 2002
+++ freetds-jb/src/tds/tds_willconvert.h Tue Oct 8 23:55:09 2002
@@ -13,6 +13,7 @@
, { SYBVARCHAR, SYBINT1 , 1 }
, { SYBVARCHAR, SYBINT2 , 1 }
, { SYBVARCHAR, SYBINT4 , 1 }
+ , { SYBVARCHAR, SYBINT8 , 1 }
, { SYBVARCHAR, SYBFLT8 , 1 }
, { SYBVARCHAR, SYBREAL , 1 }
, { SYBVARCHAR, SYBNUMERIC , 1 }
@@ -30,6 +31,7 @@
, { SYBCHAR, SYBINT1 , 1 }
, { SYBCHAR, SYBINT2 , 1 }
, { SYBCHAR, SYBINT4 , 1 }
+ , { SYBCHAR, SYBINT8 , 1 }
, { SYBCHAR, SYBFLT8 , 1 }
, { SYBCHAR, SYBREAL , 1 }
, { SYBCHAR, SYBNUMERIC , 1 }
@@ -47,6 +49,7 @@
, { SYBTEXT, SYBINT1 , 1 }
, { SYBTEXT, SYBINT2 , 1 }
, { SYBTEXT, SYBINT4 , 1 }
+ , { SYBTEXT, SYBINT8 , 1 }
, { SYBTEXT, SYBFLT8 , 1 }
, { SYBTEXT, SYBREAL , 1 }
, { SYBTEXT, SYBNUMERIC , 1 }
@@ -64,6 +67,7 @@
, { SYBBINARY, SYBINT1 , 1 }
, { SYBBINARY, SYBINT2 , 1 }
, { SYBBINARY, SYBINT4 , 1 }
+ , { SYBBINARY, SYBINT8 , 1 }
, { SYBBINARY, SYBFLT8 , 1 }
, { SYBBINARY, SYBREAL , 1 }
, { SYBBINARY, SYBNUMERIC , 1 }
@@ -81,6 +85,7 @@
, { SYBIMAGE, SYBINT1 , 1 }
, { SYBIMAGE, SYBINT2 , 1 }
, { SYBIMAGE, SYBINT4 , 1 }
+ , { SYBIMAGE, SYBINT8 , 1 }
, { SYBIMAGE, SYBFLT8 , 1 }
, { SYBIMAGE, SYBREAL , 1 }
, { SYBIMAGE, SYBNUMERIC , 1 }
@@ -98,6 +103,7 @@
, { SYBINT1, SYBINT1 , 1 }
, { SYBINT1, SYBINT2 , 1 }
, { SYBINT1, SYBINT4 , 1 }
+ , { SYBINT1, SYBINT8 , 1 }
, { SYBINT1, SYBFLT8 , 1 }
, { SYBINT1, SYBREAL , 1 }
, { SYBINT1, SYBNUMERIC , 1 }
@@ -115,6 +121,7 @@
, { SYBINT2, SYBINT1 , 1 }
, { SYBINT2, SYBINT2 , 1 }
, { SYBINT2, SYBINT4 , 1 }
+ , { SYBINT2, SYBINT8 , 1 }
, { SYBINT2, SYBFLT8 , 1 }
, { SYBINT2, SYBREAL , 1 }
, { SYBINT2, SYBNUMERIC , 1 }
@@ -132,6 +139,7 @@
, { SYBINT4, SYBINT1 , 1 }
, { SYBINT4, SYBINT2 , 1 }
, { SYBINT4, SYBINT4 , 1 }
+ , { SYBINT4, SYBINT8 , 1 }
, { SYBINT4, SYBFLT8 , 1 }
, { SYBINT4, SYBREAL , 1 }
, { SYBINT4, SYBNUMERIC , 1 }
@@ -141,6 +149,24 @@
, { SYBINT4, SYBMONEY4 , 1 }
, { SYBINT4, SYBDATETIME , 0 }
, { SYBINT4, SYBDATETIME4 , 0 }
+ , { SYBINT8, SYBVARCHAR , 1 }
+ , { SYBINT8, SYBCHAR , 1 }
+ , { SYBINT8, SYBTEXT , 1 }
+ , { SYBINT8, SYBBINARY , 1 }
+ , { SYBINT8, SYBIMAGE , 1 }
+ , { SYBINT8, SYBINT1 , 1 }
+ , { SYBINT8, SYBINT2 , 1 }
+ , { SYBINT8, SYBINT4 , 1 }
+ , { SYBINT8, SYBINT8 , 1 }
+ , { SYBINT8, SYBFLT8 , 1 }
+ , { SYBINT8, SYBREAL , 1 }
+ , { SYBINT8, SYBNUMERIC , 1 }
+ , { SYBINT8, SYBDECIMAL , 1 }
+ , { SYBINT8, SYBBIT , 1 }
+ , { SYBINT8, SYBMONEY , 1 }
+ , { SYBINT8, SYBMONEY4 , 1 }
+ , { SYBINT8, SYBDATETIME , 0 }
+ , { SYBINT8, SYBDATETIME4 , 0 }
, { SYBFLT8, SYBVARCHAR , 1 }
, { SYBFLT8, SYBCHAR , 1 }
, { SYBFLT8, SYBTEXT , 1 }
@@ -149,6 +175,7 @@
, { SYBFLT8, SYBINT1 , 1 }
, { SYBFLT8, SYBINT2 , 1 }
, { SYBFLT8, SYBINT4 , 1 }
+ , { SYBFLT8, SYBINT8 , 1 }
, { SYBFLT8, SYBFLT8 , 1 }
, { SYBFLT8, SYBREAL , 1 }
, { SYBFLT8, SYBNUMERIC , 1 }
@@ -166,6 +193,7 @@
, { SYBREAL, SYBINT1 , 1 }
, { SYBREAL, SYBINT2 , 1 }
, { SYBREAL, SYBINT4 , 1 }
+ , { SYBREAL, SYBINT8 , 1 }
, { SYBREAL, SYBFLT8 , 1 }
, { SYBREAL, SYBREAL , 1 }
, { SYBREAL, SYBNUMERIC , 1 }
@@ -183,6 +211,7 @@
, { SYBNUMERIC, SYBINT1 , 1 }
, { SYBNUMERIC, SYBINT2 , 1 }
, { SYBNUMERIC, SYBINT4 , 1 }
+ , { SYBNUMERIC, SYBINT8 , 1 }
, { SYBNUMERIC, SYBFLT8 , 1 }
, { SYBNUMERIC, SYBREAL , 1 }
, { SYBNUMERIC, SYBNUMERIC , 1 }
@@ -200,6 +229,7 @@
, { SYBDECIMAL, SYBINT1 , 1 }
, { SYBDECIMAL, SYBINT2 , 1 }
, { SYBDECIMAL, SYBINT4 , 1 }
+ , { SYBDECIMAL, SYBINT8 , 1 }
, { SYBDECIMAL, SYBFLT8 , 1 }
, { SYBDECIMAL, SYBREAL , 1 }
, { SYBDECIMAL, SYBNUMERIC , 1 }
@@ -217,6 +247,7 @@
, { SYBBIT, SYBINT1 , 1 }
, { SYBBIT, SYBINT2 , 1 }
, { SYBBIT, SYBINT4 , 1 }
+ , { SYBBIT, SYBINT8 , 1 }
, { SYBBIT, SYBFLT8 , 1 }
, { SYBBIT, SYBREAL , 1 }
, { SYBBIT, SYBNUMERIC , 1 }
@@ -234,6 +265,7 @@
, { SYBMONEY, SYBINT1 , 1 }
, { SYBMONEY, SYBINT2 , 1 }
, { SYBMONEY, SYBINT4 , 1 }
+ , { SYBMONEY, SYBINT8 , 1 }
, { SYBMONEY, SYBFLT8 , 1 }
, { SYBMONEY, SYBREAL , 1 }
, { SYBMONEY, SYBNUMERIC , 1 }
@@ -251,6 +283,7 @@
, { SYBMONEY4, SYBINT1 , 1 }
, { SYBMONEY4, SYBINT2 , 1 }
, { SYBMONEY4, SYBINT4 , 1 }
+ , { SYBMONEY4, SYBINT8 , 1 }
, { SYBMONEY4, SYBFLT8 , 1 }
, { SYBMONEY4, SYBREAL , 1 }
, { SYBMONEY4, SYBNUMERIC , 1 }
@@ -268,6 +301,7 @@
, { SYBDATETIME, SYBINT1 , 0 }
, { SYBDATETIME, SYBINT2 , 0 }
, { SYBDATETIME, SYBINT4 , 0 }
+ , { SYBDATETIME, SYBINT8 , 0 }
, { SYBDATETIME, SYBFLT8 , 0 }
, { SYBDATETIME, SYBREAL , 0 }
, { SYBDATETIME, SYBNUMERIC , 0 }
@@ -285,6 +319,7 @@
, { SYBDATETIME4, SYBINT1 , 0 }
, { SYBDATETIME4, SYBINT2 , 0 }
, { SYBDATETIME4, SYBINT4 , 0 }
+ , { SYBDATETIME4, SYBINT8 , 0 }
, { SYBDATETIME4, SYBFLT8 , 0 }
, { SYBDATETIME4, SYBREAL , 0 }
, { SYBDATETIME4, SYBNUMERIC , 0 }




Archive powered by MHonArc 2.6.24.

Top of Page