Does anyone know anything about this BUG?

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("");
}
}
}

// --------------------------------------
 
W

W.G. Ryan eMVP

Dallara:

I'm not sure I follow you - I copied the code below and ran it - and I'm
getting 0 rows selected. When I change the code block to this :
DataRow Row1 = Table.NewRow();

Row1["Code"] = "A";

Row1["Description"] = "Type A";

Row1["Number"] = 1;

Table.Rows.Add(Row1);

I get exactly what I'd expect.


--
W.G. Ryan MVP (Windows Embedded)

TiBA Solutions
www.tibasolutions.com | www.devbuzz.com | www.knowdotnet.com
Dallara said:
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("");
}
}
}

// --------------------------------------
 
D

Dallara

Ok, Ryan. Thanks for your attention.

Do you get 0 rows in which one of the result sets? Because it shows 2 result
sets. One with the expected result and another one, where the extra brackets
were added with the "wrong" result. Just like bellow:


--------------------------------------------------------------------------------------------------------------------------------------
C:\Temp>AdoTableSelectTest


LESS BRACKETS FILTER RESULTS

( Description = 'Type B' and Number = 7 ) and ( Code = 'B' )
Row Count: 0
Code - Number - Description
---------------------------



EXTRA BRACKETS FILTER RESULTS

( ((Description = 'Type B')) and ((Number = 7)) ) and ( Code = 'B' )
Row Count: 2
Code - Number - Description
---------------------------
B - 2 - Type B
B - 3 - Type B


C:\Temp>
--------------------------------------------------------------------------------------------------------------------------------------


Note that the values in the Number column in the 2nd result set are 2 & 3
respectively. But the filter clause says "Number = 7"(???).
If both result sets are returning 0 rows, then I don't know what it is. It
might be that you have a different MDAC or .NET Framework version where this
problem has already been fixed.


Many thanks,
Dalmo







W.G. Ryan eMVP said:
Dallara:

I'm not sure I follow you - I copied the code below and ran it - and I'm
getting 0 rows selected. When I change the code block to this :
DataRow Row1 = Table.NewRow();

Row1["Code"] = "A";

Row1["Description"] = "Type A";

Row1["Number"] = 1;

Table.Rows.Add(Row1);

I get exactly what I'd expect.


--
W.G. Ryan MVP (Windows Embedded)

TiBA Solutions
www.tibasolutions.com | www.devbuzz.com | www.knowdotnet.com
Dallara said:
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("");
}
}
}

// --------------------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top