DataTable.Select(...) CRASHES

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'");
 
Y

Yury Romanov

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
 
M

Mythran

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.
 
W

William Ryan eMVP

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
 
Y

Yury Romanov

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
 
W

William Ryan eMVP

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...
 
Y

Yury Romanov

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
 
R

Ravi[MSFT]

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
 
R

Ravi[MSFT]

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
 
J

Jon Skeet [C# MVP]

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.
 
Y

Yury Romanov

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
 

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