summaryrefslogtreecommitdiffstats
path: root/dev-db/freetds/files/freetds-ds-odbc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-db/freetds/files/freetds-ds-odbc.patch')
-rw-r--r--dev-db/freetds/files/freetds-ds-odbc.patch222
1 files changed, 222 insertions, 0 deletions
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;