Bug #47928 Old Guids=true setting is lost after null value is encountered in a Binary(16)
Submitted: 9 Oct 2009 1:38 Modified: 23 Oct 2009 12:57
Reporter: Troy Kubicek Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S1 (Critical)
Version:6.1.2 OS:Any
Assigned to: Vladislav Vaintroub CPU Architecture:Any
Tags: Binary(16), old guids

[9 Oct 2009 1:38] Troy Kubicek
Description:
When using a binary(16) column to represent a guid and specify old guids = true in the connection string the values are returned correctly until a null value is encountered in that field.  After the null value is encountered a format exception is thrown specifying "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."  

Setup:
Connector/Net 6.1.2 running on Windows XP SP3 with all current patches
MySQL Version: MySQL 5.0.51a-3unbuntu5.4 running on Ubuntu Linux 8.04 Hardy Heron

How to repeat:
Create a table that includes a field of type binary(16).  Insert a mix of values and null entries.  Create an sproc to select the binary(16) field from all rows.
Include the 'old guids=true' option in the connection string specified in the web.config.  Create MySqlConnection object using the connection string.  Create the MySqlCommand specifying the sproc and setup the necessary calling parameters.
Using the MySqlDataAdapter.Fill(DataSet ds, "TableName"); method to fill a dataset.  Execute the program.  

Inspection of the MySqlGuid.cs file in the debugger showed that ReadValue method doesn't carry forward the OldGuid setting when a null value is encountered.  Following are lines 181-199
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
            MySqlGuid g = new MySqlGuid();
            g.isNull = true;
            if (!nullVal)
            {
                if (OldGuids)
                    return ReadOldGuid(packet, length);
                string s = String.Empty;
                if (length == -1)
                    s = packet.ReadLenString();
                else
                    s = packet.ReadString(length);
                g.mValue = new Guid(s);
                g.OldGuids = OldGuids;
                g.isNull = false;
            }
            return g;
}

Suggested fix:
Move line 195 "g.OldGuids = OldGuids;" to occur prior to the if(!nullVal) block

IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
		{
            MySqlGuid g = new MySqlGuid();
            g.isNull = true;
            g.OldGuids = OldGuids;
            if (!nullVal)
            {
                if (OldGuids)
                    return ReadOldGuid(packet, length);
                string s = String.Empty;
                if (length == -1)
                    s = packet.ReadLenString();
                else
                    s = packet.ReadString(length);
                g.mValue = new Guid(s);
                //g.OldGuids = OldGuids;
                g.isNull = false;
            }
            return g;
}
[12 Oct 2009 9:27] Tonci Grgin
Hi Troy and thanks for your report.

I would like to see full test case attached. Preferably, test case will create all the necessary SP's and tables too.
Can you do this for me please?
[16 Oct 2009 5:56] Tonci Grgin
Bug#48083 was marked as duplicate of this report.
[16 Oct 2009 7:41] Tonci Grgin
Verified as described using Troy's test case.

Troy, I see nothing sensitive in data you attached. So, if you don't mind, please make your comments/attachments public so others can see them. If you choose to do so, I might add that SQL script needs changes in SP generation part; instead of `definer` one should put proper user name.
Also, you appear to use oooolllldddd version of System.Web.Extensions (1.0) so I had to upgrade that to 3.5 in web.config.

Note to Wlad: Check on Bug#48083 too. "delete from TestTable where Id = 5;" and restarting app causes the error to appear.
[16 Oct 2009 11:37] Tonci Grgin
Reassigning to Reggie.
[16 Oct 2009 12:48] Troy Kubicek
DB Scripts to create tables, data, and sprocs along with VS2005 Solution & website

Attachment: OldGuidsTrueTestCase.zip (application/octet-stream, text), 305.64 KiB.

[16 Oct 2009 12:51] Troy Kubicek
Attached zip file that includes the complete test case files, DataBase scripts to create necessary tables, fill with data, and sprocs, along with complete sample website pages.

You will need to modify the web.config connection string "LocalMySqlServer" to specify your server name and an appropriate userName and password.

The site expects you to have version 6.1.2 of MySql.Data & MySql.Web installed in the GAC.

Upon opening the default.aspx page in a browser you will see the error reproduced.  If you want to see the page function without the error you can delete the row in 'TestTable' that has the null value for ttGuid. 
The page will function normally without that row.  To repro the problem again you can reinsert another entry with a null value by not checking the CheckBox to generate a Guid.  Followed by reinserting a second entry that does have the Checkbox checked to generate a Guid.  To manifest the problem you must have a null value in the ttGuid column followed by a non null value in the ttGuid column.

Let me know if you need anything else.
[16 Oct 2009 14:45] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/87146

778 Vladislav Vaintroub	2009-10-16
      fixed crash that can occur when oldGuids are used and binary(16) column  used for GUID 
      contains a null value (thanks Troy!) (bug#47928)
[20 Oct 2009 20:03] Reggie Burnett
Please push this to 6.0 as well if the problem exists there
[20 Oct 2009 20:08] Vladislav Vaintroub
Just rechecked - OldGuids was introduced in 6.1, in 6.0 the problem does not exist.
[23 Oct 2009 12:57] Tony Bedford
An entry was added to the 6.1.3 and 6.2.0 changelogs:

When using a BINARY(16) column to represent a GUID and having specified “old guids = true” in the connection string, the values were returned correctly until a null value was encountered in that field. After the null value was encountered a format exception was thrown with the following message:

Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)