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: "Lowden, James K" <LowdenJK AT bernstein.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 11:24:50 -0500

> From: Thompson, Bill D (London)
> Sent: Friday, December 17, 2004 5:33 AM
>
> 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...

OK, old man, I understand now. One is storage, the other is truly a
pointer. If you use cscope, you'll see res_info is still plenty used,
especially by db-lib.

And you're right, that didn't turn out to be the difficulty.

> > 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 ?

Because it's not true, that why. ;-)

What I meant to say, what I would have said if I'd said a true thing, is
that _dblib_handle_info_message() discarded messages whose msg_number is
<= 0. That meant PRINT statements were never routed to the
application's message handler (if installed). Patch attached.

Obviously, changing that won't affect the other APIs.

> > 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.
>
> As you know, dbresults() is not terribly informative.
> You just get a return code of SUCCEED/FAIL/NO_MORE_RESULTS.

Ah, but that's not the point. Given the query:

select 1 print 'hi'

dbresults() should return SUCCEED once, and NO_MORE_RESULTS thereafter.
It doesn't. It returns SUCCEED twice (the second time passing back the
return code from tds_process_msg), leading the application to try to
retrieve the ghostly second result set. It finds the prior row's
metadata, but no data of course. Usually it doesn't matter, but
sometimes the row buffering logic can get deeply confused.

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

That's basically what bsqldb does. It doesn't use DBROWS(); it calls
dbnumcols() and dbnextrow() instead. dbnumcols() lies, describing a
long-expired ex-column, but dbnextrow() correctly says there's no there
there.

dbresults() behaves that way because tds_process_result_tokens() returns
SUCCEED rather than NO_MORE_RESULTS after it finds the PRINT output.
Each function blithely returns the called function's return code, and
none is willing to say, hey buddy, there're no more results.

The app is forced to discover the truth itself by doing some extra
digging. We have at least one case where that seems to have led to an
assert() failure in the row buffering logic.

Hope that at least makes the problem clear. The solution will be
harder, I'm afraid.

Regards,

--jkl



>
> -----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

-----------------------------------------
The information contained in this transmission may contain privileged and
confidential information and is intended only for the use of the person(s)
named above. If you are not the intended recipient, or an employee or agent
responsible for delivering this message to the intended recipient, any
review, dissemination, distribution or duplication of this communication is
strictly prohibited. If you are not the intended recipient, please contact
the sender immediately by reply e-mail and destroy all copies of the original
message. Please note that we do not accept account orders and/or instructions
by e-mail, and therefore will not be responsible for carrying out such orders
and/or instructions.
If you, as the intended recipient of this message, the purpose of which is to
inform and update our clients, prospects and consultants of developments
relating to our services and products, would not like to receive further
e-mail correspondence from the sender, please "reply" to the sender
indicating your wishes. In the U.S.: 1345 Avenue of the Americas, New York,
NY 10105.

Attachment: dbutil.diff
Description: dbutil.diff




Archive powered by MHonArc 2.6.24.

Top of Page