Bug #8746 | Illegal type cast --- (string)charSets[field.CharactetSetIndex] | ||
---|---|---|---|
Submitted: | 23 Feb 2005 20:09 | Modified: | 22 Jun 2005 22:32 |
Reporter: | Jacob Cagley | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / NET | Severity: | S1 (Critical) |
Version: | 4.1.10 | OS: | Windows (Win 2000) |
Assigned to: | Reggie Burnett | CPU Architecture: | Any |
[23 Feb 2005 20:09]
Jacob Cagley
[24 Feb 2005 18:37]
Reggie Burnett
This is related to a different bug report talking about string columns sometimes coming back as binary. I have yet to reproduce this though.
[24 Feb 2005 18:42]
Jacob Cagley
I wonder if it would have anything to do with how mysql is setup. I have installed mine without the installer... just unzip to C:\mysql\mysql-4.1.10-win32 and then use cd C:\mysql\mysql-4.1.10-win32\bin mysqld --console to start it and to stop it, I use cd C:\mysql\mysql-4.1.10-win32\bin mysqladmin shutdown
[24 Feb 2005 19:00]
Reggie Burnett
Here is a unit test that I am using. I also tested it starting the server the same way you do: [Test] public void ConnectingAsUTF8() { execSQL("CREATE Database IF NOT EXISTS test2 DEFAULT CHARACTER SET utf8"); string connStr = String.Format("server={0};user id={1}; password={2}; database=test2;pooling=false;charset=utf8", host, user, password); MySqlConnection c = new MySqlConnection(connStr); c.Open(); c.Close(); execSQL("DROP DATABASE IF EXISTS test2"); }
[24 Feb 2005 19:12]
Jacob Cagley
For me... the error occurs when I try to run a select... Expand your unit test to add a table, run 3 or 4 inserts and then run a select and then view the data. See what you get after that.
[25 Feb 2005 2:58]
Reggie Burnett
Here is my new revised unit test. It works great on 4.1.10 [Test] public void ConnectingAsUTF8() { execSQL("CREATE Database IF NOT EXISTS test2 DEFAULT CHARACTER SET utf8"); string connStr = String.Format("server={0};user id={1}; password={2}; database=test2;pooling=false;charset=utf8", host, user, password); MySqlConnection c = new MySqlConnection(connStr); c.Open(); MySqlCommand cmd = new MySqlCommand("CREATE TABLE test (id int, name varchar(200))", c); cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO test VALUES (1, 'test')"; cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO test VALUES (2, 'test2')"; cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO test VALUES (3, 'test3')"; cmd.ExecuteNonQuery(); cmd.CommandText = "SELECT name FROM test"; object o = cmd.ExecuteScalar(); Assert.AreEqual("test", o); c.Close(); execSQL("DROP DATABASE IF EXISTS test2"); }
[25 Feb 2005 15:35]
Jacob Cagley
With the error I get, It is not on selection of fields but rather it starts on line 192 in MySqlClient\Driver MySqlCommand cmd = new MySqlCommand("SHOW COLLATION", connection); The data returned from this should be string but instead is byte. charSets[ Convert.ToInt32(reader["id"]) ] = reader["charset"]; Below is a simplied script that I am running that gets the error. I have altered it to fit into your design. Leave in the 2 db connections just in case the settings are saved from the inserts.. I do not think they are but just to be safe. execSQL("CREATE Database IF NOT EXISTS test2 DEFAULT CHARACTER SET utf8"); string connStr = String.Format("server={0};user id={1}; password={2}; database=test2;pooling=false;charset=utf8",host, user, password); MySqlConnection c = new MySqlConnection(connStr); c.Open(); MySqlCommand cmd = new MySqlCommand("CREATE TABLE test (id varbinary(16), active bit)", c); cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO test (id, active) VALUES (CAST(0x1234567890 AS Binary), true)"; cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO test (id, active) VALUES (CAST(0x123456789a AS Binary), true)"; cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO test (id, active) VALUES (CAST(0x123456789b AS Binary), true)"; cmd.ExecuteNonQuery(); c.Close(); MySqlConnection d = new MySqlConnection(connStr); d.Open(); cmd.CommandText = "SELECT id, name FROM test"; object o = cmd.ExecuteScalar(); Assert.AreEqual("test", o); d.Close(); execSQL("DROP DATABASE IF EXISTS test2");
[25 Feb 2005 19:43]
Reggie Burnett
Jacob I think you may have a problem in your code. The following code will not work since you are executing a command on a closed connection. MySqlConnection d = new MySqlConnection(connStr); d.Open(); cmd.CommandText = "SELECT id, name FROM test"; The cmd object is still associated with the previous connection. I moved your code over to my unit test, fixed this, and I still can't get it to fail.
[25 Feb 2005 19:56]
Jacob Cagley
Actually, I just pasted in the sql based on what you had and tried to split up the connections. I did not actually try to run that as that is not how I connect. After opening a connection, I run all select sql statements through this function IDbDataAdapter d = this.DataAdapter; IDbCommand c = con.CreateCommand(); c.CommandText = sSql; c.CommandType = CommandType.Text; d.SelectCommand = c; DataSet ds = new DataSet(); d.Fill(ds); return ds.Tables[0]; Then I use a for each loop to exact the data foreach(DataRow drow in dt.Rows) { Guid g = (Guid) drow["id"]; bool b = (bool) drow["active"]; } Now I know you cannot run without my source modifications I mentioned earlier cause the casts Guid and bool will fail. These may work... not tested out... you can also convert the byte to Int32... I just forget the format of the function right now. string g = drow["id"].ToString; byte b = (byte) drow["active"];
[22 Jun 2005 22:32]
Reggie Burnett
I have changed the code in question to this: charSets[ Convert.ToInt32(reader["id"]) ] = reader.GetString(reader.GetOrdinal("charset")); I was unable to reproduce this error, but this change won't hurt in any event.