diff options
Diffstat (limited to 'dev-db/freetds/files/SQLGetData.utf8.odbc.c.diff')
-rw-r--r-- | dev-db/freetds/files/SQLGetData.utf8.odbc.c.diff | 199 |
1 files changed, 199 insertions, 0 deletions
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); + } |