[freetds] [PATCH] Problem with VARCHAR in sybase.

James K. Lowden jklowden at freetds.org
Sat Jul 5 18:51:53 EDT 2008


Eddy Pronk wrote:
> afaict CS_FMT_NULLTERM is invalid in cs_convert (cf. 
> > http://manuals.sybase.com:80/onlinebooks/group-oc/ocg1250e/occpr/@ebt-link;pt=2420?target=%25N%14_2686_START_RESTART_N%25).
> >  
> >
> > Third, even if valid, istm the code is basically right: if the
> > destination buffer does not have room for a NULL terminator and the
> > format specification for the conversion demands one, the conversion
> > should fail. 
> 
> I isolated the way libdbi uses freetds. (modified array_bind.c)
> It demonstrates ct_fetch fails before the client code knows about the 
> lengh (20)
> 
> without datafmt.format = CS_FMT_NULLTERM; it doesn't put the '\0'

Thanks for the code.  I worked with it a little while and got it to run,
which led me to look more deeply into ct-lib.  I think the behavior is now
correct.  

There were places it was setting the bound indicator variable (see below)
to zero on failure when there was no need (and contrary to documented
behavior).  I believe you will find the attached test program fails with
your version of ct-lib and works with CVS HEAD.  

Your version didn't work for me because my server has no table named
"destination", so I changed the query to "select name from systypes".  

I was wrong about CS_FMT_NULLTERM being invalid for cs_convert, btw.  A
better
link is
http://infocenter.sybase.com/help/topic/com.sybase.help.ocs_12.5.1.comlib/html/comlib/X12687.htm.
 

The basic question is: How should ct_fetch() react when the
datafmt.maxlength argument indicates a length *exactly* equal to the
length of the returned data and datafmt.format is CS_FMT_NULLTERM?  

ct_fetch should:

1.  copy as many bytes as possible -- as fit in the bound destination
buffers -- to each bound buffer.  
2.  set each buffer's indicator variable to reflect the bytes copied.  
3.  if any buffer was too small, return CS_ROW_FAIL. 

In the test case, ct_fetch() fetches the value "uniqueidentifier", 16
bytes.  The bound variable's datafmt.maxlength is set to 16, and
datafmt.format is CS_FMT_NULLTERM.  The buffer needs to provide 17 bytes:
16 data plus the null terminator.  But it's offering only 16.  

ct_fetch() copies 16 bytes, discovers there's no room for the NULL
terminator, and returns the error.  Exactly as should be.  

I'm interested to hear if CVS HEAD resolves the original problem.  

Regards, 

--jkl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: datafmt.c
Type: application/octet-stream
Size: 3935 bytes
Desc: not available
Url : http://lists.ibiblio.org/pipermail/freetds/attachments/20080705/516f91a0/attachment.obj 


More information about the FreeTDS mailing list