Modified:
branches/1.0/TestSuite/DataReaderTests.cs
branches/1.0/TestSuite/MySql.Data.Tests.csproj
branches/1.0/mysqlclient/datareader.cs
Log:
Bug #16884 Invalid DateTime Values from DataReader
Fixed this by implementing check on all typesafe methods for null. Basically, you cannot
call the typesafe methods on null columns. You should use .IsDbNull to check for null
values.
Modified: branches/1.0/TestSuite/DataReaderTests.cs
===================================================================
--- branches/1.0/TestSuite/DataReaderTests.cs 2006-09-18 15:26:03 UTC (rev 341)
+++ branches/1.0/TestSuite/DataReaderTests.cs 2006-09-18 15:27:39 UTC (rev 342)
@@ -102,7 +102,7 @@
}
}
- [Test()]
+ [Test]
public void TestNotReadingResultset()
{
for (int x=0; x < 10; x++)
@@ -121,7 +121,7 @@
}
}
- [Test()]
+ [Test]
public void GetBytes()
{
int len = 50000;
@@ -184,7 +184,7 @@
}
- [Test()]
+ [Test]
public void TestSingleResultSetBehavior()
{
execSQL("INSERT INTO Test (id, name, b1) VALUES (1, 'Test1', NULL)");
@@ -201,7 +201,7 @@
reader.Close();
}
- [Test()]
+ [Test]
public void GetSchema()
{
string sql = "CREATE TABLE test2( " +
@@ -237,7 +237,7 @@
execSQL("DROP TABLE IF EXISTS test2");
}
- [Test()]
+ [Test]
public void CloseConnectionBehavior()
{
execSQL("INSERT INTO Test(id,name) VALUES(1,'test')");
@@ -264,7 +264,7 @@
}
}
- [Test()]
+ [Test]
public void SingleRowBehavior()
{
execSQL("INSERT INTO Test(id,name) VALUES(1,'test1')");
@@ -301,7 +301,7 @@
}
}
- [Test()]
+ [Test]
public void SingleRowBehaviorWithLimit()
{
execSQL("INSERT INTO Test(id,name) VALUES(1,'test1')");
@@ -340,7 +340,7 @@
}
}
- [Test()]
+ [Test]
public void SimpleSingleRow()
{
execSQL("INSERT INTO Test(id,name) VALUES(1,'test1')");
@@ -366,42 +366,55 @@
}
}
- [Test()]
+ [Test]
public void ConsecutiveNulls()
{
- execSQL("INSERT INTO Test (id, name) VALUES (1, 'Test')");
- execSQL("INSERT INTO Test (id, name) VALUES (2, NULL)");
- execSQL("INSERT INTO Test (id, name) VALUES (3, 'Test2')");
+ execSQL("INSERT INTO Test (id, name, dt) VALUES (1, 'Test', NULL)");
+ execSQL("INSERT INTO Test (id, name, dt) VALUES (2, NULL, now())");
+ execSQL("INSERT INTO Test (id, name, dt) VALUES (3, 'Test2', NULL)");
- MySqlCommand cmd = new MySqlCommand("SELECT * FROM Test", conn);
+ MySqlCommand cmd = new MySqlCommand("SELECT id, name, dt FROM Test", conn);
MySqlDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
reader.Read();
- Assert.AreEqual( 1, reader.GetValue(0) );
- Assert.AreEqual( "Test", reader.GetValue(1) );
- Assert.AreEqual( "Test", reader.GetString(1) );
+ Assert.AreEqual(1, reader.GetValue(0));
+ Assert.AreEqual("Test", reader.GetValue(1));
+ Assert.AreEqual("Test", reader.GetString(1));
+ Assert.AreEqual(DBNull.Value, reader.GetValue(2));
reader.Read();
- Assert.AreEqual( 2, reader.GetValue(0) );
- Assert.AreEqual( DBNull.Value, reader.GetValue(1) );
- Assert.AreEqual( null, reader.GetString(1) );
- reader.Read();
- Assert.AreEqual( 3, reader.GetValue(0) );
- Assert.AreEqual( "Test2", reader.GetValue(1) );
- Assert.AreEqual( "Test2", reader.GetString(1) );
- Assert.IsFalse( reader.Read() );
- Assert.IsFalse( reader.NextResult() );
+ Assert.AreEqual(2, reader.GetValue(0));
+ Assert.AreEqual(DBNull.Value, reader.GetValue(1));
+ try
+ {
+ reader.GetString(1);
+ Assert.Fail("Should not get here");
+ }
+ catch (Exception) { }
+ Assert.IsFalse(reader.IsDBNull(2));
+ reader.Read();
+ Assert.AreEqual(3, reader.GetValue(0));
+ Assert.AreEqual("Test2", reader.GetValue(1));
+ Assert.AreEqual("Test2", reader.GetString(1));
+ Assert.AreEqual(DBNull.Value, reader.GetValue(2));
+ try
+ {
+ reader.GetMySqlDateTime(2);
+ Assert.Fail("Should not get here");
+ }
+ catch (Exception) { }
+ Assert.IsFalse(reader.Read());
+ Assert.IsFalse(reader.NextResult());
}
catch (Exception ex)
{
- Assert.Fail( ex.Message );
+ Assert.Fail(ex.Message);
}
finally
{
if (reader != null) reader.Close();
}
-
}
[Test()]
@@ -557,7 +570,7 @@
}
}
- [Test()]
+ [Test]
public void TestManyDifferentResultsets()
{
MySqlDataReader reader =null;
Modified: branches/1.0/TestSuite/MySql.Data.Tests.csproj
===================================================================
--- branches/1.0/TestSuite/MySql.Data.Tests.csproj 2006-09-18 15:26:03 UTC (rev 341)
+++ branches/1.0/TestSuite/MySql.Data.Tests.csproj 2006-09-18 15:27:39 UTC (rev 342)
@@ -75,9 +75,9 @@
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
- <Reference Include="MySql.Data, Version=1.0.7.17581, Culture=neutral,
processorArchitecture=MSIL">
+ <Reference Include="MySql.Data, Version=1.0.7.16284, Culture=neutral,
processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\bin\net-2.0\Debug\MySql.Data.dll</HintPath>
+ <HintPath>..\mysqlclient\bin\net-2.0\Debug\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<Name>nunit.framework</Name>
Modified: branches/1.0/mysqlclient/datareader.cs
===================================================================
--- branches/1.0/mysqlclient/datareader.cs 2006-09-18 15:26:03 UTC (rev 341)
+++ branches/1.0/mysqlclient/datareader.cs 2006-09-18 15:27:39 UTC (rev 342)
@@ -215,7 +215,7 @@
/// <returns></returns>
public byte GetByte(int i)
{
- MySqlValue v = GetFieldValue(i);
+ MySqlValue v = GetFieldValue(i, false);
if (v is MySqlUByte)
return ((MySqlUByte)v).Value;
else
@@ -237,7 +237,7 @@
if (i >= fields.Length)
throw new IndexOutOfRangeException();
- MySqlValue val = GetFieldValue(i);
+ MySqlValue val = GetFieldValue(i, false);
if (! (val is MySqlBinary))
throw new MySqlException("GetBytes can only be called on binary columns");
@@ -326,13 +326,13 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetMySqlDateTime/*'/>
public MySqlDateTime GetMySqlDateTime(int index)
{
- return (MySqlDateTime)GetFieldValue(index);
+ return (MySqlDateTime)GetFieldValue(index, true);
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDateTime/*'/>
public DateTime GetDateTime(int index)
{
- MySqlValue val = GetFieldValue(index);
+ MySqlValue val = GetFieldValue(index, true);
if (val is MySqlDateTime)
{
MySqlDateTime dt = (MySqlDateTime)val;
@@ -343,17 +343,17 @@
}
else if (val is MySqlString)
{
- MySqlDateTime d = new MySqlDateTime( MySqlDbType.Datetime );
- d = d.ParseMySql( (val as MySqlString).Value, true );
+ MySqlDateTime d = new MySqlDateTime(MySqlDbType.Datetime);
+ d = d.ParseMySql((val as MySqlString).Value, true);
return d.GetDateTime();
}
- throw new NotSupportedException( "Unable to convert from type " +
val.GetType().ToString() + " to DateTime" );
+ throw new NotSupportedException("Unable to convert from type " +
val.GetType().ToString() + " to DateTime");
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimal/*'/>
public Decimal GetDecimal(int index)
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlDecimal)
return ((MySqlDecimal)v).Value;
return Convert.ToDecimal(v.ValueAsObject);
@@ -362,7 +362,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDouble/*'/>
public double GetDouble(int index)
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlDouble)
return ((MySqlDouble)v).Value;
return Convert.ToDouble(v.ValueAsObject);
@@ -386,7 +386,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetFloat/*'/>
public float GetFloat(int index)
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlFloat)
return ((MySqlFloat)v).Value;
return Convert.ToSingle(v.ValueAsObject);
@@ -401,7 +401,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt16/*'/>
public Int16 GetInt16(int index)
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlInt16)
return ((MySqlInt16)v).Value;
return Convert.ToInt16(v.ValueAsObject);
@@ -410,7 +410,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt32/*'/>
public Int32 GetInt32(int index)
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlInt32)
return ((MySqlInt32)v).Value;
return Convert.ToInt32(v.ValueAsObject);
@@ -419,7 +419,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt64/*'/>
public Int64 GetInt64(int index)
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlInt64)
return ((MySqlInt64)v).Value;
return Convert.ToInt64(v.ValueAsObject);
@@ -535,9 +535,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetString/*'/>
public String GetString(int index)
{
- MySqlValue val = GetFieldValue(index);
- if (val.IsNull)
- throw new SqlNullValueException();
+ MySqlValue val = GetFieldValue(index, true);
if (val is MySqlBinary)
return (currentResult[index] as MySqlBinary).ToString(fields[index].Encoding);
@@ -548,7 +546,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetTimeSpan/*'/>
public TimeSpan GetTimeSpan(int index)
{
- MySqlTimeSpan ts = (MySqlTimeSpan)GetFieldValue(index);
+ MySqlTimeSpan ts = (MySqlTimeSpan)GetFieldValue(index, true);
return ts.Value;
}
@@ -562,7 +560,7 @@
if (! isOpen) throw new Exception("No current query in data reader");
if (i >= fields.Length) throw new IndexOutOfRangeException();
- MySqlValue val = GetFieldValue(i);
+ MySqlValue val = GetFieldValue(i, false);
if (val.IsNull) return DBNull.Value;
// if the column is a date/time, then we return a MySqlDateTime
@@ -599,7 +597,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt16/*'/>
public UInt16 GetUInt16( int index )
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlUInt16)
return ((MySqlUInt16)v).Value;
return Convert.ToUInt16(v.ValueAsObject);
@@ -608,7 +606,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
public UInt32 GetUInt32( int index )
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlUInt32)
return ((MySqlUInt32)v).Value;
return Convert.ToUInt32(v.ValueAsObject);
@@ -617,7 +615,7 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt64/*'/>
public UInt64 GetUInt64( int index )
{
- MySqlValue v = GetFieldValue(index);
+ MySqlValue v = GetFieldValue(index, true);
if (v is MySqlUInt64)
return ((MySqlUInt64)v).Value;
return Convert.ToUInt64(v.ValueAsObject);
@@ -746,7 +744,7 @@
}
- private MySqlValue GetFieldValue(int index)
+ private MySqlValue GetFieldValue(int index, bool checkNull)
{
if (index < 0 || index >= fields.Length)
throw new ArgumentException( "You have specified an invalid column ordinal." );
@@ -754,7 +752,10 @@
try
{
MySqlValue val = currentResult.ReadColumnValue(index);
- if ( readCount == 0 )
+ if (val.IsNull && checkNull)
+ throw new SqlNullValueException();
+
+ if (readCount == 0)
throw new MySqlException("Invalid attempt to access a field before calling Read()");
return val;
| Thread |
|---|
| • Connector/NET commit: r342 - in branches/1.0: TestSuite mysqlclient | rburnett | 18 Sep |