Skip to Content.
Sympa Menu

freetds - RE: mssql_query not updating mssql_get_last_message on php4.1.2 and freetds 0.53

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Mark Gruetzner" <mgruetzner AT rw3.com>
  • To: "TDS Development Group" <freetds AT franklin.oit.unc.edu>
  • Subject: RE: mssql_query not updating mssql_get_last_message on php4.1.2 and freetds 0.53
  • Date: Fri, 17 May 2002 15:28:01 -0500


Thanks,

Yes, my first instinct, as well, was to widen the message variable to 32
bits to store the message number. Not being very familiar with the code and
the specs, I was more afraid of breaking something by doing that....but, I
agree, this would be getting to the real root of the problem...

As for the "2 sets of database results" (which I now know is only 1 set +
out of band data for the message), I was simply looking at the freetds.log
file (which works very well for debugging by the way) and found that I was
receiving both my query results and the message from raiserror in response
to my call to mssql_query--but the php code was only getting the query
results with the first call to dbresults() and the message was not getting
processed. In this case, where there is out-of-band data following the
query results, the first call to dbresults() returns SUCCESS (rather than
NO_MORE_RESULTS), and so I call it again (after processing all the rows with
dbnextrow) which will then return NO_MORE_RESULTS and cause the message to
get processed--which in turn causes the PHP callback to get called by
freetds, where PHP stores the message for subsequent calls to
mssql_get_last_message. (By the way, PHP calls dbmsghandle to register its
callback function which freetds calls when it processes a message--then, in
the callback function, PHP simply stores the message in a global variable so
it can return it when the PHP function msssql_get_last_message() is called)

I'd be interested in looking at an actual spec. since I have been solely
relying on looking at the source code and the freetds.log file...

-Mark


-----Original Message-----
From: bounce-freetds-143882 AT franklin.oit.unc.edu
[mailto:bounce-freetds-143882 AT franklin.oit.unc.edu]On Behalf Of Lowden,
James K
Sent: Friday, May 17, 2002 2:42 PM
To: TDS Development Group
Subject: [freetds] RE: mssql_query not updating mssql_get_last_message
on php4.1.2 and freetds 0.53


> From: Mark Gruetzner [mailto:mgruetzner AT rw3.com]
> Sent: May 17, 2002 12:11 PM

Mark,

Nice analysis. Always good to improve the fit of FreeTDS and PHP. I don't
think it's a question of "negative message numbers" per se, see below, but
maybe I'm overlooking something.

> mssql_query ("mystoredproc");
> $msg = mssql_get_last_message ();
> print $msg;
>
> where "mystoredproc" is a stored procedure that returns N rows of data and
> calls the SQL function below to send a warning message:
>
> raiserror ('QueryLimit',9,1)
>
> you would expect the value of $msg to be "QueryLimit" after the call to
> mssql_query. In fact, this is how it works on Windows but not on Linux
> using freetds. I have debugged this issue on both the freetds and php
> software and found the following. On Freetds, the message number that
gets
> returned from SQL is 50000 which when stored as a 16-bit signed integer is
a
> negative value in the freetds code, so the freetds code ignores the
message.

raiserror is so weird. It passes a string and a message number, and can
optionally set @@error to value of the message id ("with seterror").

To get raiserror to pass a user-defined message number, you need to install
the message in sysmessages with sp_addmessage. The syntax you're using is
an "ad hoc message", to which raiserror assigns a message number of 50,000.
That's where the 50,000 is coming from.

The maximum message number is 2^31 - 1. We need 31 bits to represent such
numbers, not the 15 we're apparently providing. Trying to stuff 31 bits of
data into a signed two-byte variable is unlikely to be a Good Thing. In
this case, the 50,000 only *coincidentally* needs just 16 bits, so you see
it as a negative value (high bit set). But someone could add, say, message
number 131,196 (2^17 + 124) to sysmessages; we'd trim off the high bytes and
represent it as #124, "CREATE PROCEDURE contains no statements". A bug, I'd
say.

The real error is treating the message id as a 16-bit variable, no? Where
does that happen? Why not just widen the variable?

What this means for Sybase, TDS 4.2, and/or big endian machines, I don't
know.

> I modified the freetds code to NOT ignore negative message numbers but to
go
> ahead and pass those messages on to the appropriate callback function in
> PHP. That helped matters, but there was still an issue in the php code in
> the "sybase_query" function in php_sybase_db.c. Basically, what is
> happening is that in the case described above, you receive 2 sets of
> database results as a result of the query, but the sybase_query function
is
> only reading the first set of results.

How does it become "2 sets of database results"? There is a result set
(output from your query), and an out-of-band message (from raiserror).
Those are two different things.

mssql_get_last_message doesn't process result sets; it looks to me like the
PHP equivilant of dbmsghandle.

Obviously, I don't know all the ramifications, either, Mark. I'm just
trying to make sure we understand the spec first.

Regards,
--jkl

---
You are currently subscribed to freetds as: [mgruetzner AT rw3.com]
To unsubscribe, forward this message to
$subst('Email.Unsub')





Archive powered by MHonArc 2.6.24.

Top of Page