| Bug #43972 | Schema Information Bug (System.Byte[] and Invalid Cast) | ||
|---|---|---|---|
| Submitted: | 31 Mar 2009 6:44 | Modified: | 17 Apr 2009 20:32 |
| Reporter: | Armando Bañuelos | Email Updates: | |
| Status: | Can't repeat | Impact on me: | |
| Category: | Connector / NET | Severity: | S1 (Critical) |
| Version: | 5.2.5, 6.0.0 | OS: | Any (Error in Schema Information) |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | .net, 5.2.5, 6.0.0, cast, configure, System.Byte[], TableAdapter | ||
[7 Apr 2009 9:33]
Tonci Grgin
Hi Armando and thanks for your report. Partially I have reported it in Bug#43991 (fixed). Can you please make complete test case for second part of your report? Are you using MySQL server 4.1 or higher?
[9 Apr 2009 23:44]
Armando Bañuelos
Hi! I'm using server 4.1.11 . Ok, the second part of the report is an issue casting the variable. You asume is long, but it returns another type at runtime. So i think you must convert it, and not only cast the value.
[17 Apr 2009 9:56]
Bogdan Degtyariov
VS 2005 Server explorer displayed the list of table columns correctly for me. I used MySQL Server 4.1.11 and Connector/NET 6.0. Did I miss anything?
[17 Apr 2009 20:32]
Armando Bañuelos
I checked and is present in 5.2.5 and also in 6.0.0. 1) Do a normal connection, Don't modify anything. 2) The Server Explorer shows tables and columns, but carefully check the Columns properties "Character Set", "Collation", "Default Value" they apper to be "System.Byte[]" 3) Try to do an "Alter Table" in the Table in Server Explorer. Hope you can repeat it. Try to follow the screenshoots with the Problem. Thanks.
[17 Apr 2009 20:38]
Armando Bañuelos
Incorrect Column Information
Attachment: ScreenShoot-1.PNG (image/png, text), 157.16 KiB.
[17 Apr 2009 20:39]
Armando Bañuelos
Error trying to "Alter Table"
Attachment: ScreenShoot-2.PNG (image/png, text), 280.70 KiB.

Description: Good Day, first of all, there are 2 bugs in the SchemaProvider.cs file. At least is broken compatibility with 4.1.11 servers. The first, is that MetaData information of GetColumns(COLUMN_DEFAULT and CHARACTER_SET_NAME), and GetIndexes(INDEX_NAME, TABLE_NAME, PRIMARY) is returned incorrectly (Returned as System.Byte[], or compared incorrectly). I readed that is a bug of the Server, I also noted that the flag "Respect Binary Flag" fixes the behaviour, but I think the Driver should read correctly, cause its database metadata. The second bug is in the GetIndexes, SEQ_IN_INDEX and NON_UNIQUE. Both are byte, and you cast to long, and Visual Studio 8 & 9 complains to generate Update and Delete statements and modify the TableAdapter. The third bug is when you try to Alter Table with Foreign Keys you get a Incorrect Table Name 'System.Byte[]'. Also if table have not Foreign Keys you get some weird info. How to repeat: Create a table in MySQL 4.1.11, and show in Visual Studio Explorer. CREATE TABLE test ( `id` varchar(5) NOT NULL default '', `id_ref` varchar(5) NOT NULL default '', `desc` varchar(45) NOT NULL default '', PRIMARY KEY (`id`), CONSTRAINT `FK_TEST` FOREIGN KEY (`id_ref`) REFERENCES `test` (`id`) ) ENGINE=InnoDB; Show the columns and the information is incorrect (System.Byte[]). Try to configure a DataAdapter and you receive and 'Invalid Cast' and no Update, Delete Statements are Generated. Try to 'Alter Table' and Gets incorrect or no data. Suggested fix: => SchemaProvider.cs LoadTableColumns(...) Change: row["COLUMN_DEFAULT"] = reader.GetValue(5); ... row["CHARACTER_SET_NAME"] = reader.GetValue(2); To: row["COLUMN_DEFAULT"] = GetString(reader, 5); ... row["CHARACTER_SET_NAME"] = GetString(reader, 2); GetIndexes(...) You can change to iterate a Reader instead of use DataTable.Fill, or you can change: From: long seq_index = (long)index["SEQ_IN_INDEX"]; ... row["INDEX_NAME"] = index["KEY_NAME"]; row["TABLE_NAME"] = index["TABLE"]; row["UNIQUE"] = (long)index["NON_UNIQUE"] == 0; row["PRIMARY"] = index["KEY_NAME"].Equals("PRIMARY"); To: long seq_index = Convert.ToInt64(index["SEQ_IN_INDEX"]); ... row["INDEX_NAME"] = GetStringMetaData(index["KEY_NAME"]); row["TABLE_NAME"] = GetStringMetaData(index["TABLE"]); row["UNIQUE"] = Convert.ToInt64(index["NON_UNIQUE"]) == 0; row["PRIMARY"] = row["INDEX_NAME"].Equals("PRIMARY"); //Add this method private string GetStringMetaData(object value) { if (value != null) { if (value is byte[]) { //As of MySQL 4.1, the server now treats its metadata using the UTF-8 encoding return Encoding.UTF8.GetString((byte[])value); } return value.ToString(); } return null; } => MySqlConnectionSupport.cs internal static DataTable ConvertAllBinaryColumns(DataTable dt) ... //FIX:Could be DBNull if (column.DataType == typeof(System.Byte[]) && row[column.Ordinal] != System.DBNull.Value) newRow[column.Ordinal] = e.GetString((byte[])row[column.Ordinal]); ... => IndexDescriptor.cs ReadTable(...) ... //BUG: Index Metadata in version 4.1.11 read as Byte[] indexes = MySqlConnectionSupport.ConvertAllBinaryColumns(indexes); // Fetch data FetchData(restrictions, table, indexes, result); ... Also I suggest the following Tests: GetSchemaTests(...) //FIX: It supported also in 4.1.11, not only 5.0.0 if (version < new Version(4, 1, 11)) return; ... //FIX: Some Schema Strings as System.Byte[] Assert.AreNotEqual("System.Byte[]", dt.Rows[0]["INDEX_NAME"]); Assert.AreNotEqual("System.Byte[]", dt.Rows[0]["INDEX_CATALOG"]); Assert.AreNotEqual("System.Byte[]", dt.Rows[0]["INDEX_SCHEMA"]); Assert.AreNotEqual("System.Byte[]", dt.Rows[0]["INDEX_NAME"]); Assert.AreNotEqual("System.Byte[]", dt.Rows[0]["TABLE_NAME"]);