List:Commits« Previous MessageNext Message »
From:Reggie Burnett Date:April 22 2010 3:30pm
Subject:bzr commit into connector-net-6.1 branch (reggie.burnett:809)
View as plain text  
#At file:///C:/work/connector-net/6.1/ based on revid:reggie.burnett@stripped

  809 Reggie Burnett	2010-04-22 [merge]
      merged

    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-21 17:27:27 +0000
+++ b/CHANGES	2010-04-22 15:30:24 +0000
@@ -35,6 +35,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.1.3
 - fixed session state provider table definition to allow more than 64K per-session data (bug#47339)

=== modified file 'MySql.Data/Provider/Source/CommandBuilder.cs'
--- a/MySql.Data/Provider/Source/CommandBuilder.cs	2009-08-25 21:26:55 +0000
+++ b/MySql.Data/Provider/Source/CommandBuilder.cs	2010-04-22 15:30:24 +0000
@@ -83,7 +83,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-28 20:40:35 +0000
+++ b/MySql.Data/Provider/Source/ProcedureCache.cs	2010-04-22 15:30:24 +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-14 22:35:44 +0000
+++ b/MySql.Data/Provider/Source/StoredProcedure.cs	2010-04-22 15:30:24 +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:27:27 +0000
+++ b/MySql.Data/Tests/Source/StoredProcedure.cs	2010-04-22 15:30:24 +0000
@@ -1288,5 +1288,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.1 branch (reggie.burnett:809)Reggie Burnett22 Apr