I used libdbi with the freetds driver from Linux to connect to a sybase server on Solaris.
My database had a table with a column which was VARCHAR(20) One of the rows had exactly 20 characters. In this case libdbi returns an empty result. I found 2 problems: * dbd_freetds.c doesn't allocate enought to store the a null terminator. * freetds ignores a field when it has exactly 20 characters. I think I fixed both. I used valgrind to find the memory allocation usage. diff --git a/drivers/freetds/dbd_freetds.c b/drivers/freetds/dbd_freetds.c index e7df09a..5b5e13e 100644 --- a/drivers/freetds/dbd_freetds.c +++ b/drivers/freetds/dbd_freetds.c @@ -977,8 +977,9 @@ dbi_row_t *_dbd_freetds_buffers_binding(dbi_conn_t * conn, dbi_result_t * result /* * Result is more that 8 bytes - * allocate additional memory + * 1 extra byte for \0 */ - addr = row->field_values[idx].d_string = (char *) malloc(row->field_sizes[idx]); + addr = row->field_values[idx].d_string = (char *) malloc(row->field_sizes[idx] + 1); break; default: /* Prepare union to data copy */ -- -------------------- I posted the following to the freetds mailing list: I used freetds from Linux to connect to a sybase server on Solaris. My database had a table with a column which was VARCHAR(20) One of the rows had exactly 20 characters. With a simple SELECT it hit this piece of code which returns CS_FAIL without logging anything: 538 case CS_FMT_NULLTERM: 539 if (src_len == destlen) { 540 ret = CS_FAIL; /* not enough room for data + a null terminator - error */ 541 } else { 542 memcpy(dest, srcdata, src_len); 543 dest[src_len] = '\0'; 544 if (resultlen != NULL) 545 *resultlen = src_len + 1; 546 ret = CS_SUCCEED; 547 } 548 break; and the similar: 765 case CS_FMT_NULLTERM: 766 tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_NULLTERM\n"); 767 if (len == destlen) { 768 tdsdump_log(TDS_DBG_FUNC, "not enough room for data + a null terminator - error\n"); 769 ret = CS_FAIL; /* not enough room for data + a null terminator - error */ 770 } else { 771 memcpy(dest, cres.c, len); 772 dest[len] = 0; 773 if (resultlen != NULL) 774 *resultlen = len + 1; 775 ret = CS_SUCCEED; 776 } 777 break; I included a patch below. I'm not sure if the data structure which holds the length of the field needs updating. If I allocate 1 byte extra for the null terminator my query works. I tried this with Debian testing. Eddy diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index de6bbda..7fc0595 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -389,15 +389,12 @@ CS_RETCODE ret; switch (destfmt->format) { case CS_FMT_NULLTERM: - if (src_len == destlen) { - ret = CS_FAIL; /* not enough room for data + a null terminator - error */ - } else { - memcpy(dest, srcdata, src_len); - dest[src_len] = '\0'; - if (resultlen != (CS_INT *) NULL) - *resultlen = src_len + 1; - ret = CS_SUCCEED; - } + memcpy(dest, srcdata, src_len); + /* client code should allocate enough room for data + a null terminator */ + dest[src_len] = '\0'; + if (resultlen != (CS_INT *) NULL) + *resultlen = src_len + 1; + ret = CS_SUCCEED; break; case CS_FMT_PADBLANK: @@ -615,16 +612,12 @@ CS_RETCODE ret; case CS_FMT_NULLTERM: tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_NULLTERM\n"); - if (len == destlen) { - tdsdump_log(TDS_DBG_FUNC, "not enough room for data + a null terminator - error\n"); - ret = CS_FAIL; /* not enough room for data + a null terminator - error */ - } else { - memcpy(dest, cres.c, len); - dest[len] = 0; - if (resultlen != (CS_INT *) NULL) - *resultlen = len + 1; - ret = CS_SUCCEED; - } + /* client code should allocate enough room for data + a null terminator */ + memcpy(dest, cres.c, len); + dest[len] = '\0'; + if (resultlen != (CS_INT *) NULL) + *resultlen = len + 1; + ret = CS_SUCCEED; break; case CS_FMT_PADBLANK: -- ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ Libdbi-drivers-devel mailing list Libdbi-drivers-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libdbi-drivers-devel