From: Date: October 30 2006 10:51pm
Subject: Connector/NET commit: r443 - in trunk: . mysqlclient
List-Archive: http://lists.mysql.com/commits/14583
X-Bug: 18186
Message-Id: <200610302151.k9ULp0wX002318@bk-internal.mysql.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Modified:
trunk/CHANGES
trunk/mysqlclient/MySql.Data.2005.csproj
trunk/mysqlclient/PreparableStatement.cs
Log:
Bug #18186 Problem with implementation of PreparedStatement
Apparently Mono doesn't ignore the the case where BitArray yields a byte array of zero length and we try to copy that to an array so we put a check in.
Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES 2006-10-30 20:40:34 UTC (rev 442)
+++ trunk/CHANGES 2006-10-30 21:50:59 UTC (rev 443)
@@ -7,6 +7,7 @@
Bug #23245 Connector Net 5.01 Beta Installer produces Antivirus Error Message
Bug #23758 Unable to connect to any server - IPv6 related
Bug #22882 Registry key 'Global' access denied
+ Bug #18186 Problem with implementation of PreparedStatement
Other changes
-------------
Modified: trunk/mysqlclient/MySql.Data.2005.csproj
===================================================================
--- trunk/mysqlclient/MySql.Data.2005.csproj 2006-10-30 20:40:34 UTC (rev 442)
+++ trunk/mysqlclient/MySql.Data.2005.csproj 2006-10-30 21:50:59 UTC (rev 443)
@@ -11,7 +11,8 @@
MySql.Data
- cnet.snk
+
+
JScript
Grid
IE50
@@ -25,7 +26,7 @@
- true
+ false
bin\net-2.0\Debug\
@@ -112,7 +113,6 @@
-
Modified: trunk/mysqlclient/PreparableStatement.cs
===================================================================
--- trunk/mysqlclient/PreparableStatement.cs 2006-10-30 20:40:34 UTC (rev 442)
+++ trunk/mysqlclient/PreparableStatement.cs 2006-10-30 21:50:59 UTC (rev 443)
@@ -33,67 +33,67 @@
{
private MySqlField[] paramList;
private int executionCount;
- private int pageSize;
- private int statementId;
+ private int pageSize;
+ private int statementId;
- public PreparableStatement(MySqlConnection connection, string text)
- : base(connection, text)
- {
- pageSize = 0;
- statementId = 0;
- }
+ public PreparableStatement(MySqlConnection connection, string text)
+ : base(connection, text)
+ {
+ pageSize = 0;
+ statementId = 0;
+ }
#region Properties
- public int NumParameters
+ public int NumParameters
{
get { return paramList.Length; }
}
- public int ExecutionCount
+ public int ExecutionCount
{
get { return executionCount; }
set { executionCount = value; }
}
- public bool IsPrepared
- {
- get { return statementId > 0; }
- }
+ public bool IsPrepared
+ {
+ get { return statementId > 0; }
+ }
- public int StatementId
- {
- get { return statementId; }
- }
+ public int StatementId
+ {
+ get { return statementId; }
+ }
#endregion
- public virtual void Prepare(MySqlParameterCollection parameters)
- {
- // store our parameters.
- this.parameters = parameters;
+ public virtual void Prepare(MySqlParameterCollection parameters)
+ {
+ // store our parameters.
+ this.parameters = parameters;
- // strip out names from parameter markers
- string text;
- ArrayList parameter_names = PrepareCommandText(out text);
+ // strip out names from parameter markers
+ string text;
+ ArrayList parameter_names = PrepareCommandText(out text);
- // ask our connection to send the prepare command
- statementId = driver.PrepareStatement(text, ref paramList);
+ // ask our connection to send the prepare command
+ statementId = driver.PrepareStatement(text, ref paramList);
- // now we need to assign our field names since we stripped them out
- // for the prepare
- for (int i=0; i < parameter_names.Count; i++)
- paramList[i].ColumnName = (string)parameter_names[i];
- }
+ // now we need to assign our field names since we stripped them out
+ // for the prepare
+ for (int i = 0; i < parameter_names.Count; i++)
+ paramList[i].ColumnName = (string)parameter_names[i];
+ }
public override void Execute(MySqlParameterCollection parameters)
{
- // if we are not prepared, then call down to our base
- if (!IsPrepared)
- {
- base.Execute(parameters);
- return;
- }
+ // if we are not prepared, then call down to our base
+ if (!IsPrepared)
+ {
+ base.Execute(parameters);
+ return;
+ }
MySqlStream stream = new MySqlStream(driver.Encoding);
@@ -101,100 +101,104 @@
// create our null bitmap
BitArray nullMap = new BitArray(parameters.Count);
- // now we run through the parameters that PREPARE sent back and use
- // those names to index into the parameters the user gave us.
- // if the user set that parameter to NULL, then we set the null map
- // accordingly
- if (paramList != null)
- for (int x=0; x < paramList.Length; x++)
- {
- MySqlParameter p = parameters[paramList[x].ColumnName];
- if (p.Value == DBNull.Value || p.Value == null)
- nullMap[x] = true;
- }
- byte[] nullMapBytes = new byte[(parameters.Count + 7)/8];
- nullMap.CopyTo(nullMapBytes, 0);
+ // now we run through the parameters that PREPARE sent back and use
+ // those names to index into the parameters the user gave us.
+ // if the user set that parameter to NULL, then we set the null map
+ // accordingly
+ if (paramList != null)
+ for (int x = 0; x < paramList.Length; x++)
+ {
+ MySqlParameter p = parameters[paramList[x].ColumnName];
+ if (p.Value == DBNull.Value || p.Value == null)
+ nullMap[x] = true;
+ }
+ byte[] nullMapBytes = new byte[(parameters.Count + 7) / 8];
+ // we check this because Mono doesn't ignore the case where nullMapBytes
+ // is zero length.
+ if (nullMapBytes.Length > 0)
+ nullMap.CopyTo(nullMapBytes, 0);
+
// start constructing our packet
stream.WriteInteger(statementId, 4);
- stream.WriteByte((byte)pageSize); // flags; always 0 for 4.1
- stream.WriteInteger(1, 4); // interation count; 1 for 4.1
- stream.Write(nullMapBytes);
+ stream.WriteByte((byte)pageSize); // flags; always 0 for 4.1
+ stream.WriteInteger(1, 4); // interation count; 1 for 4.1
+ stream.Write(nullMapBytes);
//if (parameters != null && parameters.Count > 0)
- stream.WriteByte(1); // rebound flag
+ stream.WriteByte(1); // rebound flag
//else
// packet.WriteByte( 0 );
//TODO: only send rebound if parms change
// write out the parameter types
- if (paramList != null)
- {
- foreach (MySqlField param in paramList)
- {
- MySqlParameter parm = parameters[param.ColumnName];
- stream.WriteInteger((long)parm.GetPSType(), 2);
- }
+ if (paramList != null)
+ {
+ foreach (MySqlField param in paramList)
+ {
+ MySqlParameter parm = parameters[param.ColumnName];
+ stream.WriteInteger((long)parm.GetPSType(), 2);
+ }
- // now write out all non-null values
- foreach (MySqlField param in paramList)
- {
- int index = parameters.IndexOf(param.ColumnName);
- if (index == -1)
- throw new MySqlException("Parameter '" + param.ColumnName +
- "' is not defined.");
- MySqlParameter parm = parameters[index];
- if (parm.Value == DBNull.Value || parm.Value == null)
- continue;
+ // now write out all non-null values
+ foreach (MySqlField param in paramList)
+ {
+ int index = parameters.IndexOf(param.ColumnName);
+ if (index == -1)
+ throw new MySqlException("Parameter '" + param.ColumnName +
+ "' is not defined.");
+ MySqlParameter parm = parameters[index];
+ if (parm.Value == DBNull.Value || parm.Value == null)
+ continue;
- stream.Encoding = param.Encoding;
- parm.Serialize(stream, true);
- }
- }
+ stream.Encoding = param.Encoding;
+ parm.Serialize(stream, true);
+ }
+ }
- executionCount ++;
+ executionCount++;
- driver.ExecuteStatement(stream.InternalBuffer.ToArray());
+ driver.ExecuteStatement(stream.InternalBuffer.ToArray());
}
- public override bool ExecuteNext()
- {
- if (!IsPrepared)
- return base.ExecuteNext();
- return false;
- }
+ public override bool ExecuteNext()
+ {
+ if (!IsPrepared)
+ return base.ExecuteNext();
+ return false;
+ }
- ///
- /// Prepares CommandText for use with the Prepare method
- ///
- /// Command text stripped of all paramter names
- ///
- /// Takes the output of TokenizeSql and creates a single string of SQL
- /// that only contains '?' markers for each parameter. It also creates
- /// the parameterMap array list that includes all the paramter names in the
- /// order they appeared in the SQL
- ///
- private ArrayList PrepareCommandText(out string stripped_sql)
- {
- StringBuilder newSQL = new StringBuilder();
- ArrayList parameterMap = new ArrayList();
+ ///
+ /// Prepares CommandText for use with the Prepare method
+ ///
+ /// Command text stripped of all paramter names
+ ///
+ /// Takes the output of TokenizeSql and creates a single string of SQL
+ /// that only contains '?' markers for each parameter. It also creates
+ /// the parameterMap array list that includes all the paramter names in the
+ /// order they appeared in the SQL
+ ///
+ private ArrayList PrepareCommandText(out string stripped_sql)
+ {
+ StringBuilder newSQL = new StringBuilder();
+ ArrayList parameterMap = new ArrayList();
- // tokenize the sql first
- ArrayList tokens = TokenizeSql(ProcessedCommandText);
- parameterMap.Clear();
+ // tokenize the sql first
+ ArrayList tokens = TokenizeSql(ProcessedCommandText);
+ parameterMap.Clear();
- foreach (string token in tokens)
- {
- if ( token[0] != connection.ParameterMarker)
- newSQL.Append(token);
- else
- {
- parameterMap.Add(token);
- newSQL.Append(connection.ParameterMarker);
- }
- }
+ foreach (string token in tokens)
+ {
+ if (token[0] != connection.ParameterMarker)
+ newSQL.Append(token);
+ else
+ {
+ parameterMap.Add(token);
+ newSQL.Append(connection.ParameterMarker);
+ }
+ }
- stripped_sql = newSQL.ToString();
- return parameterMap;
- }
+ stripped_sql = newSQL.ToString();
+ return parameterMap;
+ }
}
}