diff options
Diffstat (limited to 'dev-db/freetds/files/freetds-ds-odbc.patch')
-rw-r--r-- | dev-db/freetds/files/freetds-ds-odbc.patch | 222 |
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; |