D
Dallara
Hi
Just found a bug in the System.Data.DataTable.Select() method in ADO.NET.
To reproduce the bug, just create a C# Console application with the code
bellow on the start up class and execute it.
What happens is that in some specific situations when you add some extra
brackets to the filter string, rows that don't match the filter criteria are
selected. If you remove the brackets the select works fine. And it's not a
matter of precedence as all conditions are joined by AND.
In the spike bellow, one of the filter conditions is "Number = 7". This
condition doesn't match any rows in the test table. Even thought, in the
select where extra brackets are added to the filter, 2 rows that match the
other conditions are improperly selected. These rows have Numbers 2 and 3
respectively (not 7).
Thanks,
Dallara
// --------------------------------------
// -- SPIKE TO CATCH THE BUG --
// --------------------------------------
using System;
using System.Data;
namespace AdoTableSelectSpike
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
TestAdoTableSelect();
}
protected static void TestAdoTableSelect()
{
DataTable Table = GetTestTable();
string Condition0 = "Description = 'Type B'";
string Condition1 = "Number = 7";
string Condition2 = "Code = 'B'";
string LessBracketsFilter = String.Format("( {0} and {1} ) and ( {2} )",
Condition0, Condition1, Condition2);
DataRow[] LessBracketsRows = Table.Select(LessBracketsFilter);
WriteResults(LessBracketsRows, LessBracketsFilter, "LESS BRACKETS FILTER
RESULTS");
string ExtraBracketsFilter = String.Format("( (({0})) and (({1})) ) and
( {2} )", Condition0, Condition1, Condition2);
DataRow[] ExtraBracketsRows = Table.Select(ExtraBracketsFilter);
WriteResults(ExtraBracketsRows, ExtraBracketsFilter, "EXTRA BRACKETS
FILTER RESULTS");
}
protected static DataTable GetTestTable()
{
DataTable Table = new DataTable("TestTable");
Table.Columns.Add("Code", typeof(System.String));
Table.Columns.Add("Description", typeof(System.String));
Table.Columns.Add("Number", typeof(System.Int32));
DataRow Row1 = Table.NewRow();
Row1["Code"] = "A";
Row1["Description"] = "Type A";
Row1["Number"] = 1;
Table.Rows.Add(Row1);
DataRow Row2 = Table.NewRow();
Row2["Code"] = "B";
Row2["Description"] = "Type B";
Row2["Number"] = 2;
Table.Rows.Add(Row2);
DataRow Row3 = Table.NewRow();
Row3["Code"] = "B";
Row3["Description"] = "Type B";
Row3["Number"] = 3;
Table.Rows.Add(Row3);
return Table;
}
protected static void WriteResults(DataRow[] Rows, string FilterString,
string ResultsCaption)
{
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine(ResultsCaption);
Console.WriteLine("");
Console.WriteLine(FilterString);
Console.WriteLine("Row Count: " + Rows.Length.ToString());
Console.WriteLine("Code - Number - Description");
Console.WriteLine("---------------------------");
foreach (DataRow Row in Rows)
{
string Line = String.Format(
"{0} - {1} - {2}",
Row["Code"].ToString(),
Row["Number"].ToString(),
Row["Description"].ToString());
Console.WriteLine(Line);
}
Console.WriteLine("");
}
}
}
// --------------------------------------
Just found a bug in the System.Data.DataTable.Select() method in ADO.NET.
To reproduce the bug, just create a C# Console application with the code
bellow on the start up class and execute it.
What happens is that in some specific situations when you add some extra
brackets to the filter string, rows that don't match the filter criteria are
selected. If you remove the brackets the select works fine. And it's not a
matter of precedence as all conditions are joined by AND.
In the spike bellow, one of the filter conditions is "Number = 7". This
condition doesn't match any rows in the test table. Even thought, in the
select where extra brackets are added to the filter, 2 rows that match the
other conditions are improperly selected. These rows have Numbers 2 and 3
respectively (not 7).
Thanks,
Dallara
// --------------------------------------
// -- SPIKE TO CATCH THE BUG --
// --------------------------------------
using System;
using System.Data;
namespace AdoTableSelectSpike
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
TestAdoTableSelect();
}
protected static void TestAdoTableSelect()
{
DataTable Table = GetTestTable();
string Condition0 = "Description = 'Type B'";
string Condition1 = "Number = 7";
string Condition2 = "Code = 'B'";
string LessBracketsFilter = String.Format("( {0} and {1} ) and ( {2} )",
Condition0, Condition1, Condition2);
DataRow[] LessBracketsRows = Table.Select(LessBracketsFilter);
WriteResults(LessBracketsRows, LessBracketsFilter, "LESS BRACKETS FILTER
RESULTS");
string ExtraBracketsFilter = String.Format("( (({0})) and (({1})) ) and
( {2} )", Condition0, Condition1, Condition2);
DataRow[] ExtraBracketsRows = Table.Select(ExtraBracketsFilter);
WriteResults(ExtraBracketsRows, ExtraBracketsFilter, "EXTRA BRACKETS
FILTER RESULTS");
}
protected static DataTable GetTestTable()
{
DataTable Table = new DataTable("TestTable");
Table.Columns.Add("Code", typeof(System.String));
Table.Columns.Add("Description", typeof(System.String));
Table.Columns.Add("Number", typeof(System.Int32));
DataRow Row1 = Table.NewRow();
Row1["Code"] = "A";
Row1["Description"] = "Type A";
Row1["Number"] = 1;
Table.Rows.Add(Row1);
DataRow Row2 = Table.NewRow();
Row2["Code"] = "B";
Row2["Description"] = "Type B";
Row2["Number"] = 2;
Table.Rows.Add(Row2);
DataRow Row3 = Table.NewRow();
Row3["Code"] = "B";
Row3["Description"] = "Type B";
Row3["Number"] = 3;
Table.Rows.Add(Row3);
return Table;
}
protected static void WriteResults(DataRow[] Rows, string FilterString,
string ResultsCaption)
{
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine(ResultsCaption);
Console.WriteLine("");
Console.WriteLine(FilterString);
Console.WriteLine("Row Count: " + Rows.Length.ToString());
Console.WriteLine("Code - Number - Description");
Console.WriteLine("---------------------------");
foreach (DataRow Row in Rows)
{
string Line = String.Format(
"{0} - {1} - {2}",
Row["Code"].ToString(),
Row["Number"].ToString(),
Row["Description"].ToString());
Console.WriteLine(Line);
}
Console.WriteLine("");
}
}
}
// --------------------------------------