List:Commits« Previous MessageNext Message »
From:rburnett Date:October 23 2006 6:57pm
Subject:Connector/NET commit: r428 - in trunk: . TestSuite mysqlclient
View as plain text  
Modified:
   trunk/CHANGES
   trunk/TestSuite/DataReaderTests.cs
   trunk/mysqlclient/datareader.cs
Log:
Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null. 



Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES	2006-10-23 15:44:57 UTC (rev 427)
+++ trunk/CHANGES	2006-10-23 16:57:27 UTC (rev 428)
@@ -3,6 +3,7 @@
     Bugs fixed
     ----------
     Bug #23268 System.FormatException when invoking procedure with ENUM input parameter 	
+    Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null. 
     
     Other changes
     -------------

Modified: trunk/TestSuite/DataReaderTests.cs
===================================================================
--- trunk/TestSuite/DataReaderTests.cs	2006-10-23 15:44:57 UTC (rev 427)
+++ trunk/TestSuite/DataReaderTests.cs	2006-10-23 16:57:27 UTC (rev 428)
@@ -840,5 +840,23 @@
                     reader.Close();
             }
         }
+
+		/// <summary>
+		/// Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null. 
+		/// </summary>
+		[Category("5.0")]
+		[Test]
+		public void GetSchemaTableOnEmptyResultset()
+		{
+			execSQL("CREATE PROCEDURE spTest() BEGIN END");
+
+			MySqlCommand cmd = new MySqlCommand("spTest", conn);
+			cmd.CommandType = CommandType.StoredProcedure;
+			using (MySqlDataReader reader = cmd.ExecuteReader())
+			{
+				DataTable dt = reader.GetSchemaTable();
+				Assert.IsNull(dt);
+			}
+		}
 	}
 }

Modified: trunk/mysqlclient/datareader.cs
===================================================================
--- trunk/mysqlclient/datareader.cs	2006-10-23 15:44:57 UTC (rev 427)
+++ trunk/mysqlclient/datareader.cs	2006-10-23 16:57:27 UTC (rev 428)
@@ -31,24 +31,24 @@
 	public sealed class MySqlDataReader : DbDataReader, IDataReader, IDisposable,
