summaryrefslogtreecommitdiffstats
path: root/dev-db/freetds
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2019-09-01 00:00:32 +0200
committerSuren A. Chilingaryan <csa@suren.me>2019-09-01 00:00:32 +0200
commitca9627e70852f6b2e835660df870fe3ab405882d (patch)
tree0a008b1d5b16fa0679a195ed7b5662c7891f591c /dev-db/freetds
downloaddarklin4-ca9627e70852f6b2e835660df870fe3ab405882d.tar.gz
darklin4-ca9627e70852f6b2e835660df870fe3ab405882d.tar.bz2
darklin4-ca9627e70852f6b2e835660df870fe3ab405882d.tar.xz
darklin4-ca9627e70852f6b2e835660df870fe3ab405882d.zip
Initial import
Diffstat (limited to 'dev-db/freetds')
-rw-r--r--dev-db/freetds/Manifest13
-rw-r--r--dev-db/freetds/files/SQLGetData.utf8.odbc.c-r3.diff196
-rw-r--r--dev-db/freetds/files/SQLGetData.utf8.odbc.c.diff199
-rw-r--r--dev-db/freetds/files/SQLGetData_cvs.patch67
-rw-r--r--dev-db/freetds/files/freetds-0.82-odbc-csa2.patch484
-rw-r--r--dev-db/freetds/files/freetds-20080603-odbc-csa2.patch404
-rw-r--r--dev-db/freetds/files/freetds-ds-connect_timeout.patch12
-rw-r--r--dev-db/freetds/files/freetds-ds-odbc.patch222
-rw-r--r--dev-db/freetds/freetds-0.82-r1.ebuild37
-rw-r--r--dev-db/freetds/freetds-0.82-r2.ebuild38
-rw-r--r--dev-db/freetds/freetds-0.82-r3.ebuild37
-rw-r--r--dev-db/freetds/freetds-0.82-r4.ebuild38
-rw-r--r--dev-db/freetds/freetds-0.82-r5.ebuild38
13 files changed, 1785 insertions, 0 deletions
diff --git a/dev-db/freetds/Manifest b/dev-db/freetds/Manifest
new file mode 100644
index 0000000..82ebebf
--- /dev/null
+++ b/dev-db/freetds/Manifest
@@ -0,0 +1,13 @@
+AUX SQLGetData.utf8.odbc.c-r3.diff 6680 RMD160 6198a9fbc7672e0ac8683feb07bf720cb8a5867b SHA1 d2aea252de40b45dc690c0f53d14bbfc0c6650ff SHA256 eb32b59a11ed2c02c326fc565370bfed09fadcdd828e2ce8851a8614161beec2
+AUX SQLGetData.utf8.odbc.c.diff 6780 RMD160 6283137106503c40dec71ea526cf16eacdb9b3e7 SHA1 989ada87c5d7ef7984ff82698a93caa26af61045 SHA256 4f60e53f3b4157c8ee22752d2fa32c5b4546d1ae8248644898af7222ee7cc69e
+AUX SQLGetData_cvs.patch 2134 RMD160 ac879054de7207801777908d9d7d9ee8e1209d3e SHA1 cb6a20dd4f29cde581c1e75ddf68f65ce84d498a SHA256 2ce73cfb9a1bd8f60296d3374221fce82eda46f7d2c4318eb8471af694e3443c
+AUX freetds-0.82-odbc-csa2.patch 15631 RMD160 d92b72af4e22d25a3b6323bdddb23d1fc809ccee SHA1 40fc02b4303301576ea52e8da69e78138f0ef235 SHA256 930994cd10fff36888a9ef0cf19b4ea9aa5a5bf94f77e258f7e2c5d7379b5e24
+AUX freetds-20080603-odbc-csa2.patch 12562 RMD160 39dd4ba34d88860328af7c305337068e4cabc3c5 SHA1 55542007834caa4c8336abd3bd53a5ce3bcfb913 SHA256 03f4b9d4e1b38cd488937a5b00788935ad3782b0b2395755365bbe8f22f13b5c
+AUX freetds-ds-connect_timeout.patch 492 RMD160 9bb69de4e2b5c7277b87aa1b2856db8f0a96756e SHA1 ae59f058e1499954695031bc0bf18b04084938a9 SHA256 ef97347277242c00d6f86c2726b5011735592942f148919ba6bf6b1b6413ac76
+AUX freetds-ds-odbc.patch 7592 RMD160 1a621530d8e15a4807a0dc4490165db65c4f4c06 SHA1 30fc69ca0d3a8ed7cdf0dd95805786dfc536bf6a SHA256 73258ba07157a24ff31cc6b9cc27ab41908d26fafc69c932c577e5be0cf87532
+DIST freetds-0.82.tar.gz 1596755 RMD160 d3596c512022332cdb3bab375950159f1e930a4b SHA1 7e2a0c9e41c240c2d1c7f69c6f278e9a5bb80c2d SHA256 e2731483614bd992c8cb133bcc38432de13cfa243cc1327f37412db50c99b2b6
+EBUILD freetds-0.82-r1.ebuild 996 RMD160 fb51029110a0eabd312fe13675446b8a49028352 SHA1 0ea5d137d3b61aafad5ade6f9c88700ce9b6c8c2 SHA256 bc2c84bb1261012068e6360d94dd4bb84ca2d0bfbf77d0c42caac165880273e8
+EBUILD freetds-0.82-r2.ebuild 1054 RMD160 7ba5c67a5f70851c2b96bd3bbab4c18619cf5adf SHA1 16477de40b943d764002559755543b7fe19c46d1 SHA256 1621385bc1b02a96cfaaeb2bdbcc8c1c73f5a145f610cab4cd80451ea317c08c
+EBUILD freetds-0.82-r3.ebuild 1007 RMD160 0ee4b2cb6047ab0792db4fe35209223513ac4990 SHA1 2e78d88ddf37812fa5a44e6d338977cb817c83cc SHA256 d2295661da6ed18edd2b5506d0c3ade70d2be1855d6d1e9bcebba366672c19e0
+EBUILD freetds-0.82-r4.ebuild 1069 RMD160 759a7399b4e4e83dd49946cd0a016d9a2ada12ec SHA1 27564de2ae850fd52fde2c230922b03b56aa4f70 SHA256 8cb7180c10b328558e0a7d97b359a4ebaedd9f98f86a41ff3c442eda318f8136
+EBUILD freetds-0.82-r5.ebuild 1067 RMD160 6ceb0e8fb1a88c43c16ff6257ca9531925493840 SHA1 82067b926263c2c897aff56d254634d6f0895f67 SHA256 ad5d3a99eac7a68daa9ca6b88a31a7760f7cb257d0f568877a466065d2d2a006
diff --git a/dev-db/freetds/files/SQLGetData.utf8.odbc.c-r3.diff b/dev-db/freetds/files/SQLGetData.utf8.odbc.c-r3.diff
new file mode 100644
index 0000000..0039347
--- /dev/null
+++ b/dev-db/freetds/files/SQLGetData.utf8.odbc.c-r3.diff
@@ -0,0 +1,196 @@
+diff -dPNur freetds-0.82/src/odbc/odbc.c freetds-0.82-new-ds/src/odbc/odbc.c
+--- freetds-0.82/src/odbc/odbc.c 2008-05-06 04:57:26.000000000 +0200
++++ freetds-0.82-new-ds/src/odbc/odbc.c 2008-06-25 22:47:06.000000000 +0200
+@@ -4564,6 +4564,9 @@
+ SQLLEN dummy_cb;
+ int nSybType;
+
++ TDS_INT converted_column_cur_size;
++ int extra_bytes = 0;
++
+ INIT_HSTMT;
+
+ tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n",
+@@ -4597,46 +4600,154 @@
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ colinfo = resinfo->columns[icol - 1];
++ converted_column_cur_size = colinfo->column_cur_size;
+
+ if (colinfo->column_cur_size < 0) {
+ *pcbValue = SQL_NULL_DATA;
+ } else {
++ nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++ if (fCType == SQL_C_DEFAULT)
++ fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++ if (fCType == SQL_ARD_TYPE) {
++ if (icol > stmt->ard->header.sql_desc_count) {
++ odbc_errs_add(&stmt->errs, "07009", NULL);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++ }
++ assert(fCType);
++
+ src = (TDS_CHAR *) colinfo->column_data;
+ if (is_variable_type(colinfo->column_type)) {
+- if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+- ODBC_RETURN(stmt, SQL_NO_DATA);
+-
++ int nread = 0;
++
+ /* 2003-8-29 check for an old bug -- freddy77 */
+ assert(colinfo->column_text_sqlgetdatapos >= 0);
+ if (is_blob_type(colinfo->column_type))
+ src = ((TDSBLOB *) src)->textvalue;
+- src += colinfo->column_text_sqlgetdatapos;
+- srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ if (fCType == SQL_C_CHAR) {
++ TDS_CHAR buf[3];
++ SQLLEN len;
++
++ switch (nSybType) {
++ case SYBLONGBINARY:
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case SYBIMAGE:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case TDS_CONVERT_BINARY:
++ if (colinfo->column_text_sqlgetdatapos % 2) {
++ nread = (colinfo->column_text_sqlgetdatapos - 1) / 2;
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ if (cbValueMax > 2) {
++ len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
++ if (len < 2) {
++ if (len < 0)
++ odbc_convert_err_set(&stmt->errs, len);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ *(TDS_CHAR *) rgbValue = buf[1];
++ *((TDS_CHAR *) rgbValue + 1) = 0;
++
++ rgbValue++;
++ cbValueMax--;
++
++ extra_bytes = 1;
++ nread++;
++
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN_(stmt);
++ } else {
++ if (cbValueMax)
++ *(TDS_CHAR *) rgbValue = 0;
++ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
++ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
++ }
++ } else {
++ nread = colinfo->column_text_sqlgetdatapos / 2;
++
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++ }
++
++ src += nread;
++ srclen = colinfo->column_cur_size - nread;
++ converted_column_cur_size *= 2;
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ }
++ } else if (fCType == SQL_C_BINARY) {
++ switch (nSybType) {
++ case SYBCHAR:
++ case SYBVARCHAR:
++ case SYBTEXT:
++ case XSYBCHAR:
++ case XSYBVARCHAR:
++ nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
++
++ while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0'))
++ nread++;
++
++ nread += colinfo->column_text_sqlgetdatapos * 2;
++
++ if (nread && nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += nread;
++ srclen = colinfo->column_cur_size - nread;
++
++ if (converted_column_cur_size%2)
++ converted_column_cur_size = (converted_column_cur_size + 1) / 2;
++ else
++ converted_column_cur_size /= 2;
++
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
++ } else {
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
+ } else {
+ if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+ ODBC_RETURN(stmt, SQL_NO_DATA);
+
+ srclen = colinfo->column_cur_size;
+ }
+- nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+- if (fCType == SQL_C_DEFAULT)
+- fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+- if (fCType == SQL_ARD_TYPE) {
+- if (icol > stmt->ard->header.sql_desc_count) {
+- odbc_errs_add(&stmt->errs, "07009", NULL);
+- ODBC_RETURN(stmt, SQL_ERROR);
+- }
+- fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+- }
+- assert(fCType);
++
+ *pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ if (*pcbValue < 0) {
+ odbc_convert_err_set(&stmt->errs, *pcbValue);
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+-
++
++ if (extra_bytes) {
++ colinfo->column_text_sqlgetdatapos += extra_bytes;
++ *pcbValue += extra_bytes;
++ }
++
+ if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ /* calc how many bytes was readed */
+ int readed = cbValueMax;
+@@ -4651,7 +4762,7 @@
+ if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ ++colinfo->column_text_sqlgetdatapos;
+ /* not all readed ?? */
+- if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {
++ if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) {
+ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ }
diff --git a/dev-db/freetds/files/SQLGetData.utf8.odbc.c.diff b/dev-db/freetds/files/SQLGetData.utf8.odbc.c.diff
new file mode 100644
index 0000000..91a8fca
--- /dev/null
+++ b/dev-db/freetds/files/SQLGetData.utf8.odbc.c.diff
@@ -0,0 +1,199 @@
+Index: src/odbc/odbc.c
+===================================================================
+RCS file: /cvsroot/freetds/freetds/src/odbc/odbc.c,v
+retrieving revision 1.481
+diff -u -r1.481 odbc.c
+--- src/odbc/odbc.c 5 Jun 2008 16:21:54 -0000 1.481
++++ src/odbc/odbc.c 12 Jun 2008 01:55:58 -0000
+@@ -4644,6 +4646,8 @@
+ SQLLEN dummy_cb;
+ int nSybType;
+
++ int extra_bytes = 0;
++
+ INIT_HSTMT;
+
+ tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n",
+@@ -4684,42 +4688,140 @@
+ if (colinfo->column_cur_size < 0) {
+ *pcbValue = SQL_NULL_DATA;
+ } else {
++ nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++ if (fCType == SQL_C_DEFAULT)
++ fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++ if (fCType == SQL_ARD_TYPE) {
++ if (icol > stmt->ard->header.sql_desc_count) {
++ odbc_errs_add(&stmt->errs, "07009", NULL);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++ }
++ assert(fCType);
++
+ src = (TDS_CHAR *) colinfo->column_data;
+ if (is_variable_type(colinfo->column_type)) {
+- if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+- ODBC_RETURN(stmt, SQL_NO_DATA);
+-
++ int nread = 0;
++
+ /* 2003-8-29 check for an old bug -- freddy77 */
+ assert(colinfo->column_text_sqlgetdatapos >= 0);
+ if (is_blob_type(colinfo->column_type))
+ src = ((TDSBLOB *) src)->textvalue;
+- src += colinfo->column_text_sqlgetdatapos;
+- srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
++ TDS_CHAR buf[3];
++ SQLLEN len;
++
++ switch (nSybType) {
++ case SYBLONGBINARY:
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case SYBIMAGE:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case TDS_CONVERT_BINARY:
++ if (colinfo->column_text_sqlgetdatapos % 2) {
++ nread = (colinfo->column_text_sqlgetdatapos - 1) / 2;
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ if (cbValueMax > 2) {
++ len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
++ if (len < 2) {
++ if (len < 0)
++ odbc_convert_err_set(&stmt->errs, len);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ *(TDS_CHAR *) rgbValue = buf[1];
++ *((TDS_CHAR *) rgbValue + 1) = 0;
++
++ rgbValue++;
++ cbValueMax--;
++
++ extra_bytes = 1;
++ nread++;
++
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN_(stmt);
++ } else {
++ if (cbValueMax)
++ *(TDS_CHAR *) rgbValue = 0;
++ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
++ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
++ }
++ } else {
++ nread = colinfo->column_text_sqlgetdatapos / 2;
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++ }
++
++ src += nread;
++ srclen = colinfo->column_cur_size - nread;
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ }
++ } else if (fCType == SQL_C_BINARY) {
++ switch (nSybType) {
++ case SYBCHAR:
++ case SYBVARCHAR:
++ case SYBTEXT:
++ case XSYBCHAR:
++ case XSYBVARCHAR:
++ nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
++
++ while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0'))
++ nread++;
++
++ nread += colinfo->column_text_sqlgetdatapos * 2;
++
++ if (nread && nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += nread;
++ srclen = colinfo->column_cur_size - nread;
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
++ } else {
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
+ } else {
+ if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+ ODBC_RETURN(stmt, SQL_NO_DATA);
+
+ srclen = colinfo->column_cur_size;
+ }
+- nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+- if (fCType == SQL_C_DEFAULT)
+- fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+- if (fCType == SQL_ARD_TYPE) {
+- if (icol > stmt->ard->header.sql_desc_count) {
+- odbc_errs_add(&stmt->errs, "07009", NULL);
+- ODBC_RETURN(stmt, SQL_ERROR);
+- }
+- fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+- }
+- assert(fCType);
++
+ *pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ if (*pcbValue < 0) {
+ odbc_convert_err_set(&stmt->errs, *pcbValue);
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+-
++
++ if (extra_bytes) {
++ colinfo->column_text_sqlgetdatapos += extra_bytes;
++ *pcbValue += extra_bytes;
++ }
++
+ if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ /* calculate how many bytes were read */
+ int remaining = cbValueMax;
+Index: src/odbc/unittests/getdata.c
+===================================================================
+RCS file: /cvsroot/freetds/freetds/src/odbc/unittests/getdata.c,v
+retrieving revision 1.6
+diff -u -r1.6 getdata.c
+--- src/odbc/unittests/getdata.c 29 Jan 2008 14:30:48 -0000 1.6
++++ src/odbc/unittests/getdata.c 12 Jun 2008 01:55:58 -0000
+@@ -11,7 +11,14 @@
+ {
+ memset(odbc_err, 0, sizeof(odbc_err));
+ memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+- if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
++ if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT
++ , Statement
++ , 1
++ , (SQLCHAR *) odbc_sqlstate
++ , NULL
++ , (SQLCHAR *) odbc_err
++ , sizeof(odbc_err)
++ , NULL))) {
+ printf("SQLGetDiagRec should not fail\n");
+ exit(1);
+ }
diff --git a/dev-db/freetds/files/SQLGetData_cvs.patch b/dev-db/freetds/files/SQLGetData_cvs.patch
new file mode 100644
index 0000000..5631c22
--- /dev/null
+++ b/dev-db/freetds/files/SQLGetData_cvs.patch
@@ -0,0 +1,67 @@
+diff -dPNur freetds-0.82-ds1/src/odbc/odbc.c freetds-0.82-ds2/src/odbc/odbc.c
+--- freetds-0.82-ds1/src/odbc/odbc.c 2008-07-01 19:19:14.000000000 +0200
++++ freetds-0.82-ds2/src/odbc/odbc.c 2008-07-01 19:19:25.000000000 +0200
+@@ -4564,6 +4564,7 @@
+ SQLLEN dummy_cb;
+ int nSybType;
+
++ TDS_INT converted_column_cur_size;
+ int extra_bytes = 0;
+
+ INIT_HSTMT;
+@@ -4599,6 +4600,7 @@
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ colinfo = resinfo->columns[icol - 1];
++ converted_column_cur_size = colinfo->column_cur_size;
+
+ if (colinfo->column_cur_size < 0) {
+ *pcbValue = SQL_NULL_DATA;
+@@ -4624,7 +4626,7 @@
+ if (is_blob_type(colinfo->column_type))
+ src = ((TDSBLOB *) src)->textvalue;
+
+- if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
++ if (fCType == SQL_C_CHAR) {
+ TDS_CHAR buf[3];
+ SQLLEN len;
+
+@@ -4667,12 +4669,15 @@
+ }
+ } else {
+ nread = colinfo->column_text_sqlgetdatapos / 2;
+- if (nread >= colinfo->column_cur_size)
++
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && nread >= colinfo->column_cur_size)
+ ODBC_RETURN(stmt, SQL_NO_DATA);
+ }
+
+ src += nread;
+ srclen = colinfo->column_cur_size - nread;
++ converted_column_cur_size *= 2;
+ break;
+ default:
+ if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+@@ -4701,6 +4706,12 @@
+
+ src += nread;
+ srclen = colinfo->column_cur_size - nread;
++
++ if (converted_column_cur_size%2)
++ converted_column_cur_size = (converted_column_cur_size + 1) / 2;
++ else
++ converted_column_cur_size /= 2;
++
+ break;
+ default:
+ if (colinfo->column_text_sqlgetdatapos > 0
+@@ -4751,7 +4762,7 @@
+ if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ ++colinfo->column_text_sqlgetdatapos;
+ /* not all readed ?? */
+- if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {
++ if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) {
+ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ }
diff --git a/dev-db/freetds/files/freetds-0.82-odbc-csa2.patch b/dev-db/freetds/files/freetds-0.82-odbc-csa2.patch
new file mode 100644
index 0000000..7487c7e
--- /dev/null
+++ b/dev-db/freetds/files/freetds-0.82-odbc-csa2.patch
@@ -0,0 +1,484 @@
+diff -dPNur freetds-0.82/include/tds.h freetds-0.82-new/include/tds.h
+--- freetds-0.82/include/tds.h 2007-12-27 14:45:22.000000000 +0100
++++ freetds-0.82-new/include/tds.h 2008-07-02 22:32:56.000000000 +0200
+@@ -1005,6 +1005,7 @@
+ TDS_INT *column_lenbind;
+ TDS_INT column_textpos;
+ TDS_INT column_text_sqlgetdatapos;
++ TDS_CHAR column_text_sqlputdatainfo;
+
+ BCPCOLDATA *bcp_column_data;
+ /**
+diff -dPNur freetds-0.82/src/odbc/odbc.c freetds-0.82-new/src/odbc/odbc.c
+--- freetds-0.82/src/odbc/odbc.c 2008-05-06 04:57:26.000000000 +0200
++++ freetds-0.82-new/src/odbc/odbc.c 2008-07-02 22:32:56.000000000 +0200
+@@ -4564,6 +4564,9 @@
+ SQLLEN dummy_cb;
+ int nSybType;
+
++ TDS_INT converted_column_cur_size;
++ int extra_bytes = 0;
++
+ INIT_HSTMT;
+
+ tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n",
+@@ -4597,46 +4600,120 @@
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ colinfo = resinfo->columns[icol - 1];
++ converted_column_cur_size = colinfo->column_cur_size;
+
+ if (colinfo->column_cur_size < 0) {
+ *pcbValue = SQL_NULL_DATA;
+ } else {
++ nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++ if (fCType == SQL_C_DEFAULT)
++ fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++ if (fCType == SQL_ARD_TYPE) {
++ if (icol > stmt->ard->header.sql_desc_count) {
++ odbc_errs_add(&stmt->errs, "07009", NULL);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++ }
++ assert(fCType);
++
+ src = (TDS_CHAR *) colinfo->column_data;
+ if (is_variable_type(colinfo->column_type)) {
+- if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+- ODBC_RETURN(stmt, SQL_NO_DATA);
+-
++ int nread = 0;
++
+ /* 2003-8-29 check for an old bug -- freddy77 */
+ assert(colinfo->column_text_sqlgetdatapos >= 0);
+ if (is_blob_type(colinfo->column_type))
+ src = ((TDSBLOB *) src)->textvalue;
+- src += colinfo->column_text_sqlgetdatapos;
+- srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ if (fCType == SQL_C_CHAR) {
++ TDS_CHAR buf[3];
++ SQLLEN len;
++
++ switch (nSybType) {
++ case SYBLONGBINARY:
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case SYBIMAGE:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case TDS_CONVERT_BINARY:
++ if (colinfo->column_text_sqlgetdatapos % 2) {
++ nread = (colinfo->column_text_sqlgetdatapos - 1) / 2;
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ if (cbValueMax > 2) {
++ len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
++ if (len < 2) {
++ if (len < 0)
++ odbc_convert_err_set(&stmt->errs, len);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ *(TDS_CHAR *) rgbValue = buf[1];
++ *((TDS_CHAR *) rgbValue + 1) = 0;
++
++ rgbValue++;
++ cbValueMax--;
++
++ extra_bytes = 1;
++ nread++;
++
++ if (nread >= colinfo->column_cur_size)
++ ODBC_RETURN_(stmt);
++ } else {
++ if (cbValueMax)
++ *(TDS_CHAR *) rgbValue = 0;
++ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
++ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
++ }
++ } else {
++ nread = colinfo->column_text_sqlgetdatapos / 2;
++
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && nread >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++ }
++
++ src += nread;
++ srclen = colinfo->column_cur_size - nread;
++ converted_column_cur_size *= 2;
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
++ } else {
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
+ } else {
+ if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+ ODBC_RETURN(stmt, SQL_NO_DATA);
+
+ srclen = colinfo->column_cur_size;
+ }
+- nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+- if (fCType == SQL_C_DEFAULT)
+- fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+- if (fCType == SQL_ARD_TYPE) {
+- if (icol > stmt->ard->header.sql_desc_count) {
+- odbc_errs_add(&stmt->errs, "07009", NULL);
+- ODBC_RETURN(stmt, SQL_ERROR);
+- }
+- fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+- }
+- assert(fCType);
++
+ *pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ if (*pcbValue < 0) {
+ odbc_convert_err_set(&stmt->errs, *pcbValue);
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+-
++
++ if (extra_bytes) {
++ colinfo->column_text_sqlgetdatapos += extra_bytes;
++ *pcbValue += extra_bytes;
++ }
++
+ if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ /* calc how many bytes was readed */
+ int readed = cbValueMax;
+@@ -4651,7 +4728,7 @@
+ if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ ++colinfo->column_text_sqlgetdatapos;
+ /* not all readed ?? */
+- if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {
++ if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) {
+ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ }
+diff -dPNur freetds-0.82/src/odbc/prepare_query.c freetds-0.82-new/src/odbc/prepare_query.c
+--- freetds-0.82/src/odbc/prepare_query.c 2007-04-18 16:29:24.000000000 +0200
++++ freetds-0.82-new/src/odbc/prepare_query.c 2008-07-02 22:32:56.000000000 +0200
+@@ -275,21 +275,110 @@
+ /* copy to destination */
+ if (blob) {
+ TDS_CHAR *p;
++ int dest_type, src_type, sql_src_type, res;
++ CONV_RESULT ores;
++ TDS_DBC * dbc = stmt->dbc;
++ void *free_ptr = NULL;
++ int start = 0;
++ SQLPOINTER extradata = NULL;
++ SQLLEN extralen = 0;
++
++
++ dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type);
++ if (dest_type == TDS_FAIL)
++ return SQL_ERROR;
++
++ /* get C type */
++ sql_src_type = drec_apd->sql_desc_concise_type;
++ if (sql_src_type == SQL_C_DEFAULT)
++ sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
++
++ /* test source type */
++ /* TODO test intervals */
++ src_type = odbc_c_to_server_type(sql_src_type);
++ if (src_type == TDS_FAIL)
++ return SQL_ERROR;
++
++ if (sql_src_type == SQL_C_CHAR) {
++ switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case SYBLONGBINARY:
++ case SYBIMAGE:
++ if (!*((char*)DataPtr+len-1))
++ --len;
++
++ if (!len)
++ return SQL_SUCCESS;
++
++ if (curcol->column_cur_size > 0
++ && curcol->column_text_sqlputdatainfo) {
++ TDS_CHAR data[2];
++ data[0] = curcol->column_text_sqlputdatainfo;
++ data[1] = *(char*)DataPtr;
++
++ res = tds_convert(dbc->env->tds_ctx, src_type, data, 2, dest_type, &ores);
++ if (res < 0)
++ return SQL_ERROR;
++
++ extradata = ores.ib;
++ extralen = res;
++
++ start = 1;
++ --len;
++ }
++
++ if (len&1) {
++ --len;
++ curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
++ }
++
++ res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr+start, len, dest_type, &ores);
++ if (res < 0) {
++ if (extradata)
++ free(extradata);
++
++ return SQL_ERROR;
++ }
++
++ DataPtr = free_ptr = ores.ib;
++ len = res;
++ break;
++ }
++ }
+
+ if (blob->textvalue)
+- p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size);
++ p = (TDS_CHAR *) realloc(blob->textvalue, len + extralen + curcol->column_cur_size);
+ else {
+ assert(curcol->column_cur_size == 0);
+- p = (TDS_CHAR *) malloc(len);
++ p = (TDS_CHAR *) malloc(len + extralen);
+ }
+- if (!p)
++ if (!p) {
++ if (free_ptr)
++ free(free_ptr);
++ if (extradata)
++ free(extradata);
+ return SQL_ERROR;
++ }
+ blob->textvalue = p;
++ if (extralen) {
++ memcpy(blob->textvalue + curcol->column_cur_size, extradata, extralen);
++ curcol->column_cur_size += extralen;
++ }
+ memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len);
++
++ if (extradata)
++ free(extradata);
++ if (free_ptr)
++ free(free_ptr);
+ } else {
+ memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len);
+ }
++
+ curcol->column_cur_size += len;
++
+ if (blob && curcol->column_cur_size > curcol->column_size)
+ curcol->column_size = curcol->column_cur_size;
+
+diff -dPNur freetds-0.82/src/odbc/unittests/blob1.c freetds-0.82-new/src/odbc/unittests/blob1.c
+--- freetds-0.82/src/odbc/unittests/blob1.c 2008-01-12 01:21:39.000000000 +0100
++++ freetds-0.82-new/src/odbc/unittests/blob1.c 2008-07-02 22:32:56.000000000 +0200
+@@ -47,6 +47,16 @@
+ buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1));
+ }
+
++static void
++fill_hex(char *buf, size_t len, unsigned int start, unsigned int step)
++{
++ size_t n;
++
++ for (n = 0; n < len; ++n)
++ sprintf(buf + 2*n, "%2x", (unsigned int)('a' + ((start+n) * step % ('z' - 'a' + 1))));
++}
++
++
+ static int
+ check_chars(const char *buf, size_t len, unsigned int start, unsigned int step)
+ {
+@@ -60,6 +70,21 @@
+ }
+
+ static int
++check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
++{
++ size_t n;
++ char symbol[3];
++
++ for (n = 0; n < len; ++n) {
++ sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
++ if (buf[n] != symbol[(start+n) % 2])
++ return 0;
++ }
++
++ return 1;
++}
++
++static int
+ readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+ {
+ SQLRETURN rcode;
+@@ -93,6 +118,43 @@
+ return rcode;
+ }
+
++static int
++readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
++{
++ SQLRETURN rcode = SQL_SUCCESS_WITH_INFO;
++ char buf[8192];
++ SQLLEN len, total = 0;
++ int i = 0;
++ int check;
++ int bufsize;
++
++ if (step%2) bufsize = sizeof(buf) - 1;
++ else bufsize = sizeof(buf);
++
++ printf(">> readBlobAsChar field %d\n", pos);
++ while (rcode == SQL_SUCCESS_WITH_INFO) {
++ i++;
++ rcode = SQLGetData(stmth, pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len);
++ if (!SQL_SUCCEEDED(rcode) || len <= 0)
++ break;
++ if (len > (SQLLEN) bufsize)
++ len = (SQLLEN) bufsize - 1;
++ printf(">> step %d: %d bytes readed\n", i, (int) len);
++
++ check = check_hex(buf, len, 2*987 + total, 25);
++ if (!check) {
++ fprintf(stderr, "Wrong buffer content\n");
++ failed = 1;
++ }
++ total += len;
++ }
++ printf(">> total bytes read = %d \n", (int) total);
++ if (total != 20000)
++ failed = 1;
++ return rcode;
++}
++
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -106,12 +168,14 @@
+ SQLLEN vind1;
+ char buf2[NBYTES];
+ SQLLEN vind2;
++ char buf3[NBYTES*2 + 1];
++ SQLLEN vind3;
+ int cnt = 2;
+
+ use_odbc_version3 = 1;
+ Connect();
+
+- Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b IMAGE, v INT )");
++ Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )");
+
+ /* Insert rows ... */
+
+@@ -121,7 +185,7 @@
+ rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+
+- rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ? )", SQL_NTS);
++ rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+
+ SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+@@ -133,9 +197,12 @@
+ SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3");
+
+- SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++ SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4");
+
++ SQLBindParameter(m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 5");
++
+ key = i;
+ vind0 = 0;
+
+@@ -144,6 +211,10 @@
+
+ fill_chars(buf2, NBYTES, 987, 25);
+ vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES);
++
++ memset(buf3, 0, sizeof(buf3));
++ vind3 = SQL_LEN_DATA_AT_EXEC(2*NBYTES+1);
++
+
+ printf(">> insert... %d\n", i);
+ rcode = SQLExecute(m_hstmt);
+@@ -155,10 +226,25 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
+ printf(">> SQLParamData: ptr = %p rcode = %d\n", (void *) p, rcode);
+ if (rcode == SQL_NEED_DATA) {
+- SQLRETURN rcode = SQLPutData(m_hstmt, p, NBYTES);
++ SQLRETURN rcode;
++ if (p == buf3) {
++ fill_hex(buf3, NBYTES, 987, 25);
++
++ rcode = SQLPutData(m_hstmt, p, NBYTES - (i&1));
+
+- CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+- printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
++
++ rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1));
++
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
++ } else {
++ rcode = SQLPutData(m_hstmt, p, NBYTES);
++
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++ }
+ }
+ }
+
+@@ -182,7 +268,7 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ }
+
+- rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
++ rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+
+ SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+@@ -192,7 +278,9 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2");
+ SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3");
+- SQLBindCol(m_hstmt, 3, SQL_C_LONG, &key, 0, &vind0);
++ SQLBindCol(m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 4");
++ SQLBindCol(m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1");
+
+ vind0 = 0;
+@@ -210,6 +298,8 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
+ rcode = readBlob(m_hstmt, 2);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
++ rcode = readBlobAsChar(m_hstmt, 3, i);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR");
+
+ rcode = SQLCloseCursor(m_hstmt);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH");
diff --git a/dev-db/freetds/files/freetds-20080603-odbc-csa2.patch b/dev-db/freetds/files/freetds-20080603-odbc-csa2.patch
new file mode 100644
index 0000000..1615ddd
--- /dev/null
+++ b/dev-db/freetds/files/freetds-20080603-odbc-csa2.patch
@@ -0,0 +1,404 @@
+diff -dPNur freetds/include/tds.h freetds-ds/include/tds.h
+--- freetds/include/tds.h 2008-06-18 11:06:26.000000000 +0200
++++ freetds-ds/include/tds.h 2008-07-02 22:10:03.000000000 +0200
+@@ -1009,6 +1009,7 @@
+ TDS_INT *column_lenbind;
+ TDS_INT column_textpos;
+ TDS_INT column_text_sqlgetdatapos;
++ TDS_CHAR column_text_sqlputdatainfo;
+
+ BCPCOLDATA *bcp_column_data;
+ /**
+diff -dPNur freetds/src/odbc/odbc.c freetds-ds/src/odbc/odbc.c
+--- freetds/src/odbc/odbc.c 2008-06-18 11:06:26.000000000 +0200
++++ freetds-ds/src/odbc/odbc.c 2008-07-02 22:10:03.000000000 +0200
+@@ -4652,6 +4652,7 @@
+ SQLLEN dummy_cb;
+ int nSybType;
+
++ TDS_INT converted_column_cur_size;
+ int extra_bytes = 0;
+
+ INIT_HSTMT;
+@@ -4690,6 +4691,7 @@
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ colinfo = tds->current_results->columns[icol - 1];
++ converted_column_cur_size = colinfo->column_cur_size;
+
+ if (colinfo->column_cur_size < 0) {
+ *pcbValue = SQL_NULL_DATA;
+@@ -4715,7 +4717,7 @@
+ if (is_blob_type(colinfo->column_type))
+ src = ((TDSBLOB *) src)->textvalue;
+
+- if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
++ if (fCType == SQL_C_CHAR) {
+ TDS_CHAR buf[3];
+ SQLLEN len;
+
+@@ -4758,40 +4760,15 @@
+ }
+ } else {
+ nread = colinfo->column_text_sqlgetdatapos / 2;
+- if (nread >= colinfo->column_cur_size)
++
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && nread >= colinfo->column_cur_size)
+ ODBC_RETURN(stmt, SQL_NO_DATA);
+ }
+
+ src += nread;
+ srclen = colinfo->column_cur_size - nread;
+- break;
+- default:
+- if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+- ODBC_RETURN(stmt, SQL_NO_DATA);
+-
+- src += colinfo->column_text_sqlgetdatapos;
+- srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+-
+- }
+- } else if (fCType == SQL_C_BINARY) {
+- switch (nSybType) {
+- case SYBCHAR:
+- case SYBVARCHAR:
+- case SYBTEXT:
+- case XSYBCHAR:
+- case XSYBVARCHAR:
+- nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
+-
+- while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0'))
+- nread++;
+-
+- nread += colinfo->column_text_sqlgetdatapos * 2;
+-
+- if (nread && nread >= colinfo->column_cur_size)
+- ODBC_RETURN(stmt, SQL_NO_DATA);
+-
+- src += nread;
+- srclen = colinfo->column_cur_size - nread;
++ converted_column_cur_size *= 2;
+ break;
+ default:
+ if (colinfo->column_text_sqlgetdatapos > 0
+@@ -4842,7 +4819,7 @@
+ if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ ++colinfo->column_text_sqlgetdatapos;
+
+- if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) { /* not all read ?? */
++ if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) { /* not all read ?? */
+ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ }
+diff -dPNur freetds/src/odbc/prepare_query.c freetds-ds/src/odbc/prepare_query.c
+--- freetds/src/odbc/prepare_query.c 2007-04-18 16:29:24.000000000 +0200
++++ freetds-ds/src/odbc/prepare_query.c 2008-07-02 22:10:03.000000000 +0200
+@@ -275,21 +275,110 @@
+ /* copy to destination */
+ if (blob) {
+ TDS_CHAR *p;
++ int dest_type, src_type, sql_src_type, res;
++ CONV_RESULT ores;
++ TDS_DBC * dbc = stmt->dbc;
++ void *free_ptr = NULL;
++ int start = 0;
++ SQLPOINTER extradata = NULL;
++ SQLLEN extralen = 0;
++
++
++ dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type);
++ if (dest_type == TDS_FAIL)
++ return SQL_ERROR;
++
++ /* get C type */
++ sql_src_type = drec_apd->sql_desc_concise_type;
++ if (sql_src_type == SQL_C_DEFAULT)
++ sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
++
++ /* test source type */
++ /* TODO test intervals */
++ src_type = odbc_c_to_server_type(sql_src_type);
++ if (src_type == TDS_FAIL)
++ return SQL_ERROR;
++
++ if (sql_src_type == SQL_C_CHAR) {
++ switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case SYBLONGBINARY:
++ case SYBIMAGE:
++ if (!*((char*)DataPtr+len-1))
++ --len;
++
++ if (!len)
++ return SQL_SUCCESS;
++
++ if (curcol->column_cur_size > 0
++ && curcol->column_text_sqlputdatainfo) {
++ TDS_CHAR data[2];
++ data[0] = curcol->column_text_sqlputdatainfo;
++ data[1] = *(char*)DataPtr;
++
++ res = tds_convert(dbc->env->tds_ctx, src_type, data, 2, dest_type, &ores);
++ if (res < 0)
++ return SQL_ERROR;
++
++ extradata = ores.ib;
++ extralen = res;
++
++ start = 1;
++ --len;
++ }
++
++ if (len&1) {
++ --len;
++ curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
++ }
++
++ res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr+start, len, dest_type, &ores);
++ if (res < 0) {
++ if (extradata)
++ free(extradata);
++
++ return SQL_ERROR;
++ }
++
++ DataPtr = free_ptr = ores.ib;
++ len = res;
++ break;
++ }
++ }
+
+ if (blob->textvalue)
+- p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size);
++ p = (TDS_CHAR *) realloc(blob->textvalue, len + extralen + curcol->column_cur_size);
+ else {
+ assert(curcol->column_cur_size == 0);
+- p = (TDS_CHAR *) malloc(len);
++ p = (TDS_CHAR *) malloc(len + extralen);
+ }
+- if (!p)
++ if (!p) {
++ if (free_ptr)
++ free(free_ptr);
++ if (extradata)
++ free(extradata);
+ return SQL_ERROR;
++ }
+ blob->textvalue = p;
++ if (extralen) {
++ memcpy(blob->textvalue + curcol->column_cur_size, extradata, extralen);
++ curcol->column_cur_size += extralen;
++ }
+ memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len);
++
++ if (extradata)
++ free(extradata);
++ if (free_ptr)
++ free(free_ptr);
+ } else {
+ memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len);
+ }
++
+ curcol->column_cur_size += len;
++
+ if (blob && curcol->column_cur_size > curcol->column_size)
+ curcol->column_size = curcol->column_cur_size;
+
+diff -dPNur freetds/src/odbc/unittests/blob1.c freetds-ds/src/odbc/unittests/blob1.c
+--- freetds/src/odbc/unittests/blob1.c 2008-01-12 01:14:11.000000000 +0100
++++ freetds-ds/src/odbc/unittests/blob1.c 2008-07-02 22:09:28.000000000 +0200
+@@ -47,6 +47,16 @@
+ buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1));
+ }
+
++static void
++fill_hex(char *buf, size_t len, unsigned int start, unsigned int step)
++{
++ size_t n;
++
++ for (n = 0; n < len; ++n)
++ sprintf(buf + 2*n, "%2x", (unsigned int)('a' + ((start+n) * step % ('z' - 'a' + 1))));
++}
++
++
+ static int
+ check_chars(const char *buf, size_t len, unsigned int start, unsigned int step)
+ {
+@@ -60,6 +70,21 @@
+ }
+
+ static int
++check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
++{
++ size_t n;
++ char symbol[3];
++
++ for (n = 0; n < len; ++n) {
++ sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
++ if (buf[n] != symbol[(start+n) % 2])
++ return 0;
++ }
++
++ return 1;
++}
++
++static int
+ readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+ {
+ SQLRETURN rcode;
+@@ -93,6 +118,43 @@
+ return rcode;
+ }
+
++static int
++readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
++{
++ SQLRETURN rcode = SQL_SUCCESS_WITH_INFO;
++ char buf[8192];
++ SQLLEN len, total = 0;
++ int i = 0;
++ int check;
++ int bufsize;
++
++ if (step%2) bufsize = sizeof(buf) - 1;
++ else bufsize = sizeof(buf);
++
++ printf(">> readBlobAsChar field %d\n", pos);
++ while (rcode == SQL_SUCCESS_WITH_INFO) {
++ i++;
++ rcode = SQLGetData(stmth, pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len);
++ if (!SQL_SUCCEEDED(rcode) || len <= 0)
++ break;
++ if (len > (SQLLEN) bufsize)
++ len = (SQLLEN) bufsize - 1;
++ printf(">> step %d: %d bytes readed\n", i, (int) len);
++
++ check = check_hex(buf, len, 2*987 + total, 25);
++ if (!check) {
++ fprintf(stderr, "Wrong buffer content\n");
++ failed = 1;
++ }
++ total += len;
++ }
++ printf(">> total bytes read = %d \n", (int) total);
++ if (total != 20000)
++ failed = 1;
++ return rcode;
++}
++
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -106,12 +168,14 @@
+ SQLLEN vind1;
+ char buf2[NBYTES];
+ SQLLEN vind2;
++ char buf3[NBYTES*2 + 1];
++ SQLLEN vind3;
+ int cnt = 2;
+
+ use_odbc_version3 = 1;
+ Connect();
+
+- Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b IMAGE, v INT )");
++ Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )");
+
+ /* Insert rows ... */
+
+@@ -121,7 +185,7 @@
+ rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+
+- rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ? )", SQL_NTS);
++ rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+
+ SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+@@ -133,9 +197,12 @@
+ SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3");
+
+- SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++ SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4");
+
++ SQLBindParameter(m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 5");
++
+ key = i;
+ vind0 = 0;
+
+@@ -144,6 +211,10 @@
+
+ fill_chars(buf2, NBYTES, 987, 25);
+ vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES);
++
++ memset(buf3, 0, sizeof(buf3));
++ vind3 = SQL_LEN_DATA_AT_EXEC(2*NBYTES+1);
++
+
+ printf(">> insert... %d\n", i);
+ rcode = SQLExecute(m_hstmt);
+@@ -155,10 +226,25 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
+ printf(">> SQLParamData: ptr = %p rcode = %d\n", (void *) p, rcode);
+ if (rcode == SQL_NEED_DATA) {
+- SQLRETURN rcode = SQLPutData(m_hstmt, p, NBYTES);
++ SQLRETURN rcode;
++ if (p == buf3) {
++ fill_hex(buf3, NBYTES, 987, 25);
++
++ rcode = SQLPutData(m_hstmt, p, NBYTES - (i&1));
+
+- CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+- printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
++
++ rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1));
++
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
++ } else {
++ rcode = SQLPutData(m_hstmt, p, NBYTES);
++
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++ }
+ }
+ }
+
+@@ -182,7 +268,7 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ }
+
+- rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
++ rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+
+ SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+@@ -192,7 +278,9 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2");
+ SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3");
+- SQLBindCol(m_hstmt, 3, SQL_C_LONG, &key, 0, &vind0);
++ SQLBindCol(m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 4");
++ SQLBindCol(m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1");
+
+ vind0 = 0;
+@@ -210,6 +298,8 @@
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
+ rcode = readBlob(m_hstmt, 2);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
++ rcode = readBlobAsChar(m_hstmt, 3, i);
++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR");
+
+ rcode = SQLCloseCursor(m_hstmt);
+ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH");
diff --git a/dev-db/freetds/files/freetds-ds-connect_timeout.patch b/dev-db/freetds/files/freetds-ds-connect_timeout.patch
new file mode 100644
index 0000000..013764e
--- /dev/null
+++ b/dev-db/freetds/files/freetds-ds-connect_timeout.patch
@@ -0,0 +1,12 @@
+diff -dPNur freetds-0.82/src/odbc/odbc.c freetds-0.82-ds/src/odbc/odbc.c
+--- freetds-0.82/src/odbc/odbc.c 2008-05-06 04:57:26.000000000 +0200
++++ freetds-0.82-ds/src/odbc/odbc.c 2008-06-26 12:20:43.000000000 +0200
+@@ -312,7 +312,7 @@
+
+ tds_fix_connection(connection);
+
+- connection->connect_timeout = dbc->attr.connection_timeout;
++ connection->connect_timeout = dbc->attr.login_timeout;
+
+ if (tds_connect(dbc->tds_socket, connection) == TDS_FAIL) {
+ tds_free_socket(dbc->tds_socket);
diff --git a/dev-db/freetds/files/freetds-ds-odbc.patch b/dev-db/freetds/files/freetds-ds-odbc.patch
new file mode 100644
index 0000000..a7b6707
--- /dev/null
+++ b/dev-db/freetds/files/freetds-ds-odbc.patch
@@ -0,0 +1,222 @@
+diff -dPNur freetds-0.82/src/odbc/odbc.c freetds-0.82-new/src/odbc/odbc.c
+--- freetds-0.82/src/odbc/odbc.c 2008-05-06 04:57:26.000000000 +0200
++++ freetds-0.82-new/src/odbc/odbc.c 2008-06-09 13:12:51.000000000 +0200
+@@ -4564,6 +4564,8 @@
+ SQLLEN dummy_cb;
+ int nSybType;
+
++ int extra_bytes = 0;
++
+ INIT_HSTMT;
+
+ tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n",
+@@ -4601,18 +4603,117 @@
+ if (colinfo->column_cur_size < 0) {
+ *pcbValue = SQL_NULL_DATA;
+ } else {
++ nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++ if (fCType == SQL_C_DEFAULT)
++ fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++ if (fCType == SQL_ARD_TYPE) {
++ if (icol > stmt->ard->header.sql_desc_count) {
++ odbc_errs_add(&stmt->errs, "07009", NULL);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++ }
++ assert(fCType);
++
+ src = (TDS_CHAR *) colinfo->column_data;
+ if (is_variable_type(colinfo->column_type)) {
+- if (colinfo->column_text_sqlgetdatapos > 0
+- && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+- ODBC_RETURN(stmt, SQL_NO_DATA);
+-
++ int readed = 0;
++
+ /* 2003-8-29 check for an old bug -- freddy77 */
+ assert(colinfo->column_text_sqlgetdatapos >= 0);
+ if (is_blob_type(colinfo->column_type))
+ src = ((TDSBLOB *) src)->textvalue;
+- src += colinfo->column_text_sqlgetdatapos;
+- srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ if ((fCType == SQL_C_CHAR)&&(colinfo->column_text_sqlgetdatapos)) {
++ TDS_CHAR buf[3];
++ SQLLEN len;
++
++ switch (nSybType) {
++ case SYBLONGBINARY:
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case SYBIMAGE:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case TDS_CONVERT_BINARY:
++ if (colinfo->column_text_sqlgetdatapos%2) {
++ readed = (colinfo->column_text_sqlgetdatapos - 1) / 2;
++ if (readed >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ if (cbValueMax > 2) {
++ len = convert_tds2sql(context, nSybType, src + readed, 1, fCType, buf, 3, NULL);
++ if (len < 2) {
++ if (len < 0) odbc_convert_err_set(&stmt->errs, len);
++ ODBC_RETURN(stmt, SQL_ERROR);
++ }
++ *(TDS_CHAR *) rgbValue = buf[1];
++ *((TDS_CHAR *) rgbValue + 1) = 0;
++
++ rgbValue++;
++ cbValueMax--;
++
++ extra_bytes = 1;
++ readed++;
++
++ if (readed >= colinfo->column_cur_size)
++ ODBC_RETURN_(stmt);
++ } else {
++ if (cbValueMax) *(TDS_CHAR *) rgbValue = 0;
++ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
++ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
++ }
++ } else {
++ readed = colinfo->column_text_sqlgetdatapos / 2;
++ if (readed >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++ }
++
++ src += readed;
++ srclen = colinfo->column_cur_size - readed;
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++ }
++ } else if (fCType == SQL_C_BINARY) {
++ switch (nSybType) {
++ case SYBCHAR:
++ case SYBVARCHAR:
++ case SYBTEXT:
++ case XSYBCHAR:
++ case XSYBVARCHAR:
++ if (src[0] == '0' && (src[1] == 'x' || src[1] == 'X')) readed = 2;
++ else readed = 0;
++ while ((readed < colinfo->column_cur_size) && (src[readed] == ' ' || src[readed] == '\0')) readed ++;
++ readed += colinfo->column_text_sqlgetdatapos * 2;
++
++ if ((readed)&&(readed >= colinfo->column_cur_size))
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += readed;
++ srclen = colinfo->column_cur_size - readed;
++ break;
++ default:
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
++ } else {
++ if (colinfo->column_text_sqlgetdatapos > 0
++ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++ ODBC_RETURN(stmt, SQL_NO_DATA);
++
++ src += colinfo->column_text_sqlgetdatapos;
++ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++ }
+ } else {
+ if (colinfo->column_text_sqlgetdatapos > 0
+ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+@@ -4620,23 +4721,18 @@
+
+ srclen = colinfo->column_cur_size;
+ }
+- nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+- if (fCType == SQL_C_DEFAULT)
+- fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+- if (fCType == SQL_ARD_TYPE) {
+- if (icol > stmt->ard->header.sql_desc_count) {
+- odbc_errs_add(&stmt->errs, "07009", NULL);
+- ODBC_RETURN(stmt, SQL_ERROR);
+- }
+- fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+- }
+- assert(fCType);
++
+ *pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ if (*pcbValue < 0) {
+ odbc_convert_err_set(&stmt->errs, *pcbValue);
+ ODBC_RETURN(stmt, SQL_ERROR);
+ }
+-
++
++ if (extra_bytes) {
++ colinfo->column_text_sqlgetdatapos += extra_bytes;
++ *pcbValue += extra_bytes;
++ }
++
+ if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ /* calc how many bytes was readed */
+ int readed = cbValueMax;
+@@ -4644,9 +4740,54 @@
+ /* FIXME test on destination char ??? */
+ if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && readed > 0)
+ --readed;
++
+ if (readed > *pcbValue)
+ readed = *pcbValue;
++
+ colinfo->column_text_sqlgetdatapos += readed;
++
++/*
++ if (fCType == SQL_C_CHAR) {
++ switch (nSybType) {
++ case SYBLONGBINARY:
++ case SYBBINARY:
++ case SYBVARBINARY:
++ case SYBIMAGE:
++ case XSYBBINARY:
++ case XSYBVARBINARY:
++ case TDS_CONVERT_BINARY:
++ if (readed%2) {
++ readed--;
++ *((TDS_CHAR *)rgbValue + readed) = 0;
++ }
++ colinfo->column_text_sqlgetdatapos += readed / 2;
++ break;
++ default:
++ colinfo->column_text_sqlgetdatapos += readed;
++ }
++ } else if (fCType == SQL_C_BINARY) {
++ switch (nSybType) {
++ case SYBCHAR:
++ case SYBVARCHAR:
++ case SYBTEXT:
++ case XSYBCHAR:
++ case XSYBVARCHAR:
++ if (!colinfo->column_text_sqlgetdatapos) {
++ if (src[0] == '0' && (src[1] == 'x' || src[1] == 'X'))
++ colinfo->column_text_sqlgetdatapos += 2;
++
++ while ((colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) && (src[colinfo->column_text_sqlgetdatapos] == ' ' || src[colinfo->column_text_sqlgetdatapos] == '\0'))
++ colinfo->column_text_sqlgetdatapos ++;
++ }
++ colinfo->column_text_sqlgetdatapos += readed * 2;
++ break;
++ default:
++ colinfo->column_text_sqlgetdatapos += readed;
++ }
++ } else {
++ colinfo->column_text_sqlgetdatapos += readed;
++ }*/
++
+ /* avoid infinite SQL_SUCCESS on empty strings */
+ if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ ++colinfo->column_text_sqlgetdatapos;
diff --git a/dev-db/freetds/freetds-0.82-r1.ebuild b/dev-db/freetds/freetds-0.82-r1.ebuild
new file mode 100644
index 0000000..11c93b1
--- /dev/null
+++ b/dev-db/freetds/freetds-0.82-r1.ebuild
@@ -0,0 +1,37 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-db/freetds/freetds-0.64.ebuild,v 1.11 2007/11/14 15:53:32 jer Exp $
+
+inherit eutils
+
+KEYWORDS="alpha amd64 arm hppa ia64 ~mips ppc ppc64 s390 sh sparc x86 ~x86-fbsd"
+DESCRIPTION="Tabular Datastream Library."
+HOMEPAGE="http://www.freetds.org/"
+SRC_URI="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/${P}.tar.gz"
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="odbc mssql"
+
+DEPEND="odbc? ( dev-db/unixODBC )"
+RDEPEND="${DEPEND}"
+
+src_unpack() {
+ unpack ${P}.tar.gz
+ cd ${S}
+
+ epatch "${FILESDIR}"/${PN}-ds-odbc.patch || die
+}
+
+src_compile() {
+ local myconf
+ use odbc && myconf="--with-unixodbc=/usr"
+ use mssql && myconf="${myconf} --enable-msdblib"
+ econf --with-tdsver=7.0 ${myconf} --cache-file="${S}/config.cache" || die "econf failed"
+ emake || die "emake failed"
+}
+
+RESTRICT="test"
+
+src_install() {
+ make DESTDIR="${D}" install || die "make install failed"
+}
diff --git a/dev-db/freetds/freetds-0.82-r2.ebuild b/dev-db/freetds/freetds-0.82-r2.ebuild
new file mode 100644
index 0000000..39586d7
--- /dev/null
+++ b/dev-db/freetds/freetds-0.82-r2.ebuild
@@ -0,0 +1,38 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-db/freetds/freetds-0.64.ebuild,v 1.11 2007/11/14 15:53:32 jer Exp $
+
+inherit eutils
+
+KEYWORDS="alpha amd64 arm hppa ia64 ~mips ppc ppc64 s390 sh sparc x86 ~x86-fbsd"
+DESCRIPTION="Tabular Datastream Library."
+HOMEPAGE="http://www.freetds.org/"
+SRC_URI="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/${P}.tar.gz"
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="odbc mssql"
+
+DEPEND="odbc? ( dev-db/unixODBC )"
+RDEPEND="${DEPEND}"
+
+src_unpack() {
+ unpack ${P}.tar.gz
+ cd ${S}
+
+# epatch "${FILESDIR}"/${PN}-ds-odbc.patch || die
+ epatch "${FILESDIR}"/SQLGetData.utf8.odbc.c.diff || die
+}
+
+src_compile() {
+ local myconf
+ use odbc && myconf="--with-unixodbc=/usr"
+ use mssql && myconf="${myconf} --enable-msdblib"
+ econf --with-tdsver=7.0 ${myconf} --cache-file="${S}/config.cache" || die "econf failed"
+ emake || die "emake failed"
+}
+
+RESTRICT="test"
+
+src_install() {
+ make DESTDIR="${D}" install || die "make install failed"
+}
diff --git a/dev-db/freetds/freetds-0.82-r3.ebuild b/dev-db/freetds/freetds-0.82-r3.ebuild
new file mode 100644
index 0000000..3d26269
--- /dev/null
+++ b/dev-db/freetds/freetds-0.82-r3.ebuild
@@ -0,0 +1,37 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-db/freetds/freetds-0.64.ebuild,v 1.11 2007/11/14 15:53:32 jer Exp $
+
+inherit eutils
+
+KEYWORDS="alpha amd64 arm hppa ia64 ~mips ppc ppc64 s390 sh sparc x86 ~x86-fbsd"
+DESCRIPTION="Tabular Datastream Library."
+HOMEPAGE="http://www.freetds.org/"
+SRC_URI="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/${P}.tar.gz"
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="odbc mssql"
+
+DEPEND="odbc? ( dev-db/unixODBC )"
+RDEPEND="${DEPEND}"
+
+src_unpack() {
+ unpack ${P}.tar.gz
+ cd ${S}
+
+ epatch "${FILESDIR}"/SQLGetData.utf8.odbc.c-r3.diff || die
+}
+
+src_compile() {
+ local myconf
+ use odbc && myconf="--with-unixodbc=/usr"
+ use mssql && myconf="${myconf} --enable-msdblib"
+ econf --with-tdsver=7.0 ${myconf} --cache-file="${S}/config.cache" || die "econf failed"
+ emake || die "emake failed"
+}
+
+RESTRICT="test"
+
+src_install() {
+ make DESTDIR="${D}" install || die "make install failed"
+}
diff --git a/dev-db/freetds/freetds-0.82-r4.ebuild b/dev-db/freetds/freetds-0.82-r4.ebuild
new file mode 100644
index 0000000..8355034
--- /dev/null
+++ b/dev-db/freetds/freetds-0.82-r4.ebuild
@@ -0,0 +1,38 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-db/freetds/freetds-0.64.ebuild,v 1.11 2007/11/14 15:53:32 jer Exp $
+
+inherit eutils
+
+KEYWORDS="alpha amd64 arm hppa ia64 ~mips ppc ppc64 s390 sh sparc x86 ~x86-fbsd"
+DESCRIPTION="Tabular Datastream Library."
+HOMEPAGE="http://www.freetds.org/"
+SRC_URI="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/${P}.tar.gz"
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="odbc mssql"
+
+DEPEND="odbc? ( dev-db/unixODBC )"
+RDEPEND="${DEPEND}"
+
+src_unpack() {
+ unpack ${P}.tar.gz
+ cd ${S}
+
+ epatch "${FILESDIR}"/SQLGetData.utf8.odbc.c-r3.diff || die
+ epatch "${FILESDIR}"/freetds-ds-connect_timeout.patch || die
+}
+
+src_compile() {
+ local myconf
+ use odbc && myconf="--with-unixodbc=/usr"
+ use mssql && myconf="${myconf} --enable-msdblib"
+ econf --with-tdsver=7.0 ${myconf} --cache-file="${S}/config.cache" || die "econf failed"
+ emake || die "emake failed"
+}
+
+RESTRICT="test"
+
+src_install() {
+ make DESTDIR="${D}" install || die "make install failed"
+}
diff --git a/dev-db/freetds/freetds-0.82-r5.ebuild b/dev-db/freetds/freetds-0.82-r5.ebuild
new file mode 100644
index 0000000..97c03a6
--- /dev/null
+++ b/dev-db/freetds/freetds-0.82-r5.ebuild
@@ -0,0 +1,38 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-db/freetds/freetds-0.64.ebuild,v 1.11 2007/11/14 15:53:32 jer Exp $
+
+inherit eutils
+
+KEYWORDS="alpha amd64 arm hppa ia64 ~mips ppc ppc64 s390 sh sparc x86 ~x86-fbsd"
+DESCRIPTION="Tabular Datastream Library."
+HOMEPAGE="http://www.freetds.org/"
+SRC_URI="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/${P}.tar.gz"
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="odbc mssql"
+
+DEPEND="odbc? ( dev-db/unixODBC )"
+RDEPEND="${DEPEND}"
+
+src_unpack() {
+ unpack ${P}.tar.gz
+ cd ${S}
+
+ epatch "${FILESDIR}"/freetds-0.82-odbc-csa2.patch || die
+ epatch "${FILESDIR}"/freetds-ds-connect_timeout.patch || die
+}
+
+src_compile() {
+ local myconf
+ use odbc && myconf="--with-unixodbc=/usr"
+ use mssql && myconf="${myconf} --enable-msdblib"
+ econf --with-tdsver=7.0 ${myconf} --cache-file="${S}/config.cache" || die "econf failed"
+ emake || die "emake failed"
+}
+
+RESTRICT="test"
+
+src_install() {
+ make DESTDIR="${D}" install || die "make install failed"
+}