DataTable.Select(...) CRASHES

  • Thread starter Thread starter Yury Romanov
  • Start date Start date
Y

Yury Romanov

Hello,

DataTable.Select( sFilter ) crashes with "Index was outside the bounds of
the array" exception when:
1. parent table has more columns than child one
2. filter expression apllied to child table addresses to parent column which
has higher order number than columns count in child table.

Repro code snippet:

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("NAME");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );
ds.Relations.Add( rel );
DataRow[] rows = dtChild.Select("Parent.NAME='testname'");
 
Hi,

No, it doesn't depend on column name.
This is BUG in DataTable.Select().
You can rename the column - the same exception.

Just put this repro in a function and run it.

Thanks,
Yury Romanov
 
Bin Song said:
Hi,

It might be the column of "Name", "Name" is a reserved word in SQL.
So try
Change the Column Name to "MainName"
Or
DataRow[] rows = dtChild.Select("Parent.[NAME]='testname'");

Bin Song, MCP


Ported the code to VB.Net and got a different error message which basically is
more explanitory to what is really wrong...

Run-time exception thrown : System.IndexOutOfRangeException - Cannot find
relation 0.
 
In the code snippet you provide below, there is no child column named Name.
If you add one, no worries. Or, change the select criteria to Id instead of
name, you're good to go (although I only have dummy data so I'm not
retrieving much of anything).

Those two tables you created are based on name..there is not Name column
specified in Child but based on the way you call select, its trying to match
columns to no avail.

This works fine:

DataSet ds = new DataSet();

DataTable dtMain = ds.Tables.Add("MAIN_TBL");

DataTable dtChild = ds.Tables.Add("CHILD_TBL");

DataColumn dcMainPK = dtMain.Columns.Add("ID");

dtMain.Columns.Add("NAME");


DataColumn dcChildFK = dtChild.Columns.Add("FK");

DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );

dtChild.Columns.Add("Name");

ds.Relations.Add( rel );

try{

DataRow[] rows = dtChild.Select("Parent.Name='testname'");}

catch(System.Exception ex){Debug.Assert(false, ex.ToString());}

Yury Romanov said:
Hi,

No, it doesn't depend on column name.
This is BUG in DataTable.Select().
You can rename the column - the same exception.

Just put this repro in a function and run it.

Thanks,
Yury Romanov

Bin Song said:
Hi,

It might be the column of "Name", "Name" is a reserved word in SQL.
So try
Change the Column Name to "MainName"
Or
DataRow[] rows = dtChild.Select("Parent.[NAME]='testname'");

Bin Song, MCP
 
Hi,
To avoid confusing NAME column and to show how to reproduce the BUG I have
create two code snippets - one with the crash and another without:

1. The following code ends up with crash:

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );

ds.Relations.Add( rel );
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

2. This code runs well without any problem (thanks to ANOTHER_DUMMY_FIELD ):

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );
ds.Relations.Add( rel );

dtChild.Columns.Add("ANOTHER_DUMMY_FIELD");
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

Thanks,
Yury Romanov
 
Yury:
I responded to this as well. Is there a matching column in the child table?
I think it's the way you are calling it...
 
Hi,
Child table has foreign key column ( "FK" ) related to parent table primary
key column( "PK" ) .
This relation (parent-child, one to many) is "testrelation".
There are no any other relations and I don't need "NAME" or "MYFIELD"
columns duplicated in my child table.
All I want to select is those children whose parent field "MYFIELD" value is
equal to "something".
Therefore, I call select method of child table with the filter
"Parent.MYFIELD='something'".
Since there is only one relation then I don't need to make the filter like
"Parent[(testrelation)].MYFIELD='something'", though It crashes also.

Of course, the workaround is to iterate all children and manually compare
their parent MYFIELD value, and it works fine.
I wanted Select method did it for me, because the filter in the real world
is more complex.

Once again, the problems comes up in certain conditions as in example one
and doesn't as in example two.

Regards,
Yury Romanov



William Ryan eMVP said:
Yury:
I responded to this as well. Is there a matching column in the child table?
I think it's the way you are calling it...
Yury Romanov said:
Hi,
To avoid confusing NAME column and to show how to reproduce the BUG I have
create two code snippets - one with the crash and another without:

1. The following code ends up with crash:

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );

ds.Relations.Add( rel );
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

2. This code runs well without any problem (thanks to ANOTHER_DUMMY_FIELD ):

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );
ds.Relations.Add( rel );

dtChild.Columns.Add("ANOTHER_DUMMY_FIELD");
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

Thanks,
Yury Romanov
 
Yury,

