#At file:///C:/Users/jcasalt/Dev/connector-net/6.2/ based on revid:reggie.burnett@stripped
926 Julio casal 2011-04-08 [merge]
merged
modified:
CHANGES
MySql.Data/Provider/Source/Connection.cs
MySql.Data/Provider/Source/Driver.cs
MySql.Data/Provider/Source/command.cs
MySql.Data/Provider/Source/datareader.cs
MySql.Data/Tests/Source/CommandTests.cs
MySql.VisualStudio/MySql.VisualStudio.csproj
=== modified file 'CHANGES'
=== modified file 'CHANGES'
--- a/CHANGES 2011-03-09 18:18:40 +0000
+++ b/CHANGES 2011-04-08 13:45:19 +0000
@@ -33,6 +33,7 @@
(MySQL bug #59346, Oracle bug #11766272)
- small but important improvements in EF sql generation
- added batching support for updates and deletes (bug #59616)
+- Introduced workaround to unexpected query aborts (server 5.1+) when executing a datareader after a command.Cancel() (MySQL bug#60541).
Version 6.2.4
- Fix authorization popup after modifying stored procedure in VS (Bug #44715)
=== modified file 'MySql.Data/Provider/Source/Connection.cs'
--- a/MySql.Data/Provider/Source/Connection.cs 2011-02-18 15:25:18 +0000
+++ b/MySql.Data/Provider/Source/Connection.cs 2011-04-08 13:45:19 +0000
@@ -51,6 +51,7 @@
private bool hasBeenOpen;
private SchemaProvider schemaProvider;
private ProcedureCache procedureCache;
+ private bool isInUse;
#if !CF
private PerformanceMonitor perfMonitor;
#endif
@@ -106,12 +107,11 @@
if (driver == null)
return null;
return driver.reader;
-
}
-
set
{
driver.reader = value;
+ isInUse = driver.reader != null;
}
}
@@ -138,6 +138,12 @@
}
}
+ internal bool IsInUse
+ {
+ get{ return isInUse; }
+ set{ isInUse = value; }
+ }
+
#endregion
#region Properties
@@ -573,7 +579,11 @@
}
catch (Exception ex)
{
- MySqlTrace.LogWarning(ServerThread, String.Concat("Error occurred aborting the connection. Exception was: ", ex.Message));
+ MySqlTrace.LogWarning(ServerThread, String.Concat("Error occurred aborting the connection. Exception was: ", ex.Message));
+ }
+ finally
+ {
+ this.isInUse = false;
}
SetState(ConnectionState.Closed, true);
}
=== modified file 'MySql.Data/Provider/Source/Driver.cs'
--- a/MySql.Data/Provider/Source/Driver.cs 2010-12-14 15:22:41 +0000
+++ b/MySql.Data/Provider/Source/Driver.cs 2011-04-08 13:45:19 +0000
@@ -336,6 +336,7 @@
List<MySqlError> warnings = new List<MySqlError>();
MySqlCommand cmd = new MySqlCommand("SHOW WARNINGS", connection);
+ cmd.InternallyCreated = true;
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
=== modified file 'MySql.Data/Provider/Source/command.cs'
--- a/MySql.Data/Provider/Source/command.cs 2011-03-09 18:18:40 +0000
+++ b/MySql.Data/Provider/Source/command.cs 2011-04-08 13:45:19 +0000
@@ -58,11 +58,13 @@
internal Int64 lastInsertedId;
private PreparableStatement statement;
private int commandTimeout;
+ private bool canceled;
private bool resetSqlSelect;
List<MySqlCommand> batch;
private string batchableCommandText;
CommandTimer commandTimer;
private bool useDefaultTimeout;
+ private bool internallyCreated;
/// <include file='docs/mysqlcommand.xml' path='docs/ctor1/*'/>
public MySqlCommand()
@@ -250,11 +252,22 @@
get { return batch; }
}
+ internal bool Canceled
+ {
+ get { return canceled; }
+ }
+
internal string BatchableCommandText
{
get { return batchableCommandText; }
}
+ internal bool InternallyCreated
+ {
+ get { return internallyCreated; }
+ set { internallyCreated = value; }
+ }
+
#endregion
#region Methods
@@ -268,6 +281,7 @@
public override void Cancel()
{
connection.CancelQuery(connection.ConnectionTimeout);
+ canceled = true;
}
/// <summary>
@@ -299,7 +313,7 @@
throw new InvalidOperationException("Connection must be valid and open.");
// Data readers have to be closed first
- if (connection.Reader != null)
+ if (connection.IsInUse && !this.internallyCreated)
throw new MySqlException("There is already an open DataReader associated with this Connection which must be closed first.");
if (CommandType == CommandType.StoredProcedure && !connection.driver.Version.isAtLeast(5, 0, 0))
@@ -359,7 +373,9 @@
if (resetSqlSelect)
{
resetSqlSelect = false;
- new MySqlCommand("SET SQL_SELECT_LIMIT=DEFAULT", connection).ExecuteNonQuery();
+ MySqlCommand command = new MySqlCommand("SET SQL_SELECT_LIMIT=DEFAULT", connection);
+ command.internallyCreated = true;
+ command.ExecuteNonQuery();
}
}
@@ -451,6 +467,7 @@
{
MySqlDataReader reader = new MySqlDataReader(this, statement, behavior);
connection.Reader = reader;
+ canceled = false;
// execute the statement
statement.Execute();
// wait for data to return
@@ -491,7 +508,6 @@
throw new MySqlException(ex.Message, true, ex);
}
-
// if we caught an exception because of a cancel, then just return null
if (ex.IsQueryAborted)
return null;
=== modified file 'MySql.Data/Provider/Source/datareader.cs'
--- a/MySql.Data/Provider/Source/datareader.cs 2010-12-14 15:22:41 +0000
+++ b/MySql.Data/Provider/Source/datareader.cs 2011-04-08 13:45:19 +0000
@@ -29,6 +29,7 @@
using System.Collections.Generic;
using System.Globalization;
using MySql.Data.MySqlClient.Properties;
+using MySql.Data.Common;
namespace MySql.Data.MySqlClient
{
@@ -231,10 +232,17 @@
// stored procedures it needs to update out and inout parameters
command.Close(this);
+ if (this.command.Canceled && connection.driver.Version.isAtLeast(5, 1, 0))
+ {
+ // Issue dummy command to clear kill flag
+ ClearKillFlag();
+ }
+
if (shouldCloseConnection)
connection.Close();
command = null;
+ connection.IsInUse = false;
connection = null;
isOpen = false;
}
@@ -972,6 +980,16 @@
return v;
}
+
+ private void ClearKillFlag()
+ {
+ // This query will silently crash because of the Kill call that happened before.
+ string dummyStatement = "SELECT * FROM bogus_table LIMIT 0"; /* dummy query used to clear kill flag */
+ MySqlCommand dummyCommand = new MySqlCommand(dummyStatement, connection);
+ dummyCommand.InternallyCreated = true;
+ IDataReader reader = dummyCommand.ExecuteReader(); // ExecuteReader catches the exception and returns null, which is expected.
+ }
+
#region IEnumerator
/// <summary>
=== modified file 'MySql.Data/Tests/Source/CommandTests.cs'
--- a/MySql.Data/Tests/Source/CommandTests.cs 2011-03-22 19:47:06 +0000
+++ b/MySql.Data/Tests/Source/CommandTests.cs 2011-04-08 13:45:19 +0000
@@ -537,6 +537,35 @@
Assert.AreEqual(1, listener.Find("Query Opened: UPDATE"));
}
#endif
+
+ [Test]
+ public void ExecuteReaderReturnsReaderAfterCancel()
+ {
+ execSQL("DROP TABLE IF EXISTS TableWithDateAsPrimaryKey");
+ execSQL("DROP TABLE IF EXISTS TableWithStringAsPrimaryKey");
+ createTable("CREATE TABLE TableWithDateAsPrimaryKey(PrimaryKey date NOT NULL, PRIMARY KEY (PrimaryKey))", "InnoDB");
+ createTable("CREATE TABLE TableWithStringAsPrimaryKey(PrimaryKey nvarchar(50) NOT NULL, PRIMARY KEY (PrimaryKey))", "InnoDB");
+
+ string connStr = GetConnectionString(true);
+ using (MySqlConnection connection = new MySqlConnection(connStr))
+ {
+ connection.Open();
+ MySqlCommand command = new MySqlCommand("SELECT PrimaryKey FROM TableWithDateAsPrimaryKey", connection);
+ IDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo);
+ DataTable dataTableSchema = reader.GetSchemaTable();
+ command.Cancel();
+ reader.Close();
+
+ command = new MySqlCommand("SELECT PrimaryKey FROM TableWithStringAsPrimaryKey", connection);
+ reader = command.ExecuteReader(CommandBehavior.KeyInfo);
+ Assert.IsNotNull(reader);
+
+ dataTableSchema = reader.GetSchemaTable();
+ Assert.AreEqual("PrimaryKey", dataTableSchema.Rows[0][dataTableSchema.Columns[0]]);
+
+ reader.Close();
+ }
+ }
}
=== modified file 'MySql.VisualStudio/MySql.VisualStudio.csproj'
--- a/MySql.VisualStudio/MySql.VisualStudio.csproj 2010-08-18 19:42:41 +0000
+++ b/MySql.VisualStudio/MySql.VisualStudio.csproj 2011-04-08 13:45:19 +0000
@@ -57,17 +57,11 @@
<ItemGroup>
<Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <Reference Include="Microsoft.Data.ConnectionUI, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>True</SpecificVersion>
- <HintPath>c:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Common\Assemblies\Microsoft.Data.ConnectionUI.dll</HintPath>
- </Reference>
+ <Reference Include="Microsoft.Data.ConnectionUI, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<SpecificVersion>True</SpecificVersion>
</Reference>
- <Reference Include="Microsoft.VisualStudio.Data, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>True</SpecificVersion>
- <HintPath>c:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.Data.dll</HintPath>
- </Reference>
+ <Reference Include="Microsoft.VisualStudio.Data, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<SpecificVersion>True</SpecificVersion>
<HintPath>c:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Common\Assemblies\Microsoft.VisualStudio.OLE.Interop.dll</HintPath>
No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
| Thread |
|---|
| • bzr commit into connector-net-6.2 branch (julio.casal:926) | Julio casal | 8 Apr |