Bug #54040 The NET connector causes an unhandled exception (TEXT > 32767)
Submitted: 27 May 2010 19:03 Modified: 28 Jun 2010 14:27
Reporter: Walt Stoneburner Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:mysql-connector-net-6.3.1-alpha OS:Windows (Windows 7)
Assigned to: CPU Architecture:Any
Tags: 6.3.1, alpha, connector, count, dot, error, exception, inner, mscorlib, negative, NET, non, non-negative, number, required

[27 May 2010 19:03] Walt Stoneburner
Description:
Please see http://forums.mysql.com/read.php?38,369389,369389#msg-369389 for a very detailed discussion of the error.

It is possible to insert values into a TEXT field that are greater than 32767 bytes, and even read them with other clients, but when the NET connector is used to read those values, it throws an exception.

Users are experiencing this as:
  Error Source: mscorlib
  Error message: Non-negative number required.
  Parameter name: count

(At first this looked like a Unicode issue, and was formed as a Unicode question, but I later discovered it was a length issue -- hence the strange name in the MySQL Forums.)

How to repeat:
Details on how to repeat, as well as a code analysis of the NET source, resides at http://forums.mysql.com/read.php?38,369389,369414#msg-369414

In short, create a simple table with a TEXT field.  Insert a Unicode string that's 32768 characters or more.  Try to read it using the NET connector.

Or, try to access it with Visual Studio's data browser, you'll get the same exception (with the added bonus of crashing the environment).

Suggested fix:
In the places shown in http://forums.mysql.com/read.php?38,369389,369414#msg-369414 perhaps change the checks from checking equality with -1, to seeing if the value is equal or less than -1.  While this won't solve the problem, it won't blow up with an exception, although I'd have concerns about silent data loss.

The larger question is why a 32-bit version is failing at a 2^15 boundary and not at 2^31.

It would be helpful to have a 64-bit version which works with data up to 2^63.
[27 May 2010 23:56] Walt Stoneburner
Did a little experimenting.  The problem still seems to exist in the NET connector, even if using MEDIUMTEXT (which handles larger strings).
[28 May 2010 8:57] Tonci Grgin
Hi Walt and thanks for your report.

I will have to think a bit but apparent problem is in that Microsoft does not have types larger than signed 32bit range. You can see the example of that in, let's say, c/ODBC which has startup option "Limit column size to signed 32-bit range" exactly for such cases. Same goes for BIGINT, unsigned values and so on.

In any case, there should not be a NPE anywhere...
[28 May 2010 8:58] Tonci Grgin
Walt, instead of forum links, could you please attach small but complete test case so I can check this?
[28 May 2010 14:11] Walt Stoneburner
Sorry Tonci, I had started in the forum before I realized it was a bug and used a lot of BBcode notation to make things look pretty; when I got to the bug reporting phase, didn't think that would convey well.  At least you have it there if need be, but as for a use case that causes this to crash -- just gen'd one up for you.  Try this.

mysql> create table t ( id int auto_increment, c mediumtext, primary key(id) );
Query OK, 0 rows affected (0.00 sec)
mysql> desc t;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| c     | medium text | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

Then, create a regular WPF application or whatever, add the MySql.Data and MySql.Data.Entity references to it, add an ADO.NET Entity Data Model (.edmx) file to it, generating from the database so you get the one table.

Then, add a button or something so you can invoke the code in the handler however you want.  The following code will cause the unhandled exception.

StringBuilder sb = new StringBuilder();
for ( int i = 0; i < 32768; i++ ) sb.Append('X');  // Make a long string

// This writes the string in, and works for any size
using (var dc = new YourDatabaseContext())
{
  t.entity = new t();        // This is our table
  entity.c = sb.ToString();  // This is the string of length 32768

  dc.AddTot(entity);         // Add the entity to the t's
  db.SaveChanges();          // ...if you peek with MySQL's client, it worked.
}

// This is where the badness happens
using (var dc = new YourDatabaseContext())
{
  var results = from r in dc.t    // from the rows in our table
                select r;         // get that row

  foreach ( t entity in results )
  {
    Console.WriteLine("{0}", entity.c.Length ); // Print the string length
  }
}

This will blow up with an EntityCommandExecutionException was unhandled on the foreach statement, which is trying to evaluate the LINQ expression.

Now here's the whacky thing.  Do this:
mysql> DELETE FROM t;
Query OK, 1 row affected (0.00 sec)

Then change the 32768 to 32767, run the program, and you'll see it prints 32767 on the console.

There's a problem with that boundary, even with MEDIUMTEXT.
[1 Jun 2010 8:17] Tonci Grgin
Walt, this is all nice but I still need to see your test case. I am not about to spend hours writing my own just to find out there was a wrong setting in connection string or somewhere. Can you please attach the solution for VS2008 as I do not have VS2010 right now.
[2 Jun 2010 14:19] Walt Stoneburner
Test Case for Bug54040

Attachment: Bug54040.zip (application/x-zip-compressed, text), 51.70 KiB.

[2 Jun 2010 14:29] Walt Stoneburner
Tonci, had to downgrade to VS2008 in order to produce a solution you could access.  (This was for 6.3.1-alpha.)

0a) Unzip the file, open the solution, 
0b)   resolve to your references for MySQL.Data and MySQL.Data.Entity.
1)  See the README file for creating the single two-column table.
2)  Run the app and press the GREEN button -- it works.
3)  Run the app and press the RED button -- it crashes.
      ...the only difference is one byte of the string length.
    [Note after you press the red button, you'll need to delete the
     rows from the table, DELETE FROM T, manually, since Entity Frameworks
     won't be able to read the table anymore for further tests.]

NOW SOME FANTASTICLY GOOD NEWS.
I happened to notice that the dot NET Connector 6.3.2 beta was out, and I happened to try it, on VS2008 and on VS2010.  It worked!

As far as I'm concerned, this problem is resolved.  Thank you for your help and effort, it is greatly appreciated.
[28 Jun 2010 13:30] Tonci Grgin
Thanks for info Walt and sorry for the delay in answering.

Will close the report now as fixed in new release.
[28 Jun 2010 13:51] Tony Bedford
Set to documenting as per request from Tonci. Needs to be added to 6.3.2 changelog.
[28 Jun 2010 14:27] Tony Bedford
An entry has been added to the 6.3.2 changelog:

MySQL Connector/NET generated an exception when used to read a TEXT column containing more than 32767 bytes.
[2 Dec 2011 16:59] levitra levitra
who watched the Oscars?