Bug #5571 Null fields aren't being handled correctly in Field.cs
Submitted: 14 Sep 2004 16:12 Modified: 16 Sep 2004 12:45
Reporter: James Moore Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / NET Severity:S1 (Critical)
Version:1.0.0 beta OS:Microsoft Windows (Windows XP)
Assigned to: Assigned Account CPU Architecture:Any

[14 Sep 2004 16:12] James Moore
Description:
When you have a column that's an int that can be null, reading it through a datareader will return null values for every row after the first null.

Looking at the code, SetTextData() in Field.cs looks like it's potentially the problem.  Line 259 sets the field as null, but there's no place where it's reset to not null.

How to repeat:
Create a DataReader using a select like so:

SELECT MsgIdID, ContentID from Articles

where MsgIdID and ContentID are both ints, but MsgIdID is "not null" but ContentID is "default null"

(the table:

CREATE TABLE articles (
  SubjectID int(11) NOT NULL default '0',
  ArticleDate datetime default NULL,
  AuthorID int(11) NOT NULL default '0',
  MsgIdID int(11) NOT NULL default '0',
  Bytes int(11) NOT NULL default '0',
  LineCount int(11) NOT NULL default '0',
  HasNoReferences tinyint(4) default NULL,
  TopicID int(11) default '0',
  StoreDate datetime default NULL,
  RefersTo varchar(255) default NULL,
  ContentID int(11) default NULL,
  Decoded tinyint(4) NOT NULL default '0',
  UNIQUE KEY Articles_Primary_Index (MsgIdID),
  KEY TopicID (TopicID),
  KEY ContentID (ContentID)
) TYPE=MyISAM;

Read the results like so:

string sql = "SELECT MsgIdID, ContentID from Articles";
			IDbCommand cmd = m_factory.Command (sql);
			Debug.WriteLine ("Dump of Articles");
			using (IDataReader reader = cmd.ExecuteReader (CommandBehavior.Default)) 
			{
				while (reader.Read ())
				{
					Debug.Write (reader.GetInt32 (0) + " ");
					if (reader.IsDBNull (1))
						Debug.WriteLine ("null");
					else
						Debug.WriteLine (reader.GetInt32 (1));
				}
			}

Once you read a null value for ContentID, every other read will return ContentID as a null.

Suggested fix:
*** /cygdrive/c/tmp/Field.cs	Tue Sep 14 08:47:56 2004
--- /cygdrive/c/Documents and Settings/James Moore/My Documents/Visual Studio Projects/NntpClient/MySqlNet/Field.cs	Tue Sep 14 08:48:40 2004
***************
*** 258,291 ****
  			{
  				colValue.IsNull = true;
  				buffer = null;
- 				return;
  			}
! 
! 			buffer = buf;
! 			bufIndex = index;
! 			bufLength = len;
! 
! 			bool is41 = version.isAtLeast(4,1,0);
! 			string sValue = encoding.GetString( buf, (int)index, (int)len );
! 
! 			if (colValue is MySqlDateTime)
! 				(colValue as MySqlDateTime).ParseMySql( sValue, is41 );
! 			else if (colValue is MySqlTimeSpan)
! 				(colValue as MySqlTimeSpan).ParseMySql( sValue, is41 );
! 			else if (colValue is MySqlBinary) 
  			{
! 				if (IsBinary) 
  				{
! 					MySqlBinary binary = (colValue as MySqlBinary);
! 					binary.Value = buffer;
! 					binary.Index = (ulong)index;
! 					binary.Length = (ulong)len;
  				}
  				else
! 					(colValue as MySqlBinary).Value = sValue;
  			}
- 			else
- 				colValue.Parse( sValue );
  		}
  
  		public string GetTypeName() 
--- 258,293 ----
  			{
  				colValue.IsNull = true;
  				buffer = null;
  			}
! 			else
  			{
! 				colValue.IsNull = false;
! 				buffer = buf;
! 				bufIndex = index;
! 				bufLength = len;
! 
! 				bool is41 = version.isAtLeast(4,1,0);
! 				string sValue = encoding.GetString( buf, (int)index, (int)len );
! 
! 				if (colValue is MySqlDateTime)
! 					(colValue as MySqlDateTime).ParseMySql( sValue, is41 );
! 				else if (colValue is MySqlTimeSpan)
! 					(colValue as MySqlTimeSpan).ParseMySql( sValue, is41 );
! 				else if (colValue is MySqlBinary) 
  				{
! 					if (IsBinary) 
! 					{
! 						MySqlBinary binary = (colValue as MySqlBinary);
! 						binary.Value = buffer;
! 						binary.Index = (ulong)index;
! 						binary.Length = (ulong)len;
! 					}
! 					else
! 						(colValue as MySqlBinary).Value = sValue;
  				}
  				else
! 					colValue.Parse( sValue );
  			}
  		}
  
  		public string GetTypeName()
[14 Sep 2004 19:12] Guy Platt
James,

This looks to be the same as the one I logged (5565). You discovered the reason for the sequence of nulls. I can confirm that it is not just int fileds but for varchar as well.
[15 Sep 2004 20:41] James Moore
Wasn't sure that this was the same issue as 5571, so I thought it would be better just to submit as another report and put in note over there.
[16 Sep 2004 12:45] Reggie Burnett
This is a duplicate of bug #5388