Re: SQL_SUCCESS_WITH[out]_INFO in ODBC lib
"James K. Lowden" <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
Nathan Bird wrote: > Reading data in chunks with SQLGetData if the buffer is not long enough > for the value to copy, it should fill the buffer, and return > SQL_SUCCESS_WITH_INFO, along with setting the StrLen_or_IndPtr to point > at the how much data is available. At least according to > http://msdn2.microsoft.com/en-us/library//ms715441.aspx [1] the info > should be "01004" to indicate the string is right truncated-- this isn't > > being set right now. The attached patch implements the change you suggest, along with a few cosmetic changes. I committed the change to to CVS HEAD. I'll apply it to 0.82 before it's released unless Frediano sees a problem. (My compliments, if I may, on a fine problem report. Thanks.) > I ran into a problem recently where trying to read data through the ODBC > > lib gave me a number of problems, updating to 0.82RC4 fixed most of > them.... Very good to hear, too. > From my searching this was the most definitive source for ODBC spec > I could find That's what I use. I figure ODBC for SQL Server is whatever Microsoft says it is, standard or no. Regards, --jkl _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds
SQLGetData.diff
(application/octet-stream, 2.7 KB)
Index: src/odbc/odbc.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/odbc/odbc.c,v
retrieving revision 1.478
diff -u -r1.478 odbc.c
--- src/odbc/odbc.c 13 Mar 2008 13:23:31 -0000 1.478
+++ src/odbc/odbc.c 10 Apr 2008 20:56:18 -0000
@@ -4637,7 +4637,10 @@
}
/* read data from TDS only if current statement */
- if ((stmt->cursor == NULL && stmt->dbc->current_statement != stmt) || stmt->row_status == PRE_NORMAL_ROW || stmt->row_status == NOT_IN_ROW) {
+ if ((stmt->cursor == NULL && stmt->dbc->current_statement != stmt)
+ || stmt->row_status == PRE_NORMAL_ROW
+ || stmt->row_status == NOT_IN_ROW)
+ {
odbc_errs_add(&stmt->errs, "24000", NULL);
ODBC_RETURN(stmt, SQL_ERROR);
}
@@ -4649,16 +4652,16 @@
tds = stmt->dbc->tds_socket;
context = stmt->dbc->env->tds_ctx;
- resinfo = tds->current_results;
- if (!resinfo) {
+
+ if (!tds->current_results) {
odbc_errs_add(&stmt->errs, "HY010", NULL);
ODBC_RETURN(stmt, SQL_ERROR);
}
- if (icol <= 0 || icol > resinfo->num_cols) {
+ if (icol <= 0 || icol > tds->current_results->num_cols) {
odbc_errs_add(&stmt->errs, "07009", "Column out of range");
ODBC_RETURN(stmt, SQL_ERROR);
}
- colinfo = resinfo->columns[icol - 1];
+ colinfo = tds->current_results->columns[icol - 1];
if (colinfo->column_cur_size < 0) {
*pcbValue = SQL_NULL_DATA;
@@ -4700,22 +4703,23 @@
}
if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
- /* calc how many bytes was readed */
- int readed = cbValueMax;
+ /* calculate how many bytes were read */
+ int remaining = cbValueMax;
/* 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 (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && remaining > 0)
+ --remaining;
+ if (remaining > *pcbValue)
+ remaining = *pcbValue;
+ colinfo->column_text_sqlgetdatapos += remaining;
/* avoid infinite SQL_SUCCESS on empty strings */
if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
++colinfo->column_text_sqlgetdatapos;
- /* not all readed ?? */
- if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size)
- /* TODO add diagnostic */
+
+ if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) { /* not all read ?? */
+ odbc_errs_add(&stmt->errs, "1004", "String data, right truncated");
ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ }
} else {
colinfo->column_text_sqlgetdatapos = colinfo->column_size;
}