Skip to Content.
Sympa Menu

freetds - RE: [freetds] db-lib does not get PRINT data

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Thompson, Bill D (London)" <bill_d_thompson AT ml.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: RE: [freetds] db-lib does not get PRINT data
  • Date: Fri, 17 Dec 2004 10:33:18 -0000

James,

> What is the difference between tds_socket::current_results and
> tds_socket::res_info? They're both TDSRESULTINFO structures. Why
two?

In the old days (before compute clauses, cursors, dynamic sql etc.) each
tds connection was assumed to only handle one result set (and
accompanying metadata) at a time. Each new result set "wiped out" the
preceding result set. So we only needed one "result_info" structure in
our tds structure.

Life has since become much more complex since those far off, innocent
days. We now have to retain on our connection the meta data for many
concurrent result sets: compute clauses in a sql statement each have
their own; any open cursor has its own; any defined dynamic statement
has its own.
current_results is a pointer to whichever set of results meta data is
currently relevant.

Really, none of the API's should access tds->res_info directly. They
should use tds->current_results
I don't think that is necessarily the problem with your example
however...

> tds_process_msg() in src/tds/token.c discarded messages whose message
> number was zero. In db-lib, EED packets are routed to the client's
> installed message handler, with a message number of zero. Because
> tds_process_msg() discarded them, db-lib never got them.

Well if that's true, how come sqsh (via ctlib) manages to get hold of
the printed message ?
ct_results calls
tds_process_result_tokens()/tds_process_default_tokens()/tds_process_msg
() just like dbresults.
I think there's something about your error/message handler in bsqldb.
BTW, it's very common to discard message numbers 5701 and 5703 (context
change messages) in error handlers...

> I removed the "if (msg.msg_number > 0)" test. I don't know what
effect
> that will have on the other libraries yet.

I don't find that code as you have specified, at least not in RC5...

$ grep 'msg.msg_number' token.c

msg.msg_number = msgnum;
msg.sql_state = tds_alloc_client_sqlstate(msg.msg_number);
msg.msg_number = rc;
msg.sql_state = tds_alloc_lookup_sqlstate(tds, msg.msg_number);
if (marker == TDS_EED_TOKEN && tds->cur_dyn && !TDS_IS_MSSQL(tds) &&
msg.msg_number == 2782) {
} else if (msg.msg_number) {
msg.msg_number,

> The problem behind the problem: db-lib clients will attempt to process
a
> result set whenever an EED packet arrives, using the previous result
set's
> metadata. This can lead to bad things.

> The reason?

As you know, dbresults() is not terribly informative.
You just get a return code of SUCCEED/FAIL/NO_MORE_RESULTS.

SUCCEED doesn't necessarily mean there's something to do.
The dblibrary manual page for dbresults says:

"To determine whether a particular command is one that returns rows
and needs results processing with dbnextrow, call DBROWS after the
dbresults call."

and suggests the following typical code...

while ((return_code =dbresults(dbproc)!=NO_MORE_RESULTS){
if ((return_code == SUCCEED)
&& (DBROWS(dbproc) == SUCCEED)) {
...

HTH,

Bill




-----Original Message-----
From: freetds-bounces AT lists.ibiblio.org
[mailto:freetds-bounces AT lists.ibiblio.org] On Behalf Of James K. Lowden
Sent: 17 December 2004 06:33
To: FreeTDS Development Group
Subject: Re: [freetds] db-lib does not get PRINT data


"Lowden, James K" <LowdenJK AT bernstein.com> wrote:
> What is the difference between tds_socket::current_results and
> tds_socket::res_info? They're both TDSRESULTINFO structures. Why
two?

(I still don't understand why, but that turns out not to be important to
honoring EED packets.)

tds_process_msg() in src/tds/token.c discarded messages whose message
number was zero. In db-lib, EED packets are routed to the client's
installed message handler, with a message number of zero. Because
tds_process_msg() discarded them, db-lib never got them.

I removed the "if (msg.msg_number > 0)" test. I don't know what effect
that will have on the other libraries yet.

The problem behind the problem: db-lib clients will attempt to process a
result set whenever an EED packet arrives, using the previous result
set's
metadata. This can lead to bad things.

The reason?

dbresults() calls
tds_process_result_tokens() calls
tds_process_default_tokens() calls
tds_process_msg()

which winds up fetching the EED packet. tds_process_msg() returns
TDS_SUCCEED, and the return code is propogated all the way back to the
application. The application interprets that as, um, success, and
attempts to fetch a row. It does not often find what it's looking for.


I'm too tired now to design a good solution. The token-reading code has
always seemed clumsy to me. I don't know if there will ever be results
to
process once tds_process_result_tokens() calls
tds_process_default_tokens(). I would guess it should always return
TDS_NO_MORE_RESULTS.

This looks like a serious bug to me. I'm hoping we can fix it for the
release.

--jkl
_______________________________________________
FreeTDS mailing list
FreeTDS AT lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
--------------------------------------------------------

If you are not an intended recipient of this e-mail, please notify the
sender, delete it and do not read, act upon, print, disclose, copy, retain or
redistribute it. Click here for important additional terms relating to this
e-mail. http://www.ml.com/email_terms/
--------------------------------------------------------





Archive powered by MHonArc 2.6.24.

Top of Page