IDataRecord
 	{
 		// The DataReader should always be open when returned to the user.
-		private bool			isOpen = true;
+		private bool isOpen = true;
 
 		// Keep track of the results and position
 		// within the resultset (starts prior to first record).
 		private MySqlField[] fields;
-        internal IMySqlValue[] values;
-		private CommandBehavior	commandBehavior;
+		internal IMySqlValue[] values;
+		private CommandBehavior commandBehavior;
 		private MySqlCommand command;
 		private bool canRead;
 		private bool hasRows;
-        private long affectedRows;
+		private long affectedRows;
 		private bool[] uaFieldsUsed;
-        private Driver driver;
-        private long lastInsertId;
-        private PreparableStatement statement;
-        private int seqIndex;
-        private bool hasRead;
-        private bool nextResultDone;
+		private Driver driver;
+		private long lastInsertId;
+		private PreparableStatement statement;
+		private int seqIndex;
+		private bool hasRead;
+		private bool nextResultDone;
 
 		/* 
 		 * Keep track of the connection in order to implement the
@@ -67,121 +67,121 @@
 			this.command = cmd;
 			connection = (MySqlConnection)command.Connection;
 			commandBehavior = behavior;
-            driver = connection.driver;
-            affectedRows = -1;
-            this.statement = statement;
-            nextResultDone = false;
-        }
+			driver = connection.driver;
+			affectedRows = -1;
+			this.statement = statement;
+			nextResultDone = false;
+		}
 
-        #region Properties
+		#region Properties
 
-        internal long InsertedId
-        {
-            get { return this.lastInsertId; }
-        }
+		internal long InsertedId
+		{
+			get { return this.lastInsertId; }
+		}
 
-        internal CommandBehavior Behavior 
+		internal CommandBehavior Behavior
 		{
 			get { return commandBehavior; }
 		}
 
-        /// <summary>
-        /// Gets a value indicating the depth of nesting for the current row.  This
method is not 
-        /// supported currently and always returns 0.
-        /// </summary>
-        public override int Depth
-        {
-            get { return 0; }
-        }
+		/// <summary>
+		/// Gets a value indicating the depth of nesting for the current row.  This method is
not 
+		/// supported currently and always returns 0.
+		/// </summary>
+		public override int Depth
+		{
+			get { return 0; }
+		}
 
-        /// <summary>
-        /// Gets the number of columns in the current row.
-        /// </summary>
-        public override int FieldCount
-        {
-            // Return the count of the number of columns, which in
-            // this case is the size of the column metadata
-            // array.
-            get
-            {
-                if (fields != null)
-                    return fields.Length;
-                return 0;
-            }
-        }
+		/// <summary>
+		/// Gets the number of columns in the current row.
+		/// </summary>
+		public override int FieldCount
+		{
+			// Return the count of the number of columns, which in
+			// this case is the size of the column metadata
+			// array.
+			get
+			{
+				if (fields != null)
+					return fields.Length;
+				return 0;
+			}
+		}
 
-        /// <summary>
-        /// Gets a value indicating whether the MySqlDataReader contains one or more
rows.
-        /// </summary>
-        public override bool HasRows
-        {
-            get { return hasRows; }
-        }
+		/// <summary>
+		/// Gets a value indicating whether the MySqlDataReader contains one or more rows.
+		/// </summary>
+		public override bool HasRows
+		{
+			get { return hasRows; }
+		}
 
-        /// <summary>
+		/// <summary>
 		/// Gets a value indicating whether the data reader is closed.
 		/// </summary>
 		public override bool IsClosed
 		{
-			get  { return ! isOpen; }
+			get { return !isOpen; }
 		}
 
-        /// <summary>
-        /// Gets the number of rows changed, inserted, or deleted by execution of the SQL
statement.
-        /// </summary>
-        public override int RecordsAffected
-        {
-            // RecordsAffected returns the number of rows affected in batch
-            // statments from insert/delete/update statments.  This property
-            // is not completely accurate until .Close() has been called.
-            get { return (int)affectedRows; }
-        }
+		/// <summary>
+		/// Gets the number of rows changed, inserted, or deleted by execution of the SQL
statement.
+		/// </summary>
+		public override int RecordsAffected
+		{
+			// RecordsAffected returns the number of rows affected in batch
+			// statments from insert/delete/update statments.  This property
+			// is not completely accurate until .Close() has been called.
+			get { return (int)affectedRows; }
+		}
 
-        /// <summary>
-        /// Overloaded. Gets the value of a column in its native format.
-        /// In C#, this property is the indexer for the MySqlDataReader class.
-        /// </summary>
-        public override object this[int i]
-        {
-            get { return GetValue(i); }
-        }
+		/// <summary>
+		/// Overloaded. Gets the value of a column in its native format.
+		/// In C#, this property is the indexer for the MySqlDataReader class.
+		/// </summary>
+		public override object this[int i]
+		{
+			get { return GetValue(i); }
+		}
 
-        /// <summary>
-        /// Gets the value of a column in its native format.
-        ///	[C#] In C#, this property is the indexer for the MySqlDataReader class.
-        /// </summary>
-        public override object this[String name]
-        {
-            // Look up the ordinal and return 
-            // the value at that position.
-            get { return this[GetOrdinal(name)]; }
-        }
+		/// <summary>
+		/// Gets the value of a column in its native format.
+		///	[C#] In C#, this property is the indexer for the MySqlDataReader class.
+		/// </summary>
+		public override object this[String name]
+		{
+			// Look up the ordinal and return 
+			// the value at that position.
+			get { return this[GetOrdinal(name)]; }
+		}
 
-        #endregion
+		#endregion
 
 		/// <summary>
 		/// Closes the MySqlDataReader object.
 		/// </summary>
 		public override void Close()
 		{
-			if (! isOpen) return;
+			if (!isOpen) return;
 
-            bool shouldCloseConnection = (commandBehavior &
CommandBehavior.CloseConnection) != 0;
-            commandBehavior = CommandBehavior.Default;
+			bool shouldCloseConnection = (commandBehavior & CommandBehavior.CloseConnection)
!= 0;
+			commandBehavior = CommandBehavior.Default;
 			connection.Reader = null;
 
-            // we set the nextResultDone var to true inside NextResult when
-            // it returns false.  This allows us to avoid calling NextResult
-            // here unnecessarily.  Calling NextResult here will work but this
-            // is just an optimization.
-            if (!nextResultDone)
-                while (NextResult()) { }
+			// we set the nextResultDone var to true inside NextResult when
+			// it returns false.  This allows us to avoid calling NextResult
+			// here unnecessarily.  Calling NextResult here will work but this
+			// is just an optimization.
+			if (!nextResultDone)
+				while (NextResult()) { }
 
-            // we now give the command a chance to terminate.  In the case of
-            // stored procedures it needs to update out and inout parameters
-            command.Close();
+			// we now give the command a chance to terminate.  In the case of
+			// stored procedures it needs to update out and inout parameters
+			command.Close();
 
-            if (shouldCloseConnection)
+			if (shouldCloseConnection)
 				connection.Close();
 
 			isOpen = false;
@@ -189,10 +189,10 @@
 
 		#region TypeSafe Accessors
 
-        public bool GetBoolean(string name)
-        {
-            return GetBoolean(GetOrdinal(name));
-        }
+		public bool GetBoolean(string name)
+		{
+			return GetBoolean(GetOrdinal(name));
+		}
 
 		/// <summary>
 		/// Gets the value of the specified column as a Boolean.
@@ -204,10 +204,10 @@
 			return Convert.ToBoolean(GetValue(i));
 		}
 
-        public byte GetByte(string name)
-        {
-            return GetByte(GetOrdinal(name));
-        }
+		public byte GetByte(string name)
+		{
+			return GetByte(GetOrdinal(name));
+		}
 
 		/// <summary>
 		/// Gets the value of the specified column as a byte.
@@ -235,43 +235,43 @@
 		/// <include file='docs/MySqlDataReader.xml'
path='MyDocs/MyMembers[@name="GetBytes"]/*'/>
 		public override long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex,
int length)
 		{
-			if (i >= fields.Length) 
+			if (i >= fields.Length)
 				throw new IndexOutOfRangeException();
 
 			IMySqlValue val = GetFieldValue(i, false);
 
-			if (! (val is MySqlBinary))
+			if (!(val is MySqlBinary))
 				throw new MySqlException("GetBytes can only be called on binary columns");
 
 			MySqlBinary binary = (MySqlBinary)val;
-			if (buffer == null) 
+			if (buffer == null)
 				return (long)binary.Value.Length;
 
 			if (bufferIndex >= buffer.Length || bufferIndex < 0)
 				throw new IndexOutOfRangeException("Buffer index must be a valid index in buffer");
 			if (buffer.Length < (bufferIndex + length))
-				throw new ArgumentException( "Buffer is not large enough to hold the requested data"
);
-			if (dataIndex < 0 || 
+				throw new ArgumentException("Buffer is not large enough to hold the requested data");
+			if (dataIndex < 0 ||
 				((ulong)dataIndex >= (ulong)binary.Value.Length &&
(ulong)binary.Value.Length > 0))
-				throw new IndexOutOfRangeException( "Data index must be a valid index in the field"
);
+				throw new IndexOutOfRangeException("Data index must be a valid index in the field");
 
-			byte[] bytes = (byte[])binary.Value; 
+			byte[] bytes = (byte[])binary.Value;
 
 			// adjust the length so we don't run off the end
-			if ( (ulong)binary.Value.Length < (ulong)(dataIndex+length)) 
+			if ((ulong)binary.Value.Length < (ulong)(dataIndex + length))
 			{
 				length = (int)((ulong)binary.Value.Length - (ulong)dataIndex);
 			}
 
-			Array.Copy( bytes, (int)dataIndex, buffer, (int)bufferIndex, (int)length );
+			Array.Copy(bytes, (int)dataIndex, buffer, (int)bufferIndex, (int)length);
 
 			return length;
 		}
 
-        public char GetChar(string name)
-        {
-            return GetChar(GetOrdinal(name));
-        }
+		public char GetChar(string name)
+		{
+			return GetChar(GetOrdinal(name));
+		}
 
 		/// <summary>
 		/// Gets the value of the specified column as a single character.
@@ -295,7 +295,7 @@
 		/// <returns></returns>
 		public override long GetChars(int i, long fieldOffset, char[] buffer, int bufferoffset,
int length)
 		{
-			if (i >= fields.Length) 
+			if (i >= fields.Length)
 				throw new IndexOutOfRangeException();
 
 			string valAsString = GetString(i);
@@ -305,13 +305,13 @@
 			if (bufferoffset >= buffer.Length || bufferoffset < 0)
 				throw new IndexOutOfRangeException("Buffer index must be a valid index in buffer");
 			if (buffer.Length < (bufferoffset + length))
-				throw new ArgumentException( "Buffer is not large enough to hold the requested data"
);
-			if (fieldOffset < 0 || fieldOffset >= valAsString.Length )
-				throw new IndexOutOfRangeException( "Field offset must be a valid index in the field"
);
-			
+				throw new ArgumentException("Buffer is not large enough to hold the requested data");
+			if (fieldOffset < 0 || fieldOffset >= valAsString.Length)
+				throw new IndexOutOfRangeException("Field offset must be a valid index in the
field");
+
 			if (valAsString.Length < length)
 				length = valAsString.Length;
-			valAsString.CopyTo( (int)fieldOffset, buffer, bufferoffset, length );
+			valAsString.CopyTo((int)fieldOffset, buffer, bufferoffset, length);
 			return length;
 		}
 
@@ -322,43 +322,43 @@
 		/// <returns></returns>
 		public override String GetDataTypeName(int i)
 		{
-			if (! isOpen) throw new Exception("No current query in data reader");
+			if (!isOpen) throw new Exception("No current query in data reader");
 			if (i >= fields.Length) throw new IndexOutOfRangeException();
 
 			// return the name of the type used on the backend
 			return values[i].MySqlTypeName;
 		}
 
-        public MySqlDateTime GetMySqlDateTime(string name)
-        {
-            return GetMySqlDateTime(GetOrdinal(name));
-        }
-        
+		public MySqlDateTime GetMySqlDateTime(string name)
+		{
+			return GetMySqlDateTime(GetOrdinal(name));
+		}
+
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetMySqlDateTime/*'/>
 		public MySqlDateTime GetMySqlDateTime(int index)
 		{
 			return (MySqlDateTime)GetFieldValue(index, true);
 		}
 
-        public DateTime GetDateTime(string name)
-        {
-            return GetDateTime(GetOrdinal(name));
-        }
+		public DateTime GetDateTime(string name)
+		{
+			return GetDateTime(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetDateTime/*'/>
 		public override DateTime GetDateTime(int index)
 		{
 			IMySqlValue val = GetFieldValue(index, true);
-            MySqlDateTime dt;
+			MySqlDateTime dt;
 
-            // we need to do this because functions like date_add return string
-            if (val is MySqlString)
-            {
-                string s = ((MySqlString)val).Value;
-                dt = MySqlDateTime.Parse(s, this.connection.driver.Version);
-            }
-            else
-                dt = (MySqlDateTime)val;
+			// we need to do this because functions like date_add return string
+			if (val is MySqlString)
+			{
+				string s = ((MySqlString)val).Value;
+				dt = MySqlDateTime.Parse(s, this.connection.driver.Version);
+			}
+			else
+				dt = (MySqlDateTime)val;
 
 			if (connection.Settings.ConvertZeroDateTime && !dt.IsValidDateTime)
 				return DateTime.MinValue;
@@ -366,30 +366,30 @@
 				return dt.GetDateTime();
 		}
 
-        public Decimal GetDecimal(string name)
-        {
-            return GetDecimal(GetOrdinal(name));
-        }
+		public Decimal GetDecimal(string name)
+		{
+			return GetDecimal(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimal/*'/>
 		public override Decimal GetDecimal(int index)
 		{
-            IMySqlValue v = GetFieldValue(index, true);
-            if (v is MySqlDecimal)
+			IMySqlValue v = GetFieldValue(index, true);
+			if (v is MySqlDecimal)
 				return ((MySqlDecimal)v).Value;
 			return Convert.ToDecimal(v.Value);
 		}
 
-        public double GetDouble(string name)
-        {
-            return GetDouble(GetOrdinal(name));
-        }
+		public double GetDouble(string name)
+		{
+			return GetDouble(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetDouble/*'/>
 		public override double GetDouble(int index)
 		{
-            IMySqlValue v = GetFieldValue(index, true);
-            if (v is MySqlDouble)
+			IMySqlValue v = GetFieldValue(index, true);
+			if (v is MySqlDouble)
 				return ((MySqlDouble)v).Value;
 			return Convert.ToDouble(v.Value);
 		}
@@ -401,36 +401,36 @@
 		/// <returns></returns>
 		public override Type GetFieldType(int i)
 		{
-			if (! isOpen) throw new Exception("No current query in data reader");
+			if (!isOpen) throw new Exception("No current query in data reader");
 			if (i >= fields.Length) throw new IndexOutOfRangeException();
 
 			if (values[i] is MySqlDateTime)
-            {
-                if (!connection.Settings.AllowZeroDateTime)
-				    return typeof(DateTime);
-                return typeof(MySqlDateTime);
-            }
+			{
+				if (!connection.Settings.AllowZeroDateTime)
+					return typeof(DateTime);
+				return typeof(MySqlDateTime);
+			}
 			return values[i].SystemType;
 		}
 
-        public float GetFloat(string name)
-        {
-            return GetFloat(GetOrdinal(name));
-        }
+		public float GetFloat(string name)
+		{
+			return GetFloat(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetFloat/*'/>
 		public override float GetFloat(int index)
 		{
-            IMySqlValue v = GetFieldValue(index, true);
-            if (v is MySqlSingle)
+			IMySqlValue v = GetFieldValue(index, true);
+			if (v is MySqlSingle)
 				return ((MySqlSingle)v).Value;
 			return Convert.ToSingle(v.Value);
 		}
 
-        public Guid GetGuid(string name)
-        {
-            return GetGuid(GetOrdinal(name));
-        }
+		public Guid GetGuid(string name)
+		{
+			return GetGuid(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetGuid/*'/>
 		public override Guid GetGuid(int index)
@@ -438,55 +438,55 @@
 			return new Guid(GetString(index));
 		}
 
-        public Int16 GetInt16(string name)
-        {
-            return GetInt16(GetOrdinal(name));
-        }
+		public Int16 GetInt16(string name)
+		{
+			return GetInt16(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt16/*'/>
 		public override Int16 GetInt16(int index)
 		{
-            IMySqlValue v = GetFieldValue(index, true);
-            if (v is MySqlInt16)
+			IMySqlValue v = GetFieldValue(index, true);
+			if (v is MySqlInt16)
 				return ((MySqlInt16)v).Value;
-            
-            connection.UsageAdvisor.Converting(command.CommandText,
-                fields[index].ColumnName, v.MySqlTypeName, "Int16");
+
+			connection.UsageAdvisor.Converting(command.CommandText,
+				 fields[index].ColumnName, v.MySqlTypeName, "Int16");
 			return ((IConvertible)v.Value).ToInt16(null);
 		}
 
-        public Int32 GetInt32(string name)
-        {
-            return GetInt32(GetOrdinal(name));
-        }
+		public Int32 GetInt32(string name)
+		{
+			return GetInt32(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt32/*'/>
 		public override Int32 GetInt32(int index)
 		{
-            IMySqlValue v = GetFieldValue(index, true);
-            if (v is MySqlInt32)
+			IMySqlValue v = GetFieldValue(index, true);
+			if (v is MySqlInt32)
 				return ((MySqlInt32)v).Value;
-            
-            connection.UsageAdvisor.Converting(command.CommandText,
-                fields[index].ColumnName, v.MySqlTypeName, "Int32");
-            return ((IConvertible)v.Value).ToInt32(null); 
+
+			connection.UsageAdvisor.Converting(command.CommandText,
+				 fields[index].ColumnName, v.MySqlTypeName, "Int32");
+			return ((IConvertible)v.Value).ToInt32(null);
 		}
 
-        public Int64 GetInt64(string name)
-        {
-            return GetInt64(GetOrdinal(name));
-        }
+		public Int64 GetInt64(string name)
+		{
+			return GetInt64(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt64/*'/>
 		public override Int64 GetInt64(int index)
 		{
-            IMySqlValue v = GetFieldValue(index, true);
+			IMySqlValue v = GetFieldValue(index, true);
 			if (v is MySqlInt64)
 				return ((MySqlInt64)v).Value;
 
-            connection.UsageAdvisor.Converting(command.CommandText,
-                fields[index].ColumnName, v.MySqlTypeName, "Int64");
-            return ((IConvertible)v.Value).ToInt64(null); 
+			connection.UsageAdvisor.Converting(command.CommandText,
+				 fields[index].ColumnName, v.MySqlTypeName, "Int64");
+			return ((IConvertible)v.Value).ToInt64(null);
 		}
 
 		/// <summary>
@@ -506,11 +506,11 @@
 		/// <returns></returns>
 		public override int GetOrdinal(string name)
 		{
-			if (! isOpen)
+			if (!isOpen)
 				throw new Exception("No current query in data reader");
 
 			name = name.ToLower(System.Globalization.CultureInfo.InvariantCulture);
-			for (int i=0; i < fields.Length; i ++) 
+			for (int i = 0; i < fields.Length; i++)
 			{
 				if (fields[i].ColumnName.ToLower(System.Globalization.CultureInfo.InvariantCulture)
== name)
 					return i;
@@ -529,44 +529,43 @@
 			// Only Results from SQL SELECT Queries 
 			// get a DataTable for schema of the result
 			// otherwise, DataTable is null reference
-			if (fields.Length == 0) return null;
+			if (fields == null || fields.Length == 0) return null;
 
-			DataTable dataTableSchema = new DataTable ("SchemaTable");
-			
-			dataTableSchema.Columns.Add ("ColumnName", typeof (string));
-			dataTableSchema.Columns.Add ("ColumnOrdinal", typeof (int));
-			dataTableSchema.Columns.Add ("ColumnSize", typeof (int));
-			dataTableSchema.Columns.Add ("NumericPrecision", typeof (int));
-			dataTableSchema.Columns.Add ("NumericScale", typeof (int));
-			dataTableSchema.Columns.Add ("IsUnique", typeof (bool));
-			dataTableSchema.Columns.Add ("IsKey", typeof (bool));
+			DataTable dataTableSchema = new DataTable("SchemaTable");
+
+			dataTableSchema.Columns.Add("ColumnName", typeof(string));
+			dataTableSchema.Columns.Add("ColumnOrdinal", typeof(int));
+			dataTableSchema.Columns.Add("ColumnSize", typeof(int));
+			dataTableSchema.Columns.Add("NumericPrecision", typeof(int));
+			dataTableSchema.Columns.Add("NumericScale", typeof(int));
+			dataTableSchema.Columns.Add("IsUnique", typeof(bool));
+			dataTableSchema.Columns.Add("IsKey", typeof(bool));
 			DataColumn dc = dataTableSchema.Columns["IsKey"];
 			dc.AllowDBNull = true; // IsKey can have a DBNull
-			dataTableSchema.Columns.Add ("BaseCatalogName", typeof (string));
-			dataTableSchema.Columns.Add ("BaseColumnName", typeof (string));
-			dataTableSchema.Columns.Add ("BaseSchemaName", typeof (string));
-			dataTableSchema.Columns.Add ("BaseTableName", typeof (string));
-			dataTableSchema.Columns.Add ("DataType", typeof(Type));
-			dataTableSchema.Columns.Add ("AllowDBNull", typeof (bool));
-			dataTableSchema.Columns.Add ("ProviderType", typeof (int));
-			dataTableSchema.Columns.Add ("IsAliased", typeof (bool));
-			dataTableSchema.Columns.Add ("IsExpression", typeof (bool));
-			dataTableSchema.Columns.Add ("IsIdentity", typeof (bool));
-			dataTableSchema.Columns.Add ("IsAutoIncrement", typeof (bool));
-			dataTableSchema.Columns.Add ("IsRowVersion", typeof (bool));
-			dataTableSchema.Columns.Add ("IsHidden", typeof (bool));
-			dataTableSchema.Columns.Add ("IsLong", typeof (bool));
-			dataTableSchema.Columns.Add ("IsReadOnly", typeof (bool));
+			dataTableSchema.Columns.Add("BaseCatalogName", typeof(string));
+			dataTableSchema.Columns.Add("BaseColumnName", typeof(string));
+			dataTableSchema.Columns.Add("BaseSchemaName", typeof(string));
+			dataTableSchema.Columns.Add("BaseTableName", typeof(string));
+			dataTableSchema.Columns.Add("DataType", typeof(Type));
+			dataTableSchema.Columns.Add("AllowDBNull", typeof(bool));
+			dataTableSchema.Columns.Add("ProviderType", typeof(int));
+			dataTableSchema.Columns.Add("IsAliased", typeof(bool));
+			dataTableSchema.Columns.Add("IsExpression", typeof(bool));
+			dataTableSchema.Columns.Add("IsIdentity", typeof(bool));
+			dataTableSchema.Columns.Add("IsAutoIncrement", typeof(bool));
+			dataTableSchema.Columns.Add("IsRowVersion", typeof(bool));
+			dataTableSchema.Columns.Add("IsHidden", typeof(bool));
+			dataTableSchema.Columns.Add("IsLong", typeof(bool));
+			dataTableSchema.Columns.Add("IsReadOnly", typeof(bool));
 
 			int ord = 1;
-			for (int i=0; i < fields.Length; i++)
+			for (int i = 0; i < fields.Length; i++)
 			{
 				MySqlField f = fields[i];
 				DataRow r = dataTableSchema.NewRow();
 				r["ColumnName"] = f.ColumnName;
 				r["ColumnOrdinal"] = ord++;
-                int maxByteCount = f.Encoding.GetMaxByteCount(1) >> 1;
-                r["ColumnSize"] = f.IsTextField ? f.ColumnLength / maxByteCount :
f.ColumnLength;
+				r["ColumnSize"] = f.IsTextField ? f.ColumnLength / f.MaxLength : f.ColumnLength;
 				int prec = f.Precision;
 				int pscale = f.Scale;
 				if (prec != -1)
@@ -574,7 +573,7 @@
 				if (pscale != -1)
 					r["NumericScale"] = (short)pscale;
 				r["DataType"] = GetFieldType(i);
-                r["ProviderType"] = (int)f.Type;
+				r["ProviderType"] = (int)f.Type;
 				r["IsLong"] = f.IsBlob && f.ColumnLength > 255;
 				r["AllowDBNull"] = f.AllowsNull;
 				r["IsReadOnly"] = false;
@@ -583,20 +582,20 @@
 				r["IsKey"] = f.IsPrimaryKey;
 				r["IsAutoIncrement"] = f.IsAutoIncrement;
 				r["BaseSchemaName"] = f.DatabaseName;
-                r["BaseCatalogName"] = null;
+				r["BaseCatalogName"] = null;
 				r["BaseTableName"] = f.RealTableName;
 				r["BaseColumnName"] = f.OriginalColumnName;
 
-				dataTableSchema.Rows.Add( r );
+				dataTableSchema.Rows.Add(r);
 			}
 
 			return dataTableSchema;
 		}
 
-        public string GetString(string name)
-        {
-            return GetString(GetOrdinal(name));
-        }
+		public string GetString(string name)
+		{
+			return GetString(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetString/*'/>
 		public override String GetString(int index)
@@ -612,17 +611,17 @@
 			return val.Value.ToString();
 		}
 
-        public TimeSpan GetTimeSpan(string name)
-        {
-            return GetTimeSpan(GetOrdinal(name));
-        }
+		public TimeSpan GetTimeSpan(string name)
+		{
+			return GetTimeSpan(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetTimeSpan/*'/>
 		public TimeSpan GetTimeSpan(int index)
 		{
-            IMySqlValue val = GetFieldValue(index, true);
+			IMySqlValue val = GetFieldValue(index, true);
 
-            MySqlTimeSpan ts = (MySqlTimeSpan)val;
+			MySqlTimeSpan ts = (MySqlTimeSpan)val;
 			return ts.Value;
 		}
 
@@ -633,21 +632,21 @@
 		/// <returns></returns>
 		public override object GetValue(int i)
 		{
-			if (! isOpen) throw new Exception("No current query in data reader");
+			if (!isOpen) throw new Exception("No current query in data reader");
 			if (i >= fields.Length) throw new IndexOutOfRangeException();
 
 			IMySqlValue val = GetFieldValue(i, false);
-			if (val.IsNull) 
-                return DBNull.Value;
+			if (val.IsNull)
+				return DBNull.Value;
 
 			// if the column is a date/time, then we return a MySqlDateTime
 			// so .ToString() will print '0000-00-00' correctly
-			if (val is MySqlDateTime) 
+			if (val is MySqlDateTime)
 			{
-                MySqlDateTime dt = (MySqlDateTime)val;
-				if (! dt.IsValidDateTime && connection.Settings.ConvertZeroDateTime)
+				MySqlDateTime dt = (MySqlDateTime)val;
+				if (!dt.IsValidDateTime && connection.Settings.ConvertZeroDateTime)
 					return DateTime.MinValue;
-				else if (connection.Settings.AllowZeroDateTime) 
+				else if (connection.Settings.AllowZeroDateTime)
 					return val;
 				else
 					return dt.GetDateTime();
@@ -663,18 +662,18 @@
 		/// <returns></returns>
 		public override int GetValues(object[] values)
 		{
-			if (! hasRead) return 0;
-			int numCols = Math.Min( values.Length, fields.Length );
-			for (int i=0; i < numCols; i ++) 
+			if (!hasRead) return 0;
+			int numCols = Math.Min(values.Length, fields.Length);
+			for (int i = 0; i < numCols; i++)
 				values[i] = GetValue(i);
 
 			return numCols;
 		}
 
-        public UInt16 GetUInt16(string name)
-        {
-            return GetUInt16(GetOrdinal(name));
-        }
+		public UInt16 GetUInt16(string name)
+		{
+			return GetUInt16(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt16/*'/>
 		public UInt16 GetUInt16(int index)
@@ -683,32 +682,32 @@
 			if (v is MySqlUInt16)
 				return ((MySqlUInt16)v).Value;
 
-            connection.UsageAdvisor.Converting(command.CommandText,
-                fields[index].ColumnName, v.MySqlTypeName, "UInt16");
-            return Convert.ToUInt16(v.Value);
+			connection.UsageAdvisor.Converting(command.CommandText,
+				 fields[index].ColumnName, v.MySqlTypeName, "UInt16");
+			return Convert.ToUInt16(v.Value);
 		}
 
-        public UInt32 GetUInt32(string name)
-        {
-            return GetUInt32(GetOrdinal(name));
-        }
+		public UInt32 GetUInt32(string name)
+		{
+			return GetUInt32(GetOrdinal(name));
+		}
 
-        /// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
+		/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
 		public UInt32 GetUInt32(int index)
 		{
 			IMySqlValue v = GetFieldValue(index, true);
 			if (v is MySqlUInt32)
 				return ((MySqlUInt32)v).Value;
 
-            connection.UsageAdvisor.Converting(command.CommandText,
-                fields[index].ColumnName, v.MySqlTypeName, "UInt32");
-            return Convert.ToUInt32(v.Value);
+			connection.UsageAdvisor.Converting(command.CommandText,
+				 fields[index].ColumnName, v.MySqlTypeName, "UInt32");
+			return Convert.ToUInt32(v.Value);
 		}
 
-        public UInt64 GetUInt64(string name)
-        {
-            return GetUInt64(GetOrdinal(name));
-        }
+		public UInt64 GetUInt64(string name)
+		{
+			return GetUInt64(GetOrdinal(name));
+		}
 
 		/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt64/*'/>
 		public UInt64 GetUInt64(int index)
@@ -717,9 +716,9 @@
 			if (v is MySqlUInt64)
 				return ((MySqlUInt64)v).Value;
 
-            connection.UsageAdvisor.Converting(command.CommandText,
-                fields[index].ColumnName, v.MySqlTypeName, "UInt64");
-            return Convert.ToUInt64(v.Value);
+			connection.UsageAdvisor.Converting(command.CommandText,
+				 fields[index].ColumnName, v.MySqlTypeName, "UInt64");
+			return Convert.ToUInt64(v.Value);
 		}
 
 
@@ -740,35 +739,35 @@
 			return DBNull.Value == GetValue(i);
 		}
 
-        /// <summary>
-        /// GetResultSet is the core resultset processing method.  It gets called by
NextResult
-        /// and will loop until it finds a select resultset at which point it will return
the 
-        /// number of columns in that result.  It will _not_ return for non-select
resultsets instead
-        /// just updating the internal lastInsertId and affectedRows variables.  
-        /// </summary>
-        /// <returns>-1 if no more results exist, >= 0 for select
results</returns>
-        private long GetResultSet()
-        {
-            while (true)
-            {
-                ulong affectedRowsTemp = 0;
-                long fieldCount = driver.ReadResult(ref affectedRowsTemp, ref
lastInsertId);
-                if (fieldCount > 0)
-                    return fieldCount;
-                else if (fieldCount == 0)
-                {
-                    command.lastInsertedId = lastInsertId;
-                    if (affectedRows == -1)
-                        affectedRows = (long)affectedRowsTemp;
-                    else
-                        affectedRows += (long)affectedRowsTemp;
-                }
-                else if (fieldCount == -1)
-                    if (!statement.ExecuteNext())
-                        break;
-            }
-            return -1;
-        }
+		/// <summary>
+		/// GetResultSet is the core resultset processing method.  It gets called by NextResult
+		/// and will loop until it finds a select resultset at which point it will return the 
+		/// number of columns in that result.  It will _not_ return for non-select resultsets
instead
+		/// just updating the internal lastInsertId and affectedRows variables.  
+		/// </summary>
+		/// <returns>-1 if no more results exist, >= 0 for select
results</returns>
+		private long GetResultSet()
+		{
+			while (true)
+			{
+				ulong affectedRowsTemp = 0;
+				long fieldCount = driver.ReadResult(ref affectedRowsTemp, ref lastInsertId);
+				if (fieldCount > 0)
+					return fieldCount;
+				else if (fieldCount == 0)
+				{
+					command.lastInsertedId = lastInsertId;
+					if (affectedRows == -1)
+						affectedRows = (long)affectedRowsTemp;
+					else
+						affectedRows += (long)affectedRowsTemp;
+				}
+				else if (fieldCount == -1)
+					if (!statement.ExecuteNext())
+						break;
+			}
+			return -1;
+		}
 
 		/// <summary>
 		/// Advances the data reader to the next result, when reading the results of batch SQL
statements.
@@ -776,56 +775,56 @@
 		/// <returns></returns>
 		public override bool NextResult()
 		{
-			if (! isOpen)
+			if (!isOpen)
 				throw new MySqlException("Invalid attempt to NextResult when reader is closed.");
 
-            bool firstResult = fields == null;
-            if (fields != null)
-            {
-                ClearCurrentResultset();
-                fields = null;
-            }
+			bool firstResult = fields == null;
+			if (fields != null)
+			{
+				ClearCurrentResultset();
+				fields = null;
+			}
 
-            // single result means we only return a single resultset.  If we have already
-            // returned one, then we return false;
-            if (!firstResult && (commandBehavior &
CommandBehavior.SingleResult) != 0)
-                return false;
+			// single result means we only return a single resultset.  If we have already
+			// returned one, then we return false;
+			if (!firstResult && (commandBehavior & CommandBehavior.SingleResult) != 0)
+				return false;
 
 			// tell our command to continue execution of the SQL batch until it its
 			// another resultset
-			try 
+			try
 			{
-                long fieldCount = GetResultSet();
-                if (fieldCount == -1)
-                {
-                    nextResultDone = true;
-                    hasRows = canRead = false;
-                    return false;
-                }
+				long fieldCount = GetResultSet();
+				if (fieldCount == -1)
+				{
+					nextResultDone = true;
+					hasRows = canRead = false;
+					return false;
+				}
 
 				// issue any requested UA warnings
-				if (connection.Settings.UseUsageAdvisor) 
+				if (connection.Settings.UseUsageAdvisor)
 				{
 					if ((connection.driver.ServerStatus & ServerStatusFlags.NoIndex) != 0)
-						connection.UsageAdvisor.UsingNoIndex( command.CommandText );
+						connection.UsageAdvisor.UsingNoIndex(command.CommandText);
 					if ((connection.driver.ServerStatus & ServerStatusFlags.BadIndex) != 0)
-						connection.UsageAdvisor.UsingBadIndex( command.CommandText );
+						connection.UsageAdvisor.UsingBadIndex(command.CommandText);
 				}
 
-                fields = driver.ReadColumnMetadata((int)fieldCount);
-                values = new IMySqlValue[fields.Length];
-                for (int i = 0; i < fields.Length; i++)
-                    values[i] = fields[i].GetValueObject();
-                hasRead = false;
+				fields = driver.ReadColumnMetadata((int)fieldCount);
+				values = new IMySqlValue[fields.Length];
+				for (int i = 0; i < fields.Length; i++)
+					values[i] = fields[i].GetValueObject();
+				hasRead = false;
 
-                uaFieldsUsed = new bool[fields.Length];
-                hasRows = canRead = driver.FetchDataRow(statement.StatementId, 0,
fields.Length);
-                return true;
-            }
-			catch (MySqlException ex) 
+				uaFieldsUsed = new bool[fields.Length];
+				hasRows = canRead = driver.FetchDataRow(statement.StatementId, 0, fields.Length);
+				return true;
+			}
+			catch (MySqlException ex)
 			{
-				if (ex.IsFatal) 
-                    connection.Abort();
+				if (ex.IsFatal)
+					connection.Abort();
 				throw;
 			}
 
@@ -837,72 +836,72 @@
 		/// <returns></returns>
 		public override bool Read()
 		{
-			if (! isOpen)
+			if (!isOpen)
 				throw new MySqlException("Invalid attempt to Read when reader is closed.");
 
-			if (! canRead) 
-                return false;
+			if (!canRead)
+				return false;
 
-            if (Behavior == CommandBehavior.SingleRow && hasRead)
-                return false;
+			if (Behavior == CommandBehavior.SingleRow && hasRead)
+				return false;
 
-            try 
+			try
 			{
 				bool isSequential = (Behavior & CommandBehavior.SequentialAccess) != 0;
-                seqIndex = -1;
-                if (hasRead)
-                    canRead = driver.FetchDataRow(statement.StatementId, 0,
fields.Length);
-                hasRead = true;
-                if (canRead && !isSequential)
-                    for (int i = 0; i < fields.Length; i++)
-                        values[i] = driver.ReadColumnValue(i, fields[i], values[i]);
+				seqIndex = -1;
+				if (hasRead)
+					canRead = driver.FetchDataRow(statement.StatementId, 0, fields.Length);
+				hasRead = true;
+				if (canRead && !isSequential)
+					for (int i = 0; i < fields.Length; i++)
+						values[i] = driver.ReadColumnValue(i, fields[i], values[i]);
 
-                return canRead;
+				return canRead;
 			}
-			catch (MySqlException ex) 
+			catch (MySqlException ex)
 			{
-				if (ex.IsFatal) 
-                    connection.Abort();
+				if (ex.IsFatal)
+					connection.Abort();
 				throw;
 			}
 		}
 
 
-		private IMySqlValue GetFieldValue(int index, bool checkNull) 
+		private IMySqlValue GetFieldValue(int index, bool checkNull)
 		{
-			if (index < 0 || index >= fields.Length) 
-				throw new ArgumentException( "You have specified an invalid column ordinal." );
+			if (index < 0 || index >= fields.Length)
+				throw new ArgumentException("You have specified an invalid column ordinal.");
 
-			if (! hasRead)
+			if (!hasRead)
 				throw new MySqlException("Invalid attempt to access a field before calling Read()");
 
 			// keep count of how many columns we have left to access
 			this.uaFieldsUsed[index] = true;
 
-            if ((this.commandBehavior & CommandBehavior.SequentialAccess) != 0
&& 
-                index != seqIndex)
-            {
-                if (index < seqIndex)
-                    throw new MySqlException("Invalid attempt to read a prior column
using SequentialAccess");
-                while (seqIndex < (index-1))
-                    driver.SkipColumnValue(values[++seqIndex]);
-                values[index] = driver.ReadColumnValue(index, fields[index],
values[index]);
-                seqIndex = index;
-            }
+			if ((this.commandBehavior & CommandBehavior.SequentialAccess) != 0 &&
+				 index != seqIndex)
+			{
+				if (index < seqIndex)
+					throw new MySqlException("Invalid attempt to read a prior column using
SequentialAccess");
+				while (seqIndex < (index - 1))
+					driver.SkipColumnValue(values[++seqIndex]);
+				values[index] = driver.ReadColumnValue(index, fields[index], values[index]);
+				seqIndex = index;
+			}
 
-            IMySqlValue v = values[index];
-            if (checkNull && v.IsNull)
-                throw new SqlNullValueException();
+			IMySqlValue v = values[index];
+			if (checkNull && v.IsNull)
+				throw new SqlNullValueException();
 
-            return v;
+			return v;
 		}
 
-		private void ClearCurrentResultset() 
+		private void ClearCurrentResultset()
 		{
-            if (!canRead) return;
-            while (driver.SkipDataRow())
-            {
-            }
+			if (!canRead) return;
+			while (driver.SkipDataRow())
+			{
+			}
 
 			if (!connection.Settings.UseUsageAdvisor) return;
 
@@ -914,13 +913,13 @@
 			bool readAll = true;
 			foreach (bool b in this.uaFieldsUsed)
 				readAll &= b;
-			if (! readAll)
+			if (!readAll)
 				connection.UsageAdvisor.ReadPartialRowSet(command.CommandText, uaFieldsUsed, fields);
 		}
 
 		#region IEnumerator
 
-		public override IEnumerator	GetEnumerator()
+		public override IEnumerator GetEnumerator()
 		{
 			return new DbEnumerator(this);
 		}

Thread
Connector/NET commit: r428 - in trunk: . TestSuite mysqlclientrburnett23 Oct