What version of .NET framework are you using? Does this repro on 1.1 .NET
Framework?

Thanks,
Ravi

Yury Romanov said:
Hi,
Child table has foreign key column ( "FK" ) related to parent table
primary
key column( "PK" ) .
This relation (parent-child, one to many) is "testrelation".
There are no any other relations and I don't need "NAME" or "MYFIELD"
columns duplicated in my child table.
All I want to select is those children whose parent field "MYFIELD" value
is
equal to "something".
Therefore, I call select method of child table with the filter
"Parent.MYFIELD='something'".
Since there is only one relation then I don't need to make the filter like
"Parent[(testrelation)].MYFIELD='something'", though It crashes also.

Of course, the workaround is to iterate all children and manually compare
their parent MYFIELD value, and it works fine.
I wanted Select method did it for me, because the filter in the real world
is more complex.

Once again, the problems comes up in certain conditions as in example one
and doesn't as in example two.

Regards,
Yury Romanov



William Ryan eMVP said:
Yury:
I responded to this as well. Is there a matching column in the child table?
I think it's the way you are calling it...
Yury Romanov said:
Hi,
To avoid confusing NAME column and to show how to reproduce the BUG I have
create two code snippets - one with the crash and another without:

1. The following code ends up with crash:

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );

ds.Relations.Add( rel );
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

2. This code runs well without any problem (thanks to ANOTHER_DUMMY_FIELD ):

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );
ds.Relations.Add( rel );

dtChild.Columns.Add("ANOTHER_DUMMY_FIELD");
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

Thanks,
Yury Romanov
 
Yury,

What version of .NET framework are you using? Does this repro on 1.1 .NET
Framework?

Thanks,
Ravi

Yury Romanov said:
Hi,
Child table has foreign key column ( "FK" ) related to parent table
primary
key column( "PK" ) .
This relation (parent-child, one to many) is "testrelation".
There are no any other relations and I don't need "NAME" or "MYFIELD"
columns duplicated in my child table.
All I want to select is those children whose parent field "MYFIELD" value
is
equal to "something".
Therefore, I call select method of child table with the filter
"Parent.MYFIELD='something'".
Since there is only one relation then I don't need to make the filter like
"Parent[(testrelation)].MYFIELD='something'", though It crashes also.

Of course, the workaround is to iterate all children and manually compare
their parent MYFIELD value, and it works fine.
I wanted Select method did it for me, because the filter in the real world
is more complex.

Once again, the problems comes up in certain conditions as in example one
and doesn't as in example two.

Regards,
Yury Romanov



William Ryan eMVP said:
Yury:
I responded to this as well. Is there a matching column in the child table?
I think it's the way you are calling it...
Yury Romanov said:
Hi,
To avoid confusing NAME column and to show how to reproduce the BUG I have
create two code snippets - one with the crash and another without:

1. The following code ends up with crash:

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );

ds.Relations.Add( rel );
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

2. This code runs well without any problem (thanks to ANOTHER_DUMMY_FIELD ):

DataSet ds = new DataSet();
DataTable dtMain = ds.Tables.Add("MAIN_TBL");
DataTable dtChild = ds.Tables.Add("CHILD_TBL");
DataColumn dcMainPK = dtMain.Columns.Add("ID");
dtMain.Columns.Add("MYFIELD");
DataColumn dcChildFK = dtChild.Columns.Add("FK");
DataRelation rel = new DataRelation("testrelation", dcMainPK, dcChildFK );
ds.Relations.Add( rel );

dtChild.Columns.Add("ANOTHER_DUMMY_FIELD");
DataRow[] rows = dtChild.Select("Parent.MYFIELD='something'");

Thanks,
Yury Romanov
 
Ravi said:
What version of .NET framework are you using? Does this repro on 1.1 .NET
Framework?

Yes it does - I tried it and got the same exception.
 
Hi,
Yes, I use 1.1 .Net Framework too.

And here are few lines of call stack dump when exception is fired:

system.data.dll!System.Data.Select.InitCandidateColumns() + 0xc6 bytes
system.data.dll!System.Data.Select.SelectRows() + 0x38 bytes
system.data.dll!System.Data.DataTable.Select(string filterExpression =
"Parent.MYFIELD='something'") + 0x34 bytes
dsreltest.exe!dsreltest.Form1.button2_Click(System.Object sender =
{Text="button2"}, System.EventArgs e = {System.EventArgs}) Line 140 + 0x10
bytes C#
.....

As you can see System.Data.Select.InitCandidateColumns() throws the
exception.

Thanks,
Yury Romanov
 
Back
Top