[freetds] NTBSTRINGBIND in dbgetnull?

Reid, Roger L. roger.reid at dpw.com
Thu Jun 12 19:27:05 EDT 2008

We had an app break with 0.82.    We worked around it, but I'm trying to figure out if it's an issue in dbgetnull, or if there's something up with our app.   It's worked for years with various Sybase dblibs, and then FreeTDS's up to 0.63 - but sometimes long standing "working bugs" get broken by a new release of something or other.

       dbbind (dbproc, i+1, NTBSTRINGBIND, MAXFIELD
	      , how == MANY ? (BYTE *)databuf[i] : (BYTE *)tmpbuf[i]);

I don't think any values are interesting here but NTBSTRINGBIND (maxfield is 256, databuf[i] and tmpbuf[i] are both pointers to 

If I got this right from my colleague, the problem is triggered when the value in the db is NULL (not sure that makes sense though).
It logs the error "unknown bindtype" - which thankfully exists in one place only, in dblib.c, in dbgetnull() (See Below).

I can trace this in better detail over the weekend.  I have hopes someone looks and says "oh, yeah..."

Obviously, we enter the block shown below, and fall through to the default.  

It appears that a type NTBSTRINGBIND should not have made it to this block, but should have hit the block that handles varlen < 0.   

varlen < 0,  if I read right, indicates NOT to pad the space, which is correct for NTBSTRINGBIND.   I presume using negative numbers to flag this is a dblib internal, not something to be set from the application.

       dbbind (dbproc, i+1, NTBSTRINGBIND, MAXFIELD
	      , how == MANY ? (BYTE *)databuf[i] : (BYTE *)tmpbuf[i]);

My current thesis is that somewhere inside dblib, varlen or whatever sets varlen should have been set negative, but wasn't in the case of a NULL value.   

But I could be an idiot.  - best regards - -  Roger Reid

----------------- 0.82 excerpt from dblib.c:dbgetnull ---------------------
      if (varlen > 0) {
              switch (bindtype) {
              case CHARBIND:
                      memset(varaddr, ' ', varlen);
              case STRINGBIND:
                      memset(varaddr, ' ', varlen);
                      varaddr[varlen-1] = '\0';
              case BINARYBIND:
                      memset(varaddr, 0, varlen);
                      assert(!"unknown bindtype");
      return SUCCEED;

More information about the FreeTDS mailing list