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;
 		}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.