Re: errors from dblib
Frediano Ziglio <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
2009/4/19 James K. Lowden <[email protected]>: > 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? > Yes, only errors > 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.) > Yes, both fails > 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 > I always though tds_get/peak/read as low level. The layer is Client libraries <-> Token Processing <-> Reading processing. Client libraries should IMHO never call tds_peek/tds_read and similar. Token processing handle correctly cancellation. It's also difficult to handle cancellation in low level cause you don't know exactly the state of the connection. This cause usually low level reading functions are called by token processing which perhaps readed already a partial packet or token so you don't know if you are in a middle of some data. > 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 In this case the client, we received all the packet already. But tds_process_tokens know that client sent a cancel and correctly handle the cancel discarding all packets :) > 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(). > IMHO not as explained above. freddy77 _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds