[Mono-bugs] [Bug 69276][Nor] New - XSD generates wrong code for ForeignKeyConstraints in typed datasets
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Tue, 9 Nov 2004 11:00:28 -0500 (EST)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by martin.voelkle@epfl.ch.
http://bugzilla.ximian.com/show_bug.cgi?id=69276
--- shadow/69276 2004-11-09 11:00:28.000000000 -0500
+++ shadow/69276.tmp.29070 2004-11-09 11:00:28.000000000 -0500
@@ -0,0 +1,176 @@
+Bug#: 69276
+Product: Mono: Compilers
+Version: 1.0
+OS: All
+OS Details:
+Status: NEW
+Resolution:
+Severity:
+Priority: Normal
+Component: XSD
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: martin.voelkle@epfl.ch
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: XSD generates wrong code for ForeignKeyConstraints in typed datasets
+
+Description of Problem:
+When generating a typed dataset from a schema file which contains foreign
+key constraints, the resulting code is wrong.
+
+Steps to reproduce the problem:
+1. Here is a simple schema with 2 relations (foreign key constraints)
+<?xml version="1.0" standalone="yes"?>
+<xs:schema xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
+id="MyDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="MyDataSet" msdata:IsDataSet="true" msdata:Locale="">
+ <xs:complexType>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="Playlists">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="name" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="PlaylistsItems">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="playlist"
+type="xs:string" />
+ <xs:element minOccurs="0" name="position" type="xs:int" />
+ <xs:element minOccurs="0" name="file" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Files">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="name" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+ <xs:unique name="PlaylistsPkey" msdata:PrimaryKey="true">
+ <xs:selector xpath=".//Playlists" />
+ <xs:field xpath="name" />
+ </xs:unique>
+ <xs:unique name="PlaylistsItemsPkey" msdata:PrimaryKey="true">
+ <xs:selector xpath=".//PlaylistsItems" />
+ <xs:field xpath="playlist" />
+ <xs:field xpath="position" />
+ </xs:unique>
+ <xs:unique name="FilesPkey" msdata:PrimaryKey="true">
+ <xs:selector xpath=".//Files" />
+ <xs:field xpath="name" />
+ </xs:unique>
+ <xs:keyref refer="PlaylistsPkey" name="Relation1">
+ <xs:selector xpath=".//PlaylistsItems" />
+ <xs:field xpath="playlist" />
+ </xs:keyref>
+ <xs:keyref refer="FilesPkey" name="Relation2">
+ <xs:selector xpath=".//PlaylistsItems" />
+ <xs:field xpath="file" />
+ </xs:keyref>
+ </xs:element>
+</xs:schema>
+
+2. Generate the dataset
+xsd schema.xsd /dataset
+
+3. Try to use the generated class
+public class MyClass {
+ public static void Main(string[] args) {
+ MyDataSet data = new MyDataSet();
+ }
+}
+
+Actual Results:
+Unhandled Exception: System.ArgumentException: Neither ParentColumns or
+ChildColumns can't be zero length.
+in <0x000af> System.Data.ForeignKeyConstraint:_validateColumns
+(System.Data.DataColumn[],System.Data.DataColumn[])
+in <0x00014> System.Data.ForeignKeyConstraint:_foreignKeyConstraint
+(string,System.Data.DataColumn[],System.Data.DataColumn[])
+in <0x00047> System.Data.ForeignKeyConstraint:.ctor
+(string,System.Data.DataColumn[],System.Data.DataColumn[])
+in <0x003e1> Prometheus.Data:InitializeClass ()
+in <0x00024> Prometheus.Data:.ctor ()
+in <0x00025> Prometheus.Test:Main (string[])
+
+Expected Results:
+No error
+
+How often does this happen?
+Always
+
+Additional Information:
+By looking at the generated file, the problem is here (for Relation1):
+fkc = new System.Data.ForeignKeyConstraint("Relation1", new
+System.Data.DataColumn[] {
+ this.__tablePlaylistsItems.Columns["playlist"],
+ this.__tablePlaylistsItems.Columns["name"]}, new
+System.Data.DataColumn[0]);
+
+and should be
+fkc = new System.Data.ForeignKeyConstraint("Relation1", new
+System.Data.DataColumn[] {
+ this.__tablePlaylistsItems.Columns["name"], new System.Data.DataColumn[]
+{
+ this.__tablePlaylistsItems.Columns["playlist"]});
+
+Looking in mono's source code, I found the error. Here is the patch:
+--- class/System.Data/System.Data/CustomDataClassGenerator.old.cs
+2004-11-09 15:39:48.000000000 +0100
++++ class/System.Data/System.Data/CustomDataClassGenerator.cs 2004-11-09
+15:41:00.000000000 +0100
+@@ -759,12 +759,12 @@ namespace System.Data
+ private void CreateForeignKeyStatements (CodeMemberMethod
+m,ForeignKeyConstraint fkc, string tableField)
+ {
+ ArrayList pcols = new ArrayList ();
+- foreach (DataColumn col in fkc.Columns)
++ foreach (DataColumn col in fkc.RelatedColumns)
+ pcols.Add (IndexerRef (PropRef (FieldRef
+(tableField), "Columns"), Const (col.ColumnName)));
+
+ ArrayList ccols = new ArrayList ();
+- foreach (DataColumn col in fkc.RelatedColumns)
+- pcols.Add (IndexerRef (PropRef (FieldRef
+(tableField), "Columns"), Const (col.ColumnName)));
++ foreach (DataColumn col in fkc.Columns)
++ ccols.Add (IndexerRef (PropRef (FieldRef
+(tableField), "Columns"), Const (col.ColumnName)));
+
+ m.Statements.Add (Let (Local ("fkc"), New (
+ typeof (ForeignKeyConstraint),
+--- class/System.Data/System.Data/CustomDataClassGenerator.old.cs
+2004-11-09 15:39:48.000000000 +0100
++++ class/System.Data/System.Data/CustomDataClassGenerator.cs 2004-11-09
+15:41:00.000000000 +0100
+@@ -759,12 +759,12 @@ namespace System.Data
+ private void CreateForeignKeyStatements (CodeMemberMethod
+m,ForeignKeyConstraint fkc, string tableField)
+ {
+ ArrayList pcols = new ArrayList ();
+- foreach (DataColumn col in fkc.Columns)
++ foreach (DataColumn col in fkc.RelatedColumns)
+ pcols.Add (IndexerRef (PropRef (FieldRef
+(tableField), "Columns"), Const (col.ColumnName)));
+
+ ArrayList ccols = new ArrayList ();
+- foreach (DataColumn col in fkc.RelatedColumns)
+- pcols.Add (IndexerRef (PropRef (FieldRef
+(tableField), "Columns"), Const (col.ColumnName)));
++ foreach (DataColumn col in fkc.Columns)
++ ccols.Add (IndexerRef (PropRef (FieldRef
+(tableField), "Columns"), Const (col.ColumnName)));
+
+ m.Statements.Add (Let (Local ("fkc"), New (
+ typeof (ForeignKeyConstraint),
+
+Yes, the only problem is not only that all the columns were added to the
+same ArrayList, but also that the parent columns are the related ones.