[freetds] SQLMoreResults() and dbresults() sometimes returnextraphantom resultset

Lowden, James K james.k.lowden at alliancebernstein.com
Thu Jul 6 15:18:02 EDT 2006

> From: ZIGLIO, Frediano, VF-IT
> Sent: Thursday, July 06, 2006 3:15 AM
> Another question is... 0.64 behave correctly?

Sadly, no.  I relinked the dblib rpc.c to the 0.64 libsybdb.  It fails
the same way.  

> > SQLMoreResults() and dbresults() both sometimes return SUCCEED
> Don't mix SQLMoreResults and dbresults, they are quite different

Maybe they should be less different?  

	"dbresults Sets up the results of the next query."
	"SQLMoreResults determines whether more results are available
... and, if so, initializes processing for those results."

Both functions set up the metadata and return SUCCESS if there are rows
to be read.  

> Note that all that questions are very longstanding with lot of
> small fixes but, it seems, not real fix... the problem is that
> libraries have sligtly different behavior that should be tested
> with care... 

That's one problem, surely.  But I think the real problem is more basic,
and I wonder if you agree.  

I don't understand why there are two main processing loops in libtds:

and	tds_process_tokens

These functions are very redundant.  As just one example,
TDS_PARAM_TOKEN is handled in both.  

IMHO there should be only *one* place in libtds that reads a token.  It
should read the token ("marker") and, for packets that have them, the
length.  Then it should call the appropriate process_* function, passing
the token and length.  Each process_* function would read only 'length'
bytes from the stream and return; it would *never* read another token.
If it fails to read 'length' bytes, the single read loop would be the
place to handle that error and inform the caller.  

The token reader ("tds_read_token()") would be passed an "intention",
something to indicate what the caller expects.  Like a good librarian,
It would read as many tokens as it could looking for the requested
packet.  Examples:

expecting login token, got  e3(ENVCHANGE)
expecting login token, got  ab(INFO)
expecting login token, got  ad(LOGINACK)	<-- expected
expecting login token, got  fd(DONE)


expecting row token, got d1(ROW)	<-- expected
expecting row token, got a8(ALTFMT)
expecting row token, got d3(ALTROW)
expecting row token, got 79(RETURNSTATUS)
expecting row token, got ac(PARAM)
expecting row token, got fe(DONEPROC)

All libraries have a "get next row" function.  Always, the last row can
be followed in the stream by output parameters and/or return status.
Always, the application may ignore compute rows and other "not regular"
results.  When reading a row, the token reader should not stop until it
gets a ROW or DONE/DONEPROC.  (And the results should not be freed until
the next metadata arrive or next packet is sent.)  

I know you've been working on this "read ahead" idea; I think you
understood the problem earlier.  But I now want to simplify things by:

1.  One read loop.
2.  Read all compute rows at one time, too, and keep list of structures
3.  Free results as late as possible.  

libtds began as a set of service routines to support db-lib.  db-lib was
the "driver": it made 
requests of libtds, which handled the low-level details.  libtds was the
passive servant.  We have to make it more active, to read as far ahead
as possible.  

We should also create a "public" libtds API, functions the client
libraries will call.  I think we can identify a set of functions that
all libraries need e.g.:

	"ioctl" (get/set options)
	install callbacks
	read metadata
	read row

Not too much more, eh?  I could work on a document showing the related
client API functions.  

Do you think this idea is:

1.  feasible?
2.  good?
3.  good to do now?

> I think that dblib is the former library so probably
> fixing it will help to understand the real behavior. 


> I think I'll start trying all dblib tests under windows

I think that will be useful going forward.  Microsoft promises its
version will be very stable (they stopped distributing it).  But of
course their db-lib is 4.2.  


The information contained in this transmission may be privileged and
confidential 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.

More information about the FreeTDS mailing list