#At file:///C:/work/connector-net/6.0/ based on revid:reggie.burnett@stripped
808 Reggie Burnett 2010-04-22
- improved our procedure caching so that if you drop and recreate a proc with a different number of parameters
it will find the new proc as long as your are actually using the right number of parameters (bug #52562)
modified:
CHANGES
MySql.Data/Provider/Source/CommandBuilder.cs
MySql.Data/Provider/Source/Connection.cs
MySql.Data/Provider/Source/ProcedureCache.cs
MySql.Data/Provider/Source/StoredProcedure.cs
MySql.Data/Tests/Source/StoredProcedure.cs
=== modified file 'CHANGES'
=== modified file 'CHANGES'
--- a/CHANGES 2010-04-22 15:26:12 +0000
+++ b/CHANGES 2010-04-22 15:29:22 +0000
@@ -1,4 +1,3 @@
-test
- When sending file to server (LOAD DATA INFILE) open the file for read only, not for read/write
(bug #48944)
- Fixed precision calculation on decimal and newdecimal columns (bug #48171)
@@ -34,6 +33,8 @@
- changed mapping of latin1 from latin1 to windows-1252 (bug #51927)
- flushed out many more entires in error code enum (bug #51988)
- changed how we respond when the user selects 'functions return string=true'. Now we no longer force the type to var string but just let the underlying type come through but we strip the binary flag (bug #52187)
+- improved our procedure caching so that if you drop and recreate a proc with a different number of parameters
+ it will find the new proc as long as your are actually using the right number of parameters (bug #52562)
Version 6.0.5
- ensure that MySqlPacket always has a valid encoding. This prevents null reference exceptions in ReadString()
=== modified file 'MySql.Data/Provider/Source/CommandBuilder.cs'
--- a/MySql.Data/Provider/Source/CommandBuilder.cs 2009-08-25 16:35:54 +0000
+++ b/MySql.Data/Provider/Source/CommandBuilder.cs 2010-04-22 15:29:22 +0000
@@ -107,7 +107,7 @@
string spName = command.CommandText;
if (spName.IndexOf(".") == -1)
spName = command.Connection.Database + "." + spName;
- DataSet ds = command.Connection.ProcedureCache.GetProcedure(command.Connection, spName);
+ DataSet ds = command.Connection.ProcedureCache.GetProcedure(command.Connection, spName, null);
if (!ds.Tables.Contains("Procedure Parameters"))
throw new MySqlException(Resources.UnableToDeriveParameters);
=== modified file 'MySql.Data/Provider/Source/Connection.cs'
--- a/MySql.Data/Provider/Source/Connection.cs 2010-04-16 00:40:55 +0000
+++ b/MySql.Data/Provider/Source/Connection.cs 2010-04-22 15:29:22 +0000
@@ -573,7 +573,7 @@
catch (Exception ex)
{
if (Settings.Logging)
- Trace.TraceWarning(
+ Logger.LogWarning(
String.Concat("Error occurred aborting the connection. Exception was: ", ex.Message));
}
SetState(ConnectionState.Closed, true);
=== modified file 'MySql.Data/Provider/Source/ProcedureCache.cs'
--- a/MySql.Data/Provider/Source/ProcedureCache.cs 2009-07-13 02:34:29 +0000
+++ b/MySql.Data/Provider/Source/ProcedureCache.cs 2010-04-22 15:29:22 +0000
@@ -23,6 +23,8 @@
using System.Data;
using System.Collections.Generic;
using MySql.Data.MySqlClient.Properties;
+using System.Text;
+using System.Globalization;
namespace MySql.Data.MySqlClient
{
@@ -39,14 +41,18 @@
procHash = new Hashtable(maxSize);
}
- public DataSet GetProcedure(MySqlConnection conn, string spName)
+ public DataSet GetProcedure(MySqlConnection conn, string spName, string cacheKey)
{
- int hash = spName.GetHashCode();
-
DataSet ds = null;
- lock (procHash.SyncRoot)
+
+ if (cacheKey != null)
{
- ds = (DataSet)procHash[hash];
+ int hash = cacheKey.GetHashCode();
+
+ lock (procHash.SyncRoot)
+ {
+ ds = (DataSet)procHash[hash];
+ }
}
if (ds == null)
{
@@ -70,12 +76,36 @@
return ds;
}
+ internal string GetCacheKey(string spName, DataSet procData)
+ {
+ string retValue = String.Empty;
+ StringBuilder key = new StringBuilder(spName);
+ key.Append("(");
+ string delimiter = "";
+ if (procData.Tables.Contains("Procedure Parameters"))
+ {
+ foreach (DataRow row in procData.Tables["Procedure Parameters"].Rows)
+ {
+ if (row["ORDINAL_POSITION"].Equals(0))
+ retValue = "?=";
+ else
+ {
+ key.AppendFormat(CultureInfo.InvariantCulture, "{0}?", delimiter);
+ delimiter = ",";
+ }
+ }
+ }
+ key.Append(")");
+ return retValue + key.ToString();
+ }
+
private DataSet AddNew(MySqlConnection connection, string spName)
{
DataSet procData = GetProcData(connection, spName);
if (maxSize > 0)
{
- int hash = spName.GetHashCode();
+ string cacheKey = GetCacheKey(spName, procData);
+ int hash = cacheKey.GetHashCode();
lock (procHash.SyncRoot)
{
if (procHash.Keys.Count >= maxSize)
=== modified file 'MySql.Data/Provider/Source/StoredProcedure.cs'
--- a/MySql.Data/Provider/Source/StoredProcedure.cs 2010-01-13 17:14:55 +0000
+++ b/MySql.Data/Provider/Source/StoredProcedure.cs 2010-04-22 15:29:22 +0000
@@ -58,11 +58,30 @@
get { return resolvedCommandText; }
}
+ internal string GetCacheKey(string spName)
+ {
+ string retValue = String.Empty;
+ StringBuilder key = new StringBuilder(spName);
+ key.Append("(");
+ string delimiter = "";
+ foreach (MySqlParameter p in command.Parameters)
+ {
+ if (p.Direction == ParameterDirection.ReturnValue)
+ retValue = "?=";
+ else
+ {
+ key.AppendFormat(CultureInfo.InvariantCulture, "{0}?", delimiter);
+ delimiter = ",";
+ }
+ }
+ key.Append(")");
+ return retValue + key.ToString();
+ }
+
private DataSet GetParameters(string procName)
{
- // if we can use mysql.proc, then do so
- //if (Connection.Settings.UseProcedureBodies)
- DataSet ds = Connection.ProcedureCache.GetProcedure(Connection, procName);
+ string procCacheKey = GetCacheKey(procName);
+ DataSet ds = Connection.ProcedureCache.GetProcedure(Connection, procName, procCacheKey);
if(ds.Tables.Count == 2)
{
=== modified file 'MySql.Data/Tests/Source/StoredProcedure.cs'
--- a/MySql.Data/Tests/Source/StoredProcedure.cs 2010-04-21 17:03:42 +0000
+++ b/MySql.Data/Tests/Source/StoredProcedure.cs 2010-04-22 15:29:22 +0000
@@ -1287,5 +1287,31 @@
MySqlCommandBuilder.DeriveParameters(cmd);
Assert.AreEqual(2, cmd.Parameters.Count);
}
+
+ /// <summary>
+ /// Bug #52562 Sometimes we need to reload cached function parameters
+ /// </summary>
+ [Test]
+ public void ProcedureCacheMiss()
+ {
+ execSQL("CREATE PROCEDURE spTest(id INT) BEGIN SELECT 1; END");
+
+ string connStr = GetConnectionString(true) + ";procedure cache size=25";
+ using (MySqlConnection c = new MySqlConnection(connStr))
+ {
+ c.Open();
+ MySqlCommand cmd = new MySqlCommand("spTest", c);
+ cmd.Parameters.AddWithValue("@id", 1);
+ cmd.CommandType = CommandType.StoredProcedure;
+ cmd.ExecuteScalar();
+
+ execSQL("DROP PROCEDURE spTest");
+ execSQL("CREATE PROCEDURE spTest(id INT, id2 INT, id3 INT) BEGIN SELECT 1; END");
+
+ cmd.Parameters.AddWithValue("@id2", 2);
+ cmd.Parameters.AddWithValue("@id3", 3);
+ cmd.ExecuteScalar();
+ }
+ }
}
}
Attachment: [text/bzr-bundle]
| Thread |
|---|
| • bzr commit into connector-net-6.0 branch (reggie.burnett:808) Bug#52562 | Reggie Burnett | 22 Apr |