Skip to Content.
Sympa Menu

freetds - Re: [freetds] Problems with UnixODBC and FreeTDS

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Frediano Ziglio" <freddy77 AT gmail.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] Problems with UnixODBC and FreeTDS
  • Date: Thu, 12 Jul 2007 11:40:57 +0200





Ok, I understand the problem. When text is empty SQL_NO_DATA is returned
and string is not null-terminated. On the first call SQLGetData should
return SQL_SUCCESS instead. Note that pyODBC should check SQLGetData
results. Currently I'm attempting a course at Milano so I'm not able to do a
patch for this problem... expect a patch for next week... if I don't find an
alternate way before...



Could you try this patch ??

freddy77
? vedi.diff
Index: src/odbc/odbc.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/odbc/odbc.c,v
retrieving revision 1.451
diff -U10 -r1.451 odbc.c
--- src/odbc/odbc.c 7 Jul 2007 17:11:28 -0000 1.451
+++ src/odbc/odbc.c 12 Jul 2007 09:29:04 -0000
@@ -4441,21 +4441,22 @@
odbc_errs_add(&stmt->errs, "07009", "Column out of range");
ODBC_RETURN(stmt, SQL_ERROR);
}
colinfo = resinfo->columns[icol - 1];

if (colinfo->column_cur_size < 0) {
*pcbValue = SQL_NULL_DATA;
} else {
src = (TDS_CHAR *) colinfo->column_data;
if (is_blob_type(colinfo->column_type)) {
- if (colinfo->column_text_sqlgetdatapos >=
colinfo->column_cur_size)
+ if (colinfo->column_text_sqlgetdatapos > 0
+ && colinfo->column_text_sqlgetdatapos >=
colinfo->column_cur_size)
ODBC_RETURN(stmt, SQL_NO_DATA);

/* 2003-8-29 check for an old bug -- freddy77 */
assert(colinfo->column_text_sqlgetdatapos >= 0);
src = ((TDSBLOB *) src)->textvalue +
colinfo->column_text_sqlgetdatapos;
srclen = colinfo->column_cur_size -
colinfo->column_text_sqlgetdatapos;
} else {
srclen = colinfo->column_cur_size;
}
nSybType = tds_get_conversion_type(colinfo->column_type,
colinfo->column_size);
@@ -4469,20 +4470,23 @@
if (is_blob_type(colinfo->column_type)) {
/* calc how many bytes was readed */
int readed = cbValueMax;

/* FIXME test on destination char ??? */
if (stmt->dbc->env->attr.output_nts != SQL_FALSE &&
nSybType == SYBTEXT && readed > 0)
--readed;
if (readed > *pcbValue)
readed = *pcbValue;
colinfo->column_text_sqlgetdatapos += readed;
+ /* avoid infinite SQL_SUCCESS on empty strings */
+ if (colinfo->column_text_sqlgetdatapos == 0)
+ ++colinfo->column_text_sqlgetdatapos;
/* not all readed ?? */
if (colinfo->column_text_sqlgetdatapos <
colinfo->column_cur_size)
/* TODO add diagnostic */
ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
}
}
ODBC_RETURN_(stmt);
}

SQLRETURN SQL_API
Index: src/odbc/unittests/getdata.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/odbc/unittests/getdata.c,v
retrieving revision 1.1
diff -U10 -r1.1 getdata.c
--- src/odbc/unittests/getdata.c 29 Aug 2003 15:07:11 -0000 1.1
+++ src/odbc/unittests/getdata.c 12 Jul 2007 09:29:04 -0000
@@ -1,19 +1,20 @@
#include "common.h"

static char software_version[] = "$Id: getdata.c,v 1.1 2003/08/29 15:07:11
freddy77 Exp $";
static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };

int
main(int argc, char *argv[])
{
char buf[16];
+ SQLLEN len;

Connect();

/* TODO test with VARCHAR too */
Command(Statement, "SELECT CONVERT(TEXT,'Prova')");

if (SQLFetch(Statement) != SQL_SUCCESS) {
printf("Unable to fetch row\n");
CheckReturn();
exit(1);
@@ -47,13 +48,35 @@
CheckReturn();
exit(1);
}
if (strcmp(buf, "ova") != 0) {
printf("Wrong data result 2 res = '%s'\n", buf);
exit(1);
}

Disconnect();

+ use_odbc_version3 = 1;
+ Connect();
+
+ Command(Statement, "SELECT CONVERT(TEXT,'')");
+
+ if (SQLFetch(Statement) != SQL_SUCCESS)
+ ODBC_REPORT_ERROR("Unable to fetch row");
+
+ len = 1234;
+ if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 1, &len) != SQL_SUCCESS)
+ ODBC_REPORT_ERROR("invalid return from SQLGetData");
+
+ if (len != 0) {
+ fprintf(stderr, "Wrong len returned, returned %ld\n", (long)
len);
+ return 1;
+ }
+
+ if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 1, NULL) != SQL_NO_DATA)
+ ODBC_REPORT_ERROR("invalid return from SQLGetData");
+
+ Disconnect();
+
printf("Done.\n");
return 0;
}



Archive powered by MHonArc 2.6.24.

Top of Page