Bug #13991 oldsyntax configuration and ParameterMarker value bug
Submitted: 13 Oct 2005 4:28 Modified: 13 Nov 2007 11:43
Reporter: Matt Petteys Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S4 (Feature request)
Version:1.0.6 OS:Linux (Linux/Windows)
Assigned to: CPU Architecture:Any

[13 Oct 2005 4:28] Matt Petteys
Description:

I use mssql data access classes build in vs.net that are converted over to mysql data access classes using the MysqlClient namespace.  Since this classes are built for mssql and then converted to mysql, it requires use of the @ parameters and therefore requires the oldsyntax directive.  The component classes create and configure the objects (Connections, Commands, etc) first (without the dsn) and then set the appropriate dsn right before the commands are executed.   Since all classes are initalized first the MySqlParameterCollection class is initalized using the ? ParameterMarker.  Once the connection is initialized with the dsn, the connection class is referencing the correct ParameterMarker @ but the MySqlParameterCollection is still referencing the ParameterMarker of ?.  Of couse the queries then fail.

How to repeat:

Initialize a command using a connection that is not using the oldsyntax directive.  Update the command text with a statement that uses @ parameters.  Update the dsn of the connection to use the oldsyntax configuration in the dsn.  Attempt to execute the Command and it should fail because the Command still references the ParameterMarker of ?.

Suggested fix:

This removes the paramMarker value from the parameter collection object in favor of a reference to the MySqlConnection object.  If the connection object is updated, the parameter collection knows about the change through the reference to the MySqlConnection.

--- C:\Documents and Settings\mpetteys\Desktop\mysqlclient.1.0.6\parameter_collection.cs	Thu Jul 14 09:43:20 2005
+++ C:\Program Files\mysql\MySQL Connector Net 1.0.6\src\MySqlClient\parameter_collection.cs	Wed Oct 12 23:58:44 2005
@@ -36,6 +36,7 @@
 	{
 		private ArrayList	_parms = new ArrayList();
 		private char		paramMarker = '?';
+		private MySqlConnection _connection;
 
 		internal char ParameterMarker 
 		{
@@ -43,6 +44,12 @@
 			set { paramMarker = value; }
 		}
 
+		public MySqlConnection Connection
+		{
+			get { return _connection;  }
+			set { _connection = value; }
+		}
+
 		private int InternalIndexOf(string name)
 		{
 			int index = IndexOf(name);
@@ -202,14 +209,14 @@
 		/// <returns>The zero-based location of the <see cref="MySqlParameter"/> in the collection.</returns>
 		public int IndexOf(string parameterName)
 		{
-			if (parameterName[0] == paramMarker)
+			if (parameterName[0] == this.Connection.ParameterMarker)
 				parameterName = parameterName.Substring(1, parameterName.Length-1);
 			parameterName = parameterName.ToLower();
 			for (int x=0; x < _parms.Count; x++) 
 			{
 				MySqlParameter p = (MySqlParameter)_parms[x];
 				string listName = p.ParameterName;
-				if (listName[0] == paramMarker)
+				if (listName[0] == this.Connection.ParameterMarker)
 					listName = listName.Substring(1, listName.Length-1);
 				if (listName.ToLower() == parameterName) return x;
 			}
--- C:\Documents and Settings\mpetteys\Desktop\mysqlclient.1.0.6\command.cs	Fri Aug 19 15:47:52 2005
+++ C:\Program Files\mysql\MySQL Connector Net 1.0.6\src\MySqlClient\command.cs	Wed Oct 12 23:57:17 2005
@@ -67,8 +67,6 @@
 		public MySqlCommand(string cmdText, MySqlConnection connection) : this(cmdText)
 		{
 			Connection = connection;
-			if (connection != null)
-				parameters.ParameterMarker = connection.ParameterMarker;
 		}
 
 		/// <include file='docs/mysqlcommand.xml' path='docs/ctor4/*'/>
@@ -145,8 +143,7 @@
 					this.Transaction = null;
 
 				connection = (MySqlConnection)value;
-				if (connection != null)
-					parameters.ParameterMarker = connection.ParameterMarker;
+				parameters.Connection = connection;
 			}
 		}
 
@@ -555,12 +552,12 @@
 
 			foreach (string token in tokens)
 			{
-				if ( token[0] != parameters.ParameterMarker )
+				if ( token[0] != this.Connection.ParameterMarker )
 					newSQL.Append( token );
 				else
 				{
 					parameterMap.Add( token );
-					newSQL.Append( parameters.ParameterMarker );
+					newSQL.Append( this.Connection.ParameterMarker );
 				}
 			}
 
@@ -601,12 +598,12 @@
 					delim=c;
 				else if (c == '\\') 
 					escaped = ! escaped;
-				else if (c == parameters.ParameterMarker && delim == Char.MinValue && ! escaped) 
+				else if (c == this.Connection.ParameterMarker && delim == Char.MinValue && ! escaped) 
 				{
 					tokens.Add( sqlPart.ToString() );
 					sqlPart.Remove( 0, sqlPart.Length ); 
 				}
-				else if (sqlPart.Length > 0 && sqlPart[0] == parameters.ParameterMarker && 
+				else if (sqlPart.Length > 0 && sqlPart[0] == this.Connection.ParameterMarker && 
 					! Char.IsLetterOrDigit(c) && c != '_' && c != '.' && c != '$')
 				{
 					tokens.Add( sqlPart.ToString() );
[13 Oct 2005 4:30] Matt Petteys
parameter_collection.1.0.6.diff

Attachment: parameter_collection.1.0.6.diff (text/x-patch), 1.43 KiB.

[13 Oct 2005 4:30] Matt Petteys
command.1.0.6.diff

Attachment: command.1.0.6.diff (text/x-patch), 1.78 KiB.

[6 Nov 2007 16:09] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/37194
[6 Nov 2007 16:15] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/37196
[6 Nov 2007 16:20] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/37197
[6 Nov 2007 16:20] Reggie Burnett
Fixed in 1.0.11, 5.0.9, and 5.1.4+
[13 Nov 2007 11:43] MC Brown
A note has been added to the 1.0.11, 5.0.9 and 5.1.4 changelogs: 

        Changing the connection string of a connection to one that
        changes the parameter marker after the connection had been
        assigned to a command but before the connection is opened could
        cause parameters to not be found.