Bug 853 - DataSet/DataAdapter throws an exception on table update
Summary: DataSet/DataAdapter throws an exception on table update
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Data ()
Version: 2.10.x
Hardware: All All
: Normal major
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
: 2214 ()
Depends on:
Blocks:
 
Reported: 2011-09-16 08:45 UTC by Robert Fuszenecker
Modified: 2012-07-05 06:18 UTC (History)
6 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
The project to reproduce the bug (6.10 KB, application/gzip)
2011-09-16 08:45 UTC, Robert Fuszenecker
Details
Bug 853 patch attempt generated from diff (1.46 KB, patch)
2012-07-05 06:16 UTC, Robert Wilkens
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Robert Fuszenecker 2011-09-16 08:45:45 UTC
Created attachment 398 [details]
The project to reproduce the bug

DataSet/DataAdapter throws an exception on table update.
The phenomenon also occurs when I use SQLite3, PostgreSQL, MySQL.

----------------------------------

fuszenecker@neutralino:~$ Projects/DataSetBugReport/DataSetBugReport/bin/Debug/DataSetBugReport.exe 
id: 1, name: "Hello", value: 123 

Unhandled Exception: Mono.Data.Sqlite.SqliteException: Abort due to constraint violation
primus.name may not be NULL
  at Mono.Data.Sqlite.SQLite3.Reset (Mono.Data.Sqlite.SqliteStatement stmt) [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SQLite3.Step (Mono.Data.Sqlite.SqliteStatement stmt) [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SqliteDataReader.NextResult () [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SqliteDataReader..ctor (Mono.Data.Sqlite.SqliteCommand cmd, CommandBehavior behave) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) Mono.Data.Sqlite.SqliteDataReader:.ctor (Mono.Data.Sqlite.SqliteCommand,System.Data.CommandBehavior)
  at Mono.Data.Sqlite.SqliteCommand.ExecuteReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SqliteCommand.ExecuteDbDataReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at System.Data.Common.DbCommand.ExecuteReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at System.Data.Common.DbDataAdapter.Update (System.Data.DataRow[] dataRows, System.Data.Common.DataTableMapping tableMapping) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: Mono.Data.Sqlite.SqliteException: Abort due to constraint violation
primus.name may not be NULL
  at Mono.Data.Sqlite.SQLite3.Reset (Mono.Data.Sqlite.SqliteStatement stmt) [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SQLite3.Step (Mono.Data.Sqlite.SqliteStatement stmt) [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SqliteDataReader.NextResult () [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SqliteDataReader..ctor (Mono.Data.Sqlite.SqliteCommand cmd, CommandBehavior behave) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) Mono.Data.Sqlite.SqliteDataReader:.ctor (Mono.Data.Sqlite.SqliteCommand,System.Data.CommandBehavior)
  at Mono.Data.Sqlite.SqliteCommand.ExecuteReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at Mono.Data.Sqlite.SqliteCommand.ExecuteDbDataReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at System.Data.Common.DbCommand.ExecuteReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader (CommandBehavior behavior) [0x00000] in <filename unknown>:0 
  at System.Data.Common.DbDataAdapter.Update (System.Data.DataRow[] dataRows, System.Data.Common.DataTableMapping tableMapping) [0x00000] in <filename unknown>:0
Comment 1 Robert Fuszenecker 2011-12-01 02:16:12 UTC
*** Bug 2214 has been marked as a duplicate of this bug. ***
Comment 2 Robert Wilkens 2012-05-24 19:16:12 UTC
Worth noting, if you forget the 'not null' constraint in table creation, it seems to succeed at entering a completely blank row into the database on each run without raising an exception.  Of course, i presume a blank row is not what you were after, judging from the code in the sample.  But the insertion of the blank row is why the 'not null' constraint is being violated.

I am not committing to look into this problem further, but i might if time allows, it is interesting.  I hope i am not stepping on anyone's feet here who may already be working on it.
Comment 3 Robert Wilkens 2012-05-24 20:40:52 UTC
I added the below before the update call:
-------------------------------------------------
Console.WriteLine(builder.GetInsertCommand().CommandText);
			
foreach (SqliteParameter param in builder.GetInsertCommand().Parameters){
      Console.WriteLine(param.ParameterName.ToString());
      if (param.Value!=null)
      {
	Console.WriteLine(param.Value.ToString());
      }else{
	Console.WriteLine("<NULL>");
      }
}
--------------------------------------------------

IT appears the insert command from the builder is wrong, which may or may not be because it is being used wrong (I've never used it, i don't know).  The output of the above is:

-------------
INSERT INTO [primus] ([id], [name], [value]) VALUES (@param1, @param2, @param3)
@param1
<NULL>
@param2
<NULL>
@param3
<NULL>
----------------

And that appears to be what is happening, it's inserting an all null row.

This is why the not null constraint is being violated in this bug report.
Comment 4 Robert Wilkens 2012-05-25 11:42:01 UTC
I did a little tracing through the mono source for this...

The null value appears to be coming from this function in DbDataAdapter.cs:

(pay attention to parameters - there are multiple Update functions with unique parameters)

 private int Update (DataTable dataTable, DataTableMapping tableMapping)


Skipping down to relevant code:
     string dsColumnName = parameter.SourceColumn;
     ... note: the column name is right, i verified ....
#if NET_2_0
     if (columnMappings.Contains(dsColumnName)) {
        ....doesn't get here - this is where non-null value would be assigned
     } else {
        ..it always gets here in this sample code:...
        parameter.Value = null;
     }
....
    

Which implies something is wrong with the columnMappings not containing the column names of the table..

I believe the mappings come from (at least when running the sample code attached by bug reporter):

DataTableMappingCollection.cs GetTableMappingBySchemaAction

But i have not had time to trace through that function other than to see it reaches the end of the function and returns there as opposed to a short circuit failure before the end...

I have to step away from this bug soon for probably most of the rest of the day (maybe more tonight), but i did want to document what i found so far in the bug report.
Comment 5 Robert Wilkens 2012-05-25 16:04:02 UTC
I've got a fix for this -- 

Needed to copy and paste some code from another update call path which was missing from this particular path 

(I realize it might be smarter to break this code into a separate function, but i'll leave that for someone to optimize later).  

I'll clean up my debug code, and try to commit this later, and afterwards will attempt to issue a pull request to the main mono branch.
Comment 6 Miguel de Icaza [MSFT] 2012-05-25 21:21:54 UTC
Thanks!
Comment 7 faibistes 2012-07-05 02:19:48 UTC
This bug is a showstopper for Mono. It has driven me insane for ages. Makes me want to punch the stupid computer and shout "Didn't you see that I DID supply a valid parameter?".
Anyway. Where should I download the fix? I'm using 2.10.8.1-1ubuntu2.1 ATM. Shall I expect some specific breakage? Will monodevelop work?
Comment 8 Robert Wilkens 2012-07-05 06:00:27 UTC
https://github.com/mono/mono/commit/6cfebdcea70673e7274583c9837500914529745b 

Would seem to indicate that this fix should be in the github source to mono .. 

It has not, to my knowledge, been backported to 2.10 but i could be wrong and didn't double check.
Comment 9 faibistes 2012-07-05 06:06:32 UTC
Is 2.11 known for breaking everything, being backwards incompatible, not working with Monodevelop and/or drowning babies?
Would it be feasible to patch 2.10 myself and compile&install System.Data only?
Comment 10 Robert Wilkens 2012-07-05 06:11:56 UTC
I'll try to create a patch file if your willing to patch 2.10 yourself and rebuild it, presuming a patch to 2.11 works well enough on 2.10.
Comment 11 Robert Wilkens 2012-07-05 06:16:36 UTC
Created attachment 2154 [details]
Bug 853 patch attempt generated from diff

The attached patch file was from 2.11 (latest github) but it might work unaltered in 2.10 if you want to try to rebuild it yourself.  Alternatively, if you can wait, you can ask Miguel to backport this to 2.10 and be patient until it reaches you via standard ubuntu update channels (which could take months to years).
Comment 12 Robert Wilkens 2012-07-05 06:18:08 UTC
BTW I've never seen a patch on github before but you might have to selet 'raw unified' to get a traditional patchfile out of it.
Comment 13 Robert Wilkens 2012-07-05 06:18:31 UTC
oops i meant bugzilla, not github in that last post.