[freetds] Server - Problems with TDS 4.2 COLFMT token

Steve Kirkendall skirkendall at dsl-only.net
Fri May 14 16:31:47 EDT 2004


"James K. Lowden" <jklowden at schemamania.org> wrote on Friday, May 14, 2004:
> On Thu, 13 May 2004, Steve Kirkendall <skirkendall at dsl-only.net> wrote:
> > 
> > Most of my success in writing a tiny SQL server has come with TDS 5.0.
> > Now I'm making another attempt at using TDS 4.2, and I'm running into a
> > problem.  It seems that the client (the FreeTDS ODBC driver on a Windows
> > machine) is parsing the 0xA1(COLFMT) token incorrectly.  It keeps
> > reading column info past the end of the token.
> 
> OK, first you send 0xA0, from which the client derives the number of
> columns.  That looks fine, and, you're right, the information is not
> repeated in the next packet.  

Got it!  There's a bug in src/server/server.c:tds_send_col_name()
-- it's sending the NUL byte at the end of each column name.  On
the receiving end, tds_process_col_name() reads a 1-byte length,
and then the characters of the name itself but not the NUL.  Then,
in the next loop iteration, it misinterprets the NUL character
as a 0 length byte.  Consequently, it ends up thinking there are
twice as many columns as there really are.

It looks like this was intentional.  There's even a comment in
tds_send_col_name() saying that it is sending the NUL character.
But it *is* wrong.

I hope to get my altered versions of the server functions cleaned
up and submitted this weekend.  That's kind of important, because
my available time for this tiny server project has just about ended.

> sp_datatype_info normally has these metadata ('-' indicates it's missing
> from your 0xA0 packet, which you presumably intend):
> 
> col     name                type      size    varies  
> ------  ------------------  --------  ------  ------  
>      1  	 TYPE_NAME  	char	 255	   1  
>      2  	 DATA_TYPE  smallint	   2	   0  
>      3  	 PRECISION	 int	   4	   1  
>      4      LITERAL_PREFIX  	char	  32	   1  
>      5      LITERAL_SUFFIX  	char	  32	   1  
>      6       CREATE_PARAMS  	char	  32	   1  
>      7  	  NULLABLE  smallint	   2	   1  
>      8      CASE_SENSITIVE  smallint	   2	   0  
>      9  	SEARCHABLE  smallint	   2	   0  
>     10  UNSIGNED_ATTRIBUTE  smallint	   2	   1  
>     11  	     MONEY  smallint	   2	   0  
>     12      AUTO_INCREMENT  smallint	   2	   1  
>     13     LOCAL_TYPE_NAME  	char	 255	   1  
> -   14       MINIMUM_SCALE  smallint	   2	   1  
> -   15       MAXIMUM_SCALE  smallint	   2	   1  
> -   16       SQL_DATA_TYPE  smallint	   2	   0  
> -   17    SQL_DATETIME_SUB  smallint	   2	   1  
> -   18      NUM_PREC_RADIX	 int	   4	   1  
> -   19  INTERVAL_PRECISION  smallint	   2	   1  
> -   20  	  USERTYPE  smallint	   2	   1  

I was going by the Sybase online manual, which only lists the first
13 columns.  Do you know what SQL_DATETIME_SUB and INTERVAL_PRECISION
should be?  I've had some trouble getting TIMESTAMP data types to
display correctly, and they sound like they might be relevant.

-- 
Steve Kirkendall    |A:It is confusing, since people don't read that way
kirkenda at cs.pdx.edu |Q:Why is top-posting bad?
                    |A:It is adding comments to the top of a message
                    |Q:What is top-posting?



More information about the FreeTDS mailing list