Skip to Content.
Sympa Menu

freetds - 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: mssql_query not updating mssql_get_last_message on php4.1.2 and freetds 0.53
  • Date: Fri, 17 May 2002 11:10:50 -0500


I posted a question about this a week or two ago, but was unable to find a
solution out there...so, having all the source code available (yeah!) I dug
in and found a solution.

To summarize, I modified the dblib_handle_info_message () function in
src\dblib\dbutil.c to NOT ignore negative message numbers. I'm not sure of
the ramifications of this, but it was necessary for me. Most of the
problem, however, was in the php source code which I also posted a fix for
on php.net. For details of the issue and the solution I am proposing, read
on...

If you make the following calls in PHP 4.1.2 on Linux using freetds 0.53 to
connect to a MS SQL Server 7 database:

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.
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. To remedy the problem, I modified
the sybase_query function to save the results of the first call to
dbresults(). Then, after reading all the rows of data from the first set of
results, I checked the result of the first call to dbresults. If it is not
set to NO_MORE_RESULTS, I call dbresults again to read the second set of
results, which in this case, is the warning message. By doing so, this
causes the freetds software to recognize the message and callback PHP with
the message. I have tested these fixes on Linux and they seem to work find
I can email the source code for the fix if you are interested....

For freetds, here's the simple modification I made to the
dblib_handle_info_message function in dbutil.c:

// mgruetzner--5-16-2002
// Process all messages regardless of message number. In MSSQL, if
// you use raiserror to raise a user-defined warning message, the
// message number is 50000 which when stored as a 16-bit signed int
// as tds->msg_info->msg_number is, it is treated as a negative number
// since the high bit is set. I do not want to ignore these messages,
// thus, the hack below where I simply do an 'if (1)' to process all
// messages. If someone can figure out a better solution, then great.
// I'm not sure of the ramifications for processing all messages...
if(1)
//if( tds->msg_info->msg_number > 0 )





  • mssql_query not updating mssql_get_last_message on php4.1.2 and freetds 0.53, Mark Gruetzner, 05/17/2002

Archive powered by MHonArc 2.6.24.

Top of Page