Skip to Content.
Sympa Menu

freetds - Re: [freetds] errors from dblib

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "James K. Lowden" <jklowden AT freetds.org>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] errors from dblib
  • Date: Sat, 18 Apr 2009 18:29:27 -0400

Frediano Ziglio wrote:
> I got some time to compile and run our dblib tests with MS and Sybase
> libraries.

Very nice! I assume the log contains only bad results, and the others
work OK?

It looks like we're more compatible with Sybase than Microsoft....

> You can see from attached files. I got dbsqlok fixed for timeout test
> removing these lines
>
> marker = tds_peek(tds);

I spent some time looking at this. I'm not sure we can remove those rows.


The code is deeply confused by the cancel packet. After the CANCEL is
sent, the server acknowledges it. But first it sends the pending data.
dbsqlok() sees the ROWFORMAT2 token and returns success.

With Microsoft/Sybase, does dbsqlok() fail? (I assume yes.)

The error isn't tds_peek(). The error is in tds_goodread(). It should
wait for the cancel acknowledgement, wasting any pending data. Here's the
stack:

tds_peek()
calls tds_get_byte()
calls tds_read_packet()
calls goodread()
calls tds_goodread()
calls tds_send_cancel() on timeout
and continues to wait

My log ends with:

[snip]
query.c:1951:tds_send_cancel: sending cancel packet
net.c:781:Sending packet
0000 06 01 00 08 00 00 00 00- |........|

net.c:654:Received packet
0000 04 01 00 4f 00 00 00 00-61 23 00 00 00 01 00 09 |...O.... a#......|
0010 62 65 67 69 6e 74 69 6d-65 00 00 00 09 62 65 67 |begintim e....beg|
0020 69 6e 74 69 6d 65 10 00-00 00 0c 00 00 00 3d 00 |intime.. ......=.|
0030 ae 01 00 00 d1 ef 9b 00-00 20 e0 1b 01 fd 11 00 |........ . ......|
0040 02 00 01 00 00 00 fd 20-00 02 00 00 00 00 00 |....... .......|

dblib.c:4579:dbsqlok() exits on result token 0x61
[pins]

tds_goodread() then gets a packet: Token 0x61, TDS_ROWFMT2_TOKEN!
Evidently, the server had it in its buffer, and when the CANCEL packet
arrived, it flushed the buffer and acknowledged the cancel. The token
sequence:

61: ROWFMT2
23 00 00 00: length 35 bytes
01 00: 1 column
09: label is 9 bytes
62 65 67 69 6e 74 69 6d 65: "begintime"
00: no catalog
00: no schema
00: no table
09: colname is 9 bytes
62 65 67 69 6e 74 69 6d 65: "begintime"
10 00 00 00: status updatable?
0c 00 00 00: usertype 12
3d: datatype 61
00: no locale

ae: CONTROL
01 00: length 1 byte
00: no fmt data

d1: ROW
ef 9b 00 00 20 e0 1b 01: 8-byte datetime

fd: DONE
11 00: valid count, more coming
02 00: TDS_TRAN_PROGRESS
01 00 00 00: @@rowcount = 1

fd: DONE
20 00: acknowledgement of attention (i.e. of cancel)
02 00: TDS_TRAN_PROGRESS
00 00 00 00: no rowcount

Fooey. I've run out of time today. I think the answer is that
tds_goodread() should call tds_process_cancel().

--jkl





Archive powered by MHonArc 2.6.24.

Top of